nns: Mention domain in panic messages #98
2 changed files with 47 additions and 25 deletions
|
@ -65,6 +65,8 @@ const (
|
||||||
defaultRegisterPrice = 10_0000_0000
|
defaultRegisterPrice = 10_0000_0000
|
||||||
// millisecondsInYear is amount of milliseconds per year.
|
// millisecondsInYear is amount of milliseconds per year.
|
||||||
millisecondsInYear = int64(365 * 24 * 3600 * 1000)
|
millisecondsInYear = int64(365 * 24 * 3600 * 1000)
|
||||||
|
// errInvalidDomainName is an error message for invalid domain name format.
|
||||||
|
errInvalidDomainName = "invalid domain name format"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RecordState is a type that registered entities are saved to.
|
// RecordState is a type that registered entities are saved to.
|
||||||
|
@ -220,9 +222,6 @@ func GetPrice() int {
|
||||||
// IsAvailable checks whether the provided domain name is available.
|
// IsAvailable checks whether the provided domain name is available.
|
||||||
func IsAvailable(name string) bool {
|
func IsAvailable(name string) bool {
|
||||||
fragments := splitAndCheck(name)
|
fragments := splitAndCheck(name)
|
||||||
if fragments == nil {
|
|
||||||
panic("invalid domain name format")
|
|
||||||
}
|
|
||||||
ctx := storage.GetReadOnlyContext()
|
ctx := storage.GetReadOnlyContext()
|
||||||
l := len(fragments)
|
l := len(fragments)
|
||||||
if storage.Get(ctx, append([]byte{prefixRoot}, []byte(fragments[l-1])...)) == nil {
|
if storage.Get(ctx, append([]byte{prefixRoot}, []byte(fragments[l-1])...)) == nil {
|
||||||
|
@ -267,10 +266,6 @@ func parentExpired(ctx storage.Context, fragments []string) string {
|
||||||
// Register registers a new domain with the specified owner and name if it's available.
|
// Register registers a new domain with the specified owner and name if it's available.
|
||||||
func Register(name string, owner interop.Hash160, email string, refresh, retry, expire, ttl int) bool {
|
func Register(name string, owner interop.Hash160, email string, refresh, retry, expire, ttl int) bool {
|
||||||
fragments := splitAndCheck(name)
|
fragments := splitAndCheck(name)
|
||||||
if fragments == nil {
|
|
||||||
panic("invalid domain name format")
|
|
||||||
}
|
|
||||||
|
|
||||||
l := len(fragments)
|
l := len(fragments)
|
||||||
tldKey := append([]byte{prefixRoot}, []byte(fragments[l-1])...)
|
tldKey := append([]byte{prefixRoot}, []byte(fragments[l-1])...)
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
|
@ -339,9 +334,7 @@ func Register(name string, owner interop.Hash160, email string, refresh, retry,
|
||||||
|
|
||||||
// Renew increases domain expiration date.
|
// Renew increases domain expiration date.
|
||||||
func Renew(name string) int64 {
|
func Renew(name string) int64 {
|
||||||
if len(name) > maxDomainNameLength {
|
checkDomainNameLength(name)
|
||||||
panic("invalid domain name format")
|
|
||||||
}
|
|
||||||
runtime.BurnGas(GetPrice())
|
runtime.BurnGas(GetPrice())
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
ns := getNameState(ctx, []byte(name))
|
ns := getNameState(ctx, []byte(name))
|
||||||
|
@ -353,9 +346,7 @@ func Renew(name string) int64 {
|
||||||
|
|
||||||
// UpdateSOA updates soa record.
|
// UpdateSOA updates soa record.
|
||||||
func UpdateSOA(name, email string, refresh, retry, expire, ttl int) {
|
func UpdateSOA(name, email string, refresh, retry, expire, ttl int) {
|
||||||
if len(name) > maxDomainNameLength {
|
checkDomainNameLength(name)
|
||||||
panic("invalid domain name format")
|
|
||||||
}
|
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
ns := getNameState(ctx, []byte(name))
|
ns := getNameState(ctx, []byte(name))
|
||||||
ns.checkAdmin()
|
ns.checkAdmin()
|
||||||
|
@ -364,9 +355,7 @@ func UpdateSOA(name, email string, refresh, retry, expire, ttl int) {
|
||||||
|
|
||||||
// SetAdmin updates domain admin.
|
// SetAdmin updates domain admin.
|
||||||
func SetAdmin(name string, admin interop.Hash160) {
|
func SetAdmin(name string, admin interop.Hash160) {
|
||||||
if len(name) > maxDomainNameLength {
|
checkDomainNameLength(name)
|
||||||
panic("invalid domain name format")
|
|
||||||
}
|
|
||||||
if admin != nil && !runtime.CheckWitness(admin) {
|
if admin != nil && !runtime.CheckWitness(admin) {
|
||||||
panic("not witnessed by admin")
|
panic("not witnessed by admin")
|
||||||
}
|
}
|
||||||
|
@ -722,20 +711,28 @@ func isAlNum(c uint8) bool {
|
||||||
|
|
||||||
// splitAndCheck splits domain name into parts and validates it.
|
// splitAndCheck splits domain name into parts and validates it.
|
||||||
func splitAndCheck(name string) []string {
|
func splitAndCheck(name string) []string {
|
||||||
l := len(name)
|
checkDomainNameLength(name)
|
||||||
if l < minDomainNameLength || maxDomainNameLength < l {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
fragments := std.StringSplit(name, ".")
|
fragments := std.StringSplit(name, ".")
|
||||||
l = len(fragments)
|
l := len(fragments)
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
if !checkFragment(fragments[i], i == l-1) {
|
if !checkFragment(fragments[i], i == l-1) {
|
||||||
return nil
|
panic(errInvalidDomainName + " '" + name + "': invalid fragment '" + fragments[i] + "'")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fragments
|
return fragments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkDomainNameLength panics if domain name length is out of boundaries.
|
||||||
|
func checkDomainNameLength(name string) {
|
||||||
|
l := len(name)
|
||||||
|
if l > maxDomainNameLength {
|
||||||
|
panic(errInvalidDomainName + " '" + name + "': domain name too long: got = " + std.Itoa(l, 10) + ", max = " + std.Itoa(maxDomainNameLength, 10))
|
||||||
|
}
|
||||||
|
if l < minDomainNameLength {
|
||||||
|
panic(errInvalidDomainName + " '" + name + "': domain name too short: got = " + std.Itoa(l, 10) + ", min = " + std.Itoa(minDomainNameLength, 10))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// checkIPv4 checks record on IPv4 compliance.
|
// checkIPv4 checks record on IPv4 compliance.
|
||||||
func checkIPv4(data string) bool {
|
func checkIPv4(data string) bool {
|
||||||
l := len(data)
|
l := len(data)
|
||||||
|
@ -849,9 +846,6 @@ func checkIPv6(data string) bool {
|
||||||
// tokenIDFromName returns token ID (domain.root) from the provided name.
|
// tokenIDFromName returns token ID (domain.root) from the provided name.
|
||||||
func tokenIDFromName(name string) string {
|
func tokenIDFromName(name string) string {
|
||||||
fragments := splitAndCheck(name)
|
fragments := splitAndCheck(name)
|
||||||
if fragments == nil {
|
|
||||||
panic("invalid domain name format")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := storage.GetReadOnlyContext()
|
ctx := storage.GetReadOnlyContext()
|
||||||
sum := 0
|
sum := 0
|
||||||
|
|
|
@ -54,6 +54,9 @@ func TestNNSRegisterTLD(t *testing.T) {
|
||||||
c.InvokeFail(t, "invalid domain name format", "register",
|
c.InvokeFail(t, "invalid domain name format", "register",
|
||||||
"0com", c.CommitteeHash,
|
"0com", c.CommitteeHash,
|
||||||
"email@frostfs.info", refresh, retry, expire, ttl)
|
"email@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
c.InvokeFail(t, "invalid fragment '0com'", "register",
|
||||||
|
"0com", c.CommitteeHash,
|
||||||
|
"email@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
|
||||||
acc := c.NewAccount(t)
|
acc := c.NewAccount(t)
|
||||||
cAcc := c.WithSigners(acc)
|
cAcc := c.WithSigners(acc)
|
||||||
|
@ -69,6 +72,12 @@ func TestNNSRegisterTLD(t *testing.T) {
|
||||||
c.InvokeFail(t, "invalid domain name format", "register",
|
c.InvokeFail(t, "invalid domain name format", "register",
|
||||||
"x", c.CommitteeHash,
|
"x", c.CommitteeHash,
|
||||||
"email@frostfs.info", refresh, retry, expire, ttl)
|
"email@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
c.InvokeFail(t, "domain name too short", "register",
|
||||||
|
"x", c.CommitteeHash,
|
||||||
|
"email@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
c.InvokeFail(t, "domain name too long", "register",
|
||||||
|
getTooLongDomainName(255), c.CommitteeHash,
|
||||||
|
"email@frostfs.info", refresh, retry, expire, ttl)
|
||||||
})
|
})
|
||||||
|
|
||||||
c.Invoke(t, true, "register",
|
c.Invoke(t, true, "register",
|
||||||
|
@ -101,9 +110,17 @@ func TestNNSRegister(t *testing.T) {
|
||||||
c3.InvokeFail(t, "invalid domain name format", "register",
|
c3.InvokeFail(t, "invalid domain name format", "register",
|
||||||
"-testdomain.com", acc.ScriptHash(),
|
"-testdomain.com", acc.ScriptHash(),
|
||||||
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
c3.InvokeFail(t, "invalid fragment '-testdomain'", "register",
|
||||||
|
"-testdomain.com", acc.ScriptHash(),
|
||||||
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
|
||||||
c3.InvokeFail(t, "invalid domain name format", "register",
|
c3.InvokeFail(t, "invalid domain name format", "register",
|
||||||
"testdomain-.com", acc.ScriptHash(),
|
"testdomain-.com", acc.ScriptHash(),
|
||||||
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
c3.InvokeFail(t, "invalid fragment 'testdomain-'", "register",
|
||||||
|
"testdomain-.com", acc.ScriptHash(),
|
||||||
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
|
||||||
c3.Invoke(t, true, "register",
|
c3.Invoke(t, true, "register",
|
||||||
"test-domain.com", acc.ScriptHash(),
|
"test-domain.com", acc.ScriptHash(),
|
||||||
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
@ -358,6 +375,8 @@ func TestNNSIsAvailable(t *testing.T) {
|
||||||
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
c.Invoke(t, false, "isAvailable", "dom.domain.com")
|
c.Invoke(t, false, "isAvailable", "dom.domain.com")
|
||||||
c.Invoke(t, true, "isAvailable", "dom.dom.domain.com")
|
c.Invoke(t, true, "isAvailable", "dom.dom.domain.com")
|
||||||
|
|
||||||
|
c.InvokeFail(t, "domain name too long", "isAvailable", getTooLongDomainName(255))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNNSRenew(t *testing.T) {
|
func TestNNSRenew(t *testing.T) {
|
||||||
|
@ -382,6 +401,7 @@ func TestNNSRenew(t *testing.T) {
|
||||||
{Key: stackitem.Make("expiration"), Value: stackitem.Make(ts)},
|
{Key: stackitem.Make("expiration"), Value: stackitem.Make(ts)},
|
||||||
})
|
})
|
||||||
cAcc.Invoke(t, expected, "properties", "testdomain.com")
|
cAcc.Invoke(t, expected, "properties", "testdomain.com")
|
||||||
|
c.InvokeFail(t, "domain name too long", "renew", getTooLongDomainName(255))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNNSResolve(t *testing.T) {
|
func TestNNSResolve(t *testing.T) {
|
||||||
|
@ -431,3 +451,11 @@ func TestNNSAndProxy(t *testing.T) {
|
||||||
checkBalance(t, c.CommitteeHash, 1)
|
checkBalance(t, c.CommitteeHash, 1)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTooLongDomainName(max int) (res string) {
|
||||||
|
for len(res) < max {
|
||||||
|
res += "dom."
|
||||||
|
}
|
||||||
|
res += "com"
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue