github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/rpcclient/rpc_test.go (about) 1 package rpcclient 2 3 import ( 4 "context" 5 "encoding/base64" 6 "encoding/hex" 7 "encoding/json" 8 "fmt" 9 "math/big" 10 "net/http" 11 "net/http/httptest" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/gorilla/websocket" 17 "github.com/nspcc-dev/neo-go/internal/testserdes" 18 "github.com/nspcc-dev/neo-go/pkg/config" 19 "github.com/nspcc-dev/neo-go/pkg/config/netmode" 20 "github.com/nspcc-dev/neo-go/pkg/core/block" 21 "github.com/nspcc-dev/neo-go/pkg/core/state" 22 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 23 "github.com/nspcc-dev/neo-go/pkg/crypto/hash" 24 "github.com/nspcc-dev/neo-go/pkg/crypto/keys" 25 "github.com/nspcc-dev/neo-go/pkg/encoding/address" 26 "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" 27 "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" 28 "github.com/nspcc-dev/neo-go/pkg/io" 29 "github.com/nspcc-dev/neo-go/pkg/neorpc/result" 30 "github.com/nspcc-dev/neo-go/pkg/services/rpcsrv/params" 31 "github.com/nspcc-dev/neo-go/pkg/smartcontract" 32 "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" 33 "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" 34 "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" 35 "github.com/nspcc-dev/neo-go/pkg/util" 36 "github.com/nspcc-dev/neo-go/pkg/vm/opcode" 37 "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" 38 "github.com/nspcc-dev/neo-go/pkg/vm/vmstate" 39 "github.com/stretchr/testify/assert" 40 "github.com/stretchr/testify/require" 41 ) 42 43 type rpcClientTestCase struct { 44 name string 45 invoke func(c *Client) (any, error) 46 fails bool 47 serverResponse string 48 result func(c *Client) any 49 check func(t *testing.T, c *Client, result any) 50 } 51 52 const base64B1 = "AAAAAMSdeyVO3QCekJTbQ4D7YEEGFv2nXPd6CfO5Kn3htI8P9tVA4+VXLyyMG12BUj6qB3CZ+JIFwWCcDF+KBHH0VSjJICSkegEAAAAAAAAAAAAAAQAAAABouegejA5skHm0udEF6HinbT8iPwHGDEBg0hpK90iZlB4ZSCG7BOr7BsvPXGDax360lvqKeNFuzaGI1RYNH50/dhQLxocy90JdsIOyodd1sOJGEjZIt7ztDEAHc2avJzz6tK+FOQMIZO/FEEikJdLJX0+iZXFcsmDRpB7lo2wWMSQbcoTXNg7leuR0VeDsKJ+YdvCuTG5WbiqWDECa6Yjj+bK4te5KR5jdLF5kLt03csyozZcd/X7NPt89IsX01zpX8ec3e+B2qySJIOhEf3cK0i+5U5wyXiFcRI8xkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBntDcOgIAAgAAAMDYpwAAAAAADHlDAAAAAACwBAAAAWi56B6MDmyQebS50QXoeKdtPyI/AQBbCwIY3fUFDBTunqIsJ+NL0BSPxBCOCPdOj1BIsgwUaLnoHowObJB5tLnRBeh4p20/Ij8UwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQHGDEC8InWg8rQHWjklRojobu7kn4r0xZY2xWYs15ggVX4PQyEHpNTU6vZHT2TXRdPXAOKHhgWAttO0oTvo+9VZAjIVDEBF0qvBMlvmYJIYLqSoCjhBykcSN78UXrBjO5BKL8BpHtejWCld1VT6Z7nYrEBLgySD6HeMcp/fa6vqHzU220e/DECXtm5AA1jy9GFA7t8U6a+1uPrQFk4Ufp0UyXsun0PvN0NdhrHc37xm8k9Z0dB85V/7WLtkMaLLyjVNVIKImC76kxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBntDcOgADAAAAwNinAAAAAACsiEMAAAAAALAEAAABaLnoHowObJB5tLnRBeh4p20/Ij8BAF8LAwDodkgXAAAADBTunqIsJ+NL0BSPxBCOCPdOj1BIsgwUaLnoHowObJB5tLnRBeh4p20/Ij8UwB8MCHRyYW5zZmVyDBTPduKL0AYsSkeO41VhARMZ88+k0kFifVtSOQHGDEDgj/SQT84EbWRZ4ZKhyjJTuLwVPDgVlQO3CGmgacItvni9nziJvTxziZXBG/0Hqkv68ddS1EH94RtWlqLQWRCjDEAWZUeSQ8KskILSvoWPN3836xpg/TYzOGiFVoePv91CFnap4fRFxdbporBgnZ/sUsjFZ74U8f+r0riqtvkdMMyGDEDx5iho79oDVYOCwIDH3K1UeDjAT6Hq9YsD9SCfJSE1rRsAdJPh2StYxdh9Jah1lwGbW0U+Wu6zpbVFf5CS6fFckxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBntDcOg==" 53 54 const base64TxMoveNeo = "AAIAAADA2KcAAAAAAAx5QwAAAAAAsAQAAAFouegejA5skHm0udEF6HinbT8iPwEAWwsCGN31BQwU7p6iLCfjS9AUj8QQjgj3To9QSLIMFGi56B6MDmyQebS50QXoeKdtPyI/FMAfDAh0cmFuc2ZlcgwU9WPqQLwoPU0OBcSOowWz8qBzQO9BYn1bUjkBxgxAvCJ1oPK0B1o5JUaI6G7u5J+K9MWWNsVmLNeYIFV+D0MhB6TU1Or2R09k10XT1wDih4YFgLbTtKE76PvVWQIyFQxARdKrwTJb5mCSGC6kqAo4QcpHEje/FF6wYzuQSi/AaR7Xo1gpXdVU+me52KxAS4Mkg+h3jHKf32ur6h81NttHvwxAl7ZuQANY8vRhQO7fFOmvtbj60BZOFH6dFMl7Lp9D7zdDXYax3N+8ZvJPWdHQfOVf+1i7ZDGiy8o1TVSCiJgu+pMTDCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4MIQKnvFX+hoTgEZdo0QS6MHlb3MhmGehkrdJhVnI+0YXNYgwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CDCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkUQZ7Q3Do=" 55 56 const b1Verbose = `{"size":1438,"nextblockhash":"0x34c20650683940a7af1881c2798e83acf9bf98aa226025af6c1d32b5530cc900","confirmations":15,"hash":"0x88c1cbf68695f73fb7b7d185c0037ffebdf032327488ebe65e0533d269e7de9b","version":0,"previousblockhash":"0x0f8fb4e17d2ab9f3097af75ca7fd16064160fb8043db94909e00dd4e257b9dc4","merkleroot":"0x2855f471048a5f0c9c60c10592f8997007aa3e52815d1b8c2c2f57e5e340d5f6","time":1626251469001,"nonce":"0","index":1,"nextconsensus":"NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq","primary":0,"witnesses":[{"invocation":"DEBg0hpK90iZlB4ZSCG7BOr7BsvPXGDax360lvqKeNFuzaGI1RYNH50/dhQLxocy90JdsIOyodd1sOJGEjZIt7ztDEAHc2avJzz6tK+FOQMIZO/FEEikJdLJX0+iZXFcsmDRpB7lo2wWMSQbcoTXNg7leuR0VeDsKJ+YdvCuTG5WbiqWDECa6Yjj+bK4te5KR5jdLF5kLt03csyozZcd/X7NPt89IsX01zpX8ec3e+B2qySJIOhEf3cK0i+5U5wyXiFcRI8x","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6"}],"tx":[{"hash":"0xf01080c50f3198f5a539c4a06d024f1b8bdc2a360a215fa7e2488f79a56d501a","size":488,"version":0,"nonce":2,"sender":"NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq","sysfee":"11000000","netfee":"4421900","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x3f223f6da778e805d1b9b479906c0e8c1ee8b968","scopes":"CalledByEntry"}],"script":"CwIY3fUFDBTunqIsJ+NL0BSPxBCOCPdOj1BIsgwUaLnoHowObJB5tLnRBeh4p20/Ij8UwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQ==","witnesses":[{"invocation":"DEC8InWg8rQHWjklRojobu7kn4r0xZY2xWYs15ggVX4PQyEHpNTU6vZHT2TXRdPXAOKHhgWAttO0oTvo+9VZAjIVDEBF0qvBMlvmYJIYLqSoCjhBykcSN78UXrBjO5BKL8BpHtejWCld1VT6Z7nYrEBLgySD6HeMcp/fa6vqHzU220e/DECXtm5AA1jy9GFA7t8U6a+1uPrQFk4Ufp0UyXsun0PvN0NdhrHc37xm8k9Z0dB85V/7WLtkMaLLyjVNVIKImC76","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6"}]},{"hash":"0xced32af656e144f6be5d7172ed37747831456cb3eeaac4ee964d0b479b45d3a8","size":492,"version":0,"nonce":3,"sender":"NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq","sysfee":"11000000","netfee":"4425900","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x3f223f6da778e805d1b9b479906c0e8c1ee8b968","scopes":"CalledByEntry"}],"script":"CwMA6HZIFwAAAAwU7p6iLCfjS9AUj8QQjgj3To9QSLIMFGi56B6MDmyQebS50QXoeKdtPyI/FMAfDAh0cmFuc2ZlcgwUz3bii9AGLEpHjuNVYQETGfPPpNJBYn1bUjk=","witnesses":[{"invocation":"DEDgj/SQT84EbWRZ4ZKhyjJTuLwVPDgVlQO3CGmgacItvni9nziJvTxziZXBG/0Hqkv68ddS1EH94RtWlqLQWRCjDEAWZUeSQ8KskILSvoWPN3836xpg/TYzOGiFVoePv91CFnap4fRFxdbporBgnZ/sUsjFZ74U8f+r0riqtvkdMMyGDEDx5iho79oDVYOCwIDH3K1UeDjAT6Hq9YsD9SCfJSE1rRsAdJPh2StYxdh9Jah1lwGbW0U+Wu6zpbVFf5CS6fFc","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6"}]}]}` 57 58 const base64Header1 = "AAAAAMSdeyVO3QCekJTbQ4D7YEEGFv2nXPd6CfO5Kn3htI8P9tVA4+VXLyyMG12BUj6qB3CZ+JIFwWCcDF+KBHH0VSjJICSkegEAAAAAAAAAAAAAAQAAAABouegejA5skHm0udEF6HinbT8iPwHGDEBg0hpK90iZlB4ZSCG7BOr7BsvPXGDax360lvqKeNFuzaGI1RYNH50/dhQLxocy90JdsIOyodd1sOJGEjZIt7ztDEAHc2avJzz6tK+FOQMIZO/FEEikJdLJX0+iZXFcsmDRpB7lo2wWMSQbcoTXNg7leuR0VeDsKJ+YdvCuTG5WbiqWDECa6Yjj+bK4te5KR5jdLF5kLt03csyozZcd/X7NPt89IsX01zpX8ec3e+B2qySJIOhEf3cK0i+5U5wyXiFcRI8xkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBntDcOg==" 59 60 const header1Verbose = `{"hash":"0x88c1cbf68695f73fb7b7d185c0037ffebdf032327488ebe65e0533d269e7de9b","size":457,"version":0,"previousblockhash":"0x0f8fb4e17d2ab9f3097af75ca7fd16064160fb8043db94909e00dd4e257b9dc4","merkleroot":"0x2855f471048a5f0c9c60c10592f8997007aa3e52815d1b8c2c2f57e5e340d5f6","time":1626251469001,"index":1,"nextconsensus":"NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq","witnesses":[{"invocation":"DEBg0hpK90iZlB4ZSCG7BOr7BsvPXGDax360lvqKeNFuzaGI1RYNH50/dhQLxocy90JdsIOyodd1sOJGEjZIt7ztDEAHc2avJzz6tK+FOQMIZO/FEEikJdLJX0+iZXFcsmDRpB7lo2wWMSQbcoTXNg7leuR0VeDsKJ+YdvCuTG5WbiqWDECa6Yjj+bK4te5KR5jdLF5kLt03csyozZcd/X7NPt89IsX01zpX8ec3e+B2qySJIOhEf3cK0i+5U5wyXiFcRI8x","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6"}],"confirmations":15,"nextblockhash":"0x34c20650683940a7af1881c2798e83acf9bf98aa226025af6c1d32b5530cc900"}` 61 62 const txMoveNeoVerbose = `{"blockhash":"0x88c1cbf68695f73fb7b7d185c0037ffebdf032327488ebe65e0533d269e7de9b","confirmations":15,"blocktime":1626251469001,"vmstate":"HALT","hash":"0xf01080c50f3198f5a539c4a06d024f1b8bdc2a360a215fa7e2488f79a56d501a","size":488,"version":0,"nonce":2,"sender":"NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq","sysfee":"11000000","netfee":"4421900","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x3f223f6da778e805d1b9b479906c0e8c1ee8b968","scopes":"CalledByEntry"}],"script":"CwIY3fUFDBTunqIsJ+NL0BSPxBCOCPdOj1BIsgwUaLnoHowObJB5tLnRBeh4p20/Ij8UwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQ==","witnesses":[{"invocation":"DEC8InWg8rQHWjklRojobu7kn4r0xZY2xWYs15ggVX4PQyEHpNTU6vZHT2TXRdPXAOKHhgWAttO0oTvo+9VZAjIVDEBF0qvBMlvmYJIYLqSoCjhBykcSN78UXrBjO5BKL8BpHtejWCld1VT6Z7nYrEBLgySD6HeMcp/fa6vqHzU220e/DECXtm5AA1jy9GFA7t8U6a+1uPrQFk4Ufp0UyXsun0PvN0NdhrHc37xm8k9Z0dB85V/7WLtkMaLLyjVNVIKImC76","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6"}]}` 63 64 // getResultBlock1 returns data for block number 1 which is used by several tests. 65 func getResultBlock1() *result.Block { 66 binB, err := base64.StdEncoding.DecodeString(base64B1) 67 if err != nil { 68 panic(err) 69 } 70 b := block.New(false) 71 err = testserdes.DecodeBinary(binB, b) 72 if err != nil { 73 panic(err) 74 } 75 b2Hash, err := util.Uint256DecodeStringLE("34c20650683940a7af1881c2798e83acf9bf98aa226025af6c1d32b5530cc900") 76 if err != nil { 77 panic(err) 78 } 79 return &result.Block{ 80 Block: *b, 81 BlockMetadata: result.BlockMetadata{ 82 Size: 1438, 83 NextBlockHash: &b2Hash, 84 Confirmations: 15, 85 }, 86 } 87 } 88 89 func getTxMoveNeo() *result.TransactionOutputRaw { 90 b1 := getResultBlock1() 91 txBin, err := base64.StdEncoding.DecodeString(base64TxMoveNeo) 92 if err != nil { 93 panic(err) 94 } 95 tx, err := transaction.NewTransactionFromBytes(txBin) 96 if err != nil { 97 panic(err) 98 } 99 return &result.TransactionOutputRaw{ 100 Transaction: *tx, 101 TransactionMetadata: result.TransactionMetadata{ 102 Timestamp: b1.Timestamp, 103 Blockhash: b1.Block.Hash(), 104 Confirmations: int(b1.Confirmations), 105 VMState: "HALT", 106 }, 107 } 108 } 109 110 // rpcClientTestCases contains `serverResponse` json data fetched from examples 111 // published in the official C# JSON-RPC API v2.10.3 reference 112 // (see https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api.html) 113 var rpcClientTestCases = map[string][]rpcClientTestCase{ 114 "getapplicationlog": { 115 { 116 name: "positive", 117 invoke: func(c *Client) (any, error) { 118 return c.GetApplicationLog(util.Uint256{}, nil) 119 }, 120 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","executions":[{"trigger":"Application","vmstate":"HALT","gasconsumed":"1","stack":[{"type":"Integer","value":"1"}],"notifications":[]}]}}`, 121 result: func(c *Client) any { 122 txHash, err := util.Uint256DecodeStringLE("17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521") 123 if err != nil { 124 panic(err) 125 } 126 return &result.ApplicationLog{ 127 Container: txHash, 128 Executions: []state.Execution{ 129 { 130 Trigger: trigger.Application, 131 VMState: vmstate.Halt, 132 GasConsumed: 1, 133 Stack: []stackitem.Item{stackitem.NewBigInteger(big.NewInt(1))}, 134 Events: []state.NotificationEvent{}, 135 }, 136 }, 137 } 138 }, 139 }, 140 }, 141 "getbestblockhash": { 142 { 143 name: "positive", 144 invoke: func(c *Client) (any, error) { 145 return c.GetBestBlockHash() 146 }, 147 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"0x773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e"}`, 148 result: func(c *Client) any { 149 result, err := util.Uint256DecodeStringLE("773dd2dae4a9c9275290f89b56e67d7363ea4826dfd4fc13cc01cf73a44b0d0e") 150 if err != nil { 151 panic(err) 152 } 153 return result 154 }, 155 }, 156 }, 157 "getblock": { 158 { 159 name: "byIndex_positive", 160 invoke: func(c *Client) (any, error) { 161 return c.GetBlockByIndex(1) 162 }, 163 serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + base64B1 + `"}`, 164 result: func(c *Client) any { 165 b := getResultBlock1() 166 return &b.Block 167 }, 168 }, 169 { 170 name: "byIndex_verbose_positive", 171 invoke: func(c *Client) (i any, err error) { 172 return c.GetBlockByIndexVerbose(1) 173 }, 174 serverResponse: `{"id":1,"jsonrpc":"2.0","result":` + b1Verbose + `}`, 175 result: func(c *Client) any { 176 res := getResultBlock1() 177 return res 178 }, 179 }, 180 { 181 name: "byHash_positive", 182 invoke: func(c *Client) (any, error) { 183 hash, err := util.Uint256DecodeStringLE("d151651e86680a7ecbc87babf3346a42e7bc9974414ce192c9c22ac4f2e9d043") 184 if err != nil { 185 panic(err) 186 } 187 return c.GetBlockByHash(hash) 188 }, 189 serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + base64B1 + `"}`, 190 result: func(c *Client) any { 191 b := getResultBlock1() 192 return &b.Block 193 }, 194 }, 195 { 196 name: "byHash_verbose_positive", 197 invoke: func(c *Client) (i any, err error) { 198 hash, err := util.Uint256DecodeStringLE("86fe1061140b2ea791b0739fb9732abc6e5e47de4927228a1ac41de3d93eb7cb") 199 if err != nil { 200 panic(err) 201 } 202 return c.GetBlockByHashVerbose(hash) 203 }, 204 serverResponse: `{"id":1,"jsonrpc":"2.0","result":` + b1Verbose + `}`, 205 result: func(c *Client) any { 206 res := getResultBlock1() 207 return res 208 }, 209 }, 210 }, 211 "getblockcount": { 212 { 213 name: "positive", 214 invoke: func(c *Client) (any, error) { 215 return c.GetBlockCount() 216 }, 217 serverResponse: `{"jsonrpc":"2.0","id":1,"result":991991}`, 218 result: func(c *Client) any { 219 return uint32(991991) 220 }, 221 }, 222 }, 223 "getblockhash": { 224 { 225 name: "positive", 226 invoke: func(c *Client) (any, error) { 227 return c.GetBlockHash(1) 228 }, 229 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"0x4c1e879872344349067c3b1a30781eeb4f9040d3795db7922f513f6f9660b9b2"}`, 230 result: func(c *Client) any { 231 hash, err := util.Uint256DecodeStringLE("4c1e879872344349067c3b1a30781eeb4f9040d3795db7922f513f6f9660b9b2") 232 if err != nil { 233 panic(err) 234 } 235 return hash 236 }, 237 }, 238 }, 239 "getblockheader": { 240 { 241 name: "positive", 242 invoke: func(c *Client) (any, error) { 243 hash, err := util.Uint256DecodeStringLE("68e4bd688b852e807eef13a0ff7da7b02223e359a35153667e88f9cb4a3b0801") 244 if err != nil { 245 panic(err) 246 } 247 return c.GetBlockHeader(hash) 248 }, 249 serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + base64Header1 + `"}`, 250 result: func(c *Client) any { 251 b := getResultBlock1() 252 return &b.Header 253 }, 254 }, 255 { 256 name: "verbose_positive", 257 invoke: func(c *Client) (i any, err error) { 258 hash, err := util.Uint256DecodeStringLE("cbb73ed9e31dc41a8a222749de475e6ebc2a73b99f73b091a72e0b146110fe86") 259 if err != nil { 260 panic(err) 261 } 262 return c.GetBlockHeaderVerbose(hash) 263 }, 264 serverResponse: `{"id":1,"jsonrpc":"2.0","result":` + header1Verbose + `}`, 265 result: func(c *Client) any { 266 b := getResultBlock1() 267 return &result.Header{ 268 Header: b.Header, 269 BlockMetadata: result.BlockMetadata{ 270 Size: 457, 271 NextBlockHash: b.NextBlockHash, 272 Confirmations: b.Confirmations, 273 }, 274 } 275 }, 276 }, 277 }, 278 "getblockheadercount": { 279 { 280 name: "positive", 281 invoke: func(c *Client) (any, error) { 282 return c.GetBlockHeaderCount() 283 }, 284 serverResponse: `{"jsonrpc":"2.0","id":1,"result":2021}`, 285 result: func(c *Client) any { 286 return uint32(2021) 287 }, 288 }, 289 }, 290 "getblocksysfee": { 291 { 292 name: "positive", 293 invoke: func(c *Client) (any, error) { 294 return c.GetBlockSysFee(1) 295 }, 296 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"195500"}`, 297 result: func(c *Client) any { 298 return fixedn.Fixed8FromInt64(195500) 299 }, 300 }, 301 }, 302 "getcommittee": { 303 { 304 name: "positive", 305 invoke: func(c *Client) (any, error) { 306 return c.GetCommittee() 307 }, 308 serverResponse: `{"jsonrpc":"2.0","id":1,"result":["02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e"]}`, 309 result: func(c *Client) any { 310 member, err := keys.NewPublicKeyFromString("02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e") 311 if err != nil { 312 panic(fmt.Errorf("failed to decode public key: %w", err)) 313 } 314 return keys.PublicKeys{member} 315 }, 316 }, 317 }, 318 "getconnectioncount": { 319 { 320 name: "positive", 321 invoke: func(c *Client) (any, error) { 322 return c.GetConnectionCount() 323 }, 324 serverResponse: `{"jsonrpc":"2.0","id":1,"result":10}`, 325 result: func(c *Client) any { 326 return 10 327 }, 328 }, 329 }, 330 "getcontractstate": { 331 { 332 name: "positive, by hash", 333 invoke: func(c *Client) (any, error) { 334 hash, err := util.Uint160DecodeStringLE("1b4357bff5a01bdf2a6581247cf9ed1e24629176") 335 if err != nil { 336 panic(err) 337 } 338 return c.GetContractStateByHash(hash) 339 }, 340 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"nef":{"magic":860243278,"compiler":"neo-go-3.0","script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","checksum":2512077441},"manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"features":{},"permissions":[],"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`, 341 result: func(c *Client) any { 342 script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==") 343 if err != nil { 344 panic(err) 345 } 346 m := manifest.NewManifest("Test") 347 cs := &state.Contract{ 348 ContractBase: state.ContractBase{ 349 ID: 0, 350 Hash: hash.Hash160(script), 351 NEF: newTestNEF(script), 352 Manifest: *m, 353 }, 354 } 355 return cs 356 }, 357 }, 358 { 359 name: "positive, by address", 360 invoke: func(c *Client) (any, error) { 361 return c.GetContractStateByAddressOrName("NWiu5oejTu925aeL9Hc1LX8SvaJhE23h15") 362 }, 363 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"nef":{"magic":860243278,"compiler":"neo-go-3.0","script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","checksum":2512077441},"manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"features":{},"permissions":[],"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`, 364 result: func(c *Client) any { 365 script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==") 366 if err != nil { 367 panic(err) 368 } 369 m := manifest.NewManifest("Test") 370 cs := &state.Contract{ 371 ContractBase: state.ContractBase{ 372 ID: 0, 373 Hash: hash.Hash160(script), 374 NEF: newTestNEF(script), 375 Manifest: *m, 376 }, 377 } 378 return cs 379 }, 380 }, 381 { 382 name: "positive, by id", 383 invoke: func(c *Client) (any, error) { 384 return c.GetContractStateByID(0) 385 }, 386 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"nef":{"magic":860243278,"compiler":"neo-go-3.0","script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","checksum":2512077441},"manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"features":{},"permissions":[],"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`, 387 result: func(c *Client) any { 388 script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==") 389 if err != nil { 390 panic(err) 391 } 392 m := manifest.NewManifest("Test") 393 cs := &state.Contract{ 394 ContractBase: state.ContractBase{ 395 ID: 0, 396 Hash: hash.Hash160(script), 397 NEF: newTestNEF(script), 398 Manifest: *m, 399 }, 400 } 401 return cs 402 }, 403 }, 404 }, 405 "getnep11balances": { 406 { 407 name: "positive", 408 invoke: func(c *Client) (any, error) { 409 hash, err := util.Uint160DecodeStringLE("1aada0032aba1ef6d1f07bbd8bec1d85f5380fb3") 410 if err != nil { 411 panic(err) 412 } 413 return c.GetNEP11Balances(hash) 414 }, 415 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"balance":[{"assethash":"a48b6e1291ba24211ad11bb90ae2a10bf1fcd5a8","symbol":"SOME","decimals":"42","name":"Contract","tokens":[{"tokenid":"abcdef","amount":"1","lastupdatedblock":251604}]}],"address":"NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe"}}`, 416 result: func(c *Client) any { 417 hash, err := util.Uint160DecodeStringLE("a48b6e1291ba24211ad11bb90ae2a10bf1fcd5a8") 418 if err != nil { 419 panic(err) 420 } 421 return &result.NEP11Balances{ 422 Balances: []result.NEP11AssetBalance{{ 423 Asset: hash, 424 Decimals: 42, 425 Name: "Contract", 426 Symbol: "SOME", 427 Tokens: []result.NEP11TokenBalance{{ 428 ID: "abcdef", 429 Amount: "1", 430 LastUpdated: 251604, 431 }}, 432 }}, 433 Address: "NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe", 434 } 435 }, 436 }, 437 }, 438 "getnep17balances": { 439 { 440 name: "positive", 441 invoke: func(c *Client) (any, error) { 442 hash, err := util.Uint160DecodeStringLE("1aada0032aba1ef6d1f07bbd8bec1d85f5380fb3") 443 if err != nil { 444 panic(err) 445 } 446 return c.GetNEP17Balances(hash) 447 }, 448 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"balance":[{"assethash":"a48b6e1291ba24211ad11bb90ae2a10bf1fcd5a8","symbol":"N17","decimals":"8","name":"Token","amount":"50000000000","lastupdatedblock":251604}],"address":"AY6eqWjsUFCzsVELG7yG72XDukKvC34p2w"}}`, 449 result: func(c *Client) any { 450 hash, err := util.Uint160DecodeStringLE("a48b6e1291ba24211ad11bb90ae2a10bf1fcd5a8") 451 if err != nil { 452 panic(err) 453 } 454 return &result.NEP17Balances{ 455 Balances: []result.NEP17Balance{{ 456 Asset: hash, 457 Decimals: 8, 458 Name: "Token", 459 Symbol: "N17", 460 Amount: "50000000000", 461 LastUpdated: 251604, 462 }}, 463 Address: "AY6eqWjsUFCzsVELG7yG72XDukKvC34p2w", 464 } 465 }, 466 }, 467 }, 468 "getnep11properties": { 469 { 470 name: "positive", 471 invoke: func(c *Client) (any, error) { 472 hash, err := util.Uint160DecodeStringLE("1aada0032aba1ef6d1f07bbd8bec1d85f5380fb3") 473 if err != nil { 474 panic(err) 475 } 476 return c.GetNEP11Properties(hash, []byte("abcdef")) 477 }, // NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe 478 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"name":"sometoken","field1":"c29tZXRoaW5n","field2":null}}`, 479 result: func(c *Client) any { 480 return map[string]any{ 481 "name": "sometoken", 482 "field1": []byte("something"), 483 "field2": nil, 484 } 485 }, 486 }, 487 }, 488 "getnep11transfers": { 489 { 490 name: "positive", 491 invoke: func(c *Client) (any, error) { 492 hash, err := address.StringToUint160("NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe") 493 if err != nil { 494 panic(err) 495 } 496 return c.GetNEP11Transfers(hash, nil, nil, nil, nil) 497 }, 498 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"sent":[],"received":[{"timestamp":1555651816,"assethash":"600c4f5200db36177e3e8a09e9f18e2fc7d12a0f","transferaddress":"NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP","amount":"1","tokenid":"abcdef","blockindex":436036,"transfernotifyindex":0,"txhash":"df7683ece554ecfb85cf41492c5f143215dd43ef9ec61181a28f922da06aba58"}],"address":"NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe"}}`, 499 result: func(c *Client) any { 500 assetHash, err := util.Uint160DecodeStringLE("600c4f5200db36177e3e8a09e9f18e2fc7d12a0f") 501 if err != nil { 502 panic(err) 503 } 504 txHash, err := util.Uint256DecodeStringLE("df7683ece554ecfb85cf41492c5f143215dd43ef9ec61181a28f922da06aba58") 505 if err != nil { 506 panic(err) 507 } 508 return &result.NEP11Transfers{ 509 Sent: []result.NEP11Transfer{}, 510 Received: []result.NEP11Transfer{ 511 { 512 Timestamp: 1555651816, 513 Asset: assetHash, 514 Address: "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", 515 Amount: "1", 516 ID: "abcdef", 517 Index: 436036, 518 NotifyIndex: 0, 519 TxHash: txHash, 520 }, 521 }, 522 Address: "NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe", 523 } 524 }, 525 }, 526 }, 527 "getnep17transfers": { 528 { 529 name: "positive", 530 invoke: func(c *Client) (any, error) { 531 hash, err := address.StringToUint160("NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe") 532 if err != nil { 533 panic(err) 534 } 535 return c.GetNEP17Transfers(hash, nil, nil, nil, nil) 536 }, 537 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"sent":[],"received":[{"timestamp":1555651816,"assethash":"600c4f5200db36177e3e8a09e9f18e2fc7d12a0f","transferaddress":"AYwgBNMepiv5ocGcyNT4mA8zPLTQ8pDBis","amount":"1000000","blockindex":436036,"transfernotifyindex":0,"txhash":"df7683ece554ecfb85cf41492c5f143215dd43ef9ec61181a28f922da06aba58"}],"address":"NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe"}}`, 538 result: func(c *Client) any { 539 assetHash, err := util.Uint160DecodeStringLE("600c4f5200db36177e3e8a09e9f18e2fc7d12a0f") 540 if err != nil { 541 panic(err) 542 } 543 txHash, err := util.Uint256DecodeStringLE("df7683ece554ecfb85cf41492c5f143215dd43ef9ec61181a28f922da06aba58") 544 if err != nil { 545 panic(err) 546 } 547 return &result.NEP17Transfers{ 548 Sent: []result.NEP17Transfer{}, 549 Received: []result.NEP17Transfer{ 550 { 551 Timestamp: 1555651816, 552 Asset: assetHash, 553 Address: "AYwgBNMepiv5ocGcyNT4mA8zPLTQ8pDBis", 554 Amount: "1000000", 555 Index: 436036, 556 NotifyIndex: 0, 557 TxHash: txHash, 558 }, 559 }, 560 Address: "NcEkNmgWmf7HQVQvzhxpengpnt4DXjmZLe", 561 } 562 }, 563 }, 564 }, 565 "getpeers": { 566 { 567 name: "positive", 568 invoke: func(c *Client) (any, error) { 569 return c.GetPeers() 570 }, 571 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"unconnected":[{"address":"172.200.0.1","port":20333}],"connected":[{"address":"127.0.0.1","port":20335}],"bad":[{"address":"172.200.0.254","port":20332}]}}`, 572 result: func(c *Client) any { 573 574 return &result.GetPeers{ 575 Unconnected: result.Peers{ 576 { 577 Address: "172.200.0.1", 578 Port: 20333, 579 }, 580 }, 581 Connected: result.Peers{ 582 { 583 Address: "127.0.0.1", 584 Port: 20335, 585 }, 586 }, 587 Bad: result.Peers{ 588 { 589 Address: "172.200.0.254", 590 Port: 20332, 591 }, 592 }, 593 } 594 }, 595 }, 596 }, 597 "getrawmempool": { 598 { 599 name: "positive", 600 invoke: func(c *Client) (any, error) { 601 return c.GetRawMemPool() 602 }, 603 serverResponse: `{"jsonrpc":"2.0","id":1,"result":["0x9786cce0dddb524c40ddbdd5e31a41ed1f6b5c8a683c122f627ca4a007a7cf4e"]}`, 604 result: func(c *Client) any { 605 hash, err := util.Uint256DecodeStringLE("9786cce0dddb524c40ddbdd5e31a41ed1f6b5c8a683c122f627ca4a007a7cf4e") 606 if err != nil { 607 panic(err) 608 } 609 return []util.Uint256{hash} 610 }, 611 }, 612 }, 613 "getrawtransaction": { 614 { 615 name: "positive", 616 invoke: func(c *Client) (i any, err error) { 617 hash, err := util.Uint256DecodeStringLE("f5fbd303799f24ba247529d7544d4276cca54ea79f4b98095f2b0557313c5275") 618 if err != nil { 619 panic(err) 620 } 621 return c.GetRawTransaction(hash) 622 }, 623 serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + base64TxMoveNeo + `"}`, 624 result: func(c *Client) any { 625 tx := getTxMoveNeo() 626 return &tx.Transaction 627 }, 628 }, 629 { 630 name: "verbose_positive", 631 invoke: func(c *Client) (any, error) { 632 hash, err := util.Uint256DecodeStringLE("f5fbd303799f24ba247529d7544d4276cca54ea79f4b98095f2b0557313c5275") 633 if err != nil { 634 panic(err) 635 } 636 out, err := c.GetRawTransactionVerbose(hash) 637 if err != nil { 638 return nil, err 639 } 640 out.Transaction.FeePerByte() // set fee per byte 641 return out, nil 642 }, 643 serverResponse: `{"id":1,"jsonrpc":"2.0","result":` + txMoveNeoVerbose + `}`, 644 result: func(c *Client) any { 645 return getTxMoveNeo() 646 }, 647 }, 648 }, 649 "getstateroot": { 650 { 651 name: "positive, by height", 652 invoke: func(c *Client) (any, error) { 653 return c.GetStateRootByHeight(5) 654 }, 655 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"version":0,"index":5,"roothash":"0x65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686","witnesses":[]}}`, 656 result: func(c *Client) any { 657 h, err := util.Uint256DecodeStringLE("65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686") 658 if err != nil { 659 panic(err) 660 } 661 return &state.MPTRoot{ 662 Version: 0, 663 Index: 5, 664 Root: h, 665 Witness: []transaction.Witness{}, 666 } 667 }, 668 }, 669 { 670 name: "positive, by hash", 671 invoke: func(c *Client) (any, error) { 672 hash, err := util.Uint256DecodeStringLE("86fe1061140b2ea791b0739fb9732abc6e5e47de4927228a1ac41de3d93eb7cb") 673 if err != nil { 674 panic(err) 675 } 676 return c.GetStateRootByBlockHash(hash) 677 }, 678 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"version":0,"index":5,"roothash":"0x65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686","witnesses":[]}}`, 679 result: func(c *Client) any { 680 h, _ := util.Uint256DecodeStringLE("65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686") 681 return &state.MPTRoot{ 682 Version: 0, 683 Index: 5, 684 Root: h, 685 Witness: []transaction.Witness{}, 686 } 687 }, 688 }, 689 }, 690 "getstate": { 691 { 692 name: "positive", 693 invoke: func(c *Client) (any, error) { 694 root, _ := util.Uint256DecodeStringLE("252e9d73d49c95c7618d40650da504e05183a1b2eed0685e42c360413c329170") 695 cHash, _ := util.Uint160DecodeStringLE("5c9e40a12055c6b9e3f72271c9779958c842135d") 696 return c.GetState(root, cHash, []byte("testkey")) 697 }, 698 serverResponse: `{"id":1,"jsonrpc":"2.0","result":"dGVzdHZhbHVl"}`, 699 result: func(c *Client) any { 700 return []byte("testvalue") 701 }, 702 }, 703 }, 704 "getproof": { 705 { 706 name: "positive", 707 invoke: func(c *Client) (any, error) { 708 root, _ := util.Uint256DecodeStringLE("272002b11a6a39035c719defec3e4e6a8d1f4ae37a995b44734911413fcc2ba5") 709 cHash, _ := util.Uint160DecodeStringLE("cc5e4edd9f5f8dba8bb65734541df7a1c081c67b") 710 key := []byte{10} 711 return c.GetProof(root, cHash, key) 712 }, 713 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"Bfn///8KBiQBAQ8DogBnMdiiPTEW05A6bJPmQ2TNVpuca/nB1rJRdQX7R4SyAAQEBAQEBAQDHvo5Rc9v\u002BWSpfsnMXM75ku\u002BZjvbLJhWXn/lh6L\u002B1yB0EA4k\u002Bsx4f7IgmdHNm3wRMpj5kTU4l0gChSGppo5p5wZyWA2\u002BKSFn16W6tRrGSfJob\u002BgqJukLcNDk0DBFYW2wIS2/NAzkugdLfZRXHOLqq5XJr89ElzlqyXU1o9D87l9YOcXjGBAQEA7oDTOxuU4iMAKPuhn5eJjzsM56bQrx3uORa8LKm42oDBCkBBg8PDw8PDwN96s39UOSCwMJmMQZzNjfNAPCbRRyke1B4VRKqOZ0NHlIAA2woQ13XO4Ug2aQ/cW4WBricVcUVqobFUU0dnRPtfIHeAxuYERXsV6HwdGjW\u002BhtpM0FEkw/mllbH5pyhn\u002BBx4r8wBAQEBAQEBAQEBAQEBAQEJAEBCgPXvpMqBogTeGhXjtFY4Rsn9bY/PgNX0l4iYOHMzUBQQgQCAugD"}`, 714 result: func(c *Client) any { 715 b, _ := base64.StdEncoding.DecodeString("Bfn///8KBiQBAQ8DogBnMdiiPTEW05A6bJPmQ2TNVpuca/nB1rJRdQX7R4SyAAQEBAQEBAQDHvo5Rc9v\u002BWSpfsnMXM75ku\u002BZjvbLJhWXn/lh6L\u002B1yB0EA4k\u002Bsx4f7IgmdHNm3wRMpj5kTU4l0gChSGppo5p5wZyWA2\u002BKSFn16W6tRrGSfJob\u002BgqJukLcNDk0DBFYW2wIS2/NAzkugdLfZRXHOLqq5XJr89ElzlqyXU1o9D87l9YOcXjGBAQEA7oDTOxuU4iMAKPuhn5eJjzsM56bQrx3uORa8LKm42oDBCkBBg8PDw8PDwN96s39UOSCwMJmMQZzNjfNAPCbRRyke1B4VRKqOZ0NHlIAA2woQ13XO4Ug2aQ/cW4WBricVcUVqobFUU0dnRPtfIHeAxuYERXsV6HwdGjW\u002BhtpM0FEkw/mllbH5pyhn\u002BBx4r8wBAQEBAQEBAQEBAQEBAQEJAEBCgPXvpMqBogTeGhXjtFY4Rsn9bY/PgNX0l4iYOHMzUBQQgQCAugD") 716 proof := &result.ProofWithKey{} 717 r := io.NewBinReaderFromBuf(b) 718 proof.DecodeBinary(r) 719 return proof 720 }, 721 }, 722 { 723 name: "not found", 724 invoke: func(c *Client) (any, error) { 725 root, _ := util.Uint256DecodeStringLE("272002b11a6a39035c719defec3e4e6a8d1f4ae37a995b44734911413fcc2ba5") 726 cHash, _ := util.Uint160DecodeStringLE("cc5e4edd9f5f8dba8bb65734541df7a1c081c67b") 727 key := []byte{01} 728 return c.GetProof(root, cHash, key) 729 }, 730 serverResponse: `{"id":1,"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":"failed to get proof: item not found"}}`, 731 fails: true, 732 }, 733 }, 734 "verifyproof": { 735 { 736 name: "positive", 737 invoke: func(c *Client) (any, error) { 738 root, _ := util.Uint256DecodeStringLE("272002b11a6a39035c719defec3e4e6a8d1f4ae37a995b44734911413fcc2ba5") 739 b, _ := base64.StdEncoding.DecodeString("Bfn///8KBiQBAQ8DogBnMdiiPTEW05A6bJPmQ2TNVpuca/nB1rJRdQX7R4SyAAQEBAQEBAQDHvo5Rc9v\u002BWSpfsnMXM75ku\u002BZjvbLJhWXn/lh6L\u002B1yB0EA4k\u002Bsx4f7IgmdHNm3wRMpj5kTU4l0gChSGppo5p5wZyWA2\u002BKSFn16W6tRrGSfJob\u002BgqJukLcNDk0DBFYW2wIS2/NAzkugdLfZRXHOLqq5XJr89ElzlqyXU1o9D87l9YOcXjGBAQEA7oDTOxuU4iMAKPuhn5eJjzsM56bQrx3uORa8LKm42oDBCkBBg8PDw8PDwN96s39UOSCwMJmMQZzNjfNAPCbRRyke1B4VRKqOZ0NHlIAA2woQ13XO4Ug2aQ/cW4WBricVcUVqobFUU0dnRPtfIHeAxuYERXsV6HwdGjW\u002BhtpM0FEkw/mllbH5pyhn\u002BBx4r8wBAQEBAQEBAQEBAQEBAQEJAEBCgPXvpMqBogTeGhXjtFY4Rsn9bY/PgNX0l4iYOHMzUBQQgQCAugD") 740 proof := &result.ProofWithKey{} 741 r := io.NewBinReaderFromBuf(b) 742 proof.DecodeBinary(r) 743 return c.VerifyProof(root, proof) 744 }, 745 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"6AM="}`, 746 result: func(c *Client) any { 747 return bigint.ToPreallocatedBytes(big.NewInt(1000), nil) 748 }, 749 }, 750 { 751 name: "fail", 752 invoke: func(c *Client) (any, error) { 753 root, _ := util.Uint256DecodeStringLE("272002b11a6a39035c719defec3e4e6a8d1f4ae37a995b44734911413fcc2ba5") 754 b, _ := base64.StdEncoding.DecodeString("Bfn///8KBiQBAQ8DogBnMdiiPTEW05A6bJPmQ2TNVpuca/nB1rJRdQX7R4SyAAQEBAQEBAQDHvo5Rc9v\u002BWSpfsnMXM75ku\u002BZjvbLJhWXn/lh6L\u002B1yB0EA4k\u002Bsx4f7IgmdHNm3wRMpj5kTU4l0gChSGppo5p5wZyWA2\u002BKSFn16W6tRrGSfJob\u002BgqJukLcNDk0DBFYW2wIS2/NAzkugdLfZRXHOLqq5XJr89ElzlqyXU1o9D87l9YOcXjGBAQEA7oDTOxuU4iMAKPuhn5eJjzsM56bQrx3uORa8LKm42oDBCkBBg8PDw8PDwN96s39UOSCwMJmMQZzNjfNAPCbRRyke1B4VRKqOZ0NHlIAA2woQ13XO4Ug2aQ/cW4WBricVcUVqobFUU0dnRPtfIHeAxuYERXsV6HwdGjW\u002BhtpM0FEkw/mllbH5pyhn\u002BBx4r8wBAQEBAQEBAQEBAQEBAQEJAEBCgPXvpMqBogTeGhXjtFY4Rsn9bY/PgNX0l4iYOHMzUBQQgQCAugD") 755 proof := &result.ProofWithKey{} 756 r := io.NewBinReaderFromBuf(b) 757 proof.DecodeBinary(r) 758 return c.VerifyProof(root, proof) 759 }, 760 serverResponse: `{"id":1,"jsonrpc":"2.0","result":"invalid"}`, 761 fails: true, 762 }, 763 }, 764 "findstates": { 765 { 766 name: "positive", 767 invoke: func(c *Client) (any, error) { 768 root, _ := util.Uint256DecodeStringLE("252e9d73d49c95c7618d40650da504e05183a1b2eed0685e42c360413c329170") 769 cHash, _ := util.Uint160DecodeStringLE("5c9e40a12055c6b9e3f72271c9779958c842135d") 770 count := 1 771 return c.FindStates(root, cHash, []byte("aa"), []byte("aa00"), &count) 772 }, 773 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"results":[{"key":"YWExMA==","value":"djI="}],"firstProof":"CAEAAABhYTEwCXIAA5KNHjQ1+LFX4lQBLjMAhaLtTJnfuI86O7WnNdlshsYWBAQEBAQEBAQDTzD7MJp2KW6E8BNVjjjgZMTAjI/GI3ZrTmR2UUOtSeIEBAQEBAPKPqb0qnb4Ywz6gqpNKCUNQsfBmAnKc5p3dxokSQRpwgRSAAQDPplG1wee4KOfkehaF94R5uoKSgvQL1j5gkFTN4ywYaIEBAOhOyI39MZfoKc940g57XeqwRnxh7P62fKjnfEtBzQxHQQEBAQEBAQEBAQEBCkBBgAAAAAAAAM6A1UrwFYZAEMfe6go3jX25xz2sHsovQ2UO/UHqZZOXLIABAOwg7pkXyaTR85yQIvYnoGaG/OVRLRHOj+nhZnXb6dVtAQEBAPnciBUp3uspLQTajKTlAxgrNe+3tlqlbwlNRkz0eNmhQMzoMcWOFi9nCyn+eM5lA6Pq67DxzTQDlHljh8g8kRtJAPq9hxzTgreK0qDTavsethixguZYfV7wDmKfumMglnoqQQEBAQEBAM1x2dVBdf5BJ0Xvw2qqhvpKqxdHb8/HMFWiXkJj1uAAQQEJgEDAQYBA5kV2WLkgey9C5z6gZT69VLKcEuwyY8P853rNtGhT3NeUgAEBAQDiX59K9PuJ5RE7Z1uj7q/QJ8FGf8avLdWM7hwmWkVH2gEBAQEBAQEBAQEBAQD1SubX5XhFHcUOWdUzg1bXmDwWJwt+wpU3FOdFkU1PXBSAAQDHCzfEQyqwOO263EE6HER1vWDrwz8JiEHEOXfZ3kX7NYEBAQDEH++Hy8wBcniKuWVevaAwzHCh60kzncU30E5fDC3gJsEBAQEBAQEBAQEBCUBAgMAA1wt18LbxMKdYcJ+nEDMMWZbRsu550l8HGhcYhpl6DjSBAICdjI=","truncated":true}}`, 774 result: func(c *Client) any { 775 proofB, _ := base64.StdEncoding.DecodeString("CAEAAABhYTEwCXIAA5KNHjQ1+LFX4lQBLjMAhaLtTJnfuI86O7WnNdlshsYWBAQEBAQEBAQDTzD7MJp2KW6E8BNVjjjgZMTAjI/GI3ZrTmR2UUOtSeIEBAQEBAPKPqb0qnb4Ywz6gqpNKCUNQsfBmAnKc5p3dxokSQRpwgRSAAQDPplG1wee4KOfkehaF94R5uoKSgvQL1j5gkFTN4ywYaIEBAOhOyI39MZfoKc940g57XeqwRnxh7P62fKjnfEtBzQxHQQEBAQEBAQEBAQEBCkBBgAAAAAAAAM6A1UrwFYZAEMfe6go3jX25xz2sHsovQ2UO/UHqZZOXLIABAOwg7pkXyaTR85yQIvYnoGaG/OVRLRHOj+nhZnXb6dVtAQEBAPnciBUp3uspLQTajKTlAxgrNe+3tlqlbwlNRkz0eNmhQMzoMcWOFi9nCyn+eM5lA6Pq67DxzTQDlHljh8g8kRtJAPq9hxzTgreK0qDTavsethixguZYfV7wDmKfumMglnoqQQEBAQEBAM1x2dVBdf5BJ0Xvw2qqhvpKqxdHb8/HMFWiXkJj1uAAQQEJgEDAQYBA5kV2WLkgey9C5z6gZT69VLKcEuwyY8P853rNtGhT3NeUgAEBAQDiX59K9PuJ5RE7Z1uj7q/QJ8FGf8avLdWM7hwmWkVH2gEBAQEBAQEBAQEBAQD1SubX5XhFHcUOWdUzg1bXmDwWJwt+wpU3FOdFkU1PXBSAAQDHCzfEQyqwOO263EE6HER1vWDrwz8JiEHEOXfZ3kX7NYEBAQDEH++Hy8wBcniKuWVevaAwzHCh60kzncU30E5fDC3gJsEBAQEBAQEBAQEBCUBAgMAA1wt18LbxMKdYcJ+nEDMMWZbRsu550l8HGhcYhpl6DjSBAICdjI=") 776 proof := &result.ProofWithKey{} 777 r := io.NewBinReaderFromBuf(proofB) 778 proof.DecodeBinary(r) 779 return result.FindStates{ 780 Results: []result.KeyValue{{Key: []byte("aa10"), Value: []byte("v2")}}, 781 FirstProof: proof, 782 Truncated: true, 783 } 784 }, 785 }, 786 }, 787 "findstorage": { 788 { 789 name: "positive by hash", 790 invoke: func(c *Client) (any, error) { 791 cHash, _ := util.Uint160DecodeStringLE("5c9e40a12055c6b9e3f72271c9779958c842135d") 792 start := 1 793 return c.FindStorageByHash(cHash, []byte("aa"), &start) 794 }, 795 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"results":[{"key":"YWExMA==","value":"djI="}],"truncated":true, "next": 1}}`, 796 result: func(c *Client) any { 797 return result.FindStorage{ 798 Results: []result.KeyValue{{Key: []byte("aa10"), Value: []byte("v2")}}, 799 Truncated: true, 800 Next: 1, 801 } 802 }, 803 }, 804 { 805 name: "positive by ID", 806 invoke: func(c *Client) (any, error) { 807 start := 1 808 return c.FindStorageByID(1, []byte("aa"), &start) 809 }, 810 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"results":[{"key":"YWExMA==","value":"djI="}],"truncated":true, "next": 1}}`, 811 result: func(c *Client) any { 812 return result.FindStorage{ 813 Results: []result.KeyValue{{Key: []byte("aa10"), Value: []byte("v2")}}, 814 Truncated: true, 815 Next: 1, 816 } 817 }, 818 }, 819 }, 820 "findstoragehistoric": { 821 { 822 name: "positive by hash", 823 invoke: func(c *Client) (any, error) { 824 root, _ := util.Uint256DecodeStringLE("252e9d73d49c95c7618d40650da504e05183a1b2eed0685e42c360413c329170") 825 cHash, _ := util.Uint160DecodeStringLE("5c9e40a12055c6b9e3f72271c9779958c842135d") 826 start := 1 827 return c.FindStorageByHashHistoric(root, cHash, []byte("aa"), &start) 828 }, 829 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"results":[{"key":"YWExMA==","value":"djI="}],"truncated":true, "next": 1}}`, 830 result: func(c *Client) any { 831 return result.FindStorage{ 832 Results: []result.KeyValue{{Key: []byte("aa10"), Value: []byte("v2")}}, 833 Truncated: true, 834 Next: 1, 835 } 836 }, 837 }, 838 { 839 name: "positive by ID", 840 invoke: func(c *Client) (any, error) { 841 root, _ := util.Uint256DecodeStringLE("252e9d73d49c95c7618d40650da504e05183a1b2eed0685e42c360413c329170") 842 start := 1 843 return c.FindStorageByIDHistoric(root, 1, []byte("aa"), &start) 844 }, 845 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"results":[{"key":"YWExMA==","value":"djI="}],"truncated":true, "next": 1}}`, 846 result: func(c *Client) any { 847 return result.FindStorage{ 848 Results: []result.KeyValue{{Key: []byte("aa10"), Value: []byte("v2")}}, 849 Truncated: true, 850 Next: 1, 851 } 852 }, 853 }, 854 }, 855 "getstateheight": { 856 { 857 name: "positive", 858 invoke: func(c *Client) (any, error) { 859 return c.GetStateHeight() 860 }, 861 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"localrootindex":11646,"validatedrootindex":11645}}`, 862 result: func(c *Client) any { 863 return &result.StateHeight{ 864 Local: 11646, 865 Validated: 11645, 866 } 867 }, 868 }, 869 }, 870 "getstorage": { 871 { 872 name: "by hash, positive", 873 invoke: func(c *Client) (any, error) { 874 hash, err := util.Uint160DecodeStringLE("03febccf81ac85e3d795bc5cbd4e84e907812aa3") 875 if err != nil { 876 panic(err) 877 } 878 key, err := hex.DecodeString("5065746572") 879 if err != nil { 880 panic(err) 881 } 882 return c.GetStorageByHash(hash, key) 883 }, 884 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"TGlu"}`, 885 result: func(c *Client) any { 886 value, err := hex.DecodeString("4c696e") 887 if err != nil { 888 panic(err) 889 } 890 return value 891 }, 892 }, 893 { 894 name: "by ID, positive", 895 invoke: func(c *Client) (any, error) { 896 key, err := hex.DecodeString("5065746572") 897 if err != nil { 898 panic(err) 899 } 900 return c.GetStorageByID(-1, key) 901 }, 902 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"TGlu"}`, 903 result: func(c *Client) any { 904 value, err := hex.DecodeString("4c696e") 905 if err != nil { 906 panic(err) 907 } 908 return value 909 }, 910 }, 911 }, 912 "getstoragehistoric": { 913 { 914 name: "by hash, positive", 915 invoke: func(c *Client) (any, error) { 916 root, _ := util.Uint256DecodeStringLE("252e9d73d49c95c7618d40650da504e05183a1b2eed0685e42c360413c329170") 917 hash, err := util.Uint160DecodeStringLE("03febccf81ac85e3d795bc5cbd4e84e907812aa3") 918 if err != nil { 919 panic(err) 920 } 921 key, err := hex.DecodeString("5065746572") 922 if err != nil { 923 panic(err) 924 } 925 return c.GetStorageByHashHistoric(root, hash, key) 926 }, 927 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"TGlu"}`, 928 result: func(c *Client) any { 929 value, err := hex.DecodeString("4c696e") 930 if err != nil { 931 panic(err) 932 } 933 return value 934 }, 935 }, 936 { 937 name: "by ID, positive", 938 invoke: func(c *Client) (any, error) { 939 root, _ := util.Uint256DecodeStringLE("252e9d73d49c95c7618d40650da504e05183a1b2eed0685e42c360413c329170") 940 key, err := hex.DecodeString("5065746572") 941 if err != nil { 942 panic(err) 943 } 944 return c.GetStorageByIDHistoric(root, -1, key) 945 }, 946 serverResponse: `{"jsonrpc":"2.0","id":1,"result":"TGlu"}`, 947 result: func(c *Client) any { 948 value, err := hex.DecodeString("4c696e") 949 if err != nil { 950 panic(err) 951 } 952 return value 953 }, 954 }, 955 }, 956 "gettransactionheight": { 957 { 958 name: "positive", 959 invoke: func(c *Client) (any, error) { 960 hash, err := util.Uint256DecodeStringLE("cb6ddb5f99d6af4c94a6c396d5294472f2eebc91a2c933e0f527422296fa9fb2") 961 if err != nil { 962 panic(err) 963 } 964 return c.GetTransactionHeight(hash) 965 }, 966 serverResponse: `{"jsonrpc":"2.0","id":1,"result":1}`, 967 result: func(c *Client) any { 968 return uint32(1) 969 }, 970 }, 971 }, 972 "getunclaimedgas": { 973 { 974 name: "positive", 975 invoke: func(c *Client) (any, error) { 976 return c.GetUnclaimedGas("NMipL5VsNoLUBUJKPKLhxaEbPQVCZnyJyB") 977 }, 978 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"address":"NMipL5VsNoLUBUJKPKLhxaEbPQVCZnyJyB","unclaimed":"897299680935"}}`, 979 result: func(c *Client) any { 980 addr, err := address.StringToUint160("NMipL5VsNoLUBUJKPKLhxaEbPQVCZnyJyB") 981 if err != nil { 982 panic(fmt.Errorf("failed to parse UnclaimedGas address: %w", err)) 983 } 984 return result.UnclaimedGas{ 985 Address: addr, 986 Unclaimed: *big.NewInt(897299680935), 987 } 988 }, 989 }, 990 }, 991 "getcandidates": { 992 { 993 name: "positive", 994 invoke: func(c *Client) (any, error) { 995 return c.GetCandidates() 996 }, 997 serverResponse: `{"id":1,"jsonrpc":"2.0","result":[{"publickey":"02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2","votes":"0","active":true},{"publickey":"02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e","votes":"0","active":true},{"publickey":"03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699","votes":"0","active":true},{"publickey":"02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62","votes":"0","active":true}]}`, 998 result: func(c *Client) any { return []result.Candidate{} }, 999 check: func(t *testing.T, c *Client, uns any) { 1000 res, ok := uns.([]result.Candidate) 1001 require.True(t, ok) 1002 assert.Equal(t, 4, len(res)) 1003 }, 1004 }, 1005 }, 1006 "getvalidators": { 1007 { 1008 name: "positive", 1009 invoke: func(c *Client) (any, error) { 1010 return c.GetNextBlockValidators() 1011 }, 1012 serverResponse: `{"id":1,"jsonrpc":"2.0","result":[{"publickey":"02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2","votes":"0","active":true},{"publickey":"02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e","votes":"0","active":true},{"publickey":"03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699","votes":"0","active":true},{"publickey":"02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62","votes":"0","active":true}]}`, 1013 result: func(c *Client) any { return []result.Validator{} }, 1014 check: func(t *testing.T, c *Client, uns any) { 1015 res, ok := uns.([]result.Validator) 1016 require.True(t, ok) 1017 assert.Equal(t, 4, len(res)) 1018 }, 1019 }, 1020 }, 1021 "getversion": { 1022 { 1023 name: "positive", 1024 invoke: func(c *Client) (any, error) { 1025 return c.GetVersion() 1026 }, 1027 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"tcpport":20332,"wsport":20342,"nonce":2153672787,"useragent":"/NEO-GO:0.73.1-pre-273-ge381358/", "protocol": {"network": 2, "hardforks": {}}, "rpc": {"maxiteratorresultitems": 100, "sessionenabled": true}}`, 1028 result: func(c *Client) any { 1029 return &result.Version{ 1030 TCPPort: uint16(20332), 1031 WSPort: uint16(20342), 1032 Nonce: 2153672787, 1033 UserAgent: "/NEO-GO:0.73.1-pre-273-ge381358/", 1034 Protocol: result.Protocol{ 1035 Network: netmode.UnitTestNet, 1036 Hardforks: map[config.Hardfork]uint32{}, 1037 }, 1038 RPC: result.RPC{ 1039 MaxIteratorResultItems: 100, 1040 SessionEnabled: true, 1041 }, 1042 } 1043 }, 1044 }, 1045 }, 1046 "invokefunction": { 1047 { 1048 name: "positive, by scripthash", 1049 invoke: func(c *Client) (any, error) { 1050 hash, err := util.Uint160DecodeStringLE("91b83e96f2a7c4fdf0c1688441ec61986c7cae26") 1051 if err != nil { 1052 panic(err) 1053 } 1054 contr, err := util.Uint160DecodeStringLE("af7c7328eee5a275a3bcaee2bf0cf662b5e739be") 1055 if err != nil { 1056 panic(err) 1057 } 1058 return c.InvokeFunction(contr, "balanceOf", []smartcontract.Parameter{ 1059 { 1060 Type: smartcontract.Hash160Type, 1061 Value: hash, 1062 }, 1063 }, []transaction.Signer{{ 1064 Account: util.Uint160{1, 2, 3}, 1065 }}) 1066 }, 1067 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv","state":"HALT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"AAgAAACAlpgAAAAAAAIEEwAAAAAAsAQAAAGqis+FnU/kArNOZz8hVoIXlqSI6wEAVwHoAwwUqorPhZ1P5AKzTmc/IVaCF5akiOsMFOeetm08E0pKd27oB9LluEbdpP2wE8AMCHRyYW5zZmVyDBTnnrZtPBNKSndu6AfS5bhG3aT9sEFifVtSOAFCDEDYNAh3TUvYsZrocFYdBvJ0Trdnj1jRuQzy9Q6YroP2Cwgk4v7q3vbeZBikz8Q7vB+RbDPsWUy+ZiqdkkeG4XoUKQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CC0GVRA14"}}`, 1068 result: func(c *Client) any { 1069 return &result.Invoke{} 1070 }, 1071 check: func(t *testing.T, c *Client, uns any) { 1072 res, ok := uns.(*result.Invoke) 1073 require.True(t, ok) 1074 bytes, err := hex.DecodeString("262bec084432") 1075 if err != nil { 1076 panic(err) 1077 } 1078 script, err := base64.StdEncoding.DecodeString("FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv") 1079 if err != nil { 1080 panic(err) 1081 } 1082 assert.Equal(t, "HALT", res.State) 1083 assert.Equal(t, int64(31100000), res.GasConsumed) 1084 assert.Equal(t, script, res.Script) 1085 assert.Equal(t, []stackitem.Item{stackitem.NewByteArray(bytes)}, res.Stack) 1086 assert.NotNil(t, res.Transaction) 1087 }, 1088 }, 1089 { 1090 name: "positive, FAULT state", 1091 invoke: func(c *Client) (any, error) { 1092 hash, err := util.Uint160DecodeStringLE("91b83e96f2a7c4fdf0c1688441ec61986c7cae26") 1093 if err != nil { 1094 panic(err) 1095 } 1096 contr, err := util.Uint160DecodeStringLE("af7c7328eee5a275a3bcaee2bf0cf662b5e739be") 1097 if err != nil { 1098 panic(err) 1099 } 1100 return c.InvokeFunction(contr, "balanceOf", []smartcontract.Parameter{ 1101 { 1102 Type: smartcontract.Hash160Type, 1103 Value: hash, 1104 }, 1105 }, []transaction.Signer{{ 1106 Account: util.Uint160{1, 2, 3}, 1107 }}) 1108 }, 1109 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv","state":"FAULT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"AAgAAACAlpgAAAAAAAIEEwAAAAAAsAQAAAGqis+FnU/kArNOZz8hVoIXlqSI6wEAVwHoAwwUqorPhZ1P5AKzTmc/IVaCF5akiOsMFOeetm08E0pKd27oB9LluEbdpP2wE8AMCHRyYW5zZmVyDBTnnrZtPBNKSndu6AfS5bhG3aT9sEFifVtSOAFCDEDYNAh3TUvYsZrocFYdBvJ0Trdnj1jRuQzy9Q6YroP2Cwgk4v7q3vbeZBikz8Q7vB+RbDPsWUy+ZiqdkkeG4XoUKQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CC0GVRA14","exception":"gas limit exceeded"}}`, 1110 result: func(c *Client) any { 1111 return &result.Invoke{} 1112 }, 1113 check: func(t *testing.T, c *Client, uns any) { 1114 res, ok := uns.(*result.Invoke) 1115 require.True(t, ok) 1116 bytes, err := hex.DecodeString("262bec084432") 1117 if err != nil { 1118 panic(err) 1119 } 1120 script, err := base64.StdEncoding.DecodeString("FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv") 1121 if err != nil { 1122 panic(err) 1123 } 1124 assert.Equal(t, "FAULT", res.State) 1125 assert.Equal(t, int64(31100000), res.GasConsumed) 1126 assert.Equal(t, script, res.Script) 1127 assert.Equal(t, []stackitem.Item{stackitem.NewByteArray(bytes)}, res.Stack) 1128 assert.NotNil(t, res.Transaction) 1129 }, 1130 }, 1131 }, 1132 "invokescript": { 1133 { 1134 name: "positive", 1135 invoke: func(c *Client) (any, error) { 1136 script, err := base64.StdEncoding.DecodeString("AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR") 1137 if err != nil { 1138 panic(err) 1139 } 1140 return c.InvokeScript(script, []transaction.Signer{{ 1141 Account: util.Uint160{1, 2, 3}, 1142 }}) 1143 }, 1144 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR","state":"HALT","gasconsumed":"16100000","stack":[{"type":"ByteString","value":"TkVQNSBHQVM="}],"tx":null}}`, 1145 result: func(c *Client) any { 1146 bytes, err := hex.DecodeString("4e45503520474153") 1147 if err != nil { 1148 panic(err) 1149 } 1150 script, err := base64.StdEncoding.DecodeString("AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR") 1151 if err != nil { 1152 panic(err) 1153 } 1154 return &result.Invoke{ 1155 State: "HALT", 1156 GasConsumed: 16100000, 1157 Script: script, 1158 Stack: []stackitem.Item{stackitem.NewByteArray(bytes)}, 1159 } 1160 }, 1161 }, 1162 }, 1163 "invokecontractverify": { 1164 { 1165 name: "positive", 1166 invoke: func(c *Client) (any, error) { 1167 contr, err := util.Uint160DecodeStringLE("af7c7328eee5a275a3bcaee2bf0cf662b5e739be") 1168 if err != nil { 1169 panic(err) 1170 } 1171 return c.InvokeContractVerify(contr, nil, []transaction.Signer{{Account: util.Uint160{1, 2, 3}}}, transaction.Witness{InvocationScript: []byte{1, 2, 3}}) 1172 }, 1173 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv","state":"HALT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"AAgAAACAlpgAAAAAAAIEEwAAAAAAsAQAAAGqis+FnU/kArNOZz8hVoIXlqSI6wEAVwHoAwwUqorPhZ1P5AKzTmc/IVaCF5akiOsMFOeetm08E0pKd27oB9LluEbdpP2wE8AMCHRyYW5zZmVyDBTnnrZtPBNKSndu6AfS5bhG3aT9sEFifVtSOAFCDEDYNAh3TUvYsZrocFYdBvJ0Trdnj1jRuQzy9Q6YroP2Cwgk4v7q3vbeZBikz8Q7vB+RbDPsWUy+ZiqdkkeG4XoUKQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CC0GVRA14"}}`, 1174 result: func(c *Client) any { 1175 return &result.Invoke{} 1176 }, 1177 check: func(t *testing.T, c *Client, uns any) { 1178 res, ok := uns.(*result.Invoke) 1179 require.True(t, ok) 1180 bytes, err := hex.DecodeString("262bec084432") 1181 if err != nil { 1182 panic(err) 1183 } 1184 script, err := base64.StdEncoding.DecodeString("FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv") 1185 if err != nil { 1186 panic(err) 1187 } 1188 assert.Equal(t, "HALT", res.State) 1189 assert.Equal(t, int64(31100000), res.GasConsumed) 1190 assert.Equal(t, script, res.Script) 1191 assert.Equal(t, []stackitem.Item{stackitem.NewByteArray(bytes)}, res.Stack) 1192 assert.NotNil(t, res.Transaction) 1193 }, 1194 }, 1195 { 1196 name: "bad witness number", 1197 invoke: func(c *Client) (any, error) { 1198 return c.InvokeContractVerify(util.Uint160{}, nil, []transaction.Signer{{}}, []transaction.Witness{{}, {}}...) 1199 }, 1200 fails: true, 1201 }, 1202 }, 1203 "sendrawtransaction": { 1204 { 1205 name: "positive", 1206 invoke: func(c *Client) (any, error) { 1207 return c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0)) 1208 }, 1209 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"hash":"0x72159b0cf1221110daad6e1df6ef4ff03012173b63c86910bd7134deb659c875"}}`, 1210 result: func(c *Client) any { 1211 h, err := util.Uint256DecodeStringLE("72159b0cf1221110daad6e1df6ef4ff03012173b63c86910bd7134deb659c875") 1212 if err != nil { 1213 panic(fmt.Errorf("can't decode `sendrawtransaction` result hash: %w", err)) 1214 } 1215 return h 1216 }, 1217 }, 1218 }, 1219 "submitblock": { 1220 { 1221 name: "positive", 1222 invoke: func(c *Client) (any, error) { 1223 return c.SubmitBlock(block.Block{ 1224 Header: block.Header{}, 1225 Transactions: nil, 1226 Trimmed: false, 1227 }) 1228 }, 1229 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"hash":"0x1bdea8f80eb5bd97fade38d5e7fb93b02c9d3e01394e9f4324218132293f7ea6"}}`, 1230 result: func(c *Client) any { 1231 h, err := util.Uint256DecodeStringLE("1bdea8f80eb5bd97fade38d5e7fb93b02c9d3e01394e9f4324218132293f7ea6") 1232 if err != nil { 1233 panic(fmt.Errorf("can't decode `submitblock` result hash: %w", err)) 1234 } 1235 return h 1236 }, 1237 }, 1238 }, 1239 "validateaddress": { 1240 { 1241 name: "positive", 1242 invoke: func(c *Client) (any, error) { 1243 return nil, c.ValidateAddress("AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i") 1244 }, 1245 serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"address":"AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i","isvalid":true}}`, 1246 result: func(c *Client) any { 1247 // no error expected 1248 return nil 1249 }, 1250 }, 1251 }, 1252 "getrawnotarytransaction": { 1253 { 1254 name: "positive", 1255 invoke: func(c *Client) (any, error) { 1256 hash, err := util.Uint256DecodeStringLE("ad1c2875de823a54188949490e2d68580fd070fcc5ff409609f478d23d12355f") 1257 if err != nil { 1258 panic(err) 1259 } 1260 return c.GetRawNotaryTransaction(hash) 1261 }, 1262 serverResponse: `{"id":1,"jsonrpc":"2.0","result":"AAMAAAAAAAAAAAAAAAAAAAAAAAAAewAAAAHunqIsJ+NL0BSPxBCOCPdOj1BIsgABIgEBQAEDAQQHAwMGCQ=="}`, 1263 result: func(c *Client) any { 1264 return &transaction.Transaction{} 1265 }, 1266 check: func(t *testing.T, c *Client, uns any) { 1267 res, ok := uns.(*transaction.Transaction) 1268 require.True(t, ok) 1269 assert.NotNil(t, res) 1270 expectHash, err := util.Uint256DecodeStringLE("ad1c2875de823a54188949490e2d68580fd070fcc5ff409609f478d23d12355f") 1271 require.NoError(t, err) 1272 assert.Equal(t, expectHash, res.Hash()) 1273 }, 1274 }, 1275 { 1276 name: "positive verbose", 1277 invoke: func(c *Client) (any, error) { 1278 hash, err := util.Uint256DecodeStringLE("ad1c2875de823a54188949490e2d68580fd070fcc5ff409609f478d23d12355f") 1279 if err != nil { 1280 panic(err) 1281 } 1282 return c.GetRawNotaryTransactionVerbose(hash) 1283 }, 1284 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0xad1c2875de823a54188949490e2d68580fd070fcc5ff409609f478d23d12355f","size":61,"version":0,"nonce":3,"sender":"Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn","sysfee":"0","netfee":"0","validuntilblock":123,"attributes":[{"nkeys":1,"type":"NotaryAssisted"}],"signers":[{"account":"0xb248508f4ef7088e10c48f14d04be3272ca29eee","scopes":"None"}],"script":"QA==","witnesses":[{"invocation":"AQQH","verification":"AwYJ"}]}}`, 1285 result: func(c *Client) any { 1286 return &transaction.Transaction{} 1287 }, 1288 check: func(t *testing.T, c *Client, uns any) { 1289 res, ok := uns.(*transaction.Transaction) 1290 require.True(t, ok) 1291 assert.NotNil(t, res) 1292 expectHash, err := util.Uint256DecodeStringLE("ad1c2875de823a54188949490e2d68580fd070fcc5ff409609f478d23d12355f") 1293 require.NoError(t, err) 1294 assert.Equal(t, expectHash, res.Hash()) 1295 }, 1296 }, 1297 }, 1298 "getrawnotarypool": { 1299 { 1300 name: "empty pool", 1301 invoke: func(c *Client) (any, error) { 1302 return c.GetRawNotaryPool() 1303 }, 1304 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{}}`, 1305 result: func(c *Client) any { 1306 return &result.RawNotaryPool{ 1307 Hashes: map[util.Uint256][]util.Uint256{}, 1308 } 1309 }, 1310 }, 1311 { 1312 name: "nonempty pool", 1313 invoke: func(c *Client) (any, error) { 1314 return c.GetRawNotaryPool() 1315 }, 1316 serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hashes":{"0xd86b5346e9bbe6dba845cc4192fa716535a3d05c4f2084431edc99dc3862a299":["0xbb0b2f1d5539dd776637f00e5011d97921a1400d3a63c02977a38446180c6d7c"]}}}`, 1317 result: func(c *Client) any { 1318 return &result.RawNotaryPool{ 1319 Hashes: map[util.Uint256][]util.Uint256{}, 1320 } 1321 }, 1322 check: func(t *testing.T, c *Client, uns any) { 1323 res, ok := uns.(*result.RawNotaryPool) 1324 require.True(t, ok) 1325 mainHash, err := util.Uint256DecodeStringLE("d86b5346e9bbe6dba845cc4192fa716535a3d05c4f2084431edc99dc3862a299") 1326 require.NoError(t, err, "can't decode `mainHash` result hash") 1327 fallbackHash, err := util.Uint256DecodeStringLE("bb0b2f1d5539dd776637f00e5011d97921a1400d3a63c02977a38446180c6d7c") 1328 require.NoError(t, err, "can't decode `fallbackHash` result hash") 1329 fallbacks, ok := res.Hashes[mainHash] 1330 require.True(t, ok) 1331 assert.Equal(t, fallbacks[0], fallbackHash) 1332 }, 1333 }, 1334 }, 1335 } 1336 1337 type rpcClientErrorCase struct { 1338 name string 1339 invoke func(c *Client) (any, error) 1340 } 1341 1342 var rpcClientErrorCases = map[string][]rpcClientErrorCase{ 1343 `{"jsonrpc":"2.0","id":1,"result":{"name":"name","bad":42}}`: { 1344 { 1345 name: "getnep11properties_unmarshalling_error", 1346 invoke: func(c *Client) (any, error) { 1347 return c.GetNEP11Properties(util.Uint160{}, []byte{}) 1348 }, 1349 }, 1350 }, 1351 `{"jsonrpc":"2.0","id":1,"result":{"name":100500,"good":"c29tZXRoaW5n"}}`: { 1352 { 1353 name: "getnep11properties_unmarshalling_error", 1354 invoke: func(c *Client) (any, error) { 1355 return c.GetNEP11Properties(util.Uint160{}, []byte{}) 1356 }, 1357 }, 1358 }, 1359 `{"jsonrpc":"2.0","id":1,"result":"not-a-hex-string"}`: { 1360 { 1361 name: "getblock_not_a_hex_response", 1362 invoke: func(c *Client) (any, error) { 1363 return c.GetBlockByIndex(1) 1364 }, 1365 }, 1366 { 1367 name: "getblockheader_not_a_hex_response", 1368 invoke: func(c *Client) (any, error) { 1369 hash, err := util.Uint256DecodeStringLE("e93d17a52967f9e69314385482bf86f85260e811b46bf4d4b261a7f4135a623c") 1370 if err != nil { 1371 panic(err) 1372 } 1373 return c.GetBlockHeader(hash) 1374 }, 1375 }, 1376 { 1377 name: "getrawtransaction_not_a_hex_response", 1378 invoke: func(c *Client) (any, error) { 1379 hash, err := util.Uint256DecodeStringLE("e93d17a52967f9e69314385482bf86f85260e811b46bf4d4b261a7f4135a623c") 1380 if err != nil { 1381 panic(err) 1382 } 1383 return c.GetRawTransaction(hash) 1384 }, 1385 }, 1386 { 1387 name: "getstoragebyhash_not_a_hex_response", 1388 invoke: func(c *Client) (any, error) { 1389 hash, err := util.Uint160DecodeStringLE("03febccf81ac85e3d795bc5cbd4e84e907812aa3") 1390 if err != nil { 1391 panic(err) 1392 } 1393 key, err := hex.DecodeString("5065746572") 1394 if err != nil { 1395 panic(err) 1396 } 1397 return c.GetStorageByHash(hash, key) 1398 }, 1399 }, 1400 { 1401 name: "getstoragebyid_not_a_hex_response", 1402 invoke: func(c *Client) (any, error) { 1403 key, err := hex.DecodeString("5065746572") 1404 if err != nil { 1405 panic(err) 1406 } 1407 return c.GetStorageByID(-1, key) 1408 }, 1409 }, 1410 }, 1411 `{"jsonrpc":"2.0","id":1,"result":"01"}`: { 1412 { 1413 name: "getblock_decodebin_error", 1414 invoke: func(c *Client) (any, error) { 1415 return c.GetBlockByIndex(1) 1416 }, 1417 }, 1418 { 1419 name: "getheader_decodebin_err", 1420 invoke: func(c *Client) (any, error) { 1421 hash, err := util.Uint256DecodeStringLE("e93d17a52967f9e69314385482bf86f85260e811b46bf4d4b261a7f4135a623c") 1422 if err != nil { 1423 panic(err) 1424 } 1425 return c.GetBlockHeader(hash) 1426 }, 1427 }, 1428 { 1429 name: "getrawtransaction_decodebin_err", 1430 invoke: func(c *Client) (any, error) { 1431 hash, err := util.Uint256DecodeStringLE("e93d17a52967f9e69314385482bf86f85260e811b46bf4d4b261a7f4135a623c") 1432 if err != nil { 1433 panic(err) 1434 } 1435 return c.GetRawTransaction(hash) 1436 }, 1437 }, 1438 }, 1439 `{"jsonrpc":"2.0","id":1,"result":false}`: { 1440 { 1441 name: "sendrawtransaction_bad_server_answer", 1442 invoke: func(c *Client) (any, error) { 1443 return c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0)) 1444 }, 1445 }, 1446 { 1447 name: "submitblock_bad_server_answer", 1448 invoke: func(c *Client) (any, error) { 1449 return c.SubmitBlock(block.Block{ 1450 Header: block.Header{}, 1451 Transactions: nil, 1452 Trimmed: false, 1453 }) 1454 }, 1455 }, 1456 { 1457 name: "validateaddress_bad_server_answer", 1458 invoke: func(c *Client) (any, error) { 1459 return nil, c.ValidateAddress("AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i") 1460 }, 1461 }, 1462 }, 1463 `{"id":1,"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params"}}`: { 1464 { 1465 name: "getapplicationlog_invalid_params_error", 1466 invoke: func(c *Client) (any, error) { 1467 return c.GetApplicationLog(util.Uint256{}, nil) 1468 }, 1469 }, 1470 { 1471 name: "getbestblockhash_invalid_params_error", 1472 invoke: func(c *Client) (any, error) { 1473 return c.GetBestBlockHash() 1474 }, 1475 }, 1476 { 1477 name: "getblock_byindex_invalid_params_error", 1478 invoke: func(c *Client) (any, error) { 1479 return c.GetBlockByIndex(1) 1480 }, 1481 }, 1482 { 1483 name: "getblock_byindex_verbose_invalid_params_error", 1484 invoke: func(c *Client) (any, error) { 1485 return c.GetBlockByIndexVerbose(1) 1486 }, 1487 }, 1488 { 1489 name: "getblock_byhash_invalid_params_error", 1490 invoke: func(c *Client) (any, error) { 1491 return c.GetBlockByHash(util.Uint256{}) 1492 }, 1493 }, 1494 { 1495 name: "getblock_byhash_verbose_invalid_params_error", 1496 invoke: func(c *Client) (any, error) { 1497 return c.GetBlockByHashVerbose(util.Uint256{}) 1498 }, 1499 }, 1500 { 1501 name: "getblockhash_invalid_params_error", 1502 invoke: func(c *Client) (any, error) { 1503 return c.GetBlockHash(0) 1504 }, 1505 }, 1506 { 1507 name: "getblockheader_invalid_params_error", 1508 invoke: func(c *Client) (any, error) { 1509 return c.GetBlockHeader(util.Uint256{}) 1510 }, 1511 }, 1512 { 1513 name: "getblockheader_verbose_invalid_params_error", 1514 invoke: func(c *Client) (any, error) { 1515 return c.GetBlockHeaderVerbose(util.Uint256{}) 1516 }, 1517 }, 1518 { 1519 name: "getblocksysfee_invalid_params_error", 1520 invoke: func(c *Client) (any, error) { 1521 return c.GetBlockSysFee(1) 1522 }, 1523 }, 1524 { 1525 name: "getconnectioncount_invalid_params_error", 1526 invoke: func(c *Client) (any, error) { 1527 return c.GetConnectionCount() 1528 }, 1529 }, 1530 { 1531 name: "getcontractstate_invalid_params_error", 1532 invoke: func(c *Client) (any, error) { 1533 return c.GetContractStateByHash(util.Uint160{}) 1534 }, 1535 }, 1536 { 1537 name: "getnep11balances_invalid_params_error", 1538 invoke: func(c *Client) (any, error) { 1539 return c.GetNEP11Balances(util.Uint160{}) 1540 }, 1541 }, 1542 { 1543 name: "getnep17balances_invalid_params_error", 1544 invoke: func(c *Client) (any, error) { 1545 return c.GetNEP17Balances(util.Uint160{}) 1546 }, 1547 }, 1548 { 1549 name: "getnep11properties_invalid_params_error", 1550 invoke: func(c *Client) (any, error) { 1551 return c.GetNEP11Properties(util.Uint160{}, []byte{}) 1552 }, 1553 }, 1554 { 1555 name: "getnep11transfers_invalid_params_error", 1556 invoke: func(c *Client) (any, error) { 1557 return c.GetNEP11Transfers(util.Uint160{}, nil, nil, nil, nil) 1558 }, 1559 }, 1560 { 1561 name: "getnep17transfers_invalid_params_error", 1562 invoke: func(c *Client) (any, error) { 1563 return c.GetNEP17Transfers(util.Uint160{}, nil, nil, nil, nil) 1564 }, 1565 }, 1566 { 1567 name: "getnep17transfers_invalid_params_error 2", 1568 invoke: func(c *Client) (any, error) { 1569 var stop uint64 1570 return c.GetNEP17Transfers(util.Uint160{}, nil, &stop, nil, nil) 1571 }, 1572 }, 1573 { 1574 name: "getnep17transfers_invalid_params_error 3", 1575 invoke: func(c *Client) (any, error) { 1576 var start uint64 1577 var limit int 1578 return c.GetNEP17Transfers(util.Uint160{}, &start, nil, &limit, nil) 1579 }, 1580 }, 1581 { 1582 name: "getnep17transfers_invalid_params_error 4", 1583 invoke: func(c *Client) (any, error) { 1584 var start, stop uint64 1585 var page int 1586 return c.GetNEP17Transfers(util.Uint160{}, &start, &stop, nil, &page) 1587 }, 1588 }, 1589 { 1590 name: "getrawtransaction_invalid_params_error", 1591 invoke: func(c *Client) (any, error) { 1592 return c.GetRawTransaction(util.Uint256{}) 1593 }, 1594 }, 1595 { 1596 name: "getrawtransaction_verbose_invalid_params_error", 1597 invoke: func(c *Client) (any, error) { 1598 return c.GetRawTransactionVerbose(util.Uint256{}) 1599 }, 1600 }, 1601 { 1602 name: "getstoragebyhash_invalid_params_error", 1603 invoke: func(c *Client) (any, error) { 1604 return c.GetStorageByHash(util.Uint160{}, []byte{}) 1605 }, 1606 }, 1607 { 1608 name: "getstoragebyid_invalid_params_error", 1609 invoke: func(c *Client) (any, error) { 1610 return c.GetStorageByID(-1, []byte{}) 1611 }, 1612 }, 1613 { 1614 name: "gettransactionheight_invalid_params_error", 1615 invoke: func(c *Client) (any, error) { 1616 return c.GetTransactionHeight(util.Uint256{}) 1617 }, 1618 }, 1619 { 1620 name: "getunclaimedgas_invalid_params_error", 1621 invoke: func(c *Client) (any, error) { 1622 return c.GetUnclaimedGas("") 1623 }, 1624 }, 1625 { 1626 name: "invokefunction_invalid_params_error", 1627 invoke: func(c *Client) (any, error) { 1628 return c.InvokeFunction(util.Uint160{}, "", []smartcontract.Parameter{}, nil) 1629 }, 1630 }, 1631 { 1632 name: "invokescript_invalid_params_error", 1633 invoke: func(c *Client) (any, error) { 1634 return c.InvokeScript([]byte{}, nil) 1635 }, 1636 }, 1637 { 1638 name: "sendrawtransaction_invalid_params_error", 1639 invoke: func(c *Client) (any, error) { 1640 return c.SendRawTransaction(&transaction.Transaction{}) 1641 }, 1642 }, 1643 { 1644 name: "submitblock_invalid_params_error", 1645 invoke: func(c *Client) (any, error) { 1646 return c.SubmitBlock(block.Block{}) 1647 }, 1648 }, 1649 { 1650 name: "validateaddress_invalid_params_error", 1651 invoke: func(c *Client) (any, error) { 1652 return nil, c.ValidateAddress("") 1653 }, 1654 }, 1655 }, 1656 `{}`: { 1657 { 1658 name: "getapplicationlog_unmarshalling_error", 1659 invoke: func(c *Client) (any, error) { 1660 return c.GetApplicationLog(util.Uint256{}, nil) 1661 }, 1662 }, 1663 { 1664 name: "getbestblockhash_unmarshalling_error", 1665 invoke: func(c *Client) (any, error) { 1666 return c.GetBestBlockHash() 1667 }, 1668 }, 1669 { 1670 name: "getblock_byindex_unmarshalling_error", 1671 invoke: func(c *Client) (any, error) { 1672 return c.GetBlockByIndex(1) 1673 }, 1674 }, 1675 { 1676 name: "getblock_byindex_verbose_unmarshalling_error", 1677 invoke: func(c *Client) (any, error) { 1678 return c.GetBlockByIndexVerbose(1) 1679 }, 1680 }, 1681 { 1682 name: "getblock_byhash_unmarshalling_error", 1683 invoke: func(c *Client) (any, error) { 1684 return c.GetBlockByHash(util.Uint256{}) 1685 }, 1686 }, 1687 { 1688 name: "getblock_byhash_verbose_unmarshalling_error", 1689 invoke: func(c *Client) (any, error) { 1690 return c.GetBlockByHashVerbose(util.Uint256{}) 1691 }, 1692 }, 1693 { 1694 name: "getblockcount_unmarshalling_error", 1695 invoke: func(c *Client) (any, error) { 1696 return c.GetBlockCount() 1697 }, 1698 }, 1699 { 1700 name: "getblockhash_unmarshalling_error", 1701 invoke: func(c *Client) (any, error) { 1702 return c.GetBlockHash(1) 1703 }, 1704 }, 1705 { 1706 name: "getblockheader_unmarshalling_error", 1707 invoke: func(c *Client) (any, error) { 1708 return c.GetBlockHeader(util.Uint256{}) 1709 }, 1710 }, 1711 { 1712 name: "getblockheader_verbose_unmarshalling_error", 1713 invoke: func(c *Client) (any, error) { 1714 return c.GetBlockHeaderVerbose(util.Uint256{}) 1715 }, 1716 }, 1717 { 1718 name: "getblocksysfee_unmarshalling_error", 1719 invoke: func(c *Client) (any, error) { 1720 return c.GetBlockSysFee(1) 1721 }, 1722 }, 1723 { 1724 name: "getcommittee_unmarshalling_error", 1725 invoke: func(c *Client) (any, error) { 1726 return c.GetCommittee() 1727 }, 1728 }, 1729 { 1730 name: "getconnectioncount_unmarshalling_error", 1731 invoke: func(c *Client) (any, error) { 1732 return c.GetConnectionCount() 1733 }, 1734 }, 1735 { 1736 name: "getcontractstate_unmarshalling_error", 1737 invoke: func(c *Client) (any, error) { 1738 return c.GetContractStateByHash(util.Uint160{}) 1739 }, 1740 }, 1741 { 1742 name: "getnep11balances_unmarshalling_error", 1743 invoke: func(c *Client) (any, error) { 1744 return c.GetNEP11Balances(util.Uint160{}) 1745 }, 1746 }, 1747 { 1748 name: "getnep17balances_unmarshalling_error", 1749 invoke: func(c *Client) (any, error) { 1750 return c.GetNEP17Balances(util.Uint160{}) 1751 }, 1752 }, 1753 { 1754 name: "getnep11transfers_unmarshalling_error", 1755 invoke: func(c *Client) (any, error) { 1756 return c.GetNEP11Transfers(util.Uint160{}, nil, nil, nil, nil) 1757 }, 1758 }, 1759 { 1760 name: "getnep17transfers_unmarshalling_error", 1761 invoke: func(c *Client) (any, error) { 1762 return c.GetNEP17Transfers(util.Uint160{}, nil, nil, nil, nil) 1763 }, 1764 }, 1765 { 1766 name: "getpeers_unmarshalling_error", 1767 invoke: func(c *Client) (any, error) { 1768 return c.GetPeers() 1769 }, 1770 }, 1771 { 1772 name: "getrawmempool_unmarshalling_error", 1773 invoke: func(c *Client) (any, error) { 1774 return c.GetRawMemPool() 1775 }, 1776 }, 1777 { 1778 name: "getrawtransaction_unmarshalling_error", 1779 invoke: func(c *Client) (any, error) { 1780 return c.GetRawTransaction(util.Uint256{}) 1781 }, 1782 }, 1783 { 1784 name: "getrawtransaction_verbose_unmarshalling_error", 1785 invoke: func(c *Client) (any, error) { 1786 return c.GetRawTransactionVerbose(util.Uint256{}) 1787 }, 1788 }, 1789 { 1790 name: "getstoragebyhash_unmarshalling_error", 1791 invoke: func(c *Client) (any, error) { 1792 return c.GetStorageByHash(util.Uint160{}, []byte{}) 1793 }, 1794 }, 1795 { 1796 name: "getstoragebyid_unmarshalling_error", 1797 invoke: func(c *Client) (any, error) { 1798 return c.GetStorageByID(-1, []byte{}) 1799 }, 1800 }, 1801 { 1802 name: "gettransactionheight_unmarshalling_error", 1803 invoke: func(c *Client) (any, error) { 1804 return c.GetTransactionHeight(util.Uint256{}) 1805 }, 1806 }, 1807 { 1808 name: "getunclaimedgas_unmarshalling_error", 1809 invoke: func(c *Client) (any, error) { 1810 return c.GetUnclaimedGas("") 1811 }, 1812 }, 1813 { 1814 name: "getcandidates_unmarshalling_error", 1815 invoke: func(c *Client) (any, error) { 1816 return c.GetCandidates() 1817 }, 1818 }, 1819 { 1820 name: "getvalidators_unmarshalling_error", 1821 invoke: func(c *Client) (any, error) { 1822 return c.GetNextBlockValidators() 1823 }, 1824 }, 1825 { 1826 name: "invokefunction_unmarshalling_error", 1827 invoke: func(c *Client) (any, error) { 1828 return c.InvokeFunction(util.Uint160{}, "", []smartcontract.Parameter{}, nil) 1829 }, 1830 }, 1831 { 1832 name: "invokescript_unmarshalling_error", 1833 invoke: func(c *Client) (any, error) { 1834 return c.InvokeScript([]byte{}, nil) 1835 }, 1836 }, 1837 { 1838 name: "sendrawtransaction_unmarshalling_error", 1839 invoke: func(c *Client) (any, error) { 1840 return c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0)) 1841 }, 1842 }, 1843 { 1844 name: "submitblock_unmarshalling_error", 1845 invoke: func(c *Client) (any, error) { 1846 return c.SubmitBlock(block.Block{ 1847 Header: block.Header{}, 1848 Transactions: nil, 1849 Trimmed: false, 1850 }) 1851 }, 1852 }, 1853 { 1854 name: "validateaddress_unmarshalling_error", 1855 invoke: func(c *Client) (any, error) { 1856 return nil, c.ValidateAddress("") 1857 }, 1858 }, 1859 }, 1860 } 1861 1862 func TestRPCClients(t *testing.T) { 1863 t.Run("Client", func(t *testing.T) { 1864 testRPCClient(t, func(ctx context.Context, endpoint string, opts Options) (*Client, error) { 1865 c, err := New(ctx, endpoint, opts) 1866 require.NoError(t, err) 1867 c.getNextRequestID = getTestRequestID 1868 require.NoError(t, c.Init()) 1869 return c, nil 1870 }) 1871 }) 1872 t.Run("WSClient", func(t *testing.T) { 1873 testRPCClient(t, func(ctx context.Context, endpoint string, opts Options) (*Client, error) { 1874 wsc, err := NewWS(ctx, httpURLtoWS(endpoint), WSOptions{Options: opts}) 1875 require.NoError(t, err) 1876 wsc.getNextRequestID = getTestRequestID 1877 require.NoError(t, wsc.Init()) 1878 return &wsc.Client, nil 1879 }) 1880 }) 1881 } 1882 1883 func testRPCClient(t *testing.T, newClient func(context.Context, string, Options) (*Client, error)) { 1884 for method, testBatch := range rpcClientTestCases { 1885 t.Run(method, func(t *testing.T) { 1886 for _, testCase := range testBatch { 1887 t.Run(testCase.name, func(t *testing.T) { 1888 srv := initTestServer(t, testCase.serverResponse) 1889 1890 endpoint := srv.URL 1891 opts := Options{} 1892 c, err := newClient(context.TODO(), endpoint, opts) 1893 if err != nil { 1894 t.Fatal(err) 1895 } 1896 c.getNextRequestID = getTestRequestID 1897 1898 actual, err := testCase.invoke(c) 1899 if testCase.fails { 1900 assert.Error(t, err) 1901 } else { 1902 assert.NoError(t, err) 1903 1904 expected := testCase.result(c) 1905 if testCase.check == nil { 1906 assert.Equal(t, expected, actual) 1907 } else { 1908 testCase.check(t, c, actual) 1909 } 1910 } 1911 }) 1912 } 1913 }) 1914 } 1915 for serverResponse, testBatch := range rpcClientErrorCases { 1916 srv := initTestServer(t, serverResponse) 1917 1918 endpoint := srv.URL 1919 opts := Options{} 1920 for _, testCase := range testBatch { 1921 t.Run(testCase.name, func(t *testing.T) { 1922 c, err := newClient(context.TODO(), endpoint, opts) 1923 if err != nil { 1924 t.Fatal(err) 1925 } 1926 c.getNextRequestID = getTestRequestID 1927 _, err = testCase.invoke(c) 1928 assert.Error(t, err) 1929 }) 1930 } 1931 } 1932 } 1933 1934 func httpURLtoWS(url string) string { 1935 return "ws" + strings.TrimPrefix(url, "http") + "/ws" 1936 } 1937 1938 func initTestServer(t *testing.T, resp string) *httptest.Server { 1939 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 1940 if req.URL.Path == "/ws" && req.Method == "GET" { 1941 var upgrader = websocket.Upgrader{} 1942 ws, err := upgrader.Upgrade(w, req, nil) 1943 require.NoError(t, err) 1944 for { 1945 err = ws.SetReadDeadline(time.Now().Add(5 * time.Second)) 1946 require.NoError(t, err) 1947 _, p, err := ws.ReadMessage() 1948 if err != nil { 1949 break 1950 } 1951 r := params.NewIn() 1952 err = json.Unmarshal(p, r) 1953 if err != nil { 1954 t.Fatalf("Cannot decode request body: %s", req.Body) 1955 } 1956 response := wrapInitResponse(r, resp) 1957 err = ws.SetWriteDeadline(time.Now().Add(5 * time.Second)) 1958 require.NoError(t, err) 1959 err = ws.WriteMessage(1, []byte(response)) 1960 if err != nil { 1961 break 1962 } 1963 } 1964 ws.Close() 1965 return 1966 } 1967 r := params.NewRequest() 1968 err := r.DecodeData(req.Body) 1969 if err != nil { 1970 t.Fatalf("Cannot decode request body: %s", req.Body) 1971 } 1972 requestHandler(t, r.In, w, resp) 1973 })) 1974 1975 t.Cleanup(srv.Close) 1976 1977 return srv 1978 } 1979 1980 func requestHandler(t *testing.T, r *params.In, w http.ResponseWriter, resp string) { 1981 w.Header().Set("Content-Type", "application/json; charset=utf-8") 1982 response := wrapInitResponse(r, resp) 1983 _, err := w.Write([]byte(response)) 1984 if err != nil { 1985 t.Fatalf("Error writing response: %s", err.Error()) 1986 } 1987 } 1988 1989 func wrapInitResponse(r *params.In, resp string) string { 1990 var response string 1991 switch r.Method { 1992 case "getversion": 1993 response = `{"id":1,"jsonrpc":"2.0","result":{"protocol":{"network":42},"tcpport":20332,"wsport":20342,"nonce":2153672787,"useragent":"/NEO-GO:0.73.1-pre-273-ge381358/", "rpc": {"maxiteratorresultitems": 100, "sessionenabled": true}}}` 1994 case "getnativecontracts": 1995 response = `{"jsonrpc":"2.0","id":1,"result":[{"id":-1,"hash":"0xfffdc93764dbaddd97c48f252a53ea4643faa3fd","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1110259869},"manifest":{"name":"ContractManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Array","offset":0,"safe":false},{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Array","offset":7,"safe":false},{"name":"destroy","parameters":[],"returntype":"Void","offset":14,"safe":false},{"name":"getContract","parameters":[{"name":"hash","type":"Hash160"}],"returntype":"Array","offset":21,"safe":true},{"name":"getMinimumDeploymentFee","parameters":[],"returntype":"Integer","offset":28,"safe":true},{"name":"setMinimumDeploymentFee","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":35,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Void","offset":42,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","offset":49,"safe":false}],"events":[{"name":"Deploy","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Update","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Destroy","parameters":[{"name":"Hash","type":"Hash160"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-2,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1325686241},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":56,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":63,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":70,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":77,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":84,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":91,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":98,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":112,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":119,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":126,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":133,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-3,"hash":"0x726cb6e0cd8628a1350a611384688911ab75f51b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dA","checksum":1592866325},"manifest":{"name":"CryptoLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"ripemd160","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":0,"safe":true},{"name":"sha256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":7,"safe":true},{"name":"verifyWithECDsa","parameters":[{"name":"message","type":"ByteArray"},{"name":"pubkey","type":"ByteArray"},{"name":"signature","type":"ByteArray"},{"name":"curve","type":"Integer"}],"returntype":"Boolean","offset":14,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-4,"hash":"0xda65b600f7124ce6c79950c1772a36403104f2be","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dA","checksum":529571427},"manifest":{"name":"LedgerContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"currentHash","parameters":[],"returntype":"Hash256","offset":0,"safe":true},{"name":"currentIndex","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getBlock","parameters":[{"name":"indexOrHash","type":"ByteArray"}],"returntype":"Array","offset":14,"safe":true},{"name":"getTransaction","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":21,"safe":true},{"name":"getTransactionFromBlock","parameters":[{"name":"blockIndexOrHash","type":"ByteArray"},{"name":"txIndex","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getTransactionHeight","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":35,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-5,"hash":"0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":588003825},"manifest":{"name":"NeoToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getAccountState","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Array","offset":14,"safe":true},{"name":"getCandidates","parameters":[],"returntype":"Array","offset":21,"safe":true},{"name":"getCommittee","parameters":[],"returntype":"Array","offset":28,"safe":true},{"name":"getGasPerBlock","parameters":[],"returntype":"Integer","offset":35,"safe":true},{"name":"getNextBlockValidators","parameters":[],"returntype":"Array","offset":42,"safe":true},{"name":"getRegisterPrice","parameters":[],"returntype":"Integer","offset":49,"safe":true},{"name":"registerCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":56,"safe":false},{"name":"setGasPerBlock","parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Void","offset":63,"safe":false},{"name":"setRegisterPrice","parameters":[{"name":"registerPrice","type":"Integer"}],"returntype":"Void","offset":70,"safe":false},{"name":"symbol","parameters":[],"returntype":"String","offset":77,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":84,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":91,"safe":false},{"name":"unclaimedGas","parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer","offset":98,"safe":true},{"name":"unregisterCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":105,"safe":false},{"name":"vote","parameters":[{"name":"account","type":"Hash160"},{"name":"voteTo","type":"PublicKey"}],"returntype":"Boolean","offset":112,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-6,"hash":"0xd2a4cff31913016155e38e474a2c06d08be276cf","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2663858513},"manifest":{"name":"GasToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"symbol","parameters":[],"returntype":"String","offset":14,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":21,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":28,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-7,"hash":"0xcc5e4edd9f5f8dba8bb65734541df7a1c081c67b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dA","checksum":3443651689},"manifest":{"name":"PolicyContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"blockAccount","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":0,"safe":false},{"name":"getExecFeeFactor","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getFeePerByte","parameters":[],"returntype":"Integer","offset":14,"safe":true},{"name":"getStoragePrice","parameters":[],"returntype":"Integer","offset":21,"safe":true},{"name":"isBlocked","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":28,"safe":true},{"name":"setExecFeeFactor","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":35,"safe":false},{"name":"setFeePerByte","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":42,"safe":false},{"name":"setStoragePrice","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":49,"safe":false},{"name":"unblockAccount","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":56,"safe":false}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-8,"hash":"0x49cf4e5378ffcd4dec034fd98a174c5491e395e2","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0A=","checksum":983638438},"manifest":{"name":"RoleManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"designateAsRole","parameters":[{"name":"role","type":"Integer"},{"name":"nodes","type":"Array"}],"returntype":"Void","offset":0,"safe":false},{"name":"getDesignatedByRole","parameters":[{"name":"role","type":"Integer"},{"name":"index","type":"Integer"}],"returntype":"Array","offset":7,"safe":true}],"events":[{"name":"Designation","parameters":[{"name":"Role","type":"Integer"},{"name":"BlockIndex","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]},{"id":-9,"hash":"0xfe924b7cfe89ddd271abaf7210a80a7e11178758","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2663858513},"manifest":{"name":"OracleContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"finish","parameters":[],"returntype":"Void","offset":0,"safe":false},{"name":"getPrice","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"request","parameters":[{"name":"url","type":"String"},{"name":"filter","type":"String"},{"name":"callback","type":"String"},{"name":"userData","type":"Any"},{"name":"gasForResponse","type":"Integer"}],"returntype":"Void","offset":14,"safe":false},{"name":"setPrice","parameters":[{"name":"price","type":"Integer"}],"returntype":"Void","offset":21,"safe":false},{"name":"verify","parameters":[],"returntype":"Boolean","offset":28,"safe":true}],"events":[{"name":"OracleRequest","parameters":[{"name":"Id","type":"Integer"},{"name":"RequestContract","type":"Hash160"},{"name":"Url","type":"String"},{"name":"Filter","type":"String"}]},{"name":"OracleResponse","parameters":[{"name":"Id","type":"Integer"},{"name":"OriginalTx","type":"Hash256"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null},"updatehistory":[0]}]}` 1996 case "getcontractstate": 1997 p := params.Params(r.RawParams) 1998 name, _ := p.Value(0).GetString() 1999 switch name { 2000 case "NeoToken": 2001 response = `{"id":1,"jsonrpc":"2.0","result":{"id":-1,"script":"DANORU9Ba2d4Cw==","manifest":{"name":"NEO","abi":{"hash":"0xde5f57d430d3dece511cf975a8d37848cb9e0525","methods":[{"name":"name","offset":0,"parameters":null,"returntype":"String"},{"name":"symbol","offset":0,"parameters":null,"returntype":"String"},{"name":"decimals","offset":0,"parameters":null,"returntype":"Integer"},{"name":"totalSupply","offset":0,"parameters":null,"returntype":"Integer"},{"name":"balanceOf","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer"},{"name":"transfer","offset":0,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Boolean"},{"name":"onPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"postPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"unclaimedGas","offset":0,"parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer"},{"name":"registerCandidate","offset":0,"parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"unregisterCandidate","offset":0,"parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"vote","offset":0,"parameters":[{"name":"account","type":"Hash160"},{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"getCandidates","offset":0,"parameters":null,"returntype":"Array"},{"name":"getДommittee","offset":0,"parameters":null,"returntype":"Array"},{"name":"getNextBlockValidators","offset":0,"parameters":null,"returntype":"Array"},{"name":"getGasPerBlock","offset":0,"parameters":null,"returntype":"Integer"},{"name":"setGasPerBlock","offset":0,"parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Boolean"}],"events":[{"name":"Transfer","parameters":null}]},"groups":[],"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":["NEP-5"],"trusts":[],"safemethods":["name","symbol","decimals","totalSupply","balanceOf","unclaimedGas","getCandidates","getДommittee","getNextBlockValidators"],"extra":null},"hash":"0xde5f57d430d3dece511cf975a8d37848cb9e0525"}}` 2002 case "GasToken": 2003 response = `{"id":1,"jsonrpc":"2.0","result":{"id":-2,"script":"DANHQVNBa2d4Cw==","manifest":{"name":"GAS","abi":{"hash":"0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","methods":[{"name":"name","offset":0,"parameters":null,"returntype":"String"},{"name":"symbol","offset":0,"parameters":null,"returntype":"String"},{"name":"decimals","offset":0,"parameters":null,"returntype":"Integer"},{"name":"totalSupply","offset":0,"parameters":null,"returntype":"Integer"},{"name":"balanceOf","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer"},{"name":"transfer","offset":0,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Boolean"},{"name":"onPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"postPersist","offset":0,"parameters":null,"returntype":"Void"}],"events":[{"name":"Transfer","parameters":null}]},"groups":[],"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":["NEP-5"],"trusts":[],"safemethods":["name","symbol","decimals","totalSupply","balanceOf"],"extra":null},"hash":"0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"}}` 2004 case "PolicyContract": 2005 response = `{"id":1,"jsonrpc":"2.0","result":{"id":-3,"updatecounter":0,"hash":"0xac593e6183643940a9193f87c64ccf55ef19c529","script":"DAZQb2xpY3lBGvd7Zw==","manifest":{"name":"Policy","abi":{"methods":[{"name":"getMaxTransactionsPerBlock","offset":0,"parameters":null,"returntype":"Integer"},{"name":"getMaxBlockSize","offset":0,"parameters":null,"returntype":"Integer"},{"name":"getFeePerByte","offset":0,"parameters":null,"returntype":"Integer"},{"name":"isBlocked","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean"},{"name":"getMaxBlockSystemFee","offset":0,"parameters":null,"returntype":"Integer"},{"name":"setMaxBlockSize","offset":0,"parameters":[{"name":"value","type":"Integer"}],"returntype":"Boolean"},{"name":"setMaxTransactionsPerBlock","offset":0,"parameters":[{"name":"value","type":"Integer"}],"returntype":"Boolean"},{"name":"setFeePerByte","offset":0,"parameters":[{"name":"value","type":"Integer"}],"returntype":"Boolean"},{"name":"setMaxBlockSystemFee","offset":0,"parameters":[{"name":"value","type":"Integer"}],"returntype":"Boolean"},{"name":"blockAccount","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean"},{"name":"unblockAccount","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean"}],"events":[]},"groups":[],"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":[],"trusts":[],"safemethods":["getMaxTransactionsPerBlock","getMaxBlockSize","getFeePerByte","isBlocked","getMaxBlockSystemFee"],"extra":null}}}` 2006 default: 2007 response = resp 2008 } 2009 default: 2010 response = resp 2011 } 2012 return response 2013 } 2014 2015 func TestUninitedClient(t *testing.T) { 2016 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 2017 r := params.NewRequest() 2018 err := r.DecodeData(req.Body) 2019 require.NoErrorf(t, err, "Cannot decode request body: %s", req.Body) 2020 // request handler already have `getversion` response wrapper 2021 requestHandler(t, r.In, w, "") 2022 })) 2023 t.Cleanup(srv.Close) 2024 endpoint := srv.URL 2025 opts := Options{} 2026 2027 c, err := New(context.TODO(), endpoint, opts) 2028 require.NoError(t, err) 2029 c.getNextRequestID = getTestRequestID 2030 2031 _, err = c.GetBlockByIndex(0) 2032 require.Error(t, err) 2033 _, err = c.GetBlockByIndexVerbose(0) 2034 require.Error(t, err) 2035 _, err = c.GetBlockHeader(util.Uint256{}) 2036 require.Error(t, err) 2037 _, err = c.GetRawTransaction(util.Uint256{}) 2038 require.Error(t, err) 2039 _, err = c.GetRawTransactionVerbose(util.Uint256{}) 2040 require.Error(t, err) 2041 } 2042 2043 func newTestNEF(script []byte) nef.File { 2044 var ne nef.File 2045 ne.Header.Magic = nef.Magic 2046 ne.Header.Compiler = "neo-go-3.0" 2047 ne.Script = script 2048 ne.Checksum = ne.CalculateChecksum() 2049 return ne 2050 } 2051 2052 func getTestRequestID() uint64 { 2053 return 1 2054 }