nns: update to the latest version

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2021-09-15 15:42:57 +03:00 committed by Alex Vanin
parent e779f436b2
commit effa9b3863
2 changed files with 55 additions and 13 deletions

View file

@ -1,7 +1,8 @@
name: "NameService" name: "NameService"
supportedstandards: ["NEP-11"] supportedstandards: ["NEP-11"]
safemethods: ["balanceOf", "decimals", "symbol", "totalSupply", "tokensOf", "ownerOf", safemethods: ["balanceOf", "decimals", "symbol", "totalSupply", "tokensOf", "ownerOf",
"tokens", "properties", "roots", "getPrice", "isAvailable", "getRecord", "resolve"] "tokens", "properties", "roots", "getPrice", "isAvailable", "getRecord",
"resolve", "getAllRecords"]
events: events:
- name: Transfer - name: Transfer
parameters: parameters:

View file

@ -66,6 +66,13 @@ const (
millisecondsInYear = 365 * 24 * 3600 * 1000 millisecondsInYear = 365 * 24 * 3600 * 1000
) )
// RecordState is a type that registered entities are saved to.
type RecordState struct {
Name string
Type RecordType
Data string
}
// Update updates NameService contract. // Update updates NameService contract.
func Update(nef []byte, manifest string) { func Update(nef []byte, manifest string) {
checkCommittee() checkCommittee()
@ -353,6 +360,15 @@ func Resolve(name string, typ RecordType) string {
return resolve(ctx, name, typ, 2) return resolve(ctx, name, typ, 2)
} }
// GetAllRecords returns an Iterator with RecordState items for given name.
func GetAllRecords(name string) iterator.Iterator {
tokenID := []byte(tokenIDFromName(name))
ctx := storage.GetReadOnlyContext()
_ = getNameState(ctx, tokenID) // ensure not expired
recordsKey := getRecordsKey(tokenID, name)
return storage.Find(ctx, recordsKey, storage.ValuesOnly|storage.DeserializeValues)
}
// updateBalance updates account's balance and account's tokens. // updateBalance updates account's balance and account's tokens.
func updateBalance(ctx storage.Context, tokenId []byte, acc interop.Hash160, diff int) { func updateBalance(ctx storage.Context, tokenId []byte, acc interop.Hash160, diff int) {
balanceKey := append([]byte{prefixBalance}, acc...) balanceKey := append([]byte{prefixBalance}, acc...)
@ -437,20 +453,35 @@ func putNameStateWithKey(ctx storage.Context, tokenKey []byte, ns NameState) {
// getRecord returns domain record. // getRecord returns domain record.
func getRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType) string { func getRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType) string {
recordKey := getRecordKey(tokenId, name, typ) recordKey := getRecordKey(tokenId, name, typ)
record := storage.Get(ctx, recordKey) recBytes := storage.Get(ctx, recordKey)
return record.(string) if recBytes == nil {
return recBytes.(string) // A hack to actually return NULL.
}
record := std.Deserialize(recBytes.([]byte)).(RecordState)
return record.Data
} }
// putRecord stores domain record. // putRecord stores domain record.
func putRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType, record string) { func putRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType, record string) {
recordKey := getRecordKey(tokenId, name, typ) recordKey := getRecordKey(tokenId, name, typ)
storage.Put(ctx, recordKey, record) rs := RecordState{
Name: name,
Type: typ,
Data: record,
}
recBytes := std.Serialize(rs)
storage.Put(ctx, recordKey, recBytes)
}
// getRecordsKey returns prefix used to store domain records of different types.
func getRecordsKey(tokenId []byte, name string) []byte {
recordKey := append([]byte{prefixRecord}, getTokenKey(tokenId)...)
return append(recordKey, getTokenKey([]byte(name))...)
} }
// getRecordKey returns key used to store domain records. // getRecordKey returns key used to store domain records.
func getRecordKey(tokenId []byte, name string, typ RecordType) []byte { func getRecordKey(tokenId []byte, name string, typ RecordType) []byte {
recordKey := append([]byte{prefixRecord}, getTokenKey(tokenId)...) recordKey := getRecordsKey(tokenId, name)
recordKey = append(recordKey, getTokenKey([]byte(name))...)
return append(recordKey, []byte{byte(typ)}...) return append(recordKey, []byte{byte(typ)}...)
} }
@ -586,8 +617,14 @@ func checkIPv6(data string) bool {
for i, f := range fragments { for i, f := range fragments {
if len(f) == 0 { if len(f) == 0 {
if i == 0 { if i == 0 {
if len(fragments[1]) != 0 {
return false
}
nums[i] = 0 nums[i] = 0
} else if i == l-1 { } else if i == l-1 {
if len(fragments[i-1]) != 0 {
return false
}
nums[7] = 0 nums[7] = 0
} else if hasEmpty { } else if hasEmpty {
return false return false
@ -613,6 +650,9 @@ func checkIPv6(data string) bool {
nums[idx] = n nums[idx] = n
} }
} }
if l < 8 && !hasEmpty {
return false
}
f0 := nums[0] f0 := nums[0]
if f0 < 0x2000 || f0 == 0x2002 || f0 == 0x3ffe || f0 > 0x3fff { // IPv6 Global Unicast https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml if f0 < 0x2000 || f0 == 0x2002 || f0 == 0x3ffe || f0 > 0x3fff { // IPv6 Global Unicast https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
@ -646,10 +686,12 @@ func resolve(ctx storage.Context, name string, typ RecordType, redirect int) str
records := getRecords(ctx, name) records := getRecords(ctx, name)
cname := "" cname := ""
for iterator.Next(records) { for iterator.Next(records) {
r := iterator.Value(records).([]string) r := iterator.Value(records).(struct {
key := []byte(r[0]) key string
value := r[1] rs RecordState
rTyp := key[len(key)-1] })
value := r.rs.Data
rTyp := r.key[len(r.key)-1]
if rTyp == byte(typ) { if rTyp == byte(typ) {
return value return value
} }
@ -668,7 +710,6 @@ func resolve(ctx storage.Context, name string, typ RecordType, redirect int) str
func getRecords(ctx storage.Context, name string) iterator.Iterator { func getRecords(ctx storage.Context, name string) iterator.Iterator {
tokenID := []byte(tokenIDFromName(name)) tokenID := []byte(tokenIDFromName(name))
_ = getNameState(ctx, tokenID) _ = getNameState(ctx, tokenID)
recordsKey := append([]byte{prefixRecord}, getTokenKey(tokenID)...) recordsKey := getRecordsKey(tokenID, name)
recordsKey = append(recordsKey, getTokenKey([]byte(name))...) return storage.Find(ctx, recordsKey, storage.DeserializeValues)
return storage.Find(ctx, recordsKey, storage.None)
} }