2020-02-17 12:17:02 +00:00
|
|
|
package server
|
2019-01-22 12:14:52 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2020-01-30 08:03:44 +00:00
|
|
|
"encoding/hex"
|
2019-09-18 15:21:16 +00:00
|
|
|
"encoding/json"
|
2019-01-22 12:14:52 +00:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2019-11-21 16:41:28 +00:00
|
|
|
"reflect"
|
2020-03-04 17:35:37 +00:00
|
|
|
"strconv"
|
2019-02-09 15:53:58 +00:00
|
|
|
"strings"
|
2019-01-22 12:14:52 +00:00
|
|
|
"testing"
|
|
|
|
|
2020-03-03 14:21:42 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
2020-03-23 14:31:28 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
2020-03-05 12:16:03 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
2020-04-22 10:15:31 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/internal/testchain"
|
2020-03-04 17:35:37 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
2020-03-03 14:21:42 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2019-01-22 12:14:52 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2019-11-21 16:41:28 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2019-01-22 12:14:52 +00:00
|
|
|
)
|
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
type executor struct {
|
|
|
|
chain *core.Blockchain
|
|
|
|
handler http.HandlerFunc
|
|
|
|
}
|
2019-02-20 17:39:32 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
const (
|
|
|
|
defaultJSONRPC = "2.0"
|
|
|
|
defaultID = 1
|
|
|
|
)
|
2019-02-20 17:39:32 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
type rpcTestCase struct {
|
|
|
|
name string
|
|
|
|
params string
|
|
|
|
fail bool
|
|
|
|
result func(e *executor) interface{}
|
|
|
|
check func(t *testing.T, e *executor, result interface{})
|
|
|
|
}
|
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
|
|
|
|
2020-04-21 13:45:48 +00:00
|
|
|
const testContractHash = "8bb068bca226bf013e7d19400b9d85c4eb865607"
|
2020-03-05 15:26:54 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
var rpcTestCases = map[string][]rpcTestCase{
|
2020-02-21 14:56:28 +00:00
|
|
|
"getapplicationlog": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["66238fd4ac778326b0c151c025ee8f1c6d738e7e191820537564d2b887f3ecde"]`,
|
2020-02-21 14:56:28 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
|
|
|
|
check: func(t *testing.T, e *executor, acc interface{}) {
|
|
|
|
res, ok := acc.(*result.ApplicationLog)
|
|
|
|
require.True(t, ok)
|
2020-04-21 13:45:48 +00:00
|
|
|
expectedTxHash, err := util.Uint256DecodeStringLE("66238fd4ac778326b0c151c025ee8f1c6d738e7e191820537564d2b887f3ecde")
|
2020-03-04 14:45:29 +00:00
|
|
|
require.NoError(t, err)
|
2020-02-21 14:56:28 +00:00
|
|
|
assert.Equal(t, expectedTxHash, res.TxHash)
|
|
|
|
assert.Equal(t, 1, len(res.Executions))
|
|
|
|
assert.Equal(t, "Application", res.Executions[0].Trigger)
|
|
|
|
assert.Equal(t, "HALT", res.Executions[0].VMState)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid address",
|
|
|
|
params: `["notahash"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid tx hash",
|
|
|
|
params: `["d24cc1d52b5c0216cbf3835bb5bac8ccf32639fa1ab6627ec4e2b9f33f7ec02f"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid tx type",
|
|
|
|
params: `["f9adfde059810f37b3d0686d67f6b29034e0c669537df7e59b40c14a0508b9ed"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"getaccountstate": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-22 10:15:31 +00:00
|
|
|
params: `["` + testchain.MultisigAddress() + `"]`,
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.AccountState{} },
|
|
|
|
check: func(t *testing.T, e *executor, acc interface{}) {
|
|
|
|
res, ok := acc.(*result.AccountState)
|
2019-11-21 16:41:28 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, 1, len(res.Balances))
|
|
|
|
assert.Equal(t, false, res.IsFrozen)
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2020-01-29 16:01:00 +00:00
|
|
|
name: "positive null",
|
2019-11-21 16:41:28 +00:00
|
|
|
params: `["AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y"]`,
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.AccountState{} },
|
|
|
|
check: func(t *testing.T, e *executor, acc interface{}) {
|
|
|
|
res, ok := acc.(*result.AccountState)
|
2020-01-29 16:01:00 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, 0, len(res.Balances))
|
|
|
|
assert.Equal(t, false, res.IsFrozen)
|
2020-01-29 16:01:00 +00:00
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid address",
|
|
|
|
params: `["notabase58"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-02-15 17:00:38 +00:00
|
|
|
"getcontractstate": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-03-05 15:26:54 +00:00
|
|
|
params: fmt.Sprintf(`["%s"]`, testContractHash),
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.ContractState{} },
|
|
|
|
check: func(t *testing.T, e *executor, cs interface{}) {
|
|
|
|
res, ok := cs.(*result.ContractState)
|
2020-02-15 17:00:38 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, byte(0), res.Version)
|
2020-03-23 09:46:42 +00:00
|
|
|
assert.Equal(t, testContractHash, res.ScriptHash.StringLE())
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, "0.99", res.CodeVersion)
|
2020-02-15 17:00:38 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "negative",
|
|
|
|
params: `["6d1eeca891ee93de2b7a77eb91c26f3b3c04d6c3"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hash",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-03-05 11:50:06 +00:00
|
|
|
|
|
|
|
"getnep5balances": {
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid address",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-22 10:15:31 +00:00
|
|
|
params: `["` + testchain.PrivateKeyByID(0).GetScriptHash().StringLE() + `"]`,
|
2020-03-05 11:50:06 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.NEP5Balances{} },
|
|
|
|
check: func(t *testing.T, e *executor, acc interface{}) {
|
|
|
|
res, ok := acc.(*result.NEP5Balances)
|
|
|
|
require.True(t, ok)
|
2020-04-22 10:15:31 +00:00
|
|
|
require.Equal(t, testchain.PrivateKeyByID(0).Address(), res.Address)
|
2020-03-05 11:50:06 +00:00
|
|
|
require.Equal(t, 1, len(res.Balances))
|
2020-03-05 12:39:53 +00:00
|
|
|
require.Equal(t, "8.77", res.Balances[0].Amount)
|
2020-03-05 15:26:54 +00:00
|
|
|
require.Equal(t, testContractHash, res.Balances[0].Asset.StringLE())
|
2020-03-05 11:50:06 +00:00
|
|
|
require.Equal(t, uint32(208), res.Balances[0].LastUpdated)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-03-05 12:16:03 +00:00
|
|
|
"getnep5transfers": {
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid address",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-22 10:15:31 +00:00
|
|
|
params: `["` + testchain.PrivateKeyByID(0).Address() + `"]`,
|
2020-03-05 12:16:03 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.NEP5Transfers{} },
|
|
|
|
check: func(t *testing.T, e *executor, acc interface{}) {
|
|
|
|
res, ok := acc.(*result.NEP5Transfers)
|
|
|
|
require.True(t, ok)
|
2020-04-22 10:15:31 +00:00
|
|
|
require.Equal(t, testchain.PrivateKeyByID(0).Address(), res.Address)
|
2020-03-05 12:16:03 +00:00
|
|
|
|
2020-03-05 15:26:54 +00:00
|
|
|
assetHash, err := util.Uint160DecodeStringLE(testContractHash)
|
2020-03-05 12:16:03 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
require.Equal(t, 1, len(res.Received))
|
2020-03-05 12:39:53 +00:00
|
|
|
require.Equal(t, "10", res.Received[0].Amount)
|
2020-03-05 12:16:03 +00:00
|
|
|
require.Equal(t, assetHash, res.Received[0].Asset)
|
|
|
|
require.Equal(t, address.Uint160ToString(assetHash), res.Received[0].Address)
|
|
|
|
|
|
|
|
require.Equal(t, 1, len(res.Sent))
|
2020-03-05 12:39:53 +00:00
|
|
|
require.Equal(t, "1.23", res.Sent[0].Amount)
|
2020-03-05 12:16:03 +00:00
|
|
|
require.Equal(t, assetHash, res.Sent[0].Asset)
|
2020-04-22 10:15:31 +00:00
|
|
|
require.Equal(t, testchain.PrivateKeyByID(1).Address(), res.Sent[0].Address)
|
2020-03-05 12:16:03 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-01-30 08:03:44 +00:00
|
|
|
"getstorage": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-03-05 15:26:54 +00:00
|
|
|
params: fmt.Sprintf(`["%s", "746573746b6579"]`, testContractHash),
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} {
|
|
|
|
v := hex.EncodeToString([]byte("testvalue"))
|
|
|
|
return &v
|
2020-01-30 08:03:44 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "missing key",
|
2020-03-05 15:26:54 +00:00
|
|
|
params: fmt.Sprintf(`["%s", "7465"]`, testContractHash),
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} {
|
|
|
|
v := ""
|
|
|
|
return &v
|
2020-01-30 08:03:44 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no second parameter",
|
2020-03-05 15:26:54 +00:00
|
|
|
params: fmt.Sprintf(`["%s"]`, testContractHash),
|
2020-01-30 08:03:44 +00:00
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hash",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid key",
|
2020-03-05 15:26:54 +00:00
|
|
|
params: fmt.Sprintf(`["%s", "notahex"]`, testContractHash),
|
2020-01-30 08:03:44 +00:00
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"getassetstate": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-16 14:10:42 +00:00
|
|
|
params: `["b16384a950ed01ed5fc15c03fe7b98228871cb43b1bc22d67029449fc854d104"]`,
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.AssetState{} },
|
|
|
|
check: func(t *testing.T, e *executor, as interface{}) {
|
|
|
|
res, ok := as.(*result.AssetState)
|
2019-11-21 16:41:28 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, "00", res.Owner)
|
|
|
|
assert.Equal(t, "AWKECj9RD8rS8RPcpCgYVjk1DeYyHwxZm3", res.Admin)
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "negative",
|
|
|
|
params: `["602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de2"]`,
|
2020-02-15 16:06:34 +00:00
|
|
|
fail: true,
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hash",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"getbestblockhash": {
|
|
|
|
{
|
|
|
|
params: "[]",
|
|
|
|
result: func(e *executor) interface{} {
|
2020-02-21 12:10:59 +00:00
|
|
|
v := "0x" + e.chain.CurrentBlockHash().StringLE()
|
|
|
|
return &v
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
params: "1",
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-02-06 12:02:03 +00:00
|
|
|
"gettxout": {
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hash",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "missing hash",
|
|
|
|
params: `["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid index",
|
|
|
|
params: `["7aadf91ca8ac1e2c323c025a7e492bee2dd90c783b86ebfc3b18db66b530a76d", "string"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "negative index",
|
|
|
|
params: `["7aadf91ca8ac1e2c323c025a7e492bee2dd90c783b86ebfc3b18db66b530a76d", -1]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "too big index",
|
|
|
|
params: `["7aadf91ca8ac1e2c323c025a7e492bee2dd90c783b86ebfc3b18db66b530a76d", 100]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"getblock": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-03-04 14:45:29 +00:00
|
|
|
params: "[2, 1]",
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.Block{} },
|
|
|
|
check: func(t *testing.T, e *executor, blockRes interface{}) {
|
|
|
|
res, ok := blockRes.(*result.Block)
|
2019-11-21 16:41:28 +00:00
|
|
|
require.True(t, ok)
|
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
|
|
|
|
2020-03-04 14:45:29 +00:00
|
|
|
block, err := e.chain.GetBlock(e.chain.GetHeaderHash(2))
|
2019-11-21 16:41:28 +00:00
|
|
|
require.NoErrorf(t, err, "could not get block")
|
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
|
|
|
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, block.Hash(), res.Hash)
|
|
|
|
for i := range res.Tx {
|
|
|
|
tx := res.Tx[i]
|
2020-03-23 14:31:28 +00:00
|
|
|
require.Equal(t, transaction.MinerType, tx.Transaction.Type)
|
2020-02-12 14:25:44 +00:00
|
|
|
|
2020-04-10 10:41:49 +00:00
|
|
|
miner := block.Transactions[i]
|
2020-02-12 14:25:44 +00:00
|
|
|
require.True(t, ok)
|
2020-04-10 10:41:49 +00:00
|
|
|
require.Equal(t, miner.Nonce, tx.Transaction.Nonce)
|
2020-03-23 14:31:28 +00:00
|
|
|
require.Equal(t, block.Transactions[i].Hash(), tx.Transaction.Hash())
|
2020-02-12 14:25:44 +00:00
|
|
|
}
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
2019-11-26 10:31:11 +00:00
|
|
|
{
|
|
|
|
name: "bad params",
|
|
|
|
params: `[[]]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
{
|
|
|
|
name: "invalid height",
|
|
|
|
params: `[-1]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hash",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "missing hash",
|
|
|
|
params: `["` + util.Uint256{}.String() + `"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"getblockcount": {
|
|
|
|
{
|
|
|
|
params: "[]",
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} {
|
|
|
|
v := int(e.chain.BlockHeight() + 1)
|
|
|
|
return &v
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"getblockhash": {
|
|
|
|
{
|
|
|
|
params: "[1]",
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} {
|
|
|
|
// We don't have `t` here for proper handling, but
|
|
|
|
// error here would lead to panic down below.
|
|
|
|
block, _ := e.chain.GetBlock(e.chain.GetHeaderHash(1))
|
2019-11-27 09:23:18 +00:00
|
|
|
expectedHash := "0x" + block.Hash().StringLE()
|
2020-02-21 12:10:59 +00:00
|
|
|
return &expectedHash
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "string height",
|
|
|
|
params: `["first"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid number height",
|
|
|
|
params: `[-2]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-03-04 17:35:37 +00:00
|
|
|
"getblockheader": {
|
|
|
|
{
|
|
|
|
name: "positive, no verbose",
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["8c702625ab05236fda5763bbe168359b7747508e1387e4404217e0418846c94e"]`,
|
2020-03-04 17:35:37 +00:00
|
|
|
result: func(e *executor) interface{} {
|
2020-04-21 13:45:48 +00:00
|
|
|
expected := "000000007654fa898eba5ced6ab7a44fe1187e48b80ddd5340499fb2d312cc2fe4a6df1bb31cada0cb85914ee5bd6d11d25289a59203bf65f40232de8ffaa2bb7517f3b50a0ca05e010000005704000000000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c404def65e6b379e441fe1507d6d031c874e686b854b2afe9843fda5087f76e261e282b4db232079485dcf449678e2358a3d148835b85affba4ecd08a2bf1b556fe0c406b6218df12f8a7060379daf4eed312a85be51ea2fabee826a745547141694a3f49f8a61ac63db7ece1de7fbb54ecb9c5ac244a7fcdd794c9767b4cb2637a9c840c40ebaf64e3b76299d3ccc7e48e197a09af11cc0a80bd636cdef80312c61e24eebaace44cda90d17eb3ba85cfc08079676626966c75a48631b508c39375a8181ec40c402a77786cdaa5e93f0952c834cebdab25475beee0b60fce4263d85b7395bcde993ebee884667def21b7de494097f30c14c626357683680bdbace9667cc03b0da894130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb00"
|
2020-03-04 17:35:37 +00:00
|
|
|
return &expected
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "positive, verbose 0",
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["8c702625ab05236fda5763bbe168359b7747508e1387e4404217e0418846c94e", 0]`,
|
2020-03-04 17:35:37 +00:00
|
|
|
result: func(e *executor) interface{} {
|
2020-04-21 13:45:48 +00:00
|
|
|
expected := "000000007654fa898eba5ced6ab7a44fe1187e48b80ddd5340499fb2d312cc2fe4a6df1bb31cada0cb85914ee5bd6d11d25289a59203bf65f40232de8ffaa2bb7517f3b50a0ca05e010000005704000000000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c404def65e6b379e441fe1507d6d031c874e686b854b2afe9843fda5087f76e261e282b4db232079485dcf449678e2358a3d148835b85affba4ecd08a2bf1b556fe0c406b6218df12f8a7060379daf4eed312a85be51ea2fabee826a745547141694a3f49f8a61ac63db7ece1de7fbb54ecb9c5ac244a7fcdd794c9767b4cb2637a9c840c40ebaf64e3b76299d3ccc7e48e197a09af11cc0a80bd636cdef80312c61e24eebaace44cda90d17eb3ba85cfc08079676626966c75a48631b508c39375a8181ec40c402a77786cdaa5e93f0952c834cebdab25475beee0b60fce4263d85b7395bcde993ebee884667def21b7de494097f30c14c626357683680bdbace9667cc03b0da894130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb00"
|
2020-03-04 17:35:37 +00:00
|
|
|
return &expected
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "positive, verbose !=0",
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["8c702625ab05236fda5763bbe168359b7747508e1387e4404217e0418846c94e", 2]`,
|
2020-03-04 17:35:37 +00:00
|
|
|
result: func(e *executor) interface{} {
|
2020-04-21 13:45:48 +00:00
|
|
|
hash, err := util.Uint256DecodeStringLE("8c702625ab05236fda5763bbe168359b7747508e1387e4404217e0418846c94e")
|
2020-03-05 16:06:16 +00:00
|
|
|
if err != nil {
|
|
|
|
panic("can not decode hash parameter")
|
|
|
|
}
|
|
|
|
block, err := e.chain.GetBlock(hash)
|
|
|
|
if err != nil {
|
|
|
|
panic("unknown block (update block hash)")
|
|
|
|
}
|
2020-03-04 17:35:37 +00:00
|
|
|
header := block.Header()
|
|
|
|
expected := result.Header{
|
|
|
|
Hash: header.Hash(),
|
|
|
|
Size: io.GetVarSize(header),
|
|
|
|
Version: header.Version,
|
|
|
|
PrevBlockHash: header.PrevHash,
|
|
|
|
MerkleRoot: header.MerkleRoot,
|
|
|
|
Timestamp: header.Timestamp,
|
|
|
|
Index: header.Index,
|
|
|
|
Nonce: strconv.FormatUint(header.ConsensusData, 16),
|
2020-03-18 09:21:16 +00:00
|
|
|
NextConsensus: address.Uint160ToString(header.NextConsensus),
|
2020-03-04 17:35:37 +00:00
|
|
|
Script: header.Script,
|
|
|
|
Confirmations: e.chain.BlockHeight() - header.Index + 1,
|
|
|
|
}
|
|
|
|
|
|
|
|
nextHash := e.chain.GetHeaderHash(int(header.Index) + 1)
|
|
|
|
if !hash.Equals(util.Uint256{}) {
|
|
|
|
expected.NextBlockHash = &nextHash
|
|
|
|
}
|
|
|
|
return &expected
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid verbose type",
|
2020-04-06 06:27:15 +00:00
|
|
|
params: `["614a9085dc55fd0539ad3a9d68d8b8e7c52328da905c87bfe8cfca57a5c3c02f", true]`,
|
2020-03-04 17:35:37 +00:00
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid block hash",
|
|
|
|
params: `["notahash"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "unknown block",
|
|
|
|
params: `["a6e526375a780335112299f2262501e5e9574c3ba61b16bbc1e282b344f6c141"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-02-19 09:44:31 +00:00
|
|
|
"getblocksysfee": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
|
|
|
params: "[1]",
|
|
|
|
result: func(e *executor) interface{} {
|
|
|
|
block, _ := e.chain.GetBlock(e.chain.GetHeaderHash(1))
|
|
|
|
|
|
|
|
var expectedBlockSysFee util.Fixed8
|
|
|
|
for _, tx := range block.Transactions {
|
|
|
|
expectedBlockSysFee += e.chain.SystemFee(tx)
|
|
|
|
}
|
|
|
|
return &expectedBlockSysFee
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "string height",
|
|
|
|
params: `["first"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid number height",
|
|
|
|
params: `[-2]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-02-26 12:42:04 +00:00
|
|
|
"getclaimable": {
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: "[]",
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid address",
|
|
|
|
params: `["invalid"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "normal address",
|
2020-04-22 10:15:31 +00:00
|
|
|
params: `["` + testchain.MultisigAddress() + `"]`,
|
2020-02-26 12:42:04 +00:00
|
|
|
result: func(*executor) interface{} {
|
|
|
|
// hash of the issueTx
|
2020-04-21 13:45:48 +00:00
|
|
|
h, _ := util.Uint256DecodeStringBE("8a4711012932f4f79f9534803feab0ef85e7a313c52a36f5d56b9f8ec190bd92")
|
2020-03-04 14:45:29 +00:00
|
|
|
amount := util.Fixed8FromInt64(1 * 8) // (endHeight - startHeight) * genAmount[0]
|
2020-02-26 12:42:04 +00:00
|
|
|
return &result.ClaimableInfo{
|
|
|
|
Spents: []result.Claimable{
|
|
|
|
{
|
|
|
|
Tx: h,
|
|
|
|
Value: util.Fixed8FromInt64(100000000),
|
2020-03-04 14:45:29 +00:00
|
|
|
EndHeight: 1,
|
2020-02-26 12:42:04 +00:00
|
|
|
Generated: amount,
|
|
|
|
Unclaimed: amount,
|
|
|
|
},
|
|
|
|
},
|
2020-04-22 10:15:31 +00:00
|
|
|
Address: testchain.MultisigAddress(),
|
2020-02-26 12:42:04 +00:00
|
|
|
Unclaimed: amount,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"getconnectioncount": {
|
|
|
|
{
|
|
|
|
params: "[]",
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(*executor) interface{} {
|
|
|
|
v := 0
|
|
|
|
return &v
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"getpeers": {
|
|
|
|
{
|
|
|
|
params: "[]",
|
|
|
|
result: func(*executor) interface{} {
|
2020-02-21 12:10:59 +00:00
|
|
|
return &result.GetPeers{
|
|
|
|
Unconnected: []result.Peer{},
|
|
|
|
Connected: []result.Peer{},
|
|
|
|
Bad: []result.Peer{},
|
2019-11-21 16:41:28 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"getrawtransaction": {
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hash",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "missing hash",
|
|
|
|
params: `["` + util.Uint256{}.String() + `"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-03-05 14:20:50 +00:00
|
|
|
"gettransactionheight": {
|
|
|
|
{
|
2020-04-16 14:10:42 +00:00
|
|
|
name: "positive",
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["5f1e841f625d52dd3d73bbf5203f8468835353b7c476a4d367161ea959944981"]`,
|
2020-03-05 14:20:50 +00:00
|
|
|
result: func(e *executor) interface{} {
|
2020-04-10 10:41:49 +00:00
|
|
|
h := 1
|
2020-03-05 14:20:50 +00:00
|
|
|
return &h
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hash",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "missing hash",
|
|
|
|
params: `["` + util.Uint256{}.String() + `"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-03-06 17:38:17 +00:00
|
|
|
"getunclaimed": {
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: "[]",
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid address",
|
|
|
|
params: `["invalid"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-22 10:15:31 +00:00
|
|
|
params: `["` + testchain.MultisigAddress() + `"]`,
|
2020-03-06 17:38:17 +00:00
|
|
|
result: func(*executor) interface{} {
|
|
|
|
return &result.Unclaimed{}
|
|
|
|
},
|
|
|
|
check: func(t *testing.T, e *executor, uncl interface{}) {
|
|
|
|
res, ok := uncl.(*result.Unclaimed)
|
|
|
|
require.True(t, ok)
|
|
|
|
assert.Equal(t, res.Available, util.Fixed8FromInt64(8))
|
|
|
|
assert.True(t, res.Unavailable > 0)
|
2020-03-12 09:47:07 +00:00
|
|
|
assert.Equal(t, res.Available+res.Unavailable, res.Unclaimed)
|
2020-03-06 17:38:17 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"getunspents": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-22 10:15:31 +00:00
|
|
|
params: `["` + testchain.MultisigAddress() + `"]`,
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.Unspents{} },
|
|
|
|
check: func(t *testing.T, e *executor, unsp interface{}) {
|
|
|
|
res, ok := unsp.(*result.Unspents)
|
2019-11-21 16:41:28 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
require.Equal(t, 1, len(res.Balance))
|
|
|
|
assert.Equal(t, 1, len(res.Balance[0].Unspents))
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2020-01-29 16:01:00 +00:00
|
|
|
name: "positive null",
|
2019-11-21 16:41:28 +00:00
|
|
|
params: `["AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y"]`,
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.Unspents{} },
|
|
|
|
check: func(t *testing.T, e *executor, unsp interface{}) {
|
|
|
|
res, ok := unsp.(*result.Unspents)
|
2020-01-29 16:01:00 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
require.Equal(t, 0, len(res.Balance))
|
2020-01-29 16:01:00 +00:00
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
2020-03-05 14:48:30 +00:00
|
|
|
"getvalidators": {
|
|
|
|
{
|
|
|
|
params: "[]",
|
|
|
|
result: func(*executor) interface{} {
|
|
|
|
return &[]result.Validator{}
|
|
|
|
},
|
|
|
|
check: func(t *testing.T, e *executor, validators interface{}) {
|
|
|
|
var expected []result.Validator
|
|
|
|
sBValidators, err := e.chain.GetStandByValidators()
|
|
|
|
require.NoError(t, err)
|
|
|
|
for _, sbValidator := range sBValidators {
|
|
|
|
expected = append(expected, result.Validator{
|
|
|
|
PublicKey: *sbValidator,
|
|
|
|
Votes: 0,
|
|
|
|
Active: true,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
actual, ok := validators.(*[]result.Validator)
|
|
|
|
require.True(t, ok)
|
|
|
|
|
|
|
|
assert.ElementsMatch(t, expected, *actual)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"getversion": {
|
|
|
|
{
|
|
|
|
params: "[]",
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(*executor) interface{} { return &result.Version{} },
|
|
|
|
check: func(t *testing.T, e *executor, ver interface{}) {
|
|
|
|
resp, ok := ver.(*result.Version)
|
2019-11-21 16:41:28 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
require.Equal(t, "/NEO-GO:/", resp.UserAgent)
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-11-28 16:08:31 +00:00
|
|
|
"invoke": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
|
|
|
params: `["50befd26fdf6e4d957c11e078b24ebce6291456f", [{"type": "String", "value": "qwerty"}]]`,
|
2020-03-03 10:08:34 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.Invoke{} },
|
2020-02-21 12:10:59 +00:00
|
|
|
check: func(t *testing.T, e *executor, inv interface{}) {
|
2020-03-03 10:08:34 +00:00
|
|
|
res, ok := inv.(*result.Invoke)
|
2019-11-28 16:08:31 +00:00
|
|
|
require.True(t, ok)
|
2020-04-21 13:45:48 +00:00
|
|
|
assert.Equal(t, "0c06717765727479676f459162ceeb248b071ec157d9e4f6fd26fdbe50", res.Script)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.NotEqual(t, "", res.State)
|
|
|
|
assert.NotEqual(t, 0, res.GasConsumed)
|
2019-11-28 16:08:31 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not a string",
|
|
|
|
params: `[42, []]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not a scripthash",
|
|
|
|
params: `["qwerty", []]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not an array",
|
|
|
|
params: `["50befd26fdf6e4d957c11e078b24ebce6291456f", 42]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "bad params",
|
|
|
|
params: `["50befd26fdf6e4d957c11e078b24ebce6291456f", [{"type": "Integer", "value": "qwerty"}]]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2019-11-26 10:13:17 +00:00
|
|
|
"invokefunction": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
|
|
|
params: `["50befd26fdf6e4d957c11e078b24ebce6291456f", "test", []]`,
|
2020-03-03 10:08:34 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.Invoke{} },
|
2020-02-21 12:10:59 +00:00
|
|
|
check: func(t *testing.T, e *executor, inv interface{}) {
|
2020-03-03 10:08:34 +00:00
|
|
|
res, ok := inv.(*result.Invoke)
|
2019-11-26 10:13:17 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.NotEqual(t, "", res.Script)
|
|
|
|
assert.NotEqual(t, "", res.State)
|
|
|
|
assert.NotEqual(t, 0, res.GasConsumed)
|
2019-11-26 10:13:17 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not a string",
|
|
|
|
params: `[42, "test", []]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not a scripthash",
|
|
|
|
params: `["qwerty", "test", []]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "bad params",
|
|
|
|
params: `["50befd26fdf6e4d957c11e078b24ebce6291456f", "test", [{"type": "Integer", "value": "qwerty"}]]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2019-11-26 10:24:49 +00:00
|
|
|
"invokescript": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
|
|
|
params: `["51c56b0d48656c6c6f2c20776f726c6421680f4e656f2e52756e74696d652e4c6f67616c7566"]`,
|
2020-03-03 10:08:34 +00:00
|
|
|
result: func(e *executor) interface{} { return &result.Invoke{} },
|
2020-02-21 12:10:59 +00:00
|
|
|
check: func(t *testing.T, e *executor, inv interface{}) {
|
2020-03-03 10:08:34 +00:00
|
|
|
res, ok := inv.(*result.Invoke)
|
2019-11-26 10:24:49 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.NotEqual(t, "", res.Script)
|
|
|
|
assert.NotEqual(t, "", res.State)
|
|
|
|
assert.NotEqual(t, 0, res.GasConsumed)
|
2019-11-26 10:24:49 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not a string",
|
|
|
|
params: `[42]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "bas string",
|
|
|
|
params: `["qwerty"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"sendrawtransaction": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["80001300000075a94799633ed955dd85a8af314a5b435ab51903b00400000001eb15931b0544cbb9a283f934ab89a23e73cf90b9ca097bb327a0bcdcddf8ce2e010001f5bc5a9ac7b85a47be381260a06b5a1e7a667ce8f7d7c8baa5cfc6465571377a0030d3dec386230075a94799633ed955dd85a8af314a5b435ab5190301420c4082632495e555507a056eae951ad1893f27163dde40505340f6cf9578e20c3d7ec0c7e00f93cb2e770a7ce3e8a2910deabdd01fd966507a7a29106dd2add583ee290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"]`,
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(e *executor) interface{} {
|
|
|
|
v := true
|
|
|
|
return &v
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "negative",
|
|
|
|
params: `["0274d792072617720636f6e7472616374207472616e73616374696f6e206465736372697074696f6e01949354ea0a8b57dfee1e257a1aedd1e0eea2e5837de145e8da9c0f101bfccc8e0100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500a3e11100000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5004f2418010000001cc9c05cefffe6cdd7b182816a9152ec218d2ec0014140dbd3cddac5cb2bd9bf6d93701f1a6f1c9dbe2d1b480c54628bbb2a4d536158c747a6af82698edf9f8af1cac3850bcb772bd9c8e4ac38f80704751cc4e0bd0e67232103cbb45da6072c14761c9da545749d9cfd863f860c351066d16df480602a2024c6ac"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid string",
|
|
|
|
params: `["notahex"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid tx",
|
|
|
|
params: `["0274d792072617720636f6e747261637"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
},
|
2020-03-02 17:01:32 +00:00
|
|
|
"submitblock": {
|
|
|
|
{
|
2020-04-10 10:41:49 +00:00
|
|
|
// If you are planning to modify test chain from `testblocks.acc`, please, update param value (first block)
|
2020-03-02 17:01:32 +00:00
|
|
|
name: "empty block",
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["0000000007b57cc5c1902010f968adc0cb96c87e1a97005ee1ddc8510cf6272e812221820000000000000000000000000000000000000000000000000000000000000000db0ca05ed10000005704000000000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c4050da0a5d3672a56ad442a1e58129e8df0ca4c3235e33e86b8332144a253c559a35742206f87866cfdb8f809cac8b4cc9bc901372161a7a577ed6490158c492a60c4007bb4e7776a3102c183ba8e5aec77b9a436e6629f67150a77689e25c32df427b5a4c77f2198f0554fbc1ef2f2e2605f3a84d5789a48e90883203d491172c3f0d0c4049b0a16bb1decc7673d9bdca2e3a613b1102a7774e405d3d1ce1fff276acb8d6d0eff980554792d21603b9d9b6dd50941ea3eda4efad4922b063571ea49108df0c401bb53c5d0fcf94beeb7c1f0d9d9998b7af5f29c906492d49f4650de250826926cfc2c7bdb6369139563a0ed74039c4fb69c0e63ced82fc2a2b74778c7287ca5694130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb00"]`,
|
2020-03-02 17:01:32 +00:00
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid block height",
|
|
|
|
params: `["000000005fb86f62eafe8e9246bc0d1648e4e5c8389dee9fb7fe03fcc6772ec8c5e4ec2aedb908054ac1409be5f77d5369c6e03490b2f6676d68d0b3370f8159e0fdadf99bc05f5e030000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401406f299c82b513f59f5bd120317974852c9694c6e10db1ef2f1bb848b1a33e47a08f8dc03ee784166b2060a94cd4e7af88899b39787938f7f2763ea4d2182776ed40f3bafd85214fef38a4836ca97793001ea411f553c51e88781f7b916c59c145bff28314b6e7ea246789422a996fc4937e290a1b40f6b97c5222540f65b0d47aca40d2b3d19203d456428bfdb529e846285052105957385b65388b9a617f6e2d56a64ec41aa73439eafccb52987bb1975c9b67518b053d9e61b445e4a3377dbc206640bd688489bd62adf6bed9d61a73905b9591eb87053c6f0f4dd70f3bee7295541b490caef044b55b6f9f01dc4a05a756a3f2edd06f5adcbe4e984c1e552f9023f08b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae0100000000000000000000"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid hex",
|
|
|
|
params: `["000000005gb86f62eafe8e9246bc0d1648e4e5c8389dee9fb7fe03fcc6772ec8c5e4ec2aedb908054ac1409be5f77d5369c6e03490b2f6676d68d0b3370f8159e0fdadf99bc05f5e030000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401406f299c82b513f59f5bd120317974852c9694c6e10db1ef2f1bb848b1a33e47a08f8dc03ee784166b2060a94cd4e7af88899b39787938f7f2763ea4d2182776ed40f3bafd85214fef38a4836ca97793001ea411f553c51e88781f7b916c59c145bff28314b6e7ea246789422a996fc4937e290a1b40f6b97c5222540f65b0d47aca40d2b3d19203d456428bfdb529e846285052105957385b65388b9a617f6e2d56a64ec41aa73439eafccb52987bb1975c9b67518b053d9e61b445e4a3377dbc206640bd688489bd62adf6bed9d61a73905b9591eb87053c6f0f4dd70f3bee7295541b490caef044b55b6f9f01dc4a05a756a3f2edd06f5adcbe4e984c1e552f9023f08b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae0100000000000000000000"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid block bytes",
|
|
|
|
params: `["0000000027"]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no params",
|
|
|
|
params: `[]`,
|
|
|
|
fail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "positive",
|
2020-04-10 10:41:49 +00:00
|
|
|
// If you are planning to modify test chain from `testblocks.acc`, please, update param value (second block)
|
2020-04-21 13:45:48 +00:00
|
|
|
params: `["0000000007b57cc5c1902010f968adc0cb96c87e1a97005ee1ddc8510cf6272e81222182d13aba8fa5e27a16382d64ce3751b9ffaa3f81f634fbd4399bf048d58e7c5c7adb0ca05ed10000005704000000000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c405545b3ad5912f043ed975176ba1f02f64119f10d63385a472ecaef6aa4a2b04237946e66e74e53435a19abd59fb14dfa7d64d29a39b8655c23ed87c74d2674d70c40e6880ad9677b3b28f6c0a3c9172f8ff98dcc5ad7c78768e34481799edebcf5bbcafa583740808bf0668bdd07288b004b11f52db517ef68482e8cf1f5774ef6ba0c406ea533f7f49310e9156d7c6032fbc8a63d20777e9e850fdc0a0d3e3d9c5b9340e4d22eba14a8a1446b886a34dee437e6cfd4f2b6eed9048291610330968c225a0c401a7c49e25676aabd511bcf556970c28e530df561f89dd7d12285e848ef234273eca90a9344420ace9c84df798925d4c547ea120183ae5562b6507f55acb52c7e94130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb0100001400000075a94799633ed955dd85a8af314a5b435ab51903b004000000000001420c40b2eb026301528ce76f07caa304f26e3aaa08997e82f12a94350ec1354683d165f4a02c87f2250dae39abbf55dd9a0bd642ecbbbb17136ca2c202bc5757c1495c290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"]`,
|
2020-03-02 17:01:32 +00:00
|
|
|
result: func(e *executor) interface{} {
|
|
|
|
v := true
|
|
|
|
return &v
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-11-21 16:41:28 +00:00
|
|
|
"validateaddress": {
|
|
|
|
{
|
|
|
|
name: "positive",
|
|
|
|
params: `["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i"]`,
|
2020-02-21 12:10:59 +00:00
|
|
|
result: func(*executor) interface{} { return &result.ValidateAddress{} },
|
|
|
|
check: func(t *testing.T, e *executor, va interface{}) {
|
|
|
|
res, ok := va.(*result.ValidateAddress)
|
2019-11-21 16:41:28 +00:00
|
|
|
require.True(t, ok)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, "AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i", res.Address)
|
|
|
|
assert.True(t, res.IsValid)
|
2019-11-21 16:41:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "negative",
|
|
|
|
params: "[1]",
|
|
|
|
result: func(*executor) interface{} {
|
2020-02-21 12:10:59 +00:00
|
|
|
return &result.ValidateAddress{
|
|
|
|
Address: float64(1),
|
|
|
|
IsValid: false,
|
2019-11-21 16:41:28 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2019-01-22 12:14:52 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
func TestRPC(t *testing.T) {
|
|
|
|
chain, handler := initServerWithInMemoryChain(t)
|
2019-01-22 12:14:52 +00:00
|
|
|
|
2020-01-10 08:47:55 +00:00
|
|
|
defer chain.Close()
|
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
e := &executor{chain: chain, handler: handler}
|
|
|
|
for method, cases := range rpcTestCases {
|
|
|
|
t.Run(method, func(t *testing.T) {
|
|
|
|
rpc := `{"jsonrpc": "2.0", "id": 1, "method": "%s", "params": %s}`
|
2019-01-22 12:14:52 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
for _, tc := range cases {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
body := doRPCCall(fmt.Sprintf(rpc, method, tc.params), handler, t)
|
2020-02-21 12:10:59 +00:00
|
|
|
result := checkErrGetResult(t, body, tc.fail)
|
2019-11-21 16:41:28 +00:00
|
|
|
if tc.fail {
|
|
|
|
return
|
|
|
|
}
|
2019-11-15 19:04:10 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
expected, res := tc.getResultPair(e)
|
2020-02-21 12:10:59 +00:00
|
|
|
err := json.Unmarshal(result, res)
|
|
|
|
require.NoErrorf(t, err, "could not parse response: %s", result)
|
2019-02-20 17:39:32 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
if tc.check == nil {
|
|
|
|
assert.Equal(t, expected, res)
|
|
|
|
} else {
|
|
|
|
tc.check(t, e, res)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2019-11-15 19:04:10 +00:00
|
|
|
|
2019-09-18 15:21:16 +00:00
|
|
|
t.Run("getrawtransaction", func(t *testing.T) {
|
|
|
|
block, _ := chain.GetBlock(chain.GetHeaderHash(0))
|
|
|
|
TXHash := block.Transactions[1].Hash()
|
2019-11-27 09:23:18 +00:00
|
|
|
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s"]}"`, TXHash.StringLE())
|
2019-09-18 15:21:16 +00:00
|
|
|
body := doRPCCall(rpc, handler, t)
|
2020-02-21 12:10:59 +00:00
|
|
|
result := checkErrGetResult(t, body, false)
|
|
|
|
var res string
|
|
|
|
err := json.Unmarshal(result, &res)
|
|
|
|
require.NoErrorf(t, err, "could not parse response: %s", result)
|
2020-04-16 14:10:42 +00:00
|
|
|
assert.Equal(t, "400000000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000455b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e882a1227d2c7b226c616e67223a22656e222c226e616d65223a22416e745368617265227d5d0000c16ff28623000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b00000000", res)
|
2019-09-18 15:21:16 +00:00
|
|
|
})
|
2019-01-22 12:14:52 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
t.Run("getrawtransaction 2 arguments", func(t *testing.T) {
|
|
|
|
block, _ := chain.GetBlock(chain.GetHeaderHash(0))
|
|
|
|
TXHash := block.Transactions[1].Hash()
|
2019-11-27 09:23:18 +00:00
|
|
|
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 0]}"`, TXHash.StringLE())
|
2019-09-18 15:21:16 +00:00
|
|
|
body := doRPCCall(rpc, handler, t)
|
2020-02-21 12:10:59 +00:00
|
|
|
result := checkErrGetResult(t, body, false)
|
|
|
|
var res string
|
|
|
|
err := json.Unmarshal(result, &res)
|
|
|
|
require.NoErrorf(t, err, "could not parse response: %s", result)
|
2020-04-16 14:10:42 +00:00
|
|
|
assert.Equal(t, "400000000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b0000000000455b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e882a1227d2c7b226c616e67223a22656e222c226e616d65223a22416e745368617265227d5d0000c16ff28623000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b00000000", res)
|
2019-09-18 15:21:16 +00:00
|
|
|
})
|
2020-02-06 12:02:03 +00:00
|
|
|
|
2020-03-23 14:31:28 +00:00
|
|
|
t.Run("getrawtransaction 2 arguments, verbose", func(t *testing.T) {
|
|
|
|
block, _ := chain.GetBlock(chain.GetHeaderHash(0))
|
|
|
|
TXHash := block.Transactions[1].Hash()
|
|
|
|
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE())
|
|
|
|
body := doRPCCall(rpc, handler, t)
|
|
|
|
txOut := checkErrGetResult(t, body, false)
|
|
|
|
actual := result.TransactionOutputRaw{}
|
|
|
|
err := json.Unmarshal(txOut, &actual)
|
|
|
|
require.NoErrorf(t, err, "could not parse response: %s", txOut)
|
|
|
|
admin, err := util.Uint160DecodeStringBE("da1745e9b549bd0bfa1a569971c77eba30cd5a4b")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, transaction.RegisterType, actual.Transaction.Type)
|
|
|
|
assert.Equal(t, &transaction.RegisterTX{
|
|
|
|
AssetType: 0,
|
|
|
|
Name: `[{"lang":"zh-CN","name":"小蚁股"},{"lang":"en","name":"AntShare"}]`,
|
|
|
|
Amount: util.Fixed8FromInt64(100000000),
|
|
|
|
Precision: 0,
|
|
|
|
Owner: keys.PublicKey{},
|
|
|
|
Admin: admin,
|
|
|
|
}, actual.Transaction.Data.(*transaction.RegisterTX))
|
|
|
|
assert.Equal(t, 210, actual.Confirmations)
|
|
|
|
assert.Equal(t, TXHash, actual.Transaction.Hash())
|
|
|
|
})
|
|
|
|
|
2020-02-06 12:02:03 +00:00
|
|
|
t.Run("gettxout", func(t *testing.T) {
|
|
|
|
block, _ := chain.GetBlock(chain.GetHeaderHash(0))
|
|
|
|
tx := block.Transactions[3]
|
|
|
|
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "gettxout", "params": [%s, %d]}"`,
|
|
|
|
`"`+tx.Hash().StringLE()+`"`, 0)
|
|
|
|
body := doRPCCall(rpc, handler, t)
|
2020-02-21 12:10:59 +00:00
|
|
|
res := checkErrGetResult(t, body, false)
|
2020-02-06 12:02:03 +00:00
|
|
|
|
2020-02-21 12:10:59 +00:00
|
|
|
var txOut result.TransactionOutput
|
|
|
|
err := json.Unmarshal(res, &txOut)
|
|
|
|
require.NoErrorf(t, err, "could not parse response: %s", res)
|
|
|
|
assert.Equal(t, 0, txOut.N)
|
2020-04-16 14:10:42 +00:00
|
|
|
assert.Equal(t, "0xf5bc5a9ac7b85a47be381260a06b5a1e7a667ce8f7d7c8baa5cfc6465571377a", txOut.Asset)
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Equal(t, util.Fixed8FromInt64(100000000), txOut.Value)
|
2020-04-22 10:15:31 +00:00
|
|
|
assert.Equal(t, testchain.MultisigAddress(), txOut.Address)
|
2020-02-06 12:02:03 +00:00
|
|
|
})
|
2020-03-02 16:13:44 +00:00
|
|
|
|
|
|
|
t.Run("getrawmempool", func(t *testing.T) {
|
|
|
|
mp := chain.GetMemPool()
|
|
|
|
// `expected` stores hashes of previously added txs
|
|
|
|
expected := make([]util.Uint256, 0)
|
|
|
|
for _, tx := range mp.GetVerifiedTransactions() {
|
|
|
|
expected = append(expected, tx.Tx.Hash())
|
|
|
|
}
|
|
|
|
for i := 0; i < 5; i++ {
|
2020-04-10 10:41:49 +00:00
|
|
|
tx := transaction.NewMinerTX()
|
2020-03-02 16:13:44 +00:00
|
|
|
assert.NoError(t, mp.Add(tx, &FeerStub{}))
|
|
|
|
expected = append(expected, tx.Hash())
|
|
|
|
}
|
|
|
|
|
|
|
|
rpc := `{"jsonrpc": "2.0", "id": 1, "method": "getrawmempool", "params": []}`
|
|
|
|
body := doRPCCall(rpc, handler, t)
|
|
|
|
res := checkErrGetResult(t, body, false)
|
|
|
|
|
|
|
|
var actual []util.Uint256
|
|
|
|
err := json.Unmarshal(res, &actual)
|
|
|
|
require.NoErrorf(t, err, "could not parse response: %s", res)
|
|
|
|
|
|
|
|
assert.ElementsMatch(t, expected, actual)
|
|
|
|
})
|
2019-11-21 16:41:28 +00:00
|
|
|
}
|
2019-01-22 12:14:52 +00:00
|
|
|
|
2019-11-21 16:41:28 +00:00
|
|
|
func (tc rpcTestCase) getResultPair(e *executor) (expected interface{}, res interface{}) {
|
|
|
|
expected = tc.result(e)
|
2020-02-21 12:10:59 +00:00
|
|
|
resVal := reflect.New(reflect.TypeOf(expected).Elem())
|
|
|
|
return expected, resVal.Interface()
|
2019-09-18 15:21:16 +00:00
|
|
|
}
|
2019-01-22 12:14:52 +00:00
|
|
|
|
2020-02-21 12:10:59 +00:00
|
|
|
func checkErrGetResult(t *testing.T, body []byte, expectingFail bool) json.RawMessage {
|
|
|
|
var resp response.Raw
|
|
|
|
err := json.Unmarshal(body, &resp)
|
2019-11-21 16:41:28 +00:00
|
|
|
require.Nil(t, err)
|
2019-09-24 15:47:23 +00:00
|
|
|
if expectingFail {
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.NotEqual(t, 0, resp.Error.Code)
|
|
|
|
assert.NotEqual(t, "", resp.Error.Message)
|
2019-09-24 15:47:23 +00:00
|
|
|
} else {
|
2020-02-21 12:10:59 +00:00
|
|
|
assert.Nil(t, resp.Error)
|
2019-09-24 15:47:23 +00:00
|
|
|
}
|
2020-02-21 12:10:59 +00:00
|
|
|
return resp.Result
|
2019-09-24 15:47:23 +00:00
|
|
|
}
|
|
|
|
|
2019-09-18 15:21:16 +00:00
|
|
|
func doRPCCall(rpcCall string, handler http.HandlerFunc, t *testing.T) []byte {
|
|
|
|
req := httptest.NewRequest("POST", "http://0.0.0.0:20333/", strings.NewReader(rpcCall))
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
handler(w, req)
|
|
|
|
resp := w.Result()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
assert.NoErrorf(t, err, "could not read response from the request: %s", rpcCall)
|
2019-11-21 15:05:18 +00:00
|
|
|
return bytes.TrimSpace(body)
|
2019-01-22 12:14:52 +00:00
|
|
|
}
|