rpc: add NEP11-D tests to server and client

Also refactor basic chain creation.
This commit is contained in:
Anna Shaleva 2022-02-04 19:21:12 +03:00 committed by Anna Shaleva
parent 47652643df
commit e306a90554
6 changed files with 444 additions and 132 deletions

View file

@ -279,16 +279,34 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
priv0 := testchain.PrivateKeyByID(0) priv0 := testchain.PrivateKeyByID(0)
priv0ScriptHash := priv0.GetScriptHash() priv0ScriptHash := priv0.GetScriptHash()
priv1 := testchain.PrivateKeyByID(1)
priv1ScriptHash := priv1.GetScriptHash()
acc0 := wallet.NewAccountFromPrivateKey(priv0)
acc1 := wallet.NewAccountFromPrivateKey(priv1)
deployContractFromPriv0 := func(t *testing.T, path, contractName string, configPath *string, expectedID int32) (util.Uint256, util.Uint256, util.Uint160) {
txDeploy, _ := newDeployTx(t, bc, priv0ScriptHash, path, contractName, configPath)
txDeploy.Nonce = getNextNonce()
txDeploy.ValidUntilBlock = validUntilBlock
require.NoError(t, addNetworkFee(bc, txDeploy, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy))
b := bc.newBlock(txDeploy)
require.NoError(t, bc.AddBlock(b)) // block #11
checkTxHalt(t, bc, txDeploy.Hash())
sh, err := bc.GetContractScriptHash(expectedID)
require.NoError(t, err)
return b.Hash(), txDeploy.Hash(), sh
}
require.Equal(t, big.NewInt(5000_0000), bc.GetUtilityTokenBalance(priv0ScriptHash)) // gas bounty require.Equal(t, big.NewInt(5000_0000), bc.GetUtilityTokenBalance(priv0ScriptHash)) // gas bounty
// Move some NEO to one simple account.
// Block #1: move 1000 GAS and neoAmount NEO to priv0.
txMoveNeo, err := testchain.NewTransferFromOwner(bc, neoHash, priv0ScriptHash, neoAmount, getNextNonce(), validUntilBlock) txMoveNeo, err := testchain.NewTransferFromOwner(bc, neoHash, priv0ScriptHash, neoAmount, getNextNonce(), validUntilBlock)
require.NoError(t, err) require.NoError(t, err)
// Move some GAS to one simple account. // Move some GAS to one simple account.
txMoveGas, err := testchain.NewTransferFromOwner(bc, gasHash, priv0ScriptHash, int64(fixedn.Fixed8FromInt64(1000)), txMoveGas, err := testchain.NewTransferFromOwner(bc, gasHash, priv0ScriptHash, int64(fixedn.Fixed8FromInt64(1000)),
getNextNonce(), validUntilBlock) getNextNonce(), validUntilBlock)
require.NoError(t, err) require.NoError(t, err)
b := bc.newBlock(txMoveNeo, txMoveGas) b := bc.newBlock(txMoveNeo, txMoveGas)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
checkTxHalt(t, bc, txMoveGas.Hash()) checkTxHalt(t, bc, txMoveGas.Hash())
@ -322,25 +340,15 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
b.Header.EncodeBinary(buf.BinWriter) b.Header.EncodeBinary(buf.BinWriter)
t.Logf("header: %s", hex.EncodeToString(buf.Bytes())) t.Logf("header: %s", hex.EncodeToString(buf.Bytes()))
acc0 := wallet.NewAccountFromPrivateKey(priv0) // Block #2: deploy test_contract.
// Push some contract into the chain.
cfgPath := prefix + "test_contract.yml" cfgPath := prefix + "test_contract.yml"
txDeploy, cHash := newDeployTx(t, bc, priv0ScriptHash, prefix+"test_contract.go", "Rubl", &cfgPath) block2H, txDeployH, cHash := deployContractFromPriv0(t, prefix+"test_contract.go", "Rubl", &cfgPath, 1)
txDeploy.Nonce = getNextNonce() t.Logf("txDeploy: %s", txDeployH.StringLE())
txDeploy.ValidUntilBlock = validUntilBlock t.Logf("Block2 hash: %s", block2H.StringLE())
require.NoError(t, addNetworkFee(bc, txDeploy, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy))
b = bc.newBlock(txDeploy)
require.NoError(t, bc.AddBlock(b))
checkTxHalt(t, bc, txDeploy.Hash())
t.Logf("txDeploy: %s", txDeploy.Hash().StringLE())
t.Logf("Block2 hash: %s", b.Hash().StringLE())
// Now invoke this contract. // Block #3: invoke `putValue` method on the test_contract.
script := io.NewBufBinWriter() script := io.NewBufBinWriter()
emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "testkey", "testvalue") emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "testkey", "testvalue")
txInv := transaction.New(script.Bytes(), 1*native.GASFactor) txInv := transaction.New(script.Bytes(), 1*native.GASFactor)
txInv.Nonce = getNextNonce() txInv.Nonce = getNextNonce()
txInv.ValidUntilBlock = validUntilBlock txInv.ValidUntilBlock = validUntilBlock
@ -352,8 +360,8 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
checkTxHalt(t, bc, txInv.Hash()) checkTxHalt(t, bc, txInv.Hash())
t.Logf("txInv: %s", txInv.Hash().StringLE()) t.Logf("txInv: %s", txInv.Hash().StringLE())
priv1 := testchain.PrivateKeyByID(1) // Block #4: transfer 0.0000_1 NEO from priv0 to priv1.
txNeo0to1 := newNEP17Transfer(neoHash, priv0ScriptHash, priv1.GetScriptHash(), 1000) txNeo0to1 := newNEP17Transfer(neoHash, priv0ScriptHash, priv1ScriptHash, 1000)
txNeo0to1.Nonce = getNextNonce() txNeo0to1.Nonce = getNextNonce()
txNeo0to1.ValidUntilBlock = validUntilBlock txNeo0to1.ValidUntilBlock = validUntilBlock
txNeo0to1.Signers = []transaction.Signer{ txNeo0to1.Signers = []transaction.Signer{
@ -370,6 +378,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
checkTxHalt(t, bc, txNeo0to1.Hash()) checkTxHalt(t, bc, txNeo0to1.Hash())
// Block #5: initialize rubles contract and transfer 1000 rubles from the contract to priv0.
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.AppCall(w.BinWriter, cHash, "init", callflag.All) emit.AppCall(w.BinWriter, cHash, "init", callflag.All)
initTx := transaction.New(w.Bytes(), 1*native.GASFactor) initTx := transaction.New(w.Bytes(), 1*native.GASFactor)
@ -378,7 +387,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
initTx.Signers = []transaction.Signer{{Account: priv0ScriptHash}} initTx.Signers = []transaction.Signer{{Account: priv0ScriptHash}}
require.NoError(t, addNetworkFee(bc, initTx, acc0)) require.NoError(t, addNetworkFee(bc, initTx, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), initTx)) require.NoError(t, acc0.SignTx(testchain.Network(), initTx))
transferTx := newNEP17Transfer(cHash, cHash, priv0.GetScriptHash(), 1000) transferTx := newNEP17Transfer(cHash, cHash, priv0ScriptHash, 1000)
transferTx.Nonce = getNextNonce() transferTx.Nonce = getNextNonce()
transferTx.ValidUntilBlock = validUntilBlock transferTx.ValidUntilBlock = validUntilBlock
transferTx.Signers = []transaction.Signer{ transferTx.Signers = []transaction.Signer{
@ -392,14 +401,14 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
require.NoError(t, addNetworkFee(bc, transferTx, acc0)) require.NoError(t, addNetworkFee(bc, transferTx, acc0))
transferTx.SystemFee += 1000000 transferTx.SystemFee += 1000000
require.NoError(t, acc0.SignTx(testchain.Network(), transferTx)) require.NoError(t, acc0.SignTx(testchain.Network(), transferTx))
b = bc.newBlock(initTx, transferTx) b = bc.newBlock(initTx, transferTx)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
checkTxHalt(t, bc, initTx.Hash()) checkTxHalt(t, bc, initTx.Hash())
checkTxHalt(t, bc, transferTx.Hash()) checkTxHalt(t, bc, transferTx.Hash())
t.Logf("recieveRublesTx: %v", transferTx.Hash().StringLE()) t.Logf("recieveRublesTx: %v", transferTx.Hash().StringLE())
transferTx = newNEP17Transfer(cHash, priv0.GetScriptHash(), priv1.GetScriptHash(), 123) // Block #6: transfer 123 rubles from priv0 to priv1
transferTx = newNEP17Transfer(cHash, priv0.GetScriptHash(), priv1ScriptHash, 123)
transferTx.Nonce = getNextNonce() transferTx.Nonce = getNextNonce()
transferTx.ValidUntilBlock = validUntilBlock transferTx.ValidUntilBlock = validUntilBlock
transferTx.Signers = []transaction.Signer{ transferTx.Signers = []transaction.Signer{
@ -413,24 +422,16 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
require.NoError(t, addNetworkFee(bc, transferTx, acc0)) require.NoError(t, addNetworkFee(bc, transferTx, acc0))
transferTx.SystemFee += 1000000 transferTx.SystemFee += 1000000
require.NoError(t, acc0.SignTx(testchain.Network(), transferTx)) require.NoError(t, acc0.SignTx(testchain.Network(), transferTx))
b = bc.newBlock(transferTx) b = bc.newBlock(transferTx)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
checkTxHalt(t, bc, transferTx.Hash()) checkTxHalt(t, bc, transferTx.Hash())
t.Logf("sendRublesTx: %v", transferTx.Hash().StringLE()) t.Logf("sendRublesTx: %v", transferTx.Hash().StringLE())
// Push verification contract into the chain. // Block #7: push verification contract into the chain.
verifyPath := filepath.Join(prefix, "verify", "verification_contract.go") verifyPath := filepath.Join(prefix, "verify", "verification_contract.go")
txDeploy2, _ := newDeployTx(t, bc, priv0ScriptHash, verifyPath, "Verify", nil) _, _, _ = deployContractFromPriv0(t, verifyPath, "Verify", nil, 2)
txDeploy2.Nonce = getNextNonce()
txDeploy2.ValidUntilBlock = validUntilBlock
require.NoError(t, addNetworkFee(bc, txDeploy2, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy2))
b = bc.newBlock(txDeploy2)
require.NoError(t, bc.AddBlock(b))
checkTxHalt(t, bc, txDeploy2.Hash())
// Deposit some GAS to notary contract for priv0 // Block #8: deposit some GAS to notary contract for priv0.
transferTx = newNEP17Transfer(gasHash, priv0.GetScriptHash(), notaryHash, 10_0000_0000, priv0.GetScriptHash(), int64(bc.BlockHeight()+1000)) transferTx = newNEP17Transfer(gasHash, priv0.GetScriptHash(), notaryHash, 10_0000_0000, priv0.GetScriptHash(), int64(bc.BlockHeight()+1000))
transferTx.Nonce = getNextNonce() transferTx.Nonce = getNextNonce()
transferTx.ValidUntilBlock = validUntilBlock transferTx.ValidUntilBlock = validUntilBlock
@ -443,68 +444,59 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
require.NoError(t, addNetworkFee(bc, transferTx, acc0)) require.NoError(t, addNetworkFee(bc, transferTx, acc0))
transferTx.SystemFee += 10_0000 transferTx.SystemFee += 10_0000
require.NoError(t, acc0.SignTx(testchain.Network(), transferTx)) require.NoError(t, acc0.SignTx(testchain.Network(), transferTx))
b = bc.newBlock(transferTx) b = bc.newBlock(transferTx)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
checkTxHalt(t, bc, transferTx.Hash()) checkTxHalt(t, bc, transferTx.Hash())
t.Logf("notaryDepositTxPriv0: %v", transferTx.Hash().StringLE()) t.Logf("notaryDepositTxPriv0: %v", transferTx.Hash().StringLE())
// Designate new Notary node // Block #9: designate new Notary node.
ntr, err := wallet.NewWalletFromFile(path.Join(notaryModulePath, "./testdata/notary1.json")) ntr, err := wallet.NewWalletFromFile(path.Join(notaryModulePath, "./testdata/notary1.json"))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, ntr.Accounts[0].Decrypt("one", ntr.Scrypt)) require.NoError(t, ntr.Accounts[0].Decrypt("one", ntr.Scrypt))
bc.setNodesByRole(t, true, noderoles.P2PNotary, keys.PublicKeys{ntr.Accounts[0].PrivateKey().PublicKey()}) bc.setNodesByRole(t, true, noderoles.P2PNotary, keys.PublicKeys{ntr.Accounts[0].PrivateKey().PublicKey()})
t.Logf("Designated Notary node: %s", hex.EncodeToString(ntr.Accounts[0].PrivateKey().PublicKey().Bytes())) t.Logf("Designated Notary node: %s", hex.EncodeToString(ntr.Accounts[0].PrivateKey().PublicKey().Bytes()))
// Push verification contract with arguments into the chain. // Block #10: push verification contract with arguments into the chain.
verifyPath = filepath.Join(prefix, "verify_args", "verification_with_args_contract.go") verifyPath = filepath.Join(prefix, "verify_args", "verification_with_args_contract.go")
txDeploy3, _ := newDeployTx(t, bc, priv0ScriptHash, verifyPath, "VerifyWithArgs", nil) _, _, _ = deployContractFromPriv0(t, verifyPath, "VerifyWithArgs", nil, 3) // block #10
txDeploy3.Nonce = getNextNonce()
txDeploy3.ValidUntilBlock = validUntilBlock
require.NoError(t, addNetworkFee(bc, txDeploy3, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy3))
b = bc.newBlock(txDeploy3)
require.NoError(t, bc.AddBlock(b)) // block #10
checkTxHalt(t, bc, txDeploy3.Hash())
// Push NameService contract into the chain. // Block #11: push NameService contract into the chain.
nsPath := examplesPrefix + "nft-nd-nns/" nsPath := examplesPrefix + "nft-nd-nns/"
nsConfigPath := nsPath + "nns.yml" nsConfigPath := nsPath + "nns.yml"
txDeploy4, _ := newDeployTx(t, bc, priv0ScriptHash, nsPath, nsPath, &nsConfigPath) _, _, nsHash := deployContractFromPriv0(t, nsPath, nsPath, &nsConfigPath, 4) // block #11
txDeploy4.Nonce = getNextNonce()
txDeploy4.ValidUntilBlock = validUntilBlock
require.NoError(t, addNetworkFee(bc, txDeploy4, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy4))
b = bc.newBlock(txDeploy4)
require.NoError(t, bc.AddBlock(b)) // block #11
checkTxHalt(t, bc, txDeploy4.Hash())
nsHash, err := bc.GetContractScriptHash(4)
require.NoError(t, err)
t.Logf("contract (%s): \n\tHash: %s\n", nsPath, nsHash.StringLE())
// register `neo.com` with A record type and priv0 owner via NS // Block #12: transfer funds to committee for futher NS record registration.
transferFundsToCommittee(t, bc) // block #12 transferFundsToCommittee(t, bc) // block #12
// Block #13: add `.com` root to NNS.
res, err := invokeContractMethodGeneric(bc, -1, res, err := invokeContractMethodGeneric(bc, -1,
nsHash, "addRoot", true, "com") // block #13 nsHash, "addRoot", true, "com") // block #13
require.NoError(t, err) require.NoError(t, err)
checkResult(t, res, stackitem.Null{}) checkResult(t, res, stackitem.Null{})
// Block #14: register `neo.com` via NNS.
res, err = invokeContractMethodGeneric(bc, -1, res, err = invokeContractMethodGeneric(bc, -1,
nsHash, "register", acc0, "neo.com", priv0ScriptHash) // block #14 nsHash, "register", acc0, "neo.com", priv0ScriptHash) // block #14
require.NoError(t, err) require.NoError(t, err)
checkResult(t, res, stackitem.NewBool(true)) checkResult(t, res, stackitem.NewBool(true))
require.Equal(t, 1, len(res.Events)) // transfer
tokenID, err := res.Events[0].Item.Value().([]stackitem.Item)[3].TryBytes()
require.NoError(t, err)
t.Logf("NNS token #1 ID (hex): %s", hex.EncodeToString(tokenID))
// Block #15: set A record type with priv0 owner via NNS.
res, err = invokeContractMethodGeneric(bc, -1, nsHash, res, err = invokeContractMethodGeneric(bc, -1, nsHash,
"setRecord", acc0, "neo.com", int64(nns.A), "1.2.3.4") // block #15 "setRecord", acc0, "neo.com", int64(nns.A), "1.2.3.4") // block #15
require.NoError(t, err) require.NoError(t, err)
checkResult(t, res, stackitem.Null{}) checkResult(t, res, stackitem.Null{})
// Invoke `test_contract.go`: put new value with the same key to check `getstate` RPC call // Block #16: invoke `test_contract.go`: put new value with the same key to check `getstate` RPC call
script.Reset() script.Reset()
emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "testkey", "newtestvalue") emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "testkey", "newtestvalue")
// Invoke `test_contract.go`: put values to check `findstates` RPC call // Invoke `test_contract.go`: put values to check `findstates` RPC call
emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "aa", "v1") emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "aa", "v1")
emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "aa10", "v2") emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "aa10", "v2")
emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "aa50", "v3") emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "aa50", "v3")
txInv = transaction.New(script.Bytes(), 1*native.GASFactor) txInv = transaction.New(script.Bytes(), 1*native.GASFactor)
txInv.Nonce = getNextNonce() txInv.Nonce = getNextNonce()
txInv.ValidUntilBlock = validUntilBlock txInv.ValidUntilBlock = validUntilBlock
@ -512,9 +504,75 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
require.NoError(t, addNetworkFee(bc, txInv, acc0)) require.NoError(t, addNetworkFee(bc, txInv, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txInv)) require.NoError(t, acc0.SignTx(testchain.Network(), txInv))
b = bc.newBlock(txInv) b = bc.newBlock(txInv)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b)) // block #16
checkTxHalt(t, bc, txInv.Hash()) checkTxHalt(t, bc, txInv.Hash())
// Block #17: deploy NeoFS Object contract (NEP11-Divisible).
nfsPath := examplesPrefix + "nft-d/"
nfsConfigPath := nfsPath + "nft.yml"
_, _, nfsHash := deployContractFromPriv0(t, nfsPath, nfsPath, &nfsConfigPath, 5) // block #17
// Block #18: mint 1.00 NFSO token by transferring 10 GAS to NFSO contract.
containerID := util.Uint256{1, 2, 3}
objectID := util.Uint256{4, 5, 6}
txGas0toNFS := newNEP17Transfer(gasHash, priv0ScriptHash, nfsHash, 10_0000_0000, containerID.BytesBE(), objectID.BytesBE())
txGas0toNFS.SystemFee += 4000_0000
txGas0toNFS.Nonce = getNextNonce()
txGas0toNFS.ValidUntilBlock = validUntilBlock
txGas0toNFS.Signers = []transaction.Signer{
{
Account: priv0ScriptHash,
Scopes: transaction.CalledByEntry,
},
}
require.NoError(t, addNetworkFee(bc, txGas0toNFS, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txGas0toNFS))
b = bc.newBlock(txGas0toNFS)
require.NoError(t, bc.AddBlock(b)) // block #18
checkTxHalt(t, bc, txGas0toNFS.Hash())
aer, _ := bc.GetAppExecResults(txGas0toNFS.Hash(), trigger.Application)
require.Equal(t, 2, len(aer[0].Events)) // GAS transfer + NFSO transfer
tokenID, err = aer[0].Events[1].Item.Value().([]stackitem.Item)[3].TryBytes()
require.NoError(t, err)
t.Logf("NFSO token #1 ID (hex): %s", hex.EncodeToString(tokenID))
// Block #19: transfer 0.25 NFSO from priv0 to priv1.
script.Reset()
emit.AppCall(script.BinWriter, nfsHash, "transfer", callflag.All, priv0ScriptHash, priv1ScriptHash, 25, tokenID, nil)
emit.Opcodes(script.BinWriter, opcode.ASSERT)
require.NoError(t, script.Err)
txNFS0to1 := transaction.New(script.Bytes(), 1*native.GASFactor)
txNFS0to1.Nonce = getNextNonce()
txNFS0to1.ValidUntilBlock = validUntilBlock
txNFS0to1.Signers = []transaction.Signer{{Account: priv0ScriptHash, Scopes: transaction.CalledByEntry}}
require.NoError(t, addNetworkFee(bc, txNFS0to1, acc0))
require.NoError(t, acc0.SignTx(testchain.Network(), txNFS0to1))
b = bc.newBlock(txNFS0to1)
require.NoError(t, bc.AddBlock(b)) // block #19
checkTxHalt(t, bc, txNFS0to1.Hash())
// Block #20: transfer 1000 GAS to priv1.
txMoveGas, err = testchain.NewTransferFromOwner(bc, gasHash, priv1ScriptHash, int64(fixedn.Fixed8FromInt64(1000)),
getNextNonce(), validUntilBlock)
require.NoError(t, err)
require.NoError(t, bc.AddBlock(bc.newBlock(txMoveGas)))
checkTxHalt(t, bc, txMoveGas.Hash()) // block #20
// Block #21: transfer 0.05 NFSO from priv1 back to priv0.
script.Reset()
emit.AppCall(script.BinWriter, nfsHash, "transfer", callflag.All, priv1ScriptHash, priv0.GetScriptHash(), 5, tokenID, nil)
emit.Opcodes(script.BinWriter, opcode.ASSERT)
require.NoError(t, script.Err)
txNFS1to0 := transaction.New(script.Bytes(), 1*native.GASFactor)
txNFS1to0.Nonce = getNextNonce()
txNFS1to0.ValidUntilBlock = validUntilBlock
txNFS1to0.Signers = []transaction.Signer{{Account: priv1ScriptHash, Scopes: transaction.CalledByEntry}}
require.NoError(t, addNetworkFee(bc, txNFS1to0, acc0))
require.NoError(t, acc1.SignTx(testchain.Network(), txNFS1to0))
b = bc.newBlock(txNFS1to0)
require.NoError(t, bc.AddBlock(b)) // block #21
checkTxHalt(t, bc, txNFS1to0.Hash())
// Compile contract to test `invokescript` RPC call // Compile contract to test `invokescript` RPC call
invokePath := filepath.Join(prefix, "invoke", "invokescript_contract.go") invokePath := filepath.Join(prefix, "invoke", "invokescript_contract.go")
invokeCfg := filepath.Join(prefix, "invoke", "invoke.yml") invokeCfg := filepath.Join(prefix, "invoke", "invoke.yml")

