Skip to content

Commit 4260555

Browse files
committed
[#266] nns: Keep isAvailable in sync with register
If conflicting records '*.domain' are present on new domain registration, then `isAvailable` should return false for this domain. Ref. f25296b. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
1 parent abc3259 commit 4260555

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

nns/nns_contract.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ func GetPrice() int {
224224

225225
// IsAvailable checks whether the provided domain name is available.
226226
func IsAvailable(name string) bool {
227-
fragments := splitAndCheck(name, false)
227+
fragments := splitAndCheck(name, true)
228228
if fragments == nil {
229229
panic("invalid domain name format")
230230
}
@@ -236,7 +236,25 @@ func IsAvailable(name string) bool {
236236
}
237237
return true
238238
}
239-
return parentExpired(ctx, 0, fragments)
239+
if !parentExpired(ctx, 0, fragments) {
240+
return false
241+
}
242+
return len(getParentConflictingRecord(ctx, name, fragments)) == 0
243+
}
244+
245+
func getParentConflictingRecord(ctx storage.Context, name string, fragments []string) string {
246+
parentKey := getTokenKey([]byte(name[len(fragments[0])+1:]))
247+
parentRecKey := append([]byte{prefixRecord}, parentKey...)
248+
it := storage.Find(ctx, parentRecKey, storage.ValuesOnly|storage.DeserializeValues)
249+
suffix := []byte(name)
250+
for iterator.Next(it) {
251+
r := iterator.Value(it).(RecordState)
252+
ind := std.MemorySearchLastIndex([]byte(r.Name), suffix, len(r.Name))
253+
if ind > 0 && ind+len(suffix) == len(r.Name) {
254+
return r.Name
255+
}
256+
}
257+
return ""
240258
}
241259

242260
// parentExpired returns true if any domain from fragments doesn't exist or is expired.
@@ -290,15 +308,8 @@ func Register(name string, owner interop.Hash160, email string, refresh, retry,
290308
ns := std.Deserialize(nsBytes.([]byte)).(NameState)
291309
ns.checkAdmin()
292310

293-
parentRecKey := append([]byte{prefixRecord}, parentKey...)
294-
it := storage.Find(ctx, parentRecKey, storage.ValuesOnly|storage.DeserializeValues)
295-
suffix := []byte(name)
296-
for iterator.Next(it) {
297-
r := iterator.Value(it).(RecordState)
298-
ind := std.MemorySearchLastIndex([]byte(r.Name), suffix, len(r.Name))
299-
if ind > 0 && ind+len(suffix) == len(r.Name) {
300-
panic("parent domain has conflicting records: " + r.Name)
301-
}
311+
if conflict := getParentConflictingRecord(ctx, name, fragments); len(conflict) != 0 {
312+
panic("parent domain has conflicting records: " + conflict)
302313
}
303314
}
304315

tests/nns_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,13 @@ func TestNNSRegisterMulti(t *testing.T) {
178178
"another.fs.neo.com", int64(nns.A), "4.3.2.1")
179179

180180
c2 = c.WithSigners(acc, acc2)
181+
c2.Invoke(t, stackitem.NewBool(false), "isAvailable", "mainnet.fs.neo.com")
181182
c2.InvokeFail(t, "parent domain has conflicting records: something.mainnet.fs.neo.com",
182183
"register", args...)
183184

184185
c1.Invoke(t, stackitem.Null{}, "deleteRecords",
185186
"something.mainnet.fs.neo.com", int64(nns.A))
187+
c2.Invoke(t, stackitem.NewBool(true), "isAvailable", "mainnet.fs.neo.com")
186188
c2.Invoke(t, true, "register", args...)
187189

188190
c2 = c.WithSigners(acc2)

0 commit comments

Comments
 (0)