2022-03-23 19:21:07 +00:00
package nns_test
2021-10-23 11:28:25 +00:00
import (
2022-09-09 16:36:13 +00:00
"math/big"
"strconv"
2021-10-23 11:28:25 +00:00
"strings"
"testing"
nns "github.com/nspcc-dev/neo-go/examples/nft-nd-nns"
"github.com/nspcc-dev/neo-go/pkg/compiler"
2021-10-23 12:36:26 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
2021-10-23 11:28:25 +00:00
"github.com/nspcc-dev/neo-go/pkg/neotest"
"github.com/nspcc-dev/neo-go/pkg/neotest/chain"
2022-09-09 16:35:54 +00:00
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
2021-10-23 11:28:25 +00:00
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require"
)
2022-09-15 19:27:02 +00:00
const (
millisecondsInYear = 365 * 24 * 3600 * 1000
maxDomainNameFragmentLength = 63
)
func newNSClient ( t * testing . T , registerComTLD bool ) * neotest . ContractInvoker {
2021-10-23 11:28:25 +00:00
bc , acc := chain . NewSingle ( t )
2021-11-03 12:22:08 +00:00
e := neotest . NewExecutor ( t , bc , acc , acc )
2022-09-15 19:27:02 +00:00
ctr := neotest . CompileFile ( t , e . CommitteeHash , "." , "nns.yml" )
e . DeployContract ( t , ctr , nil )
2021-10-23 11:28:25 +00:00
2022-09-15 19:27:02 +00:00
c := e . CommitteeInvoker ( ctr . Hash )
if registerComTLD {
// Set expiration big enough to pass all tests.
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
c . Invoke ( t , true , "register" , "com" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
}
return c
2021-10-23 11:28:25 +00:00
}
2021-10-23 12:36:26 +00:00
func TestNameService_Price ( t * testing . T ) {
const (
minPrice = int64 ( 0 )
maxPrice = int64 ( 10000_00000000 )
)
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , false )
2021-10-23 12:36:26 +00:00
t . Run ( "set, not signed by committee" , func ( t * testing . T ) {
acc := c . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cAcc := c . WithSigners ( acc )
2021-10-23 12:36:26 +00:00
cAcc . InvokeFail ( t , "not witnessed by committee" , "setPrice" , minPrice + 1 )
} )
t . Run ( "get, default value" , func ( t * testing . T ) {
c . Invoke ( t , defaultNameServiceDomainPrice , "getPrice" )
} )
t . Run ( "set, too small value" , func ( t * testing . T ) {
c . InvokeFail ( t , "The price is out of range." , "setPrice" , minPrice - 1 )
} )
t . Run ( "set, too large value" , func ( t * testing . T ) {
c . InvokeFail ( t , "The price is out of range." , "setPrice" , maxPrice + 1 )
} )
t . Run ( "set, success" , func ( t * testing . T ) {
txSet := c . PrepareInvoke ( t , "setPrice" , int64 ( defaultNameServiceDomainPrice + 1 ) )
txGet := c . PrepareInvoke ( t , "getPrice" )
c . AddBlockCheckHalt ( t , txSet , txGet )
c . CheckHalt ( t , txSet . Hash ( ) , stackitem . Null { } )
c . CheckHalt ( t , txGet . Hash ( ) , stackitem . Make ( defaultNameServiceDomainPrice + 1 ) )
// Get in the next block.
c . Invoke ( t , stackitem . Make ( defaultNameServiceDomainPrice + 1 ) , "getPrice" )
} )
}
2021-10-23 11:28:25 +00:00
func TestNonfungible ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , false )
2021-10-23 11:28:25 +00:00
2021-11-03 10:44:46 +00:00
c . Signers = [ ] neotest . Signer { c . NewAccount ( t ) }
2021-10-23 12:36:26 +00:00
c . Invoke ( t , "NNS" , "symbol" )
c . Invoke ( t , 0 , "decimals" )
c . Invoke ( t , 0 , "totalSupply" )
2021-10-23 11:28:25 +00:00
}
2022-09-05 14:30:47 +00:00
func TestRegisterTLD ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , false )
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 11:28:25 +00:00
t . Run ( "invalid format" , func ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c . InvokeFail ( t , "invalid domain name format" , "register" , "" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 11:28:25 +00:00
} )
t . Run ( "not signed by committee" , func ( t * testing . T ) {
2021-10-23 12:36:26 +00:00
acc := c . NewAccount ( t )
2021-11-03 10:44:46 +00:00
c := c . WithSigners ( acc )
2022-09-15 19:27:02 +00:00
c . InvokeFail ( t , "not witnessed by committee" , "register" , "some" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 11:28:25 +00:00
} )
2022-09-15 19:27:02 +00:00
c . Invoke ( t , true , "register" , "some" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 11:28:25 +00:00
t . Run ( "already exists" , func ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c . InvokeFail ( t , "TLD already exists" , "register" , "some" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 11:28:25 +00:00
} )
}
func TestExpiration ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2021-10-23 12:36:26 +00:00
e := c . Executor
2021-10-23 11:28:25 +00:00
bc := e . Chain
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 11:28:25 +00:00
acc := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cAcc := c . WithSigners ( acc )
2022-09-05 14:30:54 +00:00
cAccCommittee := c . WithSigners ( acc , c . Committee ) // acc + committee signers for ".com"'s subdomains registration
2021-10-23 11:28:25 +00:00
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "first.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "first.com" , int64 ( nns . TXT ) , "sometext" )
2021-10-23 11:28:25 +00:00
b1 := e . TopBlock ( t )
2022-09-15 19:27:02 +00:00
tx := cAccCommittee . PrepareInvoke ( t , "register" , "second.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2021-10-23 12:36:26 +00:00
b2 := e . NewUnsignedBlock ( t , tx )
2021-10-23 11:28:25 +00:00
b2 . Index = b1 . Index + 1
b2 . PrevHash = b1 . Hash ( )
b2 . Timestamp = b1 . Timestamp + 10000
require . NoError ( t , bc . AddBlock ( e . SignBlock ( b2 ) ) )
2022-09-05 14:30:47 +00:00
e . CheckHalt ( t , tx . Hash ( ) , stackitem . NewBool ( true ) )
2021-10-23 11:28:25 +00:00
2021-10-23 12:36:26 +00:00
tx = cAcc . PrepareInvoke ( t , "isAvailable" , "first.com" )
b3 := e . NewUnsignedBlock ( t , tx )
2021-10-23 11:28:25 +00:00
b3 . Index = b2 . Index + 1
b3 . PrevHash = b2 . Hash ( )
2022-09-15 19:27:02 +00:00
b3 . Timestamp = b1 . Timestamp + ( uint64 ( expire ) * 1000 + 1 )
2021-10-23 11:28:25 +00:00
require . NoError ( t , bc . AddBlock ( e . SignBlock ( b3 ) ) )
2022-09-05 14:30:47 +00:00
e . CheckHalt ( t , tx . Hash ( ) , stackitem . NewBool ( true ) ) // "first.com" has been expired
2021-10-23 11:28:25 +00:00
2021-10-23 12:36:26 +00:00
tx = cAcc . PrepareInvoke ( t , "isAvailable" , "second.com" )
b4 := e . NewUnsignedBlock ( t , tx )
2021-10-23 11:28:25 +00:00
b4 . Index = b3 . Index + 1
b4 . PrevHash = b3 . Hash ( )
b4 . Timestamp = b3 . Timestamp + 1000
require . NoError ( t , bc . AddBlock ( e . SignBlock ( b4 ) ) )
2022-09-05 14:30:47 +00:00
e . CheckHalt ( t , tx . Hash ( ) , stackitem . NewBool ( true ) ) // TLD "com" has been expired
2021-10-23 11:28:25 +00:00
2022-09-09 16:36:13 +00:00
tx = cAcc . PrepareInvoke ( t , "getRecords" , "first.com" , int64 ( nns . TXT ) )
2021-10-23 12:36:26 +00:00
b5 := e . NewUnsignedBlock ( t , tx )
2021-10-23 11:28:25 +00:00
b5 . Index = b4 . Index + 1
b5 . PrevHash = b4 . Hash ( )
b5 . Timestamp = b4 . Timestamp + 1000
require . NoError ( t , bc . AddBlock ( e . SignBlock ( b5 ) ) )
e . CheckFault ( t , tx . Hash ( ) , "name has expired" )
2022-07-13 15:54:19 +00:00
2022-09-05 14:30:47 +00:00
// TODO: According to the new code, we can't re-register expired "com" TLD, because it's already registered; at the
// same time we can't renew it because it's already expired. We likely need to change this logic in the contract and
// after that uncomment the lines below.
// c.Invoke(t, true, "renew", "com")
// cAcc.Invoke(t, true, "register", "first.com", acc.ScriptHash()) // Re-register.
// cAcc.Invoke(t, stackitem.Null{}, "resolve", "first.com", int64(nns.TXT))
2021-10-23 11:28:25 +00:00
}
func TestRegisterAndRenew ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , false )
2021-10-23 12:36:26 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 12:36:26 +00:00
2022-09-05 14:30:47 +00:00
c . InvokeFail ( t , "TLD not found" , "isAvailable" , "neo.com" )
2022-09-15 19:27:02 +00:00
c . Invoke ( t , true , "register" , "org" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
2022-09-05 14:30:47 +00:00
c . InvokeFail ( t , "TLD not found" , "isAvailable" , "neo.com" )
2022-09-15 19:27:02 +00:00
c . Invoke ( t , true , "register" , "com" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 12:36:26 +00:00
c . Invoke ( t , true , "isAvailable" , "neo.com" )
2022-09-15 19:27:02 +00:00
c . InvokeWithFeeFail ( t , "GAS limit exceeded" , defaultNameServiceSysfee , "register" , "neo.org" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2022-09-15 19:27:07 +00:00
c . InvokeFail ( t , "one of the parent domains is not registered" , "register" , "docs.neo.org" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2022-09-15 19:27:02 +00:00
c . InvokeFail ( t , "invalid domain name format" , "register" , "\nneo.com'" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
c . InvokeFail ( t , "invalid domain name format" , "register" , "neo.com\n" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
c . InvokeWithFeeFail ( t , "GAS limit exceeded" , defaultNameServiceSysfee , "register" , "neo.org" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
c . InvokeWithFeeFail ( t , "GAS limit exceeded" , defaultNameServiceDomainPrice , "register" , "neo.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2022-09-05 14:30:38 +00:00
var maxLenFragment string
for i := 0 ; i < maxDomainNameFragmentLength ; i ++ {
maxLenFragment += "q"
}
c . Invoke ( t , true , "isAvailable" , maxLenFragment + ".com" )
2022-09-15 19:27:02 +00:00
c . Invoke ( t , true , "register" , maxLenFragment + ".com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
c . InvokeFail ( t , "invalid domain name format" , "register" , maxLenFragment + "q.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 12:36:26 +00:00
c . Invoke ( t , true , "isAvailable" , "neo.com" )
2022-09-05 14:30:47 +00:00
c . Invoke ( t , 3 , "balanceOf" , e . CommitteeHash ) // org, com, qqq...qqq.com
2022-09-15 19:27:02 +00:00
c . Invoke ( t , true , "register" , "neo.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 11:28:25 +00:00
topBlock := e . TopBlock ( t )
2022-09-15 19:27:02 +00:00
expectedExpiration := topBlock . Timestamp + uint64 ( expire * 1000 )
c . Invoke ( t , false , "register" , "neo.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 12:36:26 +00:00
c . Invoke ( t , false , "isAvailable" , "neo.com" )
2021-10-23 11:28:25 +00:00
2022-09-05 14:30:43 +00:00
t . Run ( "domain names with hyphen" , func ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c . InvokeFail ( t , "invalid domain name format" , "register" , "-testdomain.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
c . InvokeFail ( t , "invalid domain name format" , "register" , "testdomain-.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
c . Invoke ( t , true , "register" , "test-domain.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2022-09-05 14:30:43 +00:00
} )
2021-10-23 11:28:25 +00:00
props := stackitem . NewMap ( )
props . Add ( stackitem . Make ( "name" ) , stackitem . Make ( "neo.com" ) )
props . Add ( stackitem . Make ( "expiration" ) , stackitem . Make ( expectedExpiration ) )
2022-09-05 14:31:03 +00:00
props . Add ( stackitem . Make ( "admin" ) , stackitem . Null { } ) // no admin was set
2021-10-23 12:36:26 +00:00
c . Invoke ( t , props , "properties" , "neo.com" )
2022-09-05 14:30:47 +00:00
c . Invoke ( t , 5 , "balanceOf" , e . CommitteeHash ) // org, com, qqq...qqq.com, neo.com, test-domain.com
2021-10-23 12:36:26 +00:00
c . Invoke ( t , e . CommitteeHash . BytesBE ( ) , "ownerOf" , [ ] byte ( "neo.com" ) )
2021-10-23 11:28:25 +00:00
t . Run ( "invalid token ID" , func ( t * testing . T ) {
2021-10-23 12:36:26 +00:00
c . InvokeFail ( t , "token not found" , "properties" , "not.exists" )
c . InvokeFail ( t , "token not found" , "ownerOf" , "not.exists" )
c . InvokeFail ( t , "invalid conversion" , "properties" , [ ] interface { } { } )
c . InvokeFail ( t , "invalid conversion" , "ownerOf" , [ ] interface { } { } )
2021-10-23 11:28:25 +00:00
} )
// Renew
expectedExpiration += millisecondsInYear
2021-10-23 12:36:26 +00:00
c . Invoke ( t , expectedExpiration , "renew" , "neo.com" )
2021-10-23 11:28:25 +00:00
props . Add ( stackitem . Make ( "expiration" ) , stackitem . Make ( expectedExpiration ) )
2021-10-23 12:36:26 +00:00
c . Invoke ( t , props , "properties" , "neo.com" )
2021-10-23 11:28:25 +00:00
}
2022-09-09 16:36:13 +00:00
func TestSetAddGetRecord ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2021-10-23 12:36:26 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 11:28:25 +00:00
acc := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cAcc := c . WithSigners ( acc )
2021-10-23 11:28:25 +00:00
t . Run ( "set before register" , func ( t * testing . T ) {
2022-09-09 16:36:13 +00:00
c . InvokeFail ( t , "token not found" , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "sometext" )
2021-10-23 11:28:25 +00:00
} )
2022-09-15 19:27:02 +00:00
c . Invoke ( t , true , "register" , "neo.com" , e . CommitteeHash , mail , refresh , retry , expire , ttl )
2021-10-23 11:28:25 +00:00
t . Run ( "invalid parameters" , func ( t * testing . T ) {
2022-09-09 16:36:13 +00:00
c . InvokeFail ( t , "unsupported record type" , "addRecord" , "neo.com" , int64 ( 0xFF ) , "1.2.3.4" )
c . InvokeFail ( t , "invalid record" , "addRecord" , "neo.com" , int64 ( nns . A ) , "not.an.ip.address" )
2021-10-23 11:28:25 +00:00
} )
t . Run ( "invalid witness" , func ( t * testing . T ) {
2022-09-09 16:36:13 +00:00
cAcc . InvokeFail ( t , "not witnessed by admin" , "addRecord" , "neo.com" , int64 ( nns . A ) , "1.2.3.4" )
2021-10-23 11:28:25 +00:00
} )
2022-09-09 16:36:13 +00:00
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { } ) , "getRecords" , "neo.com" , int64 ( nns . A ) )
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . A ) , "1.2.3.4" )
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "1.2.3.4" ) } ) , "getRecords" , "neo.com" , int64 ( nns . A ) )
2022-09-09 16:36:16 +00:00
c . InvokeFail ( t , "record already exists" , "addRecord" , "neo.com" , int64 ( nns . A ) , "1.2.3.4" ) // Duplicating record.
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "1.2.3.4" ) } ) , "getRecords" , "neo.com" , int64 ( nns . A ) )
2022-09-09 16:36:13 +00:00
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . AAAA ) , "2001:0201:1f1f:0000:0000:0100:11a0:11df" )
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . CNAME ) , "nspcc.ru" )
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "sometext" )
// Add multiple records and update some of them.
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "sometext1" )
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "sometext2" )
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "sometext3" )
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item {
stackitem . Make ( "sometext" ) ,
stackitem . Make ( "sometext1" ) ,
stackitem . Make ( "sometext2" ) ,
stackitem . Make ( "sometext3" ) ,
} ) , "getRecords" , "neo.com" , int64 ( nns . TXT ) )
c . Invoke ( t , stackitem . Null { } , "setRecord" , "neo.com" , int64 ( nns . TXT ) , 2 , "sometext22" )
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item {
stackitem . Make ( "sometext" ) ,
stackitem . Make ( "sometext1" ) ,
stackitem . Make ( "sometext22" ) ,
stackitem . Make ( "sometext3" ) ,
} ) , "getRecords" , "neo.com" , int64 ( nns . TXT ) )
2021-10-23 11:28:25 +00:00
// Delete record.
t . Run ( "invalid witness" , func ( t * testing . T ) {
2022-09-09 16:36:13 +00:00
cAcc . InvokeFail ( t , "not witnessed by admin" , "deleteRecords" , "neo.com" , int64 ( nns . CNAME ) )
2021-10-23 11:28:25 +00:00
} )
2022-09-09 16:36:13 +00:00
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "nspcc.ru" ) } ) , "getRecords" , "neo.com" , int64 ( nns . CNAME ) )
c . Invoke ( t , stackitem . Null { } , "deleteRecords" , "neo.com" , int64 ( nns . CNAME ) )
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { } ) , "getRecords" , "neo.com" , int64 ( nns . CNAME ) )
2022-09-09 16:36:16 +00:00
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "1.2.3.4" ) } ) , "getRecords" , "neo.com" , int64 ( nns . A ) )
2021-10-23 11:28:25 +00:00
t . Run ( "SetRecord_compatibility" , func ( t * testing . T ) {
2022-04-20 18:30:09 +00:00
// tests are got from the NNS C# implementation and changed accordingly to non-native implementation behavior
2021-10-23 11:28:25 +00:00
testCases := [ ] struct {
Type nns . RecordType
Name string
ShouldFail bool
} {
{ Type : nns . A , Name : "0.0.0.0" , ShouldFail : true } ,
{ Type : nns . A , Name : "1.1.0.1" } ,
{ Type : nns . A , Name : "10.10.10.10" , ShouldFail : true } ,
{ Type : nns . A , Name : "255.255.255.255" , ShouldFail : true } ,
{ Type : nns . A , Name : "192.168.1.1" , ShouldFail : true } ,
{ Type : nns . A , Name : "1a" , ShouldFail : true } ,
{ Type : nns . A , Name : "256.0.0.0" , ShouldFail : true } ,
{ Type : nns . A , Name : "01.01.01.01" , ShouldFail : true } ,
{ Type : nns . A , Name : "00.0.0.0" , ShouldFail : true } ,
{ Type : nns . A , Name : "0.0.0.-1" , ShouldFail : true } ,
{ Type : nns . A , Name : "0.0.0.0.1" , ShouldFail : true } ,
{ Type : nns . A , Name : "11111111.11111111.11111111.11111111" , ShouldFail : true } ,
{ Type : nns . A , Name : "11111111.11111111.11111111.11111111" , ShouldFail : true } ,
{ Type : nns . A , Name : "ff.ff.ff.ff" , ShouldFail : true } ,
{ Type : nns . A , Name : "0.0.256" , ShouldFail : true } ,
{ Type : nns . A , Name : "0.0.0" , ShouldFail : true } ,
{ Type : nns . A , Name : "0.257" , ShouldFail : true } ,
{ Type : nns . A , Name : "1.1" , ShouldFail : true } ,
{ Type : nns . A , Name : "257" , ShouldFail : true } ,
{ Type : nns . A , Name : "1" , ShouldFail : true } ,
// {2000} & {2001} & ]2002, 3ffe[ & {3fff} are valid values for IPv6 fragment0
{ Type : nns . AAAA , Name : "2002:db8::8:800:200c:417a" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "3ffd:1b8::8:800:200c:417a" } ,
{ Type : nns . AAAA , Name : "3ffd::101" } ,
{ Type : nns . AAAA , Name : "2003::1" } ,
{ Type : nns . AAAA , Name : "2003::" } ,
{ Type : nns . AAAA , Name : "2002:db8:0:0:8:800:200c:417a" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "3ffd:db8:0:0:8:800:200c:417a" } ,
{ Type : nns . AAAA , Name : "3ffd:0:0:0:0:0:0:101" } ,
{ Type : nns . AAAA , Name : "2002:0:0:0:0:0:0:101" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "3ffd:0:0:0:0:0:0:101" } ,
{ Type : nns . AAAA , Name : "2001:200:0:0:0:0:0:1" } ,
{ Type : nns . AAAA , Name : "0:0:0:0:0:0:0:1" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "2002:0:0:0:0:0:0:1" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "2001:200:0:0:0:0:0:0" } ,
{ Type : nns . AAAA , Name : "2002:0:0:0:0:0:0:0" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "2002:DB8::8:800:200C:417A" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "3FFD:1B8::8:800:200C:417A" } ,
{ Type : nns . AAAA , Name : "3FFD::101" } ,
{ Type : nns . AAAA , Name : "3fFD::101" } ,
{ Type : nns . AAAA , Name : "2002:DB8:0:0:8:800:200C:417A" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "3FFD:DB8:0:0:8:800:200C:417A" } ,
{ Type : nns . AAAA , Name : "3FFD:0:0:0:0:0:0:101" } ,
{ Type : nns . AAAA , Name : "3FFD::ffff:1.01.1.01" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "2001:DB8:0:0:8:800:200C:4Z" , ShouldFail : true } ,
{ Type : nns . AAAA , Name : "2001::13.1.68.3" , ShouldFail : true } ,
}
for _ , testCase := range testCases {
2021-10-23 12:36:26 +00:00
args := [ ] interface { } { "neo.com" , int64 ( testCase . Type ) , testCase . Name }
2021-10-23 11:28:25 +00:00
t . Run ( testCase . Name , func ( t * testing . T ) {
2021-10-23 12:36:26 +00:00
if testCase . ShouldFail {
2022-09-09 16:36:13 +00:00
c . InvokeFail ( t , "" , "addRecord" , args ... )
2021-10-23 12:36:26 +00:00
} else {
2022-09-09 16:36:13 +00:00
c . Invoke ( t , stackitem . Null { } , "addRecord" , args ... )
2022-09-09 16:36:16 +00:00
c . Invoke ( t , stackitem . Null { } , "deleteRecords" , "neo.com" , int64 ( testCase . Type ) ) // clear records after test to avoid duplicating records.
2021-10-23 12:36:26 +00:00
}
2021-10-23 11:28:25 +00:00
} )
}
} )
}
func TestSetAdmin ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2021-10-23 12:36:26 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 11:28:25 +00:00
owner := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cOwner := c . WithSigners ( owner )
2022-09-05 14:30:54 +00:00
cOwnerCommittee := c . WithSigners ( owner , c . Committee )
2021-10-23 11:28:25 +00:00
admin := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cAdmin := c . WithSigners ( admin )
2021-10-23 11:28:25 +00:00
guest := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cGuest := c . WithSigners ( guest )
2021-10-23 12:36:26 +00:00
2022-09-15 19:27:02 +00:00
cOwner . InvokeFail ( t , "not witnessed by admin" , "register" , "neo.com" , owner . ScriptHash ( ) , mail , refresh , retry , expire , ttl ) // admin is committee
cOwnerCommittee . Invoke ( t , true , "register" , "neo.com" , owner . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
expectedExpiration := e . TopBlock ( t ) . Timestamp + uint64 ( expire ) * 1000
2021-11-03 10:44:46 +00:00
cGuest . InvokeFail ( t , "not witnessed" , "setAdmin" , "neo.com" , admin . ScriptHash ( ) )
2021-10-23 11:28:25 +00:00
// Must be witnessed by both owner and admin.
2021-11-03 10:44:46 +00:00
cOwner . InvokeFail ( t , "not witnessed by admin" , "setAdmin" , "neo.com" , admin . ScriptHash ( ) )
cAdmin . InvokeFail ( t , "not witnessed by owner" , "setAdmin" , "neo.com" , admin . ScriptHash ( ) )
cc := c . WithSigners ( owner , admin )
cc . Invoke ( t , stackitem . Null { } , "setAdmin" , "neo.com" , admin . ScriptHash ( ) )
2022-09-05 14:31:03 +00:00
props := stackitem . NewMap ( )
props . Add ( stackitem . Make ( "name" ) , stackitem . Make ( "neo.com" ) )
props . Add ( stackitem . Make ( "expiration" ) , stackitem . Make ( expectedExpiration ) )
props . Add ( stackitem . Make ( "admin" ) , stackitem . Make ( admin . ScriptHash ( ) . BytesBE ( ) ) )
c . Invoke ( t , props , "properties" , "neo.com" )
2021-10-23 11:28:25 +00:00
t . Run ( "set and delete by admin" , func ( t * testing . T ) {
2022-09-09 16:36:13 +00:00
cAdmin . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "sometext" )
cGuest . InvokeFail ( t , "not witnessed by admin" , "deleteRecords" , "neo.com" , int64 ( nns . TXT ) )
cAdmin . Invoke ( t , stackitem . Null { } , "deleteRecords" , "neo.com" , int64 ( nns . TXT ) )
2021-10-23 11:28:25 +00:00
} )
t . Run ( "set admin to null" , func ( t * testing . T ) {
2022-09-09 16:36:13 +00:00
cAdmin . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "sometext" )
2021-10-23 12:36:26 +00:00
cOwner . Invoke ( t , stackitem . Null { } , "setAdmin" , "neo.com" , nil )
2022-09-09 16:36:13 +00:00
cAdmin . InvokeFail ( t , "not witnessed by admin" , "deleteRecords" , "neo.com" , int64 ( nns . TXT ) )
2021-10-23 11:28:25 +00:00
} )
}
func TestTransfer ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2021-10-23 12:36:26 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 11:28:25 +00:00
from := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cFrom := c . WithSigners ( from )
2022-09-05 14:30:54 +00:00
cFromCommittee := c . WithSigners ( from , c . Committee )
2021-10-23 11:28:25 +00:00
to := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cTo := c . WithSigners ( to )
2021-10-23 11:28:25 +00:00
2022-09-15 19:27:02 +00:00
cFromCommittee . Invoke ( t , true , "register" , "neo.com" , from . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cFrom . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . A ) , "1.2.3.4" )
2021-11-03 10:44:46 +00:00
cFrom . InvokeFail ( t , "token not found" , "transfer" , to . ScriptHash ( ) , "not.exists" , nil )
c . Invoke ( t , false , "transfer" , to . ScriptHash ( ) , "neo.com" , nil )
cFrom . Invoke ( t , true , "transfer" , to . ScriptHash ( ) , "neo.com" , nil )
2022-09-05 14:30:47 +00:00
cFrom . Invoke ( t , 2 , "totalSupply" ) // com, neo.com
2021-11-03 10:44:46 +00:00
cFrom . Invoke ( t , to . ScriptHash ( ) . BytesBE ( ) , "ownerOf" , "neo.com" )
2021-10-23 11:28:25 +00:00
// without onNEP11Transfer
2021-10-23 12:36:26 +00:00
ctr := neotest . CompileSource ( t , e . CommitteeHash ,
2021-10-23 11:28:25 +00:00
strings . NewReader ( ` package foo
func Main ( ) int { return 0 } ` ) ,
& compiler . Options { Name : "foo" } )
2021-10-23 12:36:26 +00:00
e . DeployContract ( t , ctr , nil )
cTo . InvokeFail ( t , "method not found" , "transfer" , ctr . Hash , [ ] byte ( "neo.com" ) , nil )
2021-10-23 11:28:25 +00:00
// with onNEP11Transfer
2021-10-23 12:36:26 +00:00
ctr = neotest . CompileSource ( t , e . CommitteeHash ,
2021-10-23 11:28:25 +00:00
strings . NewReader ( ` package foo
import "github.com/nspcc-dev/neo-go/pkg/interop"
func OnNEP11Payment ( from interop . Hash160 , amount int , token [ ] byte , data interface { } ) { } ` ) ,
& compiler . Options { Name : "foo" } )
2021-10-23 12:36:26 +00:00
e . DeployContract ( t , ctr , nil )
cTo . Invoke ( t , true , "transfer" , ctr . Hash , [ ] byte ( "neo.com" ) , nil )
2022-09-05 14:30:47 +00:00
cFrom . Invoke ( t , 2 , "totalSupply" ) // com, neo.com
2021-10-23 12:36:26 +00:00
cFrom . Invoke ( t , ctr . Hash . BytesBE ( ) , "ownerOf" , [ ] byte ( "neo.com" ) )
2021-10-23 11:28:25 +00:00
}
func TestTokensOf ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , false )
2021-10-23 12:36:26 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 11:28:25 +00:00
acc1 := e . NewAccount ( t )
2022-09-05 14:30:54 +00:00
cAcc1Committee := c . WithSigners ( acc1 , c . Committee )
2021-10-23 11:28:25 +00:00
acc2 := e . NewAccount ( t )
2022-09-05 14:30:54 +00:00
cAcc2Committee := c . WithSigners ( acc2 , c . Committee )
2021-10-23 11:28:25 +00:00
2022-09-05 14:30:47 +00:00
tld := [ ] byte ( "com" )
2022-09-15 19:27:02 +00:00
c . Invoke ( t , true , "register" , tld , c . CommitteeHash , mail , refresh , retry , expire , ttl )
cAcc1Committee . Invoke ( t , true , "register" , "neo.com" , acc1 . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
cAcc2Committee . Invoke ( t , true , "register" , "nspcc.com" , acc2 . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2021-10-23 11:28:25 +00:00
2022-09-05 14:30:47 +00:00
testTokensOf ( t , c , tld , [ ] [ ] byte { [ ] byte ( "neo.com" ) } , acc1 . ScriptHash ( ) . BytesBE ( ) )
testTokensOf ( t , c , tld , [ ] [ ] byte { [ ] byte ( "nspcc.com" ) } , acc2 . ScriptHash ( ) . BytesBE ( ) )
testTokensOf ( t , c , tld , [ ] [ ] byte { [ ] byte ( "neo.com" ) , [ ] byte ( "nspcc.com" ) } )
testTokensOf ( t , c , tld , [ ] [ ] byte { } , util . Uint160 { } . BytesBE ( ) ) // empty hash is a valid hash still
2021-10-23 11:28:25 +00:00
}
2022-09-05 14:30:47 +00:00
func testTokensOf ( t * testing . T , c * neotest . ContractInvoker , tld [ ] byte , result [ ] [ ] byte , args ... interface { } ) {
2021-10-23 11:28:25 +00:00
method := "tokensOf"
if len ( args ) == 0 {
method = "tokens"
}
2021-10-23 12:36:26 +00:00
s , err := c . TestInvoke ( t , method , args ... )
2021-10-23 11:28:25 +00:00
if result == nil {
require . Error ( t , err )
return
}
require . NoError ( t , err )
2021-10-23 12:36:26 +00:00
iter := s . Pop ( ) . Interop ( ) . Value ( ) . ( * storage . Iterator )
2021-10-23 11:28:25 +00:00
arr := make ( [ ] stackitem . Item , 0 , len ( result ) )
2021-10-23 12:36:26 +00:00
for i := range result {
require . True ( t , iter . Next ( ) )
require . Equal ( t , result [ i ] , iter . Value ( ) . Value ( ) )
2021-10-23 11:28:25 +00:00
arr = append ( arr , stackitem . Make ( result [ i ] ) )
}
2022-09-05 14:30:47 +00:00
if method == "tokens" {
require . True ( t , iter . Next ( ) )
require . Equal ( t , tld , iter . Value ( ) . Value ( ) )
} else {
require . False ( t , iter . Next ( ) )
}
2021-10-23 11:28:25 +00:00
}
func TestResolve ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2021-10-23 12:36:26 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2021-10-23 11:28:25 +00:00
acc := e . NewAccount ( t )
2021-11-03 10:44:46 +00:00
cAcc := c . WithSigners ( acc )
2022-09-05 14:30:54 +00:00
cAccCommittee := c . WithSigners ( acc , c . Committee )
2021-10-23 12:36:26 +00:00
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "neo.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . A ) , "1.2.3.4" )
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . CNAME ) , "alias.com" )
2021-10-23 12:36:26 +00:00
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "alias.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "alias.com" , int64 ( nns . TXT ) , "sometxt from alias1" )
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "alias.com" , int64 ( nns . CNAME ) , "alias2.com" )
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "alias2.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "alias2.com" , int64 ( nns . TXT ) , "sometxt from alias2" )
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "1.2.3.4" ) } ) , "resolve" , "neo.com" , int64 ( nns . A ) )
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "1.2.3.4" ) } ) , "resolve" , "neo.com." , int64 ( nns . A ) )
c . InvokeFail ( t , "invalid domain name format" , "resolve" , "neo.com.." , int64 ( nns . A ) )
// Check CNAME is properly resolved and is not included into the result.
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "sometxt from alias1" ) , stackitem . Make ( "sometxt from alias2" ) } ) , "resolve" , "neo.com" , int64 ( nns . TXT ) )
// Check CNAME is included into the result and is not resolved.
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "alias.com" ) } ) , "resolve" , "neo.com" , int64 ( nns . CNAME ) )
// Empty result.
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { } ) , "resolve" , "neo.com" , int64 ( nns . AAAA ) )
2021-10-23 11:28:25 +00:00
}
2022-09-09 16:35:54 +00:00
func TestGetAllRecords ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2022-09-09 16:35:54 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2022-09-09 16:35:54 +00:00
acc := e . NewAccount ( t )
cAcc := c . WithSigners ( acc )
cAccCommittee := c . WithSigners ( acc , c . Committee )
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "neo.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . A ) , "1.2.3.4" )
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . CNAME ) , "alias.com" )
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , "bla0" )
cAcc . Invoke ( t , stackitem . Null { } , "setRecord" , "neo.com" , int64 ( nns . TXT ) , 0 , "bla1" ) // overwrite
2022-09-15 19:27:02 +00:00
time := e . TopBlock ( t ) . Timestamp
2022-09-09 16:35:54 +00:00
// Add some arbitrary data.
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "alias.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "alias.com" , int64 ( nns . TXT ) , "sometxt" )
2022-09-09 16:35:54 +00:00
script , err := smartcontract . CreateCallAndUnwrapIteratorScript ( c . Hash , "getAllRecords" , 10 , "neo.com" )
require . NoError ( t , err )
h := e . InvokeScript ( t , script , [ ] neotest . Signer { acc } )
e . CheckHalt ( t , h , stackitem . NewArray ( [ ] stackitem . Item {
stackitem . NewStruct ( [ ] stackitem . Item {
stackitem . NewByteArray ( [ ] byte ( "neo.com" ) ) ,
stackitem . Make ( nns . A ) ,
stackitem . NewByteArray ( [ ] byte ( "1.2.3.4" ) ) ,
2022-09-09 16:36:13 +00:00
stackitem . NewBigInteger ( big . NewInt ( 0 ) ) ,
2022-09-09 16:35:54 +00:00
} ) ,
stackitem . NewStruct ( [ ] stackitem . Item {
stackitem . NewByteArray ( [ ] byte ( "neo.com" ) ) ,
stackitem . Make ( nns . CNAME ) ,
stackitem . NewByteArray ( [ ] byte ( "alias.com" ) ) ,
2022-09-09 16:36:13 +00:00
stackitem . NewBigInteger ( big . NewInt ( 0 ) ) ,
2022-09-09 16:35:54 +00:00
} ) ,
2022-09-15 19:27:02 +00:00
stackitem . NewStruct ( [ ] stackitem . Item {
stackitem . NewByteArray ( [ ] byte ( "neo.com" ) ) ,
stackitem . Make ( nns . SOA ) ,
stackitem . NewBuffer ( [ ] byte ( "neo.com" + " " + mail + " " +
strconv . Itoa ( int ( time ) ) + " " + strconv . Itoa ( int ( refresh ) ) + " " +
strconv . Itoa ( int ( retry ) ) + " " + strconv . Itoa ( int ( expire ) ) + " " +
strconv . Itoa ( int ( ttl ) ) ) ) ,
stackitem . NewBigInteger ( big . NewInt ( 0 ) ) ,
} ) ,
2022-09-09 16:35:54 +00:00
stackitem . NewStruct ( [ ] stackitem . Item {
stackitem . NewByteArray ( [ ] byte ( "neo.com" ) ) ,
stackitem . Make ( nns . TXT ) ,
stackitem . NewByteArray ( [ ] byte ( "bla1" ) ) ,
2022-09-09 16:36:13 +00:00
stackitem . NewBigInteger ( big . NewInt ( 0 ) ) ,
2022-09-09 16:35:54 +00:00
} ) ,
} ) )
}
2022-09-09 16:36:13 +00:00
func TestGetRecords ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2022-09-09 16:36:13 +00:00
e := c . Executor
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2022-09-09 16:36:13 +00:00
acc := e . NewAccount ( t )
cAcc := c . WithSigners ( acc )
cAccCommittee := c . WithSigners ( acc , c . Committee )
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "neo.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . A ) , "1.2.3.4" )
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . CNAME ) , "alias.com" )
// Add some arbitrary data.
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "alias.com" , acc . ScriptHash ( ) , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
cAcc . Invoke ( t , stackitem . Null { } , "addRecord" , "alias.com" , int64 ( nns . TXT ) , "sometxt" )
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { stackitem . Make ( "1.2.3.4" ) } ) , "getRecords" , "neo.com" , int64 ( nns . A ) )
// Check empty result of `getRecords`.
c . Invoke ( t , stackitem . NewArray ( [ ] stackitem . Item { } ) , "getRecords" , "neo.com" , int64 ( nns . AAAA ) )
}
func TestNNSAddRecord ( t * testing . T ) {
2022-09-15 19:27:02 +00:00
c := newNSClient ( t , true )
2022-09-09 16:36:13 +00:00
cAccCommittee := c . WithSigners ( c . Committee )
2022-09-15 19:27:02 +00:00
mail , refresh , retry , expire , ttl := "sami@nspcc.ru" , int64 ( 101 ) , int64 ( 102 ) , int64 ( millisecondsInYear / 1000 * 100 ) , int64 ( 104 )
2022-09-09 16:36:13 +00:00
2022-09-15 19:27:02 +00:00
cAccCommittee . Invoke ( t , true , "register" , "neo.com" , c . CommitteeHash , mail , refresh , retry , expire , ttl )
2022-09-09 16:36:13 +00:00
for i := 0 ; i <= maxRecordID + 1 ; i ++ {
if i == maxRecordID + 1 {
c . InvokeFail ( t , "maximum number of records reached" , "addRecord" , "neo.com" , int64 ( nns . TXT ) , strconv . Itoa ( i ) )
} else {
c . Invoke ( t , stackitem . Null { } , "addRecord" , "neo.com" , int64 ( nns . TXT ) , strconv . Itoa ( i ) )
}
}
}
2022-09-15 19:27:07 +00:00
func TestNNSRegisterArbitraryLevelDomain ( t * testing . T ) {
c := newNSClient ( t , true )
newArgs := func ( domain string , account neotest . Signer ) [ ] interface { } {
return [ ] interface { } {
domain , account . ScriptHash ( ) , "doesnt@matter.com" ,
int64 ( 101 ) , int64 ( 102 ) , int64 ( 103 ) , int64 ( 104 ) ,
}
}
acc := c . NewAccount ( t )
cBoth := c . WithSigners ( c . Committee , acc )
args := newArgs ( "neo.com" , acc )
cBoth . Invoke ( t , true , "register" , args ... )
c1 := c . WithSigners ( acc )
// parent domain is missing
args [ 0 ] = "testnet.fs.neo.com"
c1 . InvokeFail ( t , "one of the parent domains is not registered" , "register" , args ... )
args [ 0 ] = "fs.neo.com"
c1 . Invoke ( t , true , "register" , args ... )
args [ 0 ] = "testnet.fs.neo.com"
c1 . Invoke ( t , true , "register" , args ... )
acc2 := c . NewAccount ( t )
c2 := c . WithSigners ( c . Committee , acc2 )
args = newArgs ( "mainnet.fs.neo.com" , acc2 )
c2 . InvokeFail ( t , "not witnessed by admin" , "register" , args ... )
c2 = c . WithSigners ( acc , acc2 )
c2 . Invoke ( t , true , "register" , args ... )
c2 = c . WithSigners ( acc2 )
c2 . Invoke ( t , stackitem . Null { } , "addRecord" ,
"cdn.mainnet.fs.neo.com" , int64 ( nns . A ) , "166.15.14.13" )
result := stackitem . NewArray ( [ ] stackitem . Item {
stackitem . NewByteArray ( [ ] byte ( "166.15.14.13" ) ) ,
} )
c2 . Invoke ( t , result , "resolve" , "cdn.mainnet.fs.neo.com" , int64 ( nns . A ) )
}
2021-10-23 11:28:25 +00:00
const (
defaultNameServiceDomainPrice = 10_0000_0000
defaultNameServiceSysfee = 6000_0000
2022-09-09 16:36:13 +00:00
maxRecordID = 255
2021-10-23 11:28:25 +00:00
)