View file

@ -280,7 +280,7 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
var ( var (
stateSyncInterval = 4 stateSyncInterval = 4
maxTraceable uint32 = 6 maxTraceable uint32 = 6
stateSyncPoint = 16 stateSyncPoint = 20
) )
spoutCfg := func(c *config.Config) { spoutCfg := func(c *config.Config) {
c.ProtocolConfiguration.StateRootInHeader = true c.ProtocolConfiguration.StateRootInHeader = true
@ -291,10 +291,9 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
bcSpout := newTestChainWithCustomCfg(t, spoutCfg) bcSpout := newTestChainWithCustomCfg(t, spoutCfg)
initBasicChain(t, bcSpout) initBasicChain(t, bcSpout)
// make spout chain higher that latest state sync point // make spout chain higher that latest state sync point (add several blocks up to stateSyncPoint+2)
require.NoError(t, bcSpout.AddBlock(bcSpout.newBlock())) require.NoError(t, bcSpout.AddBlock(bcSpout.newBlock()))
require.NoError(t, bcSpout.AddBlock(bcSpout.newBlock())) require.Equal(t, stateSyncPoint+2, int(bcSpout.BlockHeight()))
require.Equal(t, uint32(stateSyncPoint+2), bcSpout.BlockHeight())
boltCfg := func(c *config.Config) { boltCfg := func(c *config.Config) {
spoutCfg(c) spoutCfg(c)

View file

@ -3,6 +3,7 @@ package server
import ( import (
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/hex"
"testing" "testing"
"github.com/nspcc-dev/neo-go/internal/testchain" "github.com/nspcc-dev/neo-go/internal/testchain"
@ -107,7 +108,7 @@ func TestAddNetworkFeeCalculateNetworkFee(t *testing.T) {
acc0 := wallet.NewAccountFromPrivateKey(testchain.PrivateKeyByID(0)) acc0 := wallet.NewAccountFromPrivateKey(testchain.PrivateKeyByID(0))
check := func(t *testing.T, extraFee int64) { check := func(t *testing.T, extraFee int64) {
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
tx.ValidUntilBlock = 20 tx.ValidUntilBlock = 25
tx.Signers = []transaction.Signer{{ tx.Signers = []transaction.Signer{{
Account: acc0.PrivateKey().GetScriptHash(), Account: acc0.PrivateKey().GetScriptHash(),
Scopes: transaction.CalledByEntry, Scopes: transaction.CalledByEntry,
@ -165,7 +166,7 @@ func TestAddNetworkFeeCalculateNetworkFee(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
check := func(t *testing.T, extraFee int64) { check := func(t *testing.T, extraFee int64) {
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
tx.ValidUntilBlock = 20 tx.ValidUntilBlock = 25
tx.Signers = []transaction.Signer{ tx.Signers = []transaction.Signer{
{ {
Account: acc0.PrivateKey().GetScriptHash(), Account: acc0.PrivateKey().GetScriptHash(),
@ -801,7 +802,7 @@ func TestClient_GetNativeContracts(t *testing.T) {
require.Equal(t, chain.GetNatives(), cs) require.Equal(t, chain.GetNatives(), cs)
} }
func TestClient_NEP11(t *testing.T) { func TestClient_NEP11_ND(t *testing.T) {
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t) chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
defer chain.Close() defer chain.Close()
defer func() { _ = rpcSrv.Shutdown() }() defer func() { _ = rpcSrv.Shutdown() }()
@ -810,7 +811,7 @@ func TestClient_NEP11(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, c.Init()) require.NoError(t, c.Init())
h, err := util.Uint160DecodeStringLE(nameServiceContractHash) h, err := util.Uint160DecodeStringLE(nnsContractHash)
require.NoError(t, err) require.NoError(t, err)
acc := testchain.PrivateKeyByID(0).GetScriptHash() acc := testchain.PrivateKeyByID(0).GetScriptHash()
@ -867,6 +868,73 @@ func TestClient_NEP11(t *testing.T) {
}) })
} }
func TestClient_NEP11_D(t *testing.T) {
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
defer chain.Close()
defer func() { _ = rpcSrv.Shutdown() }()
c, err := client.New(context.Background(), httpSrv.URL, client.Options{})
require.NoError(t, err)
require.NoError(t, c.Init())
priv0 := testchain.PrivateKeyByID(0).GetScriptHash()
priv1 := testchain.PrivateKeyByID(1).GetScriptHash()
token1ID, err := hex.DecodeString(nfsoToken1ID)
require.NoError(t, err)
t.Run("Decimals", func(t *testing.T) {
d, err := c.NEP11Decimals(nfsoHash)
require.NoError(t, err)
require.EqualValues(t, 2, d) // Divisible.
})
t.Run("TotalSupply", func(t *testing.T) {
s, err := c.NEP11TotalSupply(nfsoHash)
require.NoError(t, err)
require.EqualValues(t, 1, s) // the only NFSO of acc0
})
t.Run("Symbol", func(t *testing.T) {
sym, err := c.NEP11Symbol(nfsoHash)
require.NoError(t, err)
require.Equal(t, "NFSO", sym)
})
t.Run("TokenInfo", func(t *testing.T) {
tok, err := c.NEP11TokenInfo(nfsoHash)
require.NoError(t, err)
require.Equal(t, &wallet.Token{
Name: "NeoFS Object NFT",
Hash: nfsoHash,
Decimals: 2,
Symbol: "NFSO",
Standard: manifest.NEP11StandardName,
}, tok)
})
t.Run("BalanceOf", func(t *testing.T) {
b, err := c.NEP11BalanceOf(nfsoHash, priv0)
require.NoError(t, err)
require.EqualValues(t, 80, b)
})
t.Run("OwnerOf", func(t *testing.T) {
b, err := c.NEP11DOwnerOf(nfsoHash, token1ID)
require.NoError(t, err)
require.Equal(t, []util.Uint160{priv1, priv0}, b)
})
t.Run("Properties", func(t *testing.T) {
p, err := c.NEP11Properties(nfsoHash, token1ID)
require.NoError(t, err)
expected := stackitem.NewMap()
expected.Add(stackitem.Make([]byte("name")), stackitem.NewBuffer([]byte("NeoFS Object "+base64.StdEncoding.EncodeToString(token1ID))))
expected.Add(stackitem.Make([]byte("containerID")), stackitem.Make([]byte(base64.StdEncoding.EncodeToString(nfsoToken1ContainerID.BytesBE()))))
expected.Add(stackitem.Make([]byte("objectID")), stackitem.Make([]byte(base64.StdEncoding.EncodeToString(nfsoToken1ObjectID.BytesBE()))))
require.EqualValues(t, expected, p)
})
t.Run("Transfer", func(t *testing.T) {
_, err := c.TransferNEP11D(wallet.NewAccountFromPrivateKey(testchain.PrivateKeyByID(0)),
testchain.PrivateKeyByID(1).GetScriptHash(),
nfsoHash, 20, token1ID, nil, 0, nil)
require.NoError(t, err)
})
}
func TestClient_NNS(t *testing.T) { func TestClient_NNS(t *testing.T) {
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t) chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
defer chain.Close() defer chain.Close()
@ -876,34 +944,31 @@ func TestClient_NNS(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, c.Init()) require.NoError(t, c.Init())
nsHash, err := util.Uint160DecodeStringLE(nameServiceContractHash)
require.NoError(t, err)
t.Run("NNSIsAvailable, false", func(t *testing.T) { t.Run("NNSIsAvailable, false", func(t *testing.T) {
b, err := c.NNSIsAvailable(nsHash, "neo.com") b, err := c.NNSIsAvailable(nnsHash, "neo.com")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, false, b) require.Equal(t, false, b)
}) })
t.Run("NNSIsAvailable, true", func(t *testing.T) { t.Run("NNSIsAvailable, true", func(t *testing.T) {
b, err := c.NNSIsAvailable(nsHash, "neogo.com") b, err := c.NNSIsAvailable(nnsHash, "neogo.com")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, true, b) require.Equal(t, true, b)
}) })
t.Run("NNSResolve, good", func(t *testing.T) { t.Run("NNSResolve, good", func(t *testing.T) {
b, err := c.NNSResolve(nsHash, "neo.com", nns.A) b, err := c.NNSResolve(nnsHash, "neo.com", nns.A)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "1.2.3.4", b) require.Equal(t, "1.2.3.4", b)
}) })
t.Run("NNSResolve, bad", func(t *testing.T) { t.Run("NNSResolve, bad", func(t *testing.T) {
_, err := c.NNSResolve(nsHash, "neogo.com", nns.A) _, err := c.NNSResolve(nnsHash, "neogo.com", nns.A)
require.Error(t, err) require.Error(t, err)
}) })
t.Run("NNSResolve, forbidden", func(t *testing.T) { t.Run("NNSResolve, forbidden", func(t *testing.T) {
_, err := c.NNSResolve(nsHash, "neogo.com", nns.CNAME) _, err := c.NNSResolve(nnsHash, "neogo.com", nns.CNAME)
require.Error(t, err) require.Error(t, err)
}) })
t.Run("NNSGetAllRecords, good", func(t *testing.T) { t.Run("NNSGetAllRecords, good", func(t *testing.T) {
rss, err := c.NNSGetAllRecords(nsHash, "neo.com") rss, err := c.NNSGetAllRecords(nnsHash, "neo.com")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []nns.RecordState{ require.Equal(t, []nns.RecordState{
{ {
@ -914,7 +979,7 @@ func TestClient_NNS(t *testing.T) {
}, rss) }, rss)
}) })
t.Run("NNSGetAllRecords, bad", func(t *testing.T) { t.Run("NNSGetAllRecords, bad", func(t *testing.T) {
_, err := c.NNSGetAllRecords(nsHash, "neopython.com") _, err := c.NNSGetAllRecords(nnsHash, "neopython.com")
require.Error(t, err) require.Error(t, err)
}) })
} }

View file

@ -75,7 +75,7 @@ func getUnitTestChain(t testing.TB, enableOracle bool, enableNotary bool) (*core
} }
func getTestBlocks(t *testing.T) []*block.Block { func getTestBlocks(t *testing.T) []*block.Block {
// File "./testdata/testblocks.acc" was generated by function core._ // File "./testdata/testblocks.acc" was generated by function core.TestCreateBasicChain
// ("neo-go/pkg/core/helper_test.go"). // ("neo-go/pkg/core/helper_test.go").
// To generate new "./testdata/testblocks.acc", follow the steps: // To generate new "./testdata/testblocks.acc", follow the steps:
// 1. Rename the function // 1. Rename the function

View file

@ -61,30 +61,27 @@ type rpcTestCase struct {
check func(t *testing.T, e *executor, result interface{}) check func(t *testing.T, e *executor, result interface{})
} }
const testContractHash = "5c9e40a12055c6b9e3f72271c9779958c842135d" const genesisBlockHash = "a4ae00f6ac7496cac14e709fbf8b8ecb4c9831d8a6ee396056af9350fcf22671"
const deploymentTxHash = "8de63ea12ca8a9c5233ebf8664a442c881ae1bb83708d82da7fa1da2305ecf14" const testContractHash = "1ab08f5508edafa6f28e3db3227442a9e70aac52"
const genesisBlockHash = "0f8fb4e17d2ab9f3097af75ca7fd16064160fb8043db94909e00dd4e257b9dc4" const deploymentTxHash = "017c9edb217477aeb3e0c35462361209fdb7bf104dc8e285e2385af8713926b4"
const verifyContractHash = "f68822e4ecd93de334bdf1f7c409eda3431bcbd0" const (
const verifyContractAVM = "VwIAQS1RCDAhcAwU7p6iLCfjS9AUj8QQjgj3To9QSLLbMHFoE87bKGnbKJdA" verifyContractHash = "7deef31e5c616e157cdf02a5446f36d0a4eead52"
const verifyWithArgsContractHash = "947c780f45b2a3d32e946355ee5cb57faf4decb7" verifyContractAVM = "VwIAQS1RCDBwDBTunqIsJ+NL0BSPxBCOCPdOj1BIskrZMCQE2zBxaBPOStkoJATbKGlK2SgkBNsol0A="
const invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAANswcGhB+CfsjCGqJgQRQAwUDQ8DAgkAAgEDBwMEBQIBAA4GDAnbMHFpQfgn7IwhqiYEEkATQA==" verifyWithArgsContractHash = "6df009754ce475a6a5730c9e488f80e8e47bc1f1"
nnsContractHash = "1a7530a4c6cfdd40ffed40775aa5453febab24c0"
nnsToken1ID = "6e656f2e636f6d"
nfsoContractHash = "aaf8913c501e25c42877e79f04cb7c2c1ab47e57"
nfsoToken1ID = "7e244ffd6aa85fb1579d2ed22e9b761ab62e3486"
invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAAErZMCQE2zBwaEH4J+yMqiYEEUAMFA0PAwIJAAIBAwcDBAUCAQAOBgwJStkwJATbMHFpQfgn7IyqJgQSQBNA"
)
const nameServiceContractHash = "3a602b3e7cfd760850bfac44f4a9bb0ebad3e2dc" var (
nnsHash, _ = util.Uint160DecodeStringLE(nnsContractHash)
var NNSHash = util.Uint160{0xdc, 0xe2, 0xd3, 0xba, 0x0e, 0xbb, 0xa9, 0xf4, 0x44, 0xac, 0xbf, 0x50, 0x08, 0x76, 0xfd, 0x7c, 0x3e, 0x2b, 0x60, 0x3a} nfsoHash, _ = util.Uint160DecodeStringLE(nfsoContractHash)
nfsoToken1ContainerID = util.Uint256{1, 2, 3}
var nep11Reg = &result.NEP11Balances{ nfsoToken1ObjectID = util.Uint256{4, 5, 6}
Address: "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", )
Balances: []result.NEP11AssetBalance{{
Asset: NNSHash,
Tokens: []result.NEP11TokenBalance{{
ID: "6e656f2e636f6d",
Amount: "1",
LastUpdated: 14,
}},
}},
}
var rpcTestCases = map[string][]rpcTestCase{ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": { "getapplicationlog": {
@ -245,12 +242,14 @@ var rpcTestCases = map[string][]rpcTestCase{
{ {
name: "positive", name: "positive",
params: `["` + testchain.PrivateKeyByID(0).GetScriptHash().StringLE() + `"]`, params: `["` + testchain.PrivateKeyByID(0).GetScriptHash().StringLE() + `"]`,
result: func(e *executor) interface{} { return nep11Reg }, result: func(e *executor) interface{} { return &result.NEP11Balances{} },
check: checkNep11Balances,
}, },
{ {
name: "positive_address", name: "positive_address",
params: `["` + address.Uint160ToString(testchain.PrivateKeyByID(0).GetScriptHash()) + `"]`, params: `["` + address.Uint160ToString(testchain.PrivateKeyByID(0).GetScriptHash()) + `"]`,
result: func(e *executor) interface{} { return nep11Reg }, result: func(e *executor) interface{} { return &result.NEP11Balances{} },
check: checkNep11Balances,
}, },
}, },
"getnep11properties": { "getnep11properties": {
@ -266,21 +265,21 @@ var rpcTestCases = map[string][]rpcTestCase{
}, },
{ {
name: "no token", name: "no token",
params: `["` + NNSHash.StringLE() + `"]`, params: `["` + nnsContractHash + `"]`,
fail: true, fail: true,
}, },
{ {
name: "bad token", name: "bad token",
params: `["` + NNSHash.StringLE() + `", "abcdef"]`, params: `["` + nnsContractHash + `", "abcdef"]`,
fail: true, fail: true,
}, },
{ {
name: "positive", name: "positive",
params: `["` + NNSHash.StringLE() + `", "6e656f2e636f6d"]`, params: `["` + nnsContractHash + `", "6e656f2e636f6d"]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} {
return &map[string]interface{}{ return &map[string]interface{}{
"name": "neo.com", "name": "neo.com",
"expiration": "bhORxoMB", "expiration": "HrL+G4YB",
} }
}, },
}, },
@ -309,9 +308,8 @@ var rpcTestCases = map[string][]rpcTestCase{
{ {
name: "positive", name: "positive",
params: `["` + testchain.PrivateKeyByID(0).Address() + `", 0]`, params: `["` + testchain.PrivateKeyByID(0).Address() + `", 0]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} { return &result.NEP11Transfers{} },
return &result.NEP11Transfers{Sent: []result.NEP11Transfer{}, Received: []result.NEP11Transfer{{Timestamp: 0x17c6edfe76e, Asset: util.Uint160{0xdc, 0xe2, 0xd3, 0xba, 0xe, 0xbb, 0xa9, 0xf4, 0x44, 0xac, 0xbf, 0x50, 0x8, 0x76, 0xfd, 0x7c, 0x3e, 0x2b, 0x60, 0x3a}, Address: "", ID: "6e656f2e636f6d", Amount: "1", Index: 0xe, NotifyIndex: 0x0, TxHash: util.Uint256{0x5b, 0x5a, 0x5b, 0xae, 0xf2, 0xc5, 0x63, 0x8a, 0x2e, 0xcc, 0x77, 0x27, 0xd9, 0x6b, 0xb9, 0xda, 0x3a, 0x7f, 0x30, 0xaa, 0xcf, 0xda, 0x7f, 0x8a, 0x10, 0xd3, 0x23, 0xbf, 0xd, 0x1f, 0x28, 0x69}}}, Address: "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn"} check: checkNep11Transfers,
},
}, },
}, },
"getnep17balances": { "getnep17balances": {
@ -812,7 +810,7 @@ var rpcTestCases = map[string][]rpcTestCase{
require.True(t, ok) require.True(t, ok)
expected := result.UnclaimedGas{ expected := result.UnclaimedGas{
Address: testchain.MultisigScriptHash(), Address: testchain.MultisigScriptHash(),
Unclaimed: *big.NewInt(8000), Unclaimed: *big.NewInt(10500),
} }
assert.Equal(t, expected, *actual) assert.Equal(t, expected, *actual)
}, },
@ -882,16 +880,16 @@ var rpcTestCases = map[string][]rpcTestCase{
}, },
{ {
name: "positive, with notifications", name: "positive, with notifications",
params: `["` + NNSHash.StringLE() + `", "transfer", [{"type":"Hash160", "value":"0x0bcd2978634d961c24f5aea0802297ff128724d6"},{"type":"String", "value":"neo.com"},{"type":"Any", "value":null}],["0xb248508f4ef7088e10c48f14d04be3272ca29eee"]]`, params: `["` + nnsContractHash + `", "transfer", [{"type":"Hash160", "value":"0x0bcd2978634d961c24f5aea0802297ff128724d6"},{"type":"String", "value":"neo.com"},{"type":"Any", "value":null}],["0xb248508f4ef7088e10c48f14d04be3272ca29eee"]]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} {
script := []byte{0x0b, 0x0c, 0x07, 0x6e, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x0c, 0x14, 0xd6, 0x24, 0x87, 0x12, 0xff, 0x97, 0x22, 0x80, 0xa0, 0xae, 0xf5, 0x24, 0x1c, 0x96, 0x4d, 0x63, 0x78, 0x29, 0xcd, 0x0b, 0x13, 0xc0, 0x1f, 0x0c, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x0c, 0x14, 0xdc, 0xe2, 0xd3, 0xba, 0x0e, 0xbb, 0xa9, 0xf4, 0x44, 0xac, 0xbf, 0x50, 0x08, 0x76, 0xfd, 0x7c, 0x3e, 0x2b, 0x60, 0x3a, 0x41, 0x62, 0x7d, 0x5b, 0x52} script := []byte{0x0b, 0x0c, 0x07, 0x6e, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x0c, 0x14, 0xd6, 0x24, 0x87, 0x12, 0xff, 0x97, 0x22, 0x80, 0xa0, 0xae, 0xf5, 0x24, 0x1c, 0x96, 0x4d, 0x63, 0x78, 0x29, 0xcd, 0x0b, 0x13, 0xc0, 0x1f, 0x0c, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x0c, 0x14, 0xc0, 0x24, 0xab, 0xeb, 0x3f, 0x45, 0xa5, 0x5a, 0x77, 0x40, 0xed, 0xff, 0x40, 0xdd, 0xcf, 0xc6, 0xa4, 0x30, 0x75, 0x1a, 0x41, 0x62, 0x7d, 0x5b, 0x52}
return &result.Invoke{ return &result.Invoke{
State: "HALT", State: "HALT",
GasConsumed: 33767940, GasConsumed: 32167260,
Script: script, Script: script,
Stack: []stackitem.Item{stackitem.Make(true)}, Stack: []stackitem.Item{stackitem.Make(true)},
Notifications: []state.NotificationEvent{{ Notifications: []state.NotificationEvent{{
ScriptHash: NNSHash, ScriptHash: nnsHash,
Name: "Transfer", Name: "Transfer",
Item: stackitem.NewArray([]stackitem.Item{ Item: stackitem.NewArray([]stackitem.Item{
stackitem.Make([]byte{0xee, 0x9e, 0xa2, 0x2c, 0x27, 0xe3, 0x4b, 0xd0, 0x14, 0x8f, 0xc4, 0x10, 0x8e, 0x08, 0xf7, 0x4e, 0x8f, 0x50, 0x48, 0xb2}), stackitem.Make([]byte{0xee, 0x9e, 0xa2, 0x2c, 0x27, 0xe3, 0x4b, 0xd0, 0x14, 0x8f, 0xc4, 0x10, 0x8e, 0x08, 0xf7, 0x4e, 0x8f, 0x50, 0x48, 0xb2}),
@ -917,19 +915,19 @@ var rpcTestCases = map[string][]rpcTestCase{
chg := []storage.Operation{{ chg := []storage.Operation{{
State: "Changed", State: "Changed",
Key: []byte{0xfa, 0xff, 0xff, 0xff, 0xb}, Key: []byte{0xfa, 0xff, 0xff, 0xff, 0xb},
Value: []byte{0xbc, 0xf8, 0x8b, 0xa, 0x56, 0x79, 0x12}, Value: []byte{0xe8, 0x80, 0x64, 0xcb, 0x53, 0x79, 0x12},
}, { }, {
State: "Added", State: "Added",
Key: []byte{0xfb, 0xff, 0xff, 0xff, 0x14, 0xd6, 0x24, 0x87, 0x12, 0xff, 0x97, 0x22, 0x80, 0xa0, 0xae, 0xf5, 0x24, 0x1c, 0x96, 0x4d, 0x63, 0x78, 0x29, 0xcd, 0xb}, Key: []byte{0xfb, 0xff, 0xff, 0xff, 0x14, 0xd6, 0x24, 0x87, 0x12, 0xff, 0x97, 0x22, 0x80, 0xa0, 0xae, 0xf5, 0x24, 0x1c, 0x96, 0x4d, 0x63, 0x78, 0x29, 0xcd, 0xb},
Value: []byte{0x41, 0x3, 0x21, 0x1, 0x1, 0x21, 0x1, 0x11, 0x0}, Value: []byte{0x41, 0x3, 0x21, 0x1, 0x1, 0x21, 0x1, 0x16, 0},
}, { }, {
State: "Changed", State: "Changed",
Key: []byte{0xfb, 0xff, 0xff, 0xff, 0x14, 0xee, 0x9e, 0xa2, 0x2c, 0x27, 0xe3, 0x4b, 0xd0, 0x14, 0x8f, 0xc4, 0x10, 0x8e, 0x8, 0xf7, 0x4e, 0x8f, 0x50, 0x48, 0xb2}, Key: []byte{0xfb, 0xff, 0xff, 0xff, 0x14, 0xee, 0x9e, 0xa2, 0x2c, 0x27, 0xe3, 0x4b, 0xd0, 0x14, 0x8f, 0xc4, 0x10, 0x8e, 0x8, 0xf7, 0x4e, 0x8f, 0x50, 0x48, 0xb2},
Value: []byte{0x41, 0x3, 0x21, 0x4, 0x2f, 0xd9, 0xf5, 0x5, 0x21, 0x1, 0x11, 0x0}, Value: []byte{0x41, 0x3, 0x21, 0x4, 0x2f, 0xd9, 0xf5, 0x5, 0x21, 0x1, 0x16, 0},
}, { }, {
State: "Changed", State: "Changed",
Key: []byte{0xfa, 0xff, 0xff, 0xff, 0x14, 0xee, 0x9e, 0xa2, 0x2c, 0x27, 0xe3, 0x4b, 0xd0, 0x14, 0x8f, 0xc4, 0x10, 0x8e, 0x8, 0xf7, 0x4e, 0x8f, 0x50, 0x48, 0xb2}, Key: []byte{0xfa, 0xff, 0xff, 0xff, 0x14, 0xee, 0x9e, 0xa2, 0x2c, 0x27, 0xe3, 0x4b, 0xd0, 0x14, 0x8f, 0xc4, 0x10, 0x8e, 0x8, 0xf7, 0x4e, 0x8f, 0x50, 0x48, 0xb2},
Value: []byte{0x41, 0x1, 0x21, 0x5, 0x4, 0xfa, 0xb2, 0x9b, 0xd}, Value: []byte{0x41, 0x01, 0x21, 0x05, 0x9e, 0x0b, 0x0b, 0x18, 0x0b},
}} }}
// Can be returned in any order. // Can be returned in any order.
assert.ElementsMatch(t, chg, res.Diagnostics.Changes) assert.ElementsMatch(t, chg, res.Diagnostics.Changes)
@ -937,14 +935,14 @@ var rpcTestCases = map[string][]rpcTestCase{
}, },
{ {
name: "positive, verbose", name: "positive, verbose",
params: `["` + NNSHash.StringLE() + `", "resolve", [{"type":"String", "value":"neo.com"},{"type":"Integer","value":1}], [], true]`, params: `["` + nnsContractHash + `", "resolve", [{"type":"String", "value":"neo.com"},{"type":"Integer","value":1}], [], true]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} {
script := []byte{0x11, 0xc, 0x7, 0x6e, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x12, 0xc0, 0x1f, 0xc, 0x7, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0xc, 0x14, 0xdc, 0xe2, 0xd3, 0xba, 0xe, 0xbb, 0xa9, 0xf4, 0x44, 0xac, 0xbf, 0x50, 0x8, 0x76, 0xfd, 0x7c, 0x3e, 0x2b, 0x60, 0x3a, 0x41, 0x62, 0x7d, 0x5b, 0x52} script := []byte{0x11, 0xc, 0x7, 0x6e, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x12, 0xc0, 0x1f, 0xc, 0x7, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0xc, 0x14, 0xc0, 0x24, 0xab, 0xeb, 0x3f, 0x45, 0xa5, 0x5a, 0x77, 0x40, 0xed, 0xff, 0x40, 0xdd, 0xcf, 0xc6, 0xa4, 0x30, 0x75, 0x1a, 0x41, 0x62, 0x7d, 0x5b, 0x52}
stdHash, _ := e.chain.GetNativeContractScriptHash(nativenames.StdLib) stdHash, _ := e.chain.GetNativeContractScriptHash(nativenames.StdLib)
cryptoHash, _ := e.chain.GetNativeContractScriptHash(nativenames.CryptoLib) cryptoHash, _ := e.chain.GetNativeContractScriptHash(nativenames.CryptoLib)
return &result.Invoke{ return &result.Invoke{
State: "HALT", State: "HALT",
GasConsumed: 17958510, GasConsumed: 15928320,
Script: script, Script: script,
Stack: []stackitem.Item{stackitem.Make("1.2.3.4")}, Stack: []stackitem.Item{stackitem.Make("1.2.3.4")},
Notifications: []state.NotificationEvent{}, Notifications: []state.NotificationEvent{},
@ -954,7 +952,7 @@ var rpcTestCases = map[string][]rpcTestCase{
Current: hash.Hash160(script), Current: hash.Hash160(script),
Calls: []*vm.InvocationTree{ Calls: []*vm.InvocationTree{
{ {
Current: NNSHash, Current: nnsHash,
Calls: []*vm.InvocationTree{ Calls: []*vm.InvocationTree{
{ {
Current: stdHash, Current: stdHash,
@ -1834,7 +1832,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
require.NoErrorf(t, err, "could not parse response: %s", txOut) require.NoErrorf(t, err, "could not parse response: %s", txOut)
assert.Equal(t, *block.Transactions[0], actual.Transaction) assert.Equal(t, *block.Transactions[0], actual.Transaction)
assert.Equal(t, 17, actual.Confirmations) assert.Equal(t, 22, actual.Confirmations)
assert.Equal(t, TXHash, actual.Transaction.Hash()) assert.Equal(t, TXHash, actual.Transaction.Hash())
}) })
@ -1947,12 +1945,12 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
require.NoError(t, json.Unmarshal(res, actual)) require.NoError(t, json.Unmarshal(res, actual))
checkNep17TransfersAux(t, e, actual, sent, rcvd) checkNep17TransfersAux(t, e, actual, sent, rcvd)
} }
t.Run("time frame only", func(t *testing.T) { testNEP17T(t, 4, 5, 0, 0, []int{10, 11, 12, 13}, []int{2, 3}) }) t.Run("time frame only", func(t *testing.T) { testNEP17T(t, 4, 5, 0, 0, []int{14, 15, 16, 17}, []int{3, 4}) })
t.Run("no res", func(t *testing.T) { testNEP17T(t, 100, 100, 0, 0, []int{}, []int{}) }) t.Run("no res", func(t *testing.T) { testNEP17T(t, 100, 100, 0, 0, []int{}, []int{}) })
t.Run("limit", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 0, []int{7, 8}, []int{1}) }) t.Run("limit", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 0, []int{11, 12}, []int{2}) })
t.Run("limit 2", func(t *testing.T) { testNEP17T(t, 4, 5, 2, 0, []int{10}, []int{2}) }) t.Run("limit 2", func(t *testing.T) { testNEP17T(t, 4, 5, 2, 0, []int{14}, []int{3}) })
t.Run("limit with page", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 1, []int{9, 10}, []int{2}) }) t.Run("limit with page", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 1, []int{13, 14}, []int{3}) })
t.Run("limit with page 2", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 2, []int{11, 12}, []int{3}) }) t.Run("limit with page 2", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 2, []int{15, 16}, []int{4}) })
}) })
} }
@ -2036,6 +2034,39 @@ func doRPCCallOverHTTP(rpcCall string, url string, t *testing.T) []byte {
return bytes.TrimSpace(body) return bytes.TrimSpace(body)
} }
func checkNep11Balances(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.NEP11Balances)
require.True(t, ok)
expected := result.NEP11Balances{
Balances: []result.NEP11AssetBalance{
{
Asset: nnsHash,
Tokens: []result.NEP11TokenBalance{
{
ID: nnsToken1ID,
Amount: "1",
LastUpdated: 14,
},
},
},
{
Asset: nfsoHash,
Tokens: []result.NEP11TokenBalance{
{
ID: nfsoToken1ID,
Amount: "80",
LastUpdated: 21,
},
},
},
},
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
}
require.Equal(t, testchain.PrivateKeyByID(0).Address(), res.Address)
require.ElementsMatch(t, expected.Balances, res.Balances)
}
func checkNep17Balances(t *testing.T, e *executor, acc interface{}) { func checkNep17Balances(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.NEP17Balances) res, ok := acc.(*result.NEP17Balances)
require.True(t, ok) require.True(t, ok)
@ -2055,8 +2086,8 @@ func checkNep17Balances(t *testing.T, e *executor, acc interface{}) {
}, },
{ {
Asset: e.chain.UtilityTokenHash(), Asset: e.chain.UtilityTokenHash(),
Amount: "57796785740", Amount: "46748035310",
LastUpdated: 16, LastUpdated: 19,
}}, }},
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(), Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
} }
@ -2064,8 +2095,110 @@ func checkNep17Balances(t *testing.T, e *executor, acc interface{}) {
require.ElementsMatch(t, expected.Balances, res.Balances) require.ElementsMatch(t, expected.Balances, res.Balances)
} }
func checkNep11Transfers(t *testing.T, e *executor, acc interface{}) {
checkNep11TransfersAux(t, e, acc, []int{0}, []int{0, 1, 2})
}
func checkNep11TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rcvd []int) {
res, ok := acc.(*result.NEP11Transfers)
require.True(t, ok)
blockReceiveNFSO, err := e.chain.GetBlock(e.chain.GetHeaderHash(21)) // transfer 0.05 NFSO from priv1 back to priv0.
require.NoError(t, err)
require.Equal(t, 1, len(blockReceiveNFSO.Transactions))
txReceiveNFSO := blockReceiveNFSO.Transactions[0]
blockSendNFSO, err := e.chain.GetBlock(e.chain.GetHeaderHash(19)) // transfer 0.25 NFSO from priv0 to priv1.
require.NoError(t, err)
require.Equal(t, 1, len(blockSendNFSO.Transactions))
txSendNFSO := blockSendNFSO.Transactions[0]
blockMintNFSO, err := e.chain.GetBlock(e.chain.GetHeaderHash(18)) // mint 1.00 NFSO token by transferring 10 GAS to NFSO contract.
require.NoError(t, err)
require.Equal(t, 1, len(blockMintNFSO.Transactions))
txMintNFSO := blockMintNFSO.Transactions[0]
blockRegisterNSRecordA, err := e.chain.GetBlock(e.chain.GetHeaderHash(14)) // register `neo.com` with A record type and priv0 owner via NS
require.NoError(t, err)
require.Equal(t, 1, len(blockRegisterNSRecordA.Transactions))
txRegisterNSRecordA := blockRegisterNSRecordA.Transactions[0]
// These are laid out here explicitly for 2 purposes:
// * to be able to reference any particular event for paging
// * to check chain events consistency
// Technically these could be retrieved from application log, but that would almost
// duplicate the Server method.
expected := result.NEP11Transfers{
Sent: []result.NEP11Transfer{
{
Timestamp: blockSendNFSO.Timestamp,
Asset: nfsoHash,
Address: testchain.PrivateKeyByID(1).Address(), // to priv1
ID: nfsoToken1ID, // NFSO ID
Amount: big.NewInt(25).String(),
Index: 19,
TxHash: txSendNFSO.Hash(),
},
},
Received: []result.NEP11Transfer{
{
Timestamp: blockReceiveNFSO.Timestamp,
Asset: nfsoHash,
ID: nfsoToken1ID,
Address: testchain.PrivateKeyByID(1).Address(), // from priv1
Amount: "5",
Index: 21,
TxHash: txReceiveNFSO.Hash(),
},
{
Timestamp: blockMintNFSO.Timestamp,
Asset: nfsoHash,
ID: nfsoToken1ID,
Address: "", // minting
Amount: "100",
Index: 18,
TxHash: txMintNFSO.Hash(),
},
{
Timestamp: blockRegisterNSRecordA.Timestamp,
Asset: nnsHash,
ID: nnsToken1ID,
Address: "", // minting
Amount: "1",
Index: 14,
TxHash: txRegisterNSRecordA.Hash(),
},
},
Address: testchain.PrivateKeyByID(0).Address(),
}
require.Equal(t, expected.Address, res.Address)
arr := make([]result.NEP11Transfer, 0, len(expected.Sent))
for i := range expected.Sent {
for _, j := range sent {
if i == j {
arr = append(arr, expected.Sent[i])
break
}
}
}
require.Equal(t, arr, res.Sent)
arr = arr[:0]
for i := range expected.Received {
for _, j := range rcvd {
if i == j {
arr = append(arr, expected.Received[i])
break
}
}
}
require.Equal(t, arr, res.Received)
}
func checkNep17Transfers(t *testing.T, e *executor, acc interface{}) { func checkNep17Transfers(t *testing.T, e *executor, acc interface{}) {
checkNep17TransfersAux(t, e, acc, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, []int{0, 1, 2, 3, 4, 5, 6, 7}) checkNep17TransfersAux(t, e, acc, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, []int{0, 1, 2, 3, 4, 5, 6, 7, 8})
} }
func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rcvd []int) { func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rcvd []int) {
@ -2074,6 +2207,21 @@ func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rc
rublesHash, err := util.Uint160DecodeStringLE(testContractHash) rublesHash, err := util.Uint160DecodeStringLE(testContractHash)
require.NoError(t, err) require.NoError(t, err)
blockTransferNFSO, err := e.chain.GetBlock(e.chain.GetHeaderHash(19)) // transfer 0.25 NFSO from priv0 to priv1.
require.NoError(t, err)
require.Equal(t, 1, len(blockTransferNFSO.Transactions))
txTransferNFSO := blockTransferNFSO.Transactions[0]
blockMintNFSO, err := e.chain.GetBlock(e.chain.GetHeaderHash(18)) // mint 1.00 NFSO token for priv0 by transferring 10 GAS to NFSO contract.
require.NoError(t, err)
require.Equal(t, 1, len(blockMintNFSO.Transactions))
txMintNFSO := blockMintNFSO.Transactions[0]
blockDeploy5, err := e.chain.GetBlock(e.chain.GetHeaderHash(17)) // deploy NeoFS Object contract (NEP11-Divisible)
require.NoError(t, err)
require.Equal(t, 1, len(blockDeploy5.Transactions))
txDeploy5 := blockDeploy5.Transactions[0]
blockPutNewTestValue, err := e.chain.GetBlock(e.chain.GetHeaderHash(16)) // invoke `put` method of `test_contract.go` with `testkey`, `newtestvalue` args blockPutNewTestValue, err := e.chain.GetBlock(e.chain.GetHeaderHash(16)) // invoke `put` method of `test_contract.go` with `testkey`, `newtestvalue` args
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, len(blockPutNewTestValue.Transactions)) require.Equal(t, 1, len(blockPutNewTestValue.Transactions))
@ -2155,6 +2303,39 @@ func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rc
// duplicate the Server method. // duplicate the Server method.
expected := result.NEP17Transfers{ expected := result.NEP17Transfers{
Sent: []result.NEP17Transfer{ Sent: []result.NEP17Transfer{
{
Timestamp: blockTransferNFSO.Timestamp,
Asset: e.chain.UtilityTokenHash(),
Address: "", // burn
Amount: big.NewInt(txTransferNFSO.SystemFee + txTransferNFSO.NetworkFee).String(),
Index: 19,
TxHash: blockTransferNFSO.Hash(),
},
{
Timestamp: blockMintNFSO.Timestamp,
Asset: e.chain.UtilityTokenHash(),
Address: address.Uint160ToString(nfsoHash),
Amount: "1000000000",
Index: 18,
NotifyIndex: 0,
TxHash: txMintNFSO.Hash(),
},
{
Timestamp: blockMintNFSO.Timestamp,
Asset: e.chain.UtilityTokenHash(),
Address: "", // burn
Amount: big.NewInt(txMintNFSO.SystemFee + txMintNFSO.NetworkFee).String(),
Index: 18,
TxHash: blockMintNFSO.Hash(),
},
{
Timestamp: blockDeploy5.Timestamp,
Asset: e.chain.UtilityTokenHash(),
Address: "", // burn
Amount: big.NewInt(txDeploy5.SystemFee + txDeploy5.NetworkFee).String(),
Index: 17,
TxHash: blockDeploy5.Hash(),
},
{ {
Timestamp: blockPutNewTestValue.Timestamp, Timestamp: blockPutNewTestValue.Timestamp,
Asset: e.chain.UtilityTokenHash(), Asset: e.chain.UtilityTokenHash(),
@ -2288,6 +2469,15 @@ func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rc
}, },
}, },
Received: []result.NEP17Transfer{ Received: []result.NEP17Transfer{
{
Timestamp: blockMintNFSO.Timestamp, // GAS bounty
Asset: e.chain.UtilityTokenHash(),
Address: "",
Amount: "50000000",
Index: 18,
NotifyIndex: 0,
TxHash: blockMintNFSO.Hash(),
},
{ {
Timestamp: blockGASBounty2.Timestamp, Timestamp: blockGASBounty2.Timestamp,
Asset: e.chain.UtilityTokenHash(), Asset: e.chain.UtilityTokenHash(),

Binary file not shown.