From 03b6f0479de853dd9813081a24b2625dc60575b7 Mon Sep 17 00:00:00 2001 From: Alexander Chuprov Date: Tue, 17 Sep 2024 21:55:26 +0300 Subject: [PATCH] [#114] nns: Restrict 'DeleteDomain' to delete domains with subdomains Signed-off-by: Alexander Chuprov --- nns/nns_contract.go | 24 ++++++++++++++++++------ tests/nns_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/nns/nns_contract.go b/nns/nns_contract.go index 72205f5..cced35f 100644 --- a/nns/nns_contract.go +++ b/nns/nns_contract.go @@ -565,13 +565,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) @@ -581,7 +593,7 @@ 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) runtime.Notify("DeleteDomain", name) } diff --git a/tests/nns_test.go b/tests/nns_test.go index 6c111b0..5421efc 100644 --- a/tests/nns_test.go +++ b/tests/nns_test.go @@ -189,6 +189,38 @@ 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") +} + func TestGlobalDomain(t *testing.T) { c := newNNSInvoker(t, false)