diff --git a/nns/nns_contract.go b/nns/nns_contract.go index 646b62f..7396cc3 100644 --- a/nns/nns_contract.go +++ b/nns/nns_contract.go @@ -578,13 +578,25 @@ func DeleteDomain(name string) { } func deleteDomain(ctx storage.Context, name string) { - nameKey := append([]byte{prefixName}, getTokenKey([]byte(name))...) - tldBytes := storage.Get(ctx, nameKey) - if tldBytes == nil { - return + it := Tokens() + for iterator.Next(it) { + domain := iterator.Value(it) + if std.MemorySearch([]byte(domain.(string)), []byte(name)) > 0 { + panic("can't delete a domain that has subdomains") + } } - globalDomainRaw := storage.Get(ctx, append([]byte{prefixGlobalDomain}, getTokenKey([]byte(name))...)) + nsKey := append([]byte{prefixName}, getTokenKey([]byte(name))...) + nsRaw := storage.Get(ctx, nsKey) + if nsRaw == nil { + panic("domain not found") + } + + ns := std.Deserialize(nsRaw.([]byte)).(NameState) + ns.checkAdmin() + + globalNSKey := append([]byte{prefixGlobalDomain}, getTokenKey([]byte(name))...) + globalDomainRaw := storage.Get(ctx, globalNSKey) globalDomain := globalDomainRaw.(string) if globalDomainRaw != nil && globalDomain != "" { deleteDomain(ctx, globalDomain) @@ -594,7 +606,8 @@ func deleteDomain(ctx storage.Context, name string) { deleteRecords(ctx, name, TXT) deleteRecords(ctx, name, A) deleteRecords(ctx, name, AAAA) - storage.Delete(ctx, nameKey) + storage.Delete(ctx, nsKey) + storage.Delete(ctx, append([]byte{prefixRoot}, []byte(name)...)) runtime.Notify("DeleteDomain", name) } diff --git a/tests/nns_test.go b/tests/nns_test.go index 9747669..3e2dcf6 100644 --- a/tests/nns_test.go +++ b/tests/nns_test.go @@ -230,6 +230,44 @@ func TestNNSRegister(t *testing.T) { c.InvokeFail(t, "token not found", "getRecords", "testdomain.com", int64(nns.SOA)) } +func TestDeleteDomain(t *testing.T) { + c := newNNSInvoker(t, false) + + acc1 := c.NewAccount(t) + c1 := c.WithSigners(c.Committee, acc1) + + acc2 := c.NewAccount(t) + c2 := c.WithSigners(c.Committee, acc2) + c1.Invoke(t, true, "register", + "com", acc1.ScriptHash(), + "myemail@frostfs.info", defaultRefresh, defaultRetry, defaultExpire, defaultTTL) + + c1.Invoke(t, true, "register", + "testdomain.com", acc1.ScriptHash(), + "myemail@frostfs.info", defaultRefresh, defaultRetry, defaultExpire, defaultTTL) + + c1.Invoke(t, true, "register", + "domik.testdomain.com", acc1.ScriptHash(), + "myemail@frostfs.info", defaultRefresh, defaultRetry, defaultExpire, defaultTTL) + + c1.InvokeFail(t, "domain not found", "deleteDomain", "ru") + c1.InvokeFail(t, "can't delete a domain that has subdomains", "deleteDomain", "testdomain.com") + c1.Invoke(t, stackitem.Null{}, "deleteDomain", "domik.testdomain.com") + c1.Invoke(t, stackitem.Null{}, "deleteDomain", "testdomain.com") + + c1.Invoke(t, true, "register", + "cn", acc1.ScriptHash(), + "myemail@frostfs.info", defaultRefresh, defaultRetry, defaultExpire, defaultTTL) + + c2.InvokeFail(t, "not witnessed by admin", "deleteDomain", "cn") + + c1.Invoke(t, stackitem.Null{}, "deleteDomain", "cn") + + c2.Invoke(t, true, "register", + "cn", acc2.ScriptHash(), + "myemail@frostfs.info", defaultRefresh, defaultRetry, defaultExpire, defaultTTL) +} + func TestGlobalDomain(t *testing.T) { c := newNNSInvoker(t, false)