mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-24 09:25:21 +00:00
Merge pull request #1067 from nspcc-dev/network-in-the-hash
Add network magic to block/transaction hashes (IDs)
This commit is contained in:
commit
feb7d26e00
61 changed files with 614 additions and 448 deletions
77
cli/options/options.go
Normal file
77
cli/options/options.go
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Package options contains a set of common CLI options and helper functions to use them.
|
||||
*/
|
||||
package options
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// DefaultTimeout is the default timeout used for RPC requests.
|
||||
const DefaultTimeout = 10 * time.Second
|
||||
|
||||
// RPCEndpointFlag is a long flag name for RPC endpoint. It can be used to
|
||||
// check for flag presence in the context.
|
||||
const RPCEndpointFlag = "rpc-endpoint"
|
||||
|
||||
// Network is a set of flags for choosing the network to operate on
|
||||
// (privnet/mainnet/testnet).
|
||||
var Network = RPC[2:]
|
||||
|
||||
// RPC is a set of flags used for RPC connections (endpoint and timeout).
|
||||
var RPC = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: RPCEndpointFlag + ", r",
|
||||
Usage: "RPC node address",
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "timeout, s",
|
||||
Usage: "Timeout for the operation (10 seconds by default)",
|
||||
},
|
||||
cli.BoolFlag{Name: "privnet, p"},
|
||||
cli.BoolFlag{Name: "mainnet, m"},
|
||||
cli.BoolFlag{Name: "testnet, t"},
|
||||
}
|
||||
|
||||
var errNoEndpoint = errors.New("no RPC endpoint specified, use option '--" + RPCEndpointFlag + "' or '-r'")
|
||||
|
||||
// GetNetwork examines Context's flags and returns the appropriate network. It
|
||||
// defaults to PrivNet if no flags are given.
|
||||
func GetNetwork(ctx *cli.Context) netmode.Magic {
|
||||
var net = netmode.PrivNet
|
||||
if ctx.Bool("testnet") {
|
||||
net = netmode.TestNet
|
||||
}
|
||||
if ctx.Bool("mainnet") {
|
||||
net = netmode.MainNet
|
||||
}
|
||||
return net
|
||||
}
|
||||
|
||||
// GetTimeoutContext returns a context.Context with default of user-set timeout.
|
||||
func GetTimeoutContext(ctx *cli.Context) (context.Context, func()) {
|
||||
dur := ctx.Duration("timeout")
|
||||
if dur == 0 {
|
||||
dur = DefaultTimeout
|
||||
}
|
||||
return context.WithTimeout(context.Background(), dur)
|
||||
}
|
||||
|
||||
// GetRPCClient returns an RPC client instance for the given Context.
|
||||
func GetRPCClient(gctx context.Context, ctx *cli.Context) (*client.Client, cli.ExitCoder) {
|
||||
endpoint := ctx.String(RPCEndpointFlag)
|
||||
if len(endpoint) == 0 {
|
||||
return nil, cli.NewExitError(errNoEndpoint, 1)
|
||||
}
|
||||
c, err := client.New(gctx, endpoint, client.Options{Network: GetNetwork(ctx)})
|
||||
if err != nil {
|
||||
return nil, cli.NewExitError(err, 1)
|
||||
}
|
||||
return c, nil
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/cli/options"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
|
@ -24,11 +25,9 @@ import (
|
|||
func NewCommands() []cli.Command {
|
||||
var cfgFlags = []cli.Flag{
|
||||
cli.StringFlag{Name: "config-path"},
|
||||
cli.BoolFlag{Name: "privnet, p"},
|
||||
cli.BoolFlag{Name: "mainnet, m"},
|
||||
cli.BoolFlag{Name: "testnet, t"},
|
||||
cli.BoolFlag{Name: "debug, d"},
|
||||
}
|
||||
cfgFlags = append(cfgFlags, options.Network...)
|
||||
var cfgWithCountFlags = make([]cli.Flag, len(cfgFlags))
|
||||
copy(cfgWithCountFlags, cfgFlags)
|
||||
cfgWithCountFlags = append(cfgWithCountFlags,
|
||||
|
@ -107,18 +106,11 @@ func newGraceContext() context.Context {
|
|||
// getConfigFromContext looks at path and mode flags in the given config and
|
||||
// returns appropriate config.
|
||||
func getConfigFromContext(ctx *cli.Context) (config.Config, error) {
|
||||
var net = config.ModePrivNet
|
||||
if ctx.Bool("testnet") {
|
||||
net = config.ModeTestNet
|
||||
}
|
||||
if ctx.Bool("mainnet") {
|
||||
net = config.ModeMainNet
|
||||
}
|
||||
configPath := "./config"
|
||||
if argCp := ctx.String("config-path"); argCp != "" {
|
||||
configPath = argCp
|
||||
}
|
||||
return config.Load(configPath, net)
|
||||
return config.Load(configPath, options.GetNetwork(ctx))
|
||||
}
|
||||
|
||||
// handleLoggingParams reads logging parameters.
|
||||
|
@ -290,7 +282,7 @@ func restoreDB(ctx *cli.Context) error {
|
|||
default:
|
||||
}
|
||||
bytes, err := readBlock(reader)
|
||||
block := &block.Block{}
|
||||
block := block.New(cfg.ProtocolConfiguration.Magic)
|
||||
newReader := io.NewBinReaderFromBuf(bytes)
|
||||
block.DecodeBinary(newReader)
|
||||
if err != nil {
|
||||
|
|
|
@ -2,7 +2,6 @@ package smartcontract
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -14,11 +13,11 @@ import (
|
|||
|
||||
"github.com/go-yaml/yaml"
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/options"
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
|
@ -32,7 +31,6 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
errNoEndpoint = errors.New("no RPC endpoint specified, use option '--endpoint' or '-e'")
|
||||
errNoInput = errors.New("no input file was found, specify an input file with the '--in or -i' flag")
|
||||
errNoConfFile = errors.New("no config file was found, specify a config file with the '--config' or '-c' flag")
|
||||
errNoMethod = errors.New("no method specified for function invocation command")
|
||||
|
@ -41,10 +39,6 @@ var (
|
|||
errNoSmartContractName = errors.New("no name was provided, specify the '--name or -n' flag")
|
||||
errFileExist = errors.New("A file with given smart-contract name already exists")
|
||||
|
||||
endpointFlag = cli.StringFlag{
|
||||
Name: "endpoint, e",
|
||||
Usage: "trusted RPC endpoint address (like 'http://localhost:20331')",
|
||||
}
|
||||
walletFlag = cli.StringFlag{
|
||||
Name: "wallet, w",
|
||||
Usage: "wallet to use to get the key for transaction signing",
|
||||
|
@ -76,6 +70,33 @@ func Main(op string, args []interface{}) {
|
|||
|
||||
// NewCommands returns 'contract' command.
|
||||
func NewCommands() []cli.Command {
|
||||
testInvokeScriptFlags := []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "in, i",
|
||||
Usage: "Input location of the avm file that needs to be invoked",
|
||||
},
|
||||
}
|
||||
testInvokeScriptFlags = append(testInvokeScriptFlags, options.RPC...)
|
||||
deployFlags := []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "in, i",
|
||||
Usage: "Input file for the smart contract (*.avm)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "config, c",
|
||||
Usage: "configuration input file (*.yml)",
|
||||
},
|
||||
walletFlag,
|
||||
addressFlag,
|
||||
gasFlag,
|
||||
}
|
||||
deployFlags = append(deployFlags, options.RPC...)
|
||||
invokeFunctionFlags := []cli.Flag{
|
||||
walletFlag,
|
||||
addressFlag,
|
||||
gasFlag,
|
||||
}
|
||||
invokeFunctionFlags = append(invokeFunctionFlags, options.RPC...)
|
||||
return []cli.Command{{
|
||||
Name: "contract",
|
||||
Usage: "compile - debug - deploy smart contracts",
|
||||
|
@ -121,42 +142,24 @@ func NewCommands() []cli.Command {
|
|||
to it).
|
||||
`,
|
||||
Action: contractDeploy,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "in, i",
|
||||
Usage: "Input file for the smart contract (*.avm)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "config, c",
|
||||
Usage: "configuration input file (*.yml)",
|
||||
},
|
||||
endpointFlag,
|
||||
walletFlag,
|
||||
addressFlag,
|
||||
gasFlag,
|
||||
},
|
||||
Flags: deployFlags,
|
||||
},
|
||||
{
|
||||
Name: "invokefunction",
|
||||
Usage: "invoke deployed contract on the blockchain",
|
||||
UsageText: "neo-go contract invokefunction -e endpoint -w wallet [-a address] [-g gas] scripthash [method] [arguments...] [--] [cosigners...]",
|
||||
UsageText: "neo-go contract invokefunction -r endpoint -w wallet [-a address] [-g gas] scripthash [method] [arguments...] [--] [cosigners...]",
|
||||
Description: `Executes given (as a script hash) deployed script with the given method,
|
||||
arguments and cosigners. See testinvokefunction documentation for the details
|
||||
about parameters. It differs from testinvokefunction in that this command
|
||||
sends an invocation transaction to the network.
|
||||
`,
|
||||
Action: invokeFunction,
|
||||
Flags: []cli.Flag{
|
||||
endpointFlag,
|
||||
walletFlag,
|
||||
addressFlag,
|
||||
gasFlag,
|
||||
},
|
||||
Flags: invokeFunctionFlags,
|
||||
},
|
||||
{
|
||||
Name: "testinvokefunction",
|
||||
Usage: "invoke deployed contract on the blockchain (test mode)",
|
||||
UsageText: "neo-go contract testinvokefunction -e endpoint scripthash [method] [arguments...] [--] [cosigners...]",
|
||||
UsageText: "neo-go contract testinvokefunction -r endpoint scripthash [method] [arguments...] [--] [cosigners...]",
|
||||
Description: `Executes given (as a script hash) deployed script with the given method,
|
||||
arguments and cosigners. If no method is given "" is passed to the script, if
|
||||
no arguments are given, an empty array is passed, if no cosigners are given,
|
||||
|
@ -247,25 +250,17 @@ func NewCommands() []cli.Command {
|
|||
* '0000000009070e030d0f0e020d0c06050e030c02:CalledByEntry,CustomGroups'
|
||||
`,
|
||||
Action: testInvokeFunction,
|
||||
Flags: []cli.Flag{
|
||||
endpointFlag,
|
||||
},
|
||||
Flags: options.RPC,
|
||||
},
|
||||
{
|
||||
Name: "testinvokescript",
|
||||
Usage: "Invoke compiled AVM code on the blockchain (test mode, not creating a transaction for it)",
|
||||
UsageText: "neo-go contract testinvokescript -e endpoint -i input.avm [cosigners...]",
|
||||
UsageText: "neo-go contract testinvokescript -r endpoint -i input.avm [cosigners...]",
|
||||
Description: `Executes given compiled AVM instructions with the given set of
|
||||
cosigners. See testinvokefunction documentation for the details about parameters.
|
||||
`,
|
||||
Action: testInvokeScript,
|
||||
Flags: []cli.Flag{
|
||||
endpointFlag,
|
||||
cli.StringFlag{
|
||||
Name: "in, i",
|
||||
Usage: "Input location of the avm file that needs to be invoked",
|
||||
},
|
||||
},
|
||||
Flags: testInvokeScriptFlags,
|
||||
},
|
||||
{
|
||||
Name: "init",
|
||||
|
@ -407,11 +402,6 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
|||
acc *wallet.Account
|
||||
)
|
||||
|
||||
endpoint := ctx.String("endpoint")
|
||||
if len(endpoint) == 0 {
|
||||
return cli.NewExitError(errNoEndpoint, 1)
|
||||
}
|
||||
|
||||
args := ctx.Args()
|
||||
if !args.Present() {
|
||||
return cli.NewExitError(errNoScriptHash, 1)
|
||||
|
@ -455,9 +445,12 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
c, err := client.New(context.TODO(), endpoint, client.Options{})
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err = c.InvokeFunction(script, operation, params, cosigners)
|
||||
|
@ -494,10 +487,6 @@ func testInvokeScript(ctx *cli.Context) error {
|
|||
if len(src) == 0 {
|
||||
return cli.NewExitError(errNoInput, 1)
|
||||
}
|
||||
endpoint := ctx.String("endpoint")
|
||||
if len(endpoint) == 0 {
|
||||
return cli.NewExitError(errNoEndpoint, 1)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(src)
|
||||
if err != nil {
|
||||
|
@ -516,9 +505,12 @@ func testInvokeScript(ctx *cli.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
c, err := client.New(context.TODO(), endpoint, client.Options{})
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
return err
|
||||
}
|
||||
|
||||
scriptHex := hex.EncodeToString(b)
|
||||
|
@ -640,10 +632,6 @@ func contractDeploy(ctx *cli.Context) error {
|
|||
if len(confFile) == 0 {
|
||||
return cli.NewExitError(errNoConfFile, 1)
|
||||
}
|
||||
endpoint := ctx.String("endpoint")
|
||||
if len(endpoint) == 0 {
|
||||
return cli.NewExitError(errNoEndpoint, 1)
|
||||
}
|
||||
gas := flags.Fixed8FromContext(ctx, "gas")
|
||||
|
||||
acc, err := getAccFromContext(ctx)
|
||||
|
@ -659,9 +647,12 @@ func contractDeploy(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
c, err := client.New(context.TODO(), endpoint, client.Options{})
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
return err
|
||||
}
|
||||
|
||||
m := conf.ToManifest(avm)
|
||||
|
|
|
@ -5,31 +5,31 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/cli/options"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/context"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func newMultisigCommands() []cli.Command {
|
||||
signFlags := []cli.Flag{
|
||||
walletPathFlag,
|
||||
outFlag,
|
||||
inFlag,
|
||||
cli.StringFlag{
|
||||
Name: "addr",
|
||||
Usage: "Address to use",
|
||||
},
|
||||
}
|
||||
signFlags = append(signFlags, options.RPC...)
|
||||
return []cli.Command{
|
||||
{
|
||||
Name: "sign",
|
||||
Usage: "sign a transaction",
|
||||
UsageText: "multisig sign --path <path> --addr <addr> --in <file.in> --out <file.out>",
|
||||
Action: signMultisig,
|
||||
Flags: []cli.Flag{
|
||||
walletPathFlag,
|
||||
rpcFlag,
|
||||
timeoutFlag,
|
||||
outFlag,
|
||||
inFlag,
|
||||
cli.StringFlag{
|
||||
Name: "addr",
|
||||
Usage: "Address to use",
|
||||
},
|
||||
},
|
||||
Flags: signFlags,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -75,20 +75,21 @@ func signMultisig(ctx *cli.Context) error {
|
|||
} else if err := writeParameterContext(c, ctx.String("out")); err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
if endpoint := ctx.String("rpc"); endpoint != "" {
|
||||
if len(ctx.String(options.RPCEndpointFlag)) != 0 {
|
||||
w, err := c.GetWitness(acc.Contract)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
tx.Scripts = append(tx.Scripts, *w)
|
||||
|
||||
gctx, cancel := getGoContext(ctx)
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
c, err := client.New(gctx, ctx.String("rpc"), client.Options{})
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
} else if err := c.SendRawTransaction(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.SendRawTransaction(tx); err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"io/ioutil"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/options"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/context"
|
||||
|
@ -16,39 +17,59 @@ import (
|
|||
)
|
||||
|
||||
func newNEP5Commands() []cli.Command {
|
||||
balanceFlags := []cli.Flag{
|
||||
walletPathFlag,
|
||||
cli.StringFlag{
|
||||
Name: "addr",
|
||||
Usage: "Address to use",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "Token to use",
|
||||
},
|
||||
}
|
||||
balanceFlags = append(balanceFlags, options.RPC...)
|
||||
importFlags := []cli.Flag{
|
||||
walletPathFlag,
|
||||
cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "Token contract hash in LE",
|
||||
},
|
||||
}
|
||||
importFlags = append(importFlags, options.RPC...)
|
||||
transferFlags := []cli.Flag{
|
||||
walletPathFlag,
|
||||
outFlag,
|
||||
fromAddrFlag,
|
||||
toAddrFlag,
|
||||
cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "Token to use",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "amount",
|
||||
Usage: "Amount of asset to send",
|
||||
},
|
||||
flags.Fixed8Flag{
|
||||
Name: "gas",
|
||||
Usage: "Amount of GAS to attach to a tx",
|
||||
},
|
||||
}
|
||||
transferFlags = append(transferFlags, options.RPC...)
|
||||
return []cli.Command{
|
||||
{
|
||||
Name: "balance",
|
||||
Usage: "get address balance",
|
||||
UsageText: "balance --path <path> --rpc <node> --addr <addr> [--token <hash-or-name>]",
|
||||
UsageText: "balance --path <path> --rpc-endpoint <node> --timeout <time> --addr <addr> [--token <hash-or-name>]",
|
||||
Action: getNEP5Balance,
|
||||
Flags: []cli.Flag{
|
||||
walletPathFlag,
|
||||
rpcFlag,
|
||||
timeoutFlag,
|
||||
cli.StringFlag{
|
||||
Name: "addr",
|
||||
Usage: "Address to use",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "Token to use",
|
||||
},
|
||||
},
|
||||
Flags: balanceFlags,
|
||||
},
|
||||
{
|
||||
Name: "import",
|
||||
Usage: "import NEP5 token to a wallet",
|
||||
UsageText: "import --path <path> --rpc <node> --token <hash>",
|
||||
UsageText: "import --path <path> --rpc-endpoint <node> --timeout <time> --token <hash>",
|
||||
Action: importNEP5Token,
|
||||
Flags: []cli.Flag{
|
||||
walletPathFlag,
|
||||
rpcFlag,
|
||||
cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "Token contract hash in LE",
|
||||
},
|
||||
},
|
||||
Flags: importFlags,
|
||||
},
|
||||
{
|
||||
Name: "info",
|
||||
|
@ -80,28 +101,9 @@ func newNEP5Commands() []cli.Command {
|
|||
{
|
||||
Name: "transfer",
|
||||
Usage: "transfer NEP5 tokens",
|
||||
UsageText: "transfer --path <path> --rpc <node> --from <addr> --to <addr> --token <hash> --amount string",
|
||||
UsageText: "transfer --path <path> --rpc-endpoint <node> --timeout <time> --from <addr> --to <addr> --token <hash> --amount string",
|
||||
Action: transferNEP5,
|
||||
Flags: []cli.Flag{
|
||||
walletPathFlag,
|
||||
rpcFlag,
|
||||
outFlag,
|
||||
timeoutFlag,
|
||||
fromAddrFlag,
|
||||
toAddrFlag,
|
||||
cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "Token to use",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "amount",
|
||||
Usage: "Amount of asset to send",
|
||||
},
|
||||
flags.Fixed8Flag{
|
||||
Name: "gas",
|
||||
Usage: "Amount of GAS to attach to a tx",
|
||||
},
|
||||
},
|
||||
Flags: transferFlags,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -123,12 +125,12 @@ func getNEP5Balance(ctx *cli.Context) error {
|
|||
return cli.NewExitError(fmt.Errorf("can't find account for the address: %s", addr), 1)
|
||||
}
|
||||
|
||||
gctx, cancel := getGoContext(ctx)
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
c, err := client.New(gctx, ctx.String("rpc"), client.Options{})
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
return err
|
||||
}
|
||||
|
||||
var token *wallet.Token
|
||||
|
@ -218,12 +220,12 @@ func importNEP5Token(ctx *cli.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
gctx, cancel := getGoContext(ctx)
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
c, err := client.New(gctx, ctx.String("rpc"), client.Options{})
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
return err
|
||||
}
|
||||
|
||||
tok, err := c.NEP5TokenInfo(tokenHash)
|
||||
|
@ -314,11 +316,12 @@ func transferNEP5(ctx *cli.Context) error {
|
|||
return cli.NewExitError(fmt.Errorf("can't find account for the address: %s", fromFlag), 1)
|
||||
}
|
||||
|
||||
gctx, cancel := getGoContext(ctx)
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
c, err := client.New(gctx, ctx.String("rpc"), client.Options{})
|
||||
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
return err
|
||||
}
|
||||
|
||||
toFlag := ctx.Generic("to").(*flags.Address)
|
||||
|
|
|
@ -2,7 +2,6 @@ package wallet
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -11,9 +10,9 @@ import (
|
|||
"syscall"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/options"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -38,14 +37,6 @@ var (
|
|||
Name: "decrypt, d",
|
||||
Usage: "Decrypt encrypted keys.",
|
||||
}
|
||||
rpcFlag = cli.StringFlag{
|
||||
Name: "rpc, r",
|
||||
Usage: "RPC node address",
|
||||
}
|
||||
timeoutFlag = cli.DurationFlag{
|
||||
Name: "timeout, t",
|
||||
Usage: "Timeout for the operation",
|
||||
}
|
||||
outFlag = cli.StringFlag{
|
||||
Name: "out",
|
||||
Usage: "file to put JSON transaction to",
|
||||
|
@ -70,6 +61,14 @@ var (
|
|||
|
||||
// NewCommands returns 'wallet' command.
|
||||
func NewCommands() []cli.Command {
|
||||
claimFlags := []cli.Flag{
|
||||
walletPathFlag,
|
||||
flags.AddressFlag{
|
||||
Name: "address, a",
|
||||
Usage: "Address to claim GAS for",
|
||||
},
|
||||
}
|
||||
claimFlags = append(claimFlags, options.RPC...)
|
||||
return []cli.Command{{
|
||||
Name: "wallet",
|
||||
Usage: "create, open and manage a NEO wallet",
|
||||
|
@ -78,15 +77,7 @@ func NewCommands() []cli.Command {
|
|||
Name: "claim",
|
||||
Usage: "claim GAS",
|
||||
Action: claimGas,
|
||||
Flags: []cli.Flag{
|
||||
walletPathFlag,
|
||||
rpcFlag,
|
||||
timeoutFlag,
|
||||
flags.AddressFlag{
|
||||
Name: "address, a",
|
||||
Usage: "Address to claim GAS for",
|
||||
},
|
||||
},
|
||||
Flags: claimFlags,
|
||||
},
|
||||
{
|
||||
Name: "init",
|
||||
|
@ -223,12 +214,12 @@ func claimGas(ctx *cli.Context) error {
|
|||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
|
||||
gctx, cancel := getGoContext(ctx)
|
||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
c, err := client.New(gctx, ctx.String("rpc"), client.Options{})
|
||||
c, err := options.GetRPCClient(gctx, ctx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
return err
|
||||
}
|
||||
// Temporary.
|
||||
neoHash, err := util.Uint160DecodeStringLE("3b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c")
|
||||
|
@ -476,13 +467,6 @@ func askForConsent() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func getGoContext(ctx *cli.Context) (context.Context, func()) {
|
||||
if dur := ctx.Duration("timeout"); dur != 0 {
|
||||
return context.WithTimeout(context.Background(), dur)
|
||||
}
|
||||
return context.Background(), func() {}
|
||||
}
|
||||
|
||||
func dumpWallet(ctx *cli.Context) error {
|
||||
wall, err := openWallet(ctx.String("path"))
|
||||
if err != nil {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
ProtocolConfiguration:
|
||||
Magic: 56753
|
||||
Magic: 42
|
||||
SecondsPerBlock: 15
|
||||
LowPriorityThreshold: 0.000
|
||||
MemPoolSize: 50000
|
||||
|
|
|
@ -144,10 +144,10 @@ project:
|
|||
It's passed to the `deploy` command via `-c` option:
|
||||
|
||||
```
|
||||
$ ./bin/neo-go contract deploy -i contract.avm -c contract.yml -e http://localhost:20331 -w wallet.json -g 0.001
|
||||
$ ./bin/neo-go contract deploy -i contract.avm -c contract.yml -r http://localhost:20331 -w wallet.json -g 0.001
|
||||
```
|
||||
|
||||
Deployment works via an RPC server, an address of which is passed via `-e`
|
||||
Deployment works via an RPC server, an address of which is passed via `-r`
|
||||
option and should be signed using a wallet from `-w` option. More details can
|
||||
be found in `deploy` command help.
|
||||
|
||||
|
@ -184,7 +184,7 @@ Example call (contract `f84d6a337fbc3d3a201d41da99e86b479e7a2554` with method
|
|||
given RPC server and wallet and paying 0.00001 GAS for this transaction):
|
||||
|
||||
```
|
||||
$ ./bin/neo-go contract invokefunction -e http://localhost:20331 -w my_wallet.json -g 0.00001 f84d6a337fbc3d3a201d41da99e86b479e7a2554 balanceOf AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y
|
||||
$ ./bin/neo-go contract invokefunction -r http://localhost:20331 -w my_wallet.json -g 0.00001 f84d6a337fbc3d3a201d41da99e86b479e7a2554 balanceOf AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y
|
||||
```
|
||||
|
||||
## Smart contract examples
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -20,7 +21,7 @@ import (
|
|||
// Benchmark test to measure number of processed TX.
|
||||
// Same benchmark made on reference C# node https://github.com/neo-project/neo/issues/1321.
|
||||
func BenchmarkTXPerformanceTest(t *testing.B) {
|
||||
net := config.ModeUnitTestNet
|
||||
net := netmode.UnitTestNet
|
||||
configPath := "../config"
|
||||
cfg, err := config.Load(configPath, net)
|
||||
require.NoError(t, err, "could not load config")
|
||||
|
@ -77,7 +78,7 @@ func getTX(t *testing.B, wif *keys.WIF) *transaction.Transaction {
|
|||
fromAddressHash, err := address.StringToUint160(fromAddress)
|
||||
require.NoError(t, err)
|
||||
|
||||
tx := transaction.New([]byte{0x51}, 1)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{0x51}, 1)
|
||||
tx.Version = 0
|
||||
tx.Sender = fromAddressHash
|
||||
tx.Attributes = append(tx.Attributes,
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
|
@ -80,7 +81,7 @@ func TestAppCall(t *testing.T) {
|
|||
inner, err := compiler.Compile(strings.NewReader(srcInner))
|
||||
require.NoError(t, err)
|
||||
|
||||
ic := interop.NewContext(trigger.Application, nil, dao.NewSimple(storage.NewMemoryStore()), nil, nil, nil, zaptest.NewLogger(t))
|
||||
ic := interop.NewContext(trigger.Application, nil, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil, nil, zaptest.NewLogger(t))
|
||||
require.NoError(t, ic.DAO.PutContractState(&state.Contract{Script: inner}))
|
||||
|
||||
ih := hash.Hash160(inner)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/go-yaml/yaml"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -28,7 +29,7 @@ func (c Config) GenerateUserAgent() string {
|
|||
|
||||
// Load attempts to load the config from the given
|
||||
// path for the given netMode.
|
||||
func Load(path string, netMode NetMode) (Config, error) {
|
||||
func Load(path string, netMode netmode.Magic) (Config, error) {
|
||||
configPath := fmt.Sprintf("%s/protocol.%s.yml", path, netMode)
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
return Config{}, errors.Wrap(err, "Unable to load config")
|
||||
|
|
33
pkg/config/netmode/netmode.go
Normal file
33
pkg/config/netmode/netmode.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package netmode
|
||||
|
||||
import "strconv"
|
||||
|
||||
const (
|
||||
// MainNet contains magic code used in the NEO main official network.
|
||||
MainNet Magic = 0x004f454e // 5195086
|
||||
// TestNet contains magic code used in the NEO testing network.
|
||||
TestNet Magic = 0x744f454e // 1951352142
|
||||
// PrivNet contains magic code usually used for NEO private networks.
|
||||
PrivNet Magic = 56753 // docker privnet
|
||||
// UnitTestNet is a stub magic code used for testing purposes.
|
||||
UnitTestNet Magic = 42
|
||||
)
|
||||
|
||||
// Magic describes the network the blockchain will operate on.
|
||||
type Magic uint32
|
||||
|
||||
// String implements the stringer interface.
|
||||
func (n Magic) String() string {
|
||||
switch n {
|
||||
case PrivNet:
|
||||
return "privnet"
|
||||
case TestNet:
|
||||
return "testnet"
|
||||
case MainNet:
|
||||
return "mainnet"
|
||||
case UnitTestNet:
|
||||
return "unit_testnet"
|
||||
default:
|
||||
return "net 0x" + strconv.FormatUint(uint64(n), 16)
|
||||
}
|
||||
}
|
|
@ -1,20 +1,10 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// ModeMainNet contains magic code used in the NEO main official network.
|
||||
ModeMainNet NetMode = 0x00746e41 // 7630401
|
||||
// ModeTestNet contains magic code used in the NEO testing network.
|
||||
ModeTestNet NetMode = 0x74746e41 // 1953787457
|
||||
// ModePrivNet contains magic code usually used for NEO private networks.
|
||||
ModePrivNet NetMode = 56753 // docker privnet
|
||||
// ModeUnitTestNet is a stub magic code used for testing purposes.
|
||||
ModeUnitTestNet NetMode = 0
|
||||
)
|
||||
|
||||
// ProtocolConfiguration represents the protocol config.
|
||||
type (
|
||||
ProtocolConfiguration struct {
|
||||
|
@ -22,10 +12,10 @@ type (
|
|||
// transactions exceeding the MaxFreeTransactionSize.
|
||||
FeePerExtraByte float64 `yaml:"FeePerExtraByte"`
|
||||
// FreeGasLimit is an amount of GAS which can be spent for free.
|
||||
FreeGasLimit util.Fixed8 `yaml:"FreeGasLimit"`
|
||||
LowPriorityThreshold float64 `yaml:"LowPriorityThreshold"`
|
||||
Magic NetMode `yaml:"Magic"`
|
||||
MaxTransactionsPerBlock int `yaml:"MaxTransactionsPerBlock"`
|
||||
FreeGasLimit util.Fixed8 `yaml:"FreeGasLimit"`
|
||||
LowPriorityThreshold float64 `yaml:"LowPriorityThreshold"`
|
||||
Magic netmode.Magic `yaml:"Magic"`
|
||||
MaxTransactionsPerBlock int `yaml:"MaxTransactionsPerBlock"`
|
||||
// Maximum size of low priority transaction in bytes.
|
||||
MaxFreeTransactionSize int `yaml:"MaxFreeTransactionSize"`
|
||||
// Maximum number of low priority transactions accepted into block.
|
||||
|
@ -41,23 +31,4 @@ type (
|
|||
// Whether to verify transactions in received blocks.
|
||||
VerifyTransactions bool `yaml:"VerifyTransactions"`
|
||||
}
|
||||
|
||||
// NetMode describes the mode the blockchain will operate on.
|
||||
NetMode uint32
|
||||
)
|
||||
|
||||
// String implements the stringer interface.
|
||||
func (n NetMode) String() string {
|
||||
switch n {
|
||||
case ModePrivNet:
|
||||
return "privnet"
|
||||
case ModeTestNet:
|
||||
return "testnet"
|
||||
case ModeMainNet:
|
||||
return "mainnet"
|
||||
case ModeUnitTestNet:
|
||||
return "unit_testnet"
|
||||
default:
|
||||
return "net unknown"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/dbft/block"
|
||||
"github.com/nspcc-dev/dbft/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -45,7 +46,7 @@ func TestNeoBlock_Setters(t *testing.T) {
|
|||
b.Block.PrevHash = util.Uint256{9, 8, 7}
|
||||
require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash())
|
||||
|
||||
txx := []block.Transaction{transaction.New([]byte{byte(opcode.PUSH1)}, 1)}
|
||||
txx := []block.Transaction{transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 1)}
|
||||
b.SetTransactions(txx)
|
||||
require.Equal(t, txx, b.Transactions())
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"github.com/nspcc-dev/dbft"
|
||||
"github.com/nspcc-dev/dbft/block"
|
||||
"github.com/nspcc-dev/dbft/crypto"
|
||||
"github.com/nspcc-dev/dbft/merkle"
|
||||
"github.com/nspcc-dev/dbft/payload"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
coreb "github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -61,6 +61,7 @@ type service struct {
|
|||
blockEvents chan *coreb.Block
|
||||
lastProposal []util.Uint256
|
||||
wallet *wallet.Wallet
|
||||
network netmode.Magic
|
||||
}
|
||||
|
||||
// Config is a configuration for consensus services.
|
||||
|
@ -101,6 +102,7 @@ func NewService(cfg Config) (Service, error) {
|
|||
|
||||
transactions: make(chan *transaction.Transaction, 100),
|
||||
blockEvents: make(chan *coreb.Block, 1),
|
||||
network: cfg.Chain.GetConfig().Magic,
|
||||
}
|
||||
|
||||
if cfg.Wallet == nil {
|
||||
|
@ -128,7 +130,7 @@ func NewService(cfg Config) (Service, error) {
|
|||
dbft.WithVerifyBlock(srv.verifyBlock),
|
||||
dbft.WithGetBlock(srv.getBlock),
|
||||
dbft.WithWatchOnly(func() bool { return false }),
|
||||
dbft.WithNewBlockFromContext(newBlockFromContext),
|
||||
dbft.WithNewBlockFromContext(srv.newBlockFromContext),
|
||||
dbft.WithCurrentHeight(cfg.Chain.BlockHeight),
|
||||
dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash),
|
||||
dbft.WithGetValidators(srv.getValidators),
|
||||
|
@ -460,12 +462,13 @@ func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) {
|
|||
return
|
||||
}
|
||||
|
||||
func newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||
func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||
block := new(neoBlock)
|
||||
if ctx.TransactionHashes == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
block.Block.Network = s.network
|
||||
block.Block.Timestamp = ctx.Timestamp / 1000000
|
||||
block.Block.Index = ctx.BlockIndex
|
||||
block.Block.NextConsensus = ctx.NextConsensus
|
||||
|
@ -475,12 +478,7 @@ func newBlockFromContext(ctx *dbft.Context) block.Block {
|
|||
|
||||
primaryIndex := uint32(ctx.PrimaryIndex)
|
||||
block.Block.ConsensusData.PrimaryIndex = primaryIndex
|
||||
consensusData := coreb.ConsensusData{
|
||||
PrimaryIndex: primaryIndex,
|
||||
Nonce: ctx.Nonce,
|
||||
}
|
||||
|
||||
mt := merkle.NewMerkleTree(append([]util.Uint256{consensusData.Hash()}, ctx.TransactionHashes...)...)
|
||||
block.Block.MerkleRoot = mt.Root().Hash
|
||||
block.Block.RebuildMerkleRoot()
|
||||
return block
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/nspcc-dev/dbft/block"
|
||||
"github.com/nspcc-dev/dbft/payload"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -23,7 +24,7 @@ import (
|
|||
|
||||
func TestNewService(t *testing.T) {
|
||||
srv := newTestService(t)
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.ValidUntilBlock = 1
|
||||
addSender(t, tx)
|
||||
signTx(t, srv.Chain.FeePerByte(), tx)
|
||||
|
@ -40,7 +41,7 @@ func TestService_GetVerified(t *testing.T) {
|
|||
srv := newTestService(t)
|
||||
var txs []*transaction.Transaction
|
||||
for i := 0; i < 4; i++ {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = 123 + uint32(i)
|
||||
tx.ValidUntilBlock = 1
|
||||
txs = append(txs, tx)
|
||||
|
@ -54,7 +55,7 @@ func TestService_GetVerified(t *testing.T) {
|
|||
p := new(Payload)
|
||||
p.message = &message{}
|
||||
p.SetType(payload.PrepareRequestType)
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = 999
|
||||
p.SetPayload(&prepareRequest{transactionHashes: hashes})
|
||||
p.SetValidatorIndex(1)
|
||||
|
@ -121,7 +122,7 @@ func TestService_getTx(t *testing.T) {
|
|||
srv := newTestService(t)
|
||||
|
||||
t.Run("transaction in mempool", func(t *testing.T) {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = 1234
|
||||
tx.ValidUntilBlock = 1
|
||||
addSender(t, tx)
|
||||
|
@ -138,7 +139,7 @@ func TestService_getTx(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("transaction in local cache", func(t *testing.T) {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = 4321
|
||||
tx.ValidUntilBlock = 1
|
||||
h := tx.Hash()
|
||||
|
@ -217,7 +218,7 @@ func getTestValidator(i int) (*privateKey, *publicKey) {
|
|||
}
|
||||
|
||||
func newTestChain(t *testing.T) *core.Blockchain {
|
||||
unitTestNetCfg, err := config.Load("../../config", config.ModeUnitTestNet)
|
||||
unitTestNetCfg, err := config.Load("../../config", netmode.UnitTestNet)
|
||||
require.NoError(t, err)
|
||||
|
||||
chain, err := core.NewBlockchain(storage.NewMemoryStore(), unitTestNetCfg.ProtocolConfiguration, zaptest.NewLogger(t))
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
|
||||
"github.com/Workiva/go-datastructures/queue"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -26,12 +27,18 @@ type Block struct {
|
|||
Trimmed bool
|
||||
}
|
||||
|
||||
// auxBlock is used for JSON i/o.
|
||||
type auxBlock struct {
|
||||
// auxBlockOut is used for JSON i/o.
|
||||
type auxBlockOut struct {
|
||||
ConsensusData ConsensusData `json:"consensus_data"`
|
||||
Transactions []*transaction.Transaction `json:"tx"`
|
||||
}
|
||||
|
||||
// auxBlockIn is used for JSON i/o.
|
||||
type auxBlockIn struct {
|
||||
ConsensusData ConsensusData `json:"consensus_data"`
|
||||
Transactions []json.RawMessage `json:"tx"`
|
||||
}
|
||||
|
||||
// Header returns the Header of the Block.
|
||||
func (b *Block) Header() *Header {
|
||||
return &Header{
|
||||
|
@ -88,8 +95,11 @@ func (b *Block) Verify() error {
|
|||
// This is commonly used to create a block from stored data.
|
||||
// Blocks created from trimmed data will have their Trimmed field
|
||||
// set to true.
|
||||
func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
|
||||
func NewBlockFromTrimmedBytes(network netmode.Magic, b []byte) (*Block, error) {
|
||||
block := &Block{
|
||||
Base: Base{
|
||||
Network: network,
|
||||
},
|
||||
Trimmed: true,
|
||||
}
|
||||
|
||||
|
@ -117,6 +127,15 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
|
|||
return block, br.Err
|
||||
}
|
||||
|
||||
// New creates a new blank block tied to the specific network.
|
||||
func New(network netmode.Magic) *Block {
|
||||
return &Block{
|
||||
Base: Base{
|
||||
Network: network,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Trim returns a subset of the block data to save up space
|
||||
// in storage.
|
||||
// Notice that only the hashes of the transactions are stored.
|
||||
|
@ -155,7 +174,7 @@ func (b *Block) DecodeBinary(br *io.BinReader) {
|
|||
b.ConsensusData.DecodeBinary(br)
|
||||
txes := make([]*transaction.Transaction, contentsCount-1)
|
||||
for i := 0; i < int(contentsCount)-1; i++ {
|
||||
tx := new(transaction.Transaction)
|
||||
tx := &transaction.Transaction{Network: b.Network}
|
||||
tx.DecodeBinary(br)
|
||||
txes[i] = tx
|
||||
}
|
||||
|
@ -192,7 +211,7 @@ func (b *Block) Compare(item queue.Item) int {
|
|||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (b Block) MarshalJSON() ([]byte, error) {
|
||||
auxb, err := json.Marshal(auxBlock{
|
||||
auxb, err := json.Marshal(auxBlockOut{
|
||||
ConsensusData: b.ConsensusData,
|
||||
Transactions: b.Transactions,
|
||||
})
|
||||
|
@ -217,18 +236,26 @@ func (b Block) MarshalJSON() ([]byte, error) {
|
|||
func (b *Block) UnmarshalJSON(data []byte) error {
|
||||
// As Base and auxb are at the same level in json,
|
||||
// do unmarshalling separately for both structs.
|
||||
auxb := new(auxBlock)
|
||||
auxb := new(auxBlockIn)
|
||||
err := json.Unmarshal(data, auxb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
base := new(Base)
|
||||
err = json.Unmarshal(data, base)
|
||||
err = json.Unmarshal(data, &b.Base)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Base = *base
|
||||
b.Transactions = auxb.Transactions
|
||||
if len(auxb.Transactions) != 0 {
|
||||
b.Transactions = make([]*transaction.Transaction, 0, len(auxb.Transactions))
|
||||
for _, txBytes := range auxb.Transactions {
|
||||
tx := &transaction.Transaction{Network: b.Network}
|
||||
err = tx.UnmarshalJSON(txBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Transactions = append(b.Transactions, tx)
|
||||
}
|
||||
}
|
||||
b.ConsensusData = auxb.ConsensusData
|
||||
// Some tests rely on hash presence and we're usually precomputing
|
||||
// other hashes upon deserialization.
|
||||
|
|
|
@ -3,8 +3,8 @@ package block
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
|
@ -35,12 +35,14 @@ type Base struct {
|
|||
// Contract address of the next miner
|
||||
NextConsensus util.Uint160
|
||||
|
||||
// Padding that is fixed to 1
|
||||
_ uint8
|
||||
|
||||
// Script used to validate the block
|
||||
Script transaction.Witness
|
||||
|
||||
// Network magic number this block belongs to. This one actually is not
|
||||
// a part of the wire-representation of Block, but it's absolutely
|
||||
// necessary for correct signing/verification.
|
||||
Network netmode.Magic
|
||||
|
||||
// Hash of this block, created when binary encoded (double SHA256).
|
||||
hash util.Uint256
|
||||
|
||||
|
@ -87,11 +89,9 @@ func (b *Base) VerificationHash() util.Uint256 {
|
|||
// DecodeBinary implements Serializable interface.
|
||||
func (b *Base) DecodeBinary(br *io.BinReader) {
|
||||
b.decodeHashableFields(br)
|
||||
|
||||
padding := []byte{0}
|
||||
br.ReadBytes(padding)
|
||||
if padding[0] != 1 {
|
||||
br.Err = fmt.Errorf("format error: padding must equal 1 got %d", padding)
|
||||
witnessCount := br.ReadVarUint()
|
||||
if br.Err == nil && witnessCount != 1 {
|
||||
br.Err = errors.New("wrong witness count")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -101,13 +101,14 @@ func (b *Base) DecodeBinary(br *io.BinReader) {
|
|||
// EncodeBinary implements Serializable interface
|
||||
func (b *Base) EncodeBinary(bw *io.BinWriter) {
|
||||
b.encodeHashableFields(bw)
|
||||
bw.WriteBytes([]byte{1})
|
||||
bw.WriteVarUint(1)
|
||||
b.Script.EncodeBinary(bw)
|
||||
}
|
||||
|
||||
// GetSignedPart returns serialized hashable data of the block.
|
||||
func (b *Base) GetSignedPart() []byte {
|
||||
buf := io.NewBufBinWriter()
|
||||
buf.WriteU32LE(uint32(b.Network))
|
||||
// No error can occure while encoding hashable fields.
|
||||
b.encodeHashableFields(buf.BinWriter)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package block
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -85,7 +86,7 @@ func newDumbBlock() *Block {
|
|||
Nonce: 1111,
|
||||
},
|
||||
Transactions: []*transaction.Transaction{
|
||||
transaction.New([]byte{byte(opcode.PUSH1)}, 0),
|
||||
transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ func (c *ConsensusData) createHash() error {
|
|||
}
|
||||
|
||||
b := buf.Bytes()
|
||||
c.hash = hash.Sha256(b)
|
||||
c.hash = hash.DoubleSha256(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@ import (
|
|||
type Header struct {
|
||||
// Base of the block.
|
||||
Base
|
||||
// Padding that is fixed to 0.
|
||||
_ uint8
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
|
|
|
@ -170,7 +170,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L
|
|||
}
|
||||
bc := &Blockchain{
|
||||
config: cfg,
|
||||
dao: dao.NewSimple(s),
|
||||
dao: dao.NewSimple(s, cfg.Magic),
|
||||
headersOp: make(chan headersOpFunc),
|
||||
headersOpDone: make(chan struct{}),
|
||||
stopCh: make(chan struct{}),
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
|
@ -102,7 +103,7 @@ func TestScriptFromWitness(t *testing.T) {
|
|||
|
||||
func TestGetHeader(t *testing.T) {
|
||||
bc := newTestChain(t)
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.ValidUntilBlock = bc.BlockHeight() + 1
|
||||
assert.Nil(t, addSender(tx))
|
||||
assert.Nil(t, signTx(bc, tx))
|
||||
|
@ -267,7 +268,7 @@ func TestSubscriptions(t *testing.T) {
|
|||
emit.Bytes(script.BinWriter, []byte("yay!"))
|
||||
emit.Syscall(script.BinWriter, "System.Runtime.Notify")
|
||||
require.NoError(t, script.Err)
|
||||
txGood1 := transaction.New(script.Bytes(), 0)
|
||||
txGood1 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
|
||||
txGood1.Sender = neoOwner
|
||||
txGood1.Nonce = 1
|
||||
txGood1.ValidUntilBlock = 100500
|
||||
|
@ -279,7 +280,7 @@ func TestSubscriptions(t *testing.T) {
|
|||
emit.Syscall(script.BinWriter, "System.Runtime.Notify")
|
||||
emit.Opcode(script.BinWriter, opcode.THROW)
|
||||
require.NoError(t, script.Err)
|
||||
txBad := transaction.New(script.Bytes(), 0)
|
||||
txBad := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
|
||||
txBad.Sender = neoOwner
|
||||
txBad.Nonce = 2
|
||||
txBad.ValidUntilBlock = 100500
|
||||
|
@ -289,7 +290,7 @@ func TestSubscriptions(t *testing.T) {
|
|||
emit.Bytes(script.BinWriter, []byte("yay! yay! yay!"))
|
||||
emit.Syscall(script.BinWriter, "System.Runtime.Notify")
|
||||
require.NoError(t, script.Err)
|
||||
txGood2 := transaction.New(script.Bytes(), 0)
|
||||
txGood2 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
|
||||
txGood2.Sender = neoOwner
|
||||
txGood2.Nonce = 3
|
||||
txGood2.ValidUntilBlock = 100500
|
||||
|
|
|
@ -3,6 +3,7 @@ package dao
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
|
@ -16,7 +17,7 @@ import (
|
|||
func TestCachedDaoAccounts(t *testing.T) {
|
||||
store := storage.NewMemoryStore()
|
||||
// Persistent DAO to check for backing storage.
|
||||
pdao := NewSimple(store)
|
||||
pdao := NewSimple(store, netmode.UnitTestNet)
|
||||
// Cached DAO.
|
||||
cdao := NewCached(pdao)
|
||||
|
||||
|
@ -52,7 +53,7 @@ func TestCachedDaoAccounts(t *testing.T) {
|
|||
|
||||
func TestCachedDaoContracts(t *testing.T) {
|
||||
store := storage.NewMemoryStore()
|
||||
pdao := NewSimple(store)
|
||||
pdao := NewSimple(store, netmode.UnitTestNet)
|
||||
dao := NewCached(pdao)
|
||||
|
||||
script := []byte{0xde, 0xad, 0xbe, 0xef}
|
||||
|
@ -97,7 +98,7 @@ func TestCachedDaoContracts(t *testing.T) {
|
|||
func TestCachedCachedDao(t *testing.T) {
|
||||
store := storage.NewMemoryStore()
|
||||
// Persistent DAO to check for backing storage.
|
||||
pdao := NewSimple(store)
|
||||
pdao := NewSimple(store, netmode.UnitTestNet)
|
||||
assert.NotEqual(t, store, pdao.Store)
|
||||
// Cached DAO.
|
||||
cdao := NewCached(pdao)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
|
@ -58,12 +59,13 @@ type DAO interface {
|
|||
|
||||
// Simple is memCached wrapper around DB, simple DAO implementation.
|
||||
type Simple struct {
|
||||
Store *storage.MemCachedStore
|
||||
Store *storage.MemCachedStore
|
||||
network netmode.Magic
|
||||
}
|
||||
|
||||
// NewSimple creates new simple dao using provided backend store.
|
||||
func NewSimple(backend storage.Store) *Simple {
|
||||
return &Simple{Store: storage.NewMemCachedStore(backend)}
|
||||
func NewSimple(backend storage.Store, network netmode.Magic) *Simple {
|
||||
return &Simple{Store: storage.NewMemCachedStore(backend), network: network}
|
||||
}
|
||||
|
||||
// GetBatch returns currently accumulated DB changeset.
|
||||
|
@ -74,7 +76,7 @@ func (dao *Simple) GetBatch() *storage.MemBatch {
|
|||
// GetWrapped returns new DAO instance with another layer of wrapped
|
||||
// MemCachedStore around the current DAO Store.
|
||||
func (dao *Simple) GetWrapped() DAO {
|
||||
return NewSimple(dao.Store)
|
||||
return NewSimple(dao.Store, dao.network)
|
||||
}
|
||||
|
||||
// GetAndDecode performs get operation and decoding with serializable structures.
|
||||
|
@ -376,7 +378,7 @@ func (dao *Simple) GetBlock(hash util.Uint256) (*block.Block, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
block, err := block.NewBlockFromTrimmedBytes(b)
|
||||
block, err := block.NewBlockFromTrimmedBytes(dao.network, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -455,7 +457,7 @@ func (dao *Simple) GetTransaction(hash util.Uint256) (*transaction.Transaction,
|
|||
|
||||
var height = r.ReadU32LE()
|
||||
|
||||
tx := &transaction.Transaction{}
|
||||
tx := &transaction.Transaction{Network: dao.network}
|
||||
tx.DecodeBinary(r)
|
||||
if r.Err != nil {
|
||||
return nil, 0, r.Err
|
||||
|
|
|
@ -3,6 +3,7 @@ package dao
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
|
@ -15,7 +16,7 @@ import (
|
|||
)
|
||||
|
||||
func TestPutGetAndDecode(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
serializable := &TestSerializable{field: random.String(4)}
|
||||
hash := []byte{1}
|
||||
err := dao.Put(serializable, hash)
|
||||
|
@ -40,7 +41,7 @@ func (t *TestSerializable) DecodeBinary(reader *io.BinReader) {
|
|||
}
|
||||
|
||||
func TestGetAccountStateOrNew_New(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
hash := random.Uint160()
|
||||
createdAccount, err := dao.GetAccountStateOrNew(hash)
|
||||
require.NoError(t, err)
|
||||
|
@ -48,7 +49,7 @@ func TestGetAccountStateOrNew_New(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPutAndGetAccountStateOrNew(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
hash := random.Uint160()
|
||||
accountState := &state.Account{ScriptHash: hash}
|
||||
err := dao.PutAccountState(accountState)
|
||||
|
@ -59,7 +60,7 @@ func TestPutAndGetAccountStateOrNew(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPutAndGetContractState(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
contractState := &state.Contract{Script: []byte{}}
|
||||
hash := contractState.ScriptHash()
|
||||
err := dao.PutContractState(contractState)
|
||||
|
@ -70,7 +71,7 @@ func TestPutAndGetContractState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteContractState(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
contractState := &state.Contract{Script: []byte{}}
|
||||
hash := contractState.ScriptHash()
|
||||
err := dao.PutContractState(contractState)
|
||||
|
@ -83,7 +84,7 @@ func TestDeleteContractState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSimple_GetNextContractID(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
id, err := dao.GetNextContractID()
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 0, id)
|
||||
|
@ -94,7 +95,7 @@ func TestSimple_GetNextContractID(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPutGetAppExecResult(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
hash := random.Uint256()
|
||||
appExecResult := &state.AppExecResult{
|
||||
TxHash: hash,
|
||||
|
@ -109,7 +110,7 @@ func TestPutGetAppExecResult(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPutGetStorageItem(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
hash := random.Uint160()
|
||||
key := []byte{0}
|
||||
storageItem := &state.StorageItem{Value: []uint8{}}
|
||||
|
@ -120,7 +121,7 @@ func TestPutGetStorageItem(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteStorageItem(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
hash := random.Uint160()
|
||||
key := []byte{0}
|
||||
storageItem := &state.StorageItem{Value: []uint8{}}
|
||||
|
@ -133,7 +134,7 @@ func TestDeleteStorageItem(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetBlock_NotExists(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
hash := random.Uint256()
|
||||
block, err := dao.GetBlock(hash)
|
||||
require.Error(t, err)
|
||||
|
@ -141,7 +142,7 @@ func TestGetBlock_NotExists(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPutGetBlock(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Script: transaction.Witness{
|
||||
|
@ -159,14 +160,14 @@ func TestPutGetBlock(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetVersion_NoVersion(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
version, err := dao.GetVersion()
|
||||
require.Error(t, err)
|
||||
require.Equal(t, "", version)
|
||||
}
|
||||
|
||||
func TestGetVersion(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
err := dao.PutVersion("testVersion")
|
||||
require.NoError(t, err)
|
||||
version, err := dao.GetVersion()
|
||||
|
@ -175,14 +176,14 @@ func TestGetVersion(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
height, err := dao.GetCurrentBlockHeight()
|
||||
require.Error(t, err)
|
||||
require.Equal(t, uint32(0), height)
|
||||
}
|
||||
|
||||
func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Script: transaction.Witness{
|
||||
|
@ -199,8 +200,8 @@ func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStoreAsTransaction(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore())
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 1)
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 1)
|
||||
hash := tx.Hash()
|
||||
err := dao.StoreAsTransaction(tx, 0)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -34,7 +34,7 @@ var neoOwner = testchain.MultisigScriptHash()
|
|||
// newTestChain should be called before newBlock invocation to properly setup
|
||||
// global state.
|
||||
func newTestChain(t *testing.T) *Blockchain {
|
||||
unitTestNetCfg, err := config.Load("../../config", config.ModeUnitTestNet)
|
||||
unitTestNetCfg, err := config.Load("../../config", testchain.Network())
|
||||
require.NoError(t, err)
|
||||
chain, err := NewBlockchain(storage.NewMemoryStore(), unitTestNetCfg.ProtocolConfiguration, zaptest.NewLogger(t))
|
||||
require.NoError(t, err)
|
||||
|
@ -59,6 +59,7 @@ func newBlock(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256,
|
|||
}
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Network: testchain.Network(),
|
||||
Version: 0,
|
||||
PrevHash: prev,
|
||||
Timestamp: uint64(time.Now().UTC().Unix())*1000 + uint64(index),
|
||||
|
@ -102,7 +103,7 @@ func getDecodedBlock(t *testing.T, i int) *block.Block {
|
|||
b, err := hex.DecodeString(data["raw"].(string))
|
||||
require.NoError(t, err)
|
||||
|
||||
block := &block.Block{}
|
||||
block := block.New(testchain.Network())
|
||||
require.NoError(t, testserdes.DecodeBinary(b, block))
|
||||
|
||||
return block
|
||||
|
@ -123,6 +124,7 @@ func getBlockData(i int) (map[string]interface{}, error) {
|
|||
func newDumbBlock() *block.Block {
|
||||
return &block.Block{
|
||||
Base: block.Base{
|
||||
Network: testchain.Network(),
|
||||
Version: 0,
|
||||
PrevHash: hash.Sha256([]byte("a")),
|
||||
MerkleRoot: hash.Sha256([]byte("b")),
|
||||
|
@ -139,7 +141,7 @@ func newDumbBlock() *block.Block {
|
|||
Nonce: 1111,
|
||||
},
|
||||
Transactions: []*transaction.Transaction{
|
||||
transaction.New([]byte{byte(opcode.PUSH1)}, 0),
|
||||
transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +242,7 @@ func TestCreateBasicChain(t *testing.T) {
|
|||
txScript := script.Bytes()
|
||||
|
||||
invFee := util.Fixed8FromFloat(100)
|
||||
txDeploy := transaction.New(txScript, invFee)
|
||||
txDeploy := transaction.New(testchain.Network(), txScript, invFee)
|
||||
txDeploy.Nonce = getNextNonce()
|
||||
txDeploy.ValidUntilBlock = validUntilBlock
|
||||
txDeploy.Sender = priv0ScriptHash
|
||||
|
@ -254,7 +256,7 @@ func TestCreateBasicChain(t *testing.T) {
|
|||
script = io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(script.BinWriter, hash.Hash160(avm), "Put", "testkey", "testvalue")
|
||||
|
||||
txInv := transaction.New(script.Bytes(), 0)
|
||||
txInv := transaction.New(testchain.Network(), script.Bytes(), 0)
|
||||
txInv.Nonce = getNextNonce()
|
||||
txInv.ValidUntilBlock = validUntilBlock
|
||||
txInv.Sender = priv0ScriptHash
|
||||
|
@ -285,7 +287,7 @@ func TestCreateBasicChain(t *testing.T) {
|
|||
sh := hash.Hash160(avm)
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, sh, "init")
|
||||
initTx := transaction.New(w.Bytes(), 0)
|
||||
initTx := transaction.New(testchain.Network(), w.Bytes(), 0)
|
||||
initTx.Nonce = getNextNonce()
|
||||
initTx.ValidUntilBlock = validUntilBlock
|
||||
initTx.Sender = priv0ScriptHash
|
||||
|
@ -375,7 +377,7 @@ func newNEP5Transfer(sc, from, to util.Uint160, amount int64) *transaction.Trans
|
|||
emit.Opcode(w.BinWriter, opcode.ASSERT)
|
||||
|
||||
script := w.Bytes()
|
||||
return transaction.New(script, 0)
|
||||
return transaction.New(testchain.Network(), script, 0)
|
||||
}
|
||||
|
||||
func addSender(txs ...*transaction.Transaction) error {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
|
@ -143,7 +144,7 @@ func TestECDSAVerify(t *testing.T) {
|
|||
chain := newTestChain(t)
|
||||
defer chain.Close()
|
||||
|
||||
ic := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, nil)
|
||||
ic := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil)
|
||||
runCase := func(t *testing.T, isErr bool, result interface{}, args ...interface{}) {
|
||||
v := vm.New()
|
||||
for i := range args {
|
||||
|
@ -177,14 +178,14 @@ func TestECDSAVerify(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("signed interop item", func(t *testing.T) {
|
||||
tx := transaction.New([]byte{0, 1, 2}, 1)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1)
|
||||
msg := tx.GetSignedPart()
|
||||
sign := priv.Sign(msg)
|
||||
runCase(t, false, true, sign, priv.PublicKey().Bytes(), stackitem.NewInterop(tx))
|
||||
})
|
||||
|
||||
t.Run("signed script container", func(t *testing.T) {
|
||||
tx := transaction.New([]byte{0, 1, 2}, 1)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1)
|
||||
msg := tx.GetSignedPart()
|
||||
sign := priv.Sign(msg)
|
||||
ic.Container = tx
|
||||
|
@ -218,7 +219,7 @@ func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
|
|||
v := vm.New()
|
||||
chain := newTestChain(t)
|
||||
context := chain.newInteropContext(trigger.Application,
|
||||
dao.NewSimple(storage.NewMemoryStore()), nil, nil)
|
||||
dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil)
|
||||
return v, context, chain
|
||||
}
|
||||
|
||||
|
@ -232,7 +233,7 @@ func createVMAndBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Bl
|
|||
v := vm.New()
|
||||
block := newDumbBlock()
|
||||
chain := newTestChain(t)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), block, nil)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), block, nil)
|
||||
return v, block, context, chain
|
||||
}
|
||||
|
||||
|
@ -259,7 +260,7 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.C
|
|||
}
|
||||
|
||||
chain := newTestChain(t)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, nil)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil)
|
||||
return v, contractState, context, chain
|
||||
}
|
||||
|
||||
|
@ -271,14 +272,14 @@ func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interop.Context
|
|||
|
||||
require.NoError(t, err)
|
||||
chain := newTestChain(t)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, nil)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil)
|
||||
return v, accountState, context, chain
|
||||
}
|
||||
|
||||
func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
|
||||
v := vm.New()
|
||||
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
|
||||
tx := transaction.New(script, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, script, 0)
|
||||
|
||||
bytes := make([]byte, 1)
|
||||
attributes := append(tx.Attributes, transaction.Attribute{
|
||||
|
@ -288,6 +289,6 @@ func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Con
|
|||
|
||||
tx.Attributes = attributes
|
||||
chain := newTestChain(t)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, tx)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, tx)
|
||||
return v, tx, context, chain
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
|
@ -18,7 +19,7 @@ func testNonInterop(t *testing.T, value interface{}, f func(*interop.Context, *v
|
|||
v.Estack().PushVal(value)
|
||||
chain := newTestChain(t)
|
||||
defer chain.Close()
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, nil)
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil)
|
||||
require.Error(t, f(context, v))
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -30,7 +31,7 @@ func (fs *FeerStub) GetUtilityTokenBalance(uint160 util.Uint160) util.Fixed8 {
|
|||
|
||||
func testMemPoolAddRemoveWithFeer(t *testing.T, fs Feer) {
|
||||
mp := NewMemPool(10)
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = 0
|
||||
_, ok := mp.TryGetValue(tx.Hash())
|
||||
require.Equal(t, false, ok)
|
||||
|
@ -61,7 +62,7 @@ func TestOverCapacity(t *testing.T) {
|
|||
mp := NewMemPool(mempoolSize)
|
||||
|
||||
for i := 0; i < mempoolSize; i++ {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = uint32(i)
|
||||
require.NoError(t, mp.Add(tx, fs))
|
||||
}
|
||||
|
@ -71,7 +72,7 @@ func TestOverCapacity(t *testing.T) {
|
|||
|
||||
// Fees are also prioritized.
|
||||
for i := 0; i < mempoolSize; i++ {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Attributes = append(tx.Attributes, transaction.Attribute{
|
||||
Usage: transaction.Hash1,
|
||||
Data: util.Uint256{1, 2, 3, 4}.BytesBE(),
|
||||
|
@ -85,7 +86,7 @@ func TestOverCapacity(t *testing.T) {
|
|||
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes)))
|
||||
}
|
||||
// Less prioritized txes are not allowed anymore.
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Attributes = append(tx.Attributes, transaction.Attribute{
|
||||
Usage: transaction.Hash1,
|
||||
Data: util.Uint256{1, 2, 3, 4}.BytesBE(),
|
||||
|
@ -98,7 +99,7 @@ func TestOverCapacity(t *testing.T) {
|
|||
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes)))
|
||||
|
||||
// Low net fee, but higher per-byte fee is still a better combination.
|
||||
tx = transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = txcnt
|
||||
tx.NetworkFee = util.Fixed8FromFloat(0.00007)
|
||||
txcnt++
|
||||
|
@ -111,7 +112,7 @@ func TestOverCapacity(t *testing.T) {
|
|||
// High priority always wins over low priority.
|
||||
fs.lowPriority = false
|
||||
for i := 0; i < mempoolSize; i++ {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = txcnt
|
||||
txcnt++
|
||||
require.NoError(t, mp.Add(tx, fs))
|
||||
|
@ -120,7 +121,7 @@ func TestOverCapacity(t *testing.T) {
|
|||
}
|
||||
// Good luck with low priority now.
|
||||
fs.lowPriority = true
|
||||
tx = transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = txcnt
|
||||
require.Error(t, mp.Add(tx, fs))
|
||||
require.Equal(t, mempoolSize, mp.Count())
|
||||
|
@ -134,7 +135,7 @@ func TestGetVerified(t *testing.T) {
|
|||
|
||||
txes := make([]*transaction.Transaction, 0, mempoolSize)
|
||||
for i := 0; i < mempoolSize; i++ {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = uint32(i)
|
||||
txes = append(txes, tx)
|
||||
require.NoError(t, mp.Add(tx, fs))
|
||||
|
@ -158,7 +159,7 @@ func TestRemoveStale(t *testing.T) {
|
|||
txes1 := make([]*transaction.Transaction, 0, mempoolSize/2)
|
||||
txes2 := make([]*transaction.Transaction, 0, mempoolSize/2)
|
||||
for i := 0; i < mempoolSize; i++ {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = uint32(i)
|
||||
if i%2 == 0 {
|
||||
txes1 = append(txes1, tx)
|
||||
|
@ -187,7 +188,7 @@ func TestRemoveStale(t *testing.T) {
|
|||
func TestMemPoolFees(t *testing.T) {
|
||||
mp := NewMemPool(10)
|
||||
sender0 := util.Uint160{1, 2, 3}
|
||||
tx0 := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx0 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx0.NetworkFee = util.Fixed8FromInt64(11000)
|
||||
tx0.Sender = sender0
|
||||
// insufficient funds to add transaction, but balance should be stored
|
||||
|
@ -200,7 +201,7 @@ func TestMemPoolFees(t *testing.T) {
|
|||
}, mp.fees[sender0])
|
||||
|
||||
// no problems with adding another transaction with lower fee
|
||||
tx1 := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx1 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx1.NetworkFee = util.Fixed8FromInt64(7000)
|
||||
tx1.Sender = sender0
|
||||
require.NoError(t, mp.Add(tx1, &FeerStub{}))
|
||||
|
@ -211,7 +212,7 @@ func TestMemPoolFees(t *testing.T) {
|
|||
}, mp.fees[sender0])
|
||||
|
||||
// balance shouldn't change after adding one more transaction
|
||||
tx2 := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx2 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx2.NetworkFee = util.Fixed8FromFloat(3000)
|
||||
tx2.Sender = sender0
|
||||
require.NoError(t, mp.Add(tx2, &FeerStub{}))
|
||||
|
@ -223,7 +224,7 @@ func TestMemPoolFees(t *testing.T) {
|
|||
}, mp.fees[sender0])
|
||||
|
||||
// can't add more transactions as we don't have enough GAS
|
||||
tx3 := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx3 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx3.NetworkFee = util.Fixed8FromFloat(0.5)
|
||||
tx3.Sender = sender0
|
||||
require.Equal(t, false, mp.Verify(tx3, &FeerStub{}))
|
||||
|
|
|
@ -92,7 +92,7 @@ func TestNativeContract_Invoke(t *testing.T) {
|
|||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28))
|
||||
script := w.Bytes()
|
||||
tx := transaction.New(script, 0)
|
||||
tx := transaction.New(chain.GetConfig().Magic, script, 0)
|
||||
validUntil := chain.blockHeight + 1
|
||||
tx.ValidUntilBlock = validUntil
|
||||
require.NoError(t, addSender(tx))
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -16,7 +17,7 @@ var (
|
|||
func decodeTransaction(rawTX string, t *testing.T) *Transaction {
|
||||
b, err1 := hex.DecodeString(rawTX)
|
||||
assert.Nil(t, err1)
|
||||
tx, err := NewTransactionFromBytes(b)
|
||||
tx, err := NewTransactionFromBytes(netmode.UnitTestNet, b)
|
||||
assert.NoError(t, err)
|
||||
return tx
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"math/rand"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -58,6 +59,11 @@ type Transaction struct {
|
|||
// and invocation script.
|
||||
Scripts []Witness
|
||||
|
||||
// Network magic number. This one actually is not a part of the
|
||||
// wire-representation of Transaction, but it's absolutely necessary
|
||||
// for correct signing/verification.
|
||||
Network netmode.Magic
|
||||
|
||||
// Hash of the transaction (double SHA256).
|
||||
hash util.Uint256
|
||||
|
||||
|
@ -80,7 +86,7 @@ func NewTrimmedTX(hash util.Uint256) *Transaction {
|
|||
|
||||
// New returns a new transaction to execute given script and pay given system
|
||||
// fee.
|
||||
func New(script []byte, gas util.Fixed8) *Transaction {
|
||||
func New(network netmode.Magic, script []byte, gas util.Fixed8) *Transaction {
|
||||
return &Transaction{
|
||||
Version: 0,
|
||||
Nonce: rand.Uint32(),
|
||||
|
@ -89,6 +95,7 @@ func New(script []byte, gas util.Fixed8) *Transaction {
|
|||
Attributes: []Attribute{},
|
||||
Cosigners: []Cosigner{},
|
||||
Scripts: []Witness{},
|
||||
Network: network,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,8 +119,9 @@ func (t *Transaction) VerificationHash() util.Uint256 {
|
|||
return t.verificationHash
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (t *Transaction) DecodeBinary(br *io.BinReader) {
|
||||
// decodeHashableFields decodes the fields that are used for signing the
|
||||
// transaction, which are all fields except the scripts.
|
||||
func (t *Transaction) decodeHashableFields(br *io.BinReader) {
|
||||
t.Version = uint8(br.ReadB())
|
||||
if t.Version > 0 {
|
||||
br.Err = errors.New("only version 0 is supported")
|
||||
|
@ -154,7 +162,14 @@ func (t *Transaction) DecodeBinary(br *io.BinReader) {
|
|||
br.Err = errors.New("no script")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (t *Transaction) DecodeBinary(br *io.BinReader) {
|
||||
t.decodeHashableFields(br)
|
||||
if br.Err != nil {
|
||||
return
|
||||
}
|
||||
br.ReadArray(&t.Scripts)
|
||||
|
||||
// Create the hash of the transaction at decode, so we dont need
|
||||
|
@ -195,22 +210,25 @@ func (t *Transaction) encodeHashableFields(bw *io.BinWriter) {
|
|||
|
||||
// createHash creates the hash of the transaction.
|
||||
func (t *Transaction) createHash() error {
|
||||
buf := io.NewBufBinWriter()
|
||||
t.encodeHashableFields(buf.BinWriter)
|
||||
if buf.Err != nil {
|
||||
return buf.Err
|
||||
b := t.GetSignedPart()
|
||||
if b == nil {
|
||||
return errors.New("failed to serialize hashable data")
|
||||
}
|
||||
t.updateHashes(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
b := buf.Bytes()
|
||||
// updateHashes updates Transaction's hashes based on the given buffer which should
|
||||
// be a signable data slice.
|
||||
func (t *Transaction) updateHashes(b []byte) {
|
||||
t.verificationHash = hash.Sha256(b)
|
||||
t.hash = hash.Sha256(t.verificationHash.BytesBE())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignedPart returns a part of the transaction which must be signed.
|
||||
func (t *Transaction) GetSignedPart() []byte {
|
||||
buf := io.NewBufBinWriter()
|
||||
buf.WriteU32LE(uint32(t.Network))
|
||||
t.encodeHashableFields(buf.BinWriter)
|
||||
if buf.Err != nil {
|
||||
return nil
|
||||
|
@ -218,6 +236,24 @@ func (t *Transaction) GetSignedPart() []byte {
|
|||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// DecodeSignedPart decodes a part of transaction from GetSignedPart data.
|
||||
func (t *Transaction) DecodeSignedPart(buf []byte) error {
|
||||
r := io.NewBinReaderFromBuf(buf)
|
||||
t.Network = netmode.Magic(r.ReadU32LE())
|
||||
t.decodeHashableFields(r)
|
||||
if r.Err != nil {
|
||||
return r.Err
|
||||
}
|
||||
// Ensure all the data was read.
|
||||
_ = r.ReadB()
|
||||
if r.Err == nil {
|
||||
return errors.New("additional data after the signed part")
|
||||
}
|
||||
t.Scripts = make([]Witness, 0)
|
||||
t.updateHashes(buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bytes converts the transaction to []byte
|
||||
func (t *Transaction) Bytes() []byte {
|
||||
buf := io.NewBufBinWriter()
|
||||
|
@ -229,8 +265,8 @@ func (t *Transaction) Bytes() []byte {
|
|||
}
|
||||
|
||||
// NewTransactionFromBytes decodes byte array into *Transaction
|
||||
func NewTransactionFromBytes(b []byte) (*Transaction, error) {
|
||||
tx := &Transaction{}
|
||||
func NewTransactionFromBytes(network netmode.Magic, b []byte) (*Transaction, error) {
|
||||
tx := &Transaction{Network: network}
|
||||
r := io.NewBinReaderFromBuf(b)
|
||||
tx.DecodeBinary(r)
|
||||
if r.Err != nil {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -63,12 +64,12 @@ func TestDecodeEncodeInvocationTX(t *testing.T) {
|
|||
|
||||
func TestNew(t *testing.T) {
|
||||
script := []byte{0x51}
|
||||
tx := New(script, 1)
|
||||
tx := New(netmode.UnitTestNet, script, 1)
|
||||
assert.Equal(t, util.Fixed8(1), tx.SystemFee)
|
||||
assert.Equal(t, script, tx.Script)
|
||||
// Update hash fields to match tx2 that is gonna autoupdate them on decode.
|
||||
_ = tx.Hash()
|
||||
testserdes.EncodeDecodeBinary(t, tx, new(Transaction))
|
||||
testserdes.EncodeDecodeBinary(t, tx, &Transaction{Network: netmode.UnitTestNet})
|
||||
}
|
||||
|
||||
func TestEncodingTXWithNoScript(t *testing.T) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
|
@ -53,12 +54,13 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
|
|||
InvocationScript: []byte{},
|
||||
VerificationScript: []byte{byte(opcode.PUSH1)},
|
||||
},
|
||||
Network: cfg.Magic,
|
||||
}
|
||||
|
||||
b := &block.Block{
|
||||
Base: base,
|
||||
Transactions: []*transaction.Transaction{
|
||||
deployNativeContracts(),
|
||||
deployNativeContracts(cfg.Magic),
|
||||
},
|
||||
ConsensusData: block.ConsensusData{
|
||||
PrimaryIndex: 0,
|
||||
|
@ -73,11 +75,11 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
|
|||
return b, nil
|
||||
}
|
||||
|
||||
func deployNativeContracts() *transaction.Transaction {
|
||||
func deployNativeContracts(magic netmode.Magic) *transaction.Transaction {
|
||||
buf := io.NewBufBinWriter()
|
||||
emit.Syscall(buf.BinWriter, "Neo.Native.Deploy")
|
||||
script := buf.Bytes()
|
||||
tx := transaction.New(script, 0)
|
||||
tx := transaction.New(magic, script, 0)
|
||||
tx.Nonce = 0
|
||||
tx.Sender = hash.Hash160([]byte{byte(opcode.PUSH1)})
|
||||
tx.Scripts = []transaction.Witness{
|
||||
|
|
|
@ -4,13 +4,14 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGenesisBlockMainNet(t *testing.T) {
|
||||
cfg, err := config.Load("../../config", config.ModeMainNet)
|
||||
cfg, err := config.Load("../../config", netmode.MainNet)
|
||||
require.NoError(t, err)
|
||||
|
||||
block, err := createGenesisBlock(cfg.ProtocolConfiguration)
|
||||
|
@ -20,7 +21,7 @@ func TestGenesisBlockMainNet(t *testing.T) {
|
|||
// have been changed. Consequently, hash of the genesis block has been changed.
|
||||
// Update expected genesis block hash for better times.
|
||||
// Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf"
|
||||
expect := "e4cfc549c87d4ab7b570c368d05853ffb70eb9ef0f7d9c7a2e6e9e5d713ebbf4"
|
||||
expect := "dba446947a90b2862ef050703b44828ad8b02d11978f8ef59bd3e1c97aabf6e5"
|
||||
assert.Equal(t, expect, block.Hash().StringLE())
|
||||
}
|
||||
|
||||
|
@ -30,7 +31,7 @@ func TestGetConsensusAddressMainNet(t *testing.T) {
|
|||
consensusScript = "72c3d9b3bbf776698694cd2c73fa597a10c31294"
|
||||
)
|
||||
|
||||
cfg, err := config.Load("../../config", config.ModeMainNet)
|
||||
cfg, err := config.Load("../../config", netmode.MainNet)
|
||||
require.NoError(t, err)
|
||||
|
||||
validators, err := getValidators(cfg.ProtocolConfiguration)
|
||||
|
|
|
@ -4,3 +4,10 @@ package crypto
|
|||
type Verifiable interface {
|
||||
GetSignedPart() []byte
|
||||
}
|
||||
|
||||
// VerifiableDecodable represents an object which can be both verified and
|
||||
// decoded from given data.
|
||||
type VerifiableDecodable interface {
|
||||
Verifiable
|
||||
DecodeSignedPart([]byte) error
|
||||
}
|
||||
|
|
8
pkg/internal/testchain/network.go
Normal file
8
pkg/internal/testchain/network.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package testchain
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
|
||||
// Network returns test chain network's magic number.
|
||||
func Network() netmode.Magic {
|
||||
return netmode.UnitTestNet
|
||||
}
|
|
@ -1,33 +1,29 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/pierrec/lz4"
|
||||
)
|
||||
|
||||
// compress compresses bytes using lz4.
|
||||
func compress(source []byte) ([]byte, error) {
|
||||
dest := new(bytes.Buffer)
|
||||
w := lz4.NewWriter(dest)
|
||||
_, err := io.Copy(w, bytes.NewReader(source))
|
||||
dest := make([]byte, lz4.CompressBlockBound(len(source)))
|
||||
size, err := lz4.CompressBlock(source, dest, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if w.Close() != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dest.Bytes(), nil
|
||||
return dest[:size], nil
|
||||
}
|
||||
|
||||
// decompress decompresses bytes using lz4.
|
||||
func decompress(source []byte) ([]byte, error) {
|
||||
dest := new(bytes.Buffer)
|
||||
r := lz4.NewReader(bytes.NewReader(source))
|
||||
_, err := io.Copy(dest, r)
|
||||
maxSize := len(source) * 255
|
||||
if maxSize > PayloadMaxSize {
|
||||
maxSize = PayloadMaxSize
|
||||
}
|
||||
dest := make([]byte, maxSize)
|
||||
size, err := lz4.UncompressBlock(source, dest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dest.Bytes(), nil
|
||||
return dest[:size], nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/consensus"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -33,6 +34,10 @@ type Message struct {
|
|||
|
||||
// Compressed message payload.
|
||||
compressedPayload []byte
|
||||
|
||||
// Network this message comes from, it has to be set upon Message
|
||||
// creation for correct decoding.
|
||||
Network netmode.Magic
|
||||
}
|
||||
|
||||
// MessageFlag represents compression level of message payload
|
||||
|
@ -40,8 +45,8 @@ type MessageFlag byte
|
|||
|
||||
// Possible message flags
|
||||
const (
|
||||
None MessageFlag = 0
|
||||
Compressed MessageFlag = 1 << iota
|
||||
None MessageFlag = 0
|
||||
)
|
||||
|
||||
// CommandType represents the type of a message command.
|
||||
|
@ -83,7 +88,8 @@ const (
|
|||
CMDAlert CommandType = 0x40
|
||||
)
|
||||
|
||||
// NewMessage returns a new message with the given payload.
|
||||
// NewMessage returns a new message with the given payload. It's intended to be
|
||||
// used for messages to be sent, thus it doesn't care much about the Network.
|
||||
func NewMessage(cmd CommandType, p payload.Payload) *Message {
|
||||
return &Message{
|
||||
Command: cmd,
|
||||
|
@ -103,14 +109,14 @@ func (m *Message) Decode(br *io.BinReader) error {
|
|||
m.Payload = payload.NewNullPayload()
|
||||
return nil
|
||||
}
|
||||
if l > PayloadMaxSize {
|
||||
return errors.New("invalid payload size")
|
||||
}
|
||||
m.compressedPayload = make([]byte, l)
|
||||
br.ReadBytes(m.compressedPayload)
|
||||
if br.Err != nil {
|
||||
return br.Err
|
||||
}
|
||||
if len(m.compressedPayload) > PayloadMaxSize {
|
||||
return errors.New("invalid payload size")
|
||||
}
|
||||
return m.decodePayload()
|
||||
}
|
||||
|
||||
|
@ -135,7 +141,7 @@ func (m *Message) decodePayload() error {
|
|||
case CMDAddr:
|
||||
p = &payload.AddressList{}
|
||||
case CMDBlock:
|
||||
p = &block.Block{}
|
||||
p = block.New(m.Network)
|
||||
case CMDConsensus:
|
||||
p = &consensus.Payload{}
|
||||
case CMDGetBlocks:
|
||||
|
@ -145,9 +151,9 @@ func (m *Message) decodePayload() error {
|
|||
case CMDGetBlockData:
|
||||
p = &payload.GetBlockData{}
|
||||
case CMDHeaders:
|
||||
p = &payload.Headers{}
|
||||
p = &payload.Headers{Network: m.Network}
|
||||
case CMDTX:
|
||||
p = &transaction.Transaction{}
|
||||
p = &transaction.Transaction{Network: m.Network}
|
||||
case CMDMerkleBlock:
|
||||
p = &payload.MerkleBlock{}
|
||||
case CMDPing, CMDPong:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package payload
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -8,7 +9,8 @@ import (
|
|||
|
||||
// Headers payload.
|
||||
type Headers struct {
|
||||
Hdrs []*block.Header
|
||||
Hdrs []*block.Header
|
||||
Network netmode.Magic
|
||||
}
|
||||
|
||||
// Users can at most request 2k header.
|
||||
|
@ -34,6 +36,7 @@ func (p *Headers) DecodeBinary(br *io.BinReader) {
|
|||
|
||||
for i := 0; i < int(lenHeaders); i++ {
|
||||
header := &block.Header{}
|
||||
header.Network = p.Network
|
||||
header.DecodeBinary(br)
|
||||
p.Hdrs[i] = header
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package payload
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/network/capability"
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ import (
|
|||
// Version payload.
|
||||
type Version struct {
|
||||
// NetMode of the node
|
||||
Magic config.NetMode
|
||||
Magic netmode.Magic
|
||||
// currently the version of the protocol is 0
|
||||
Version uint32
|
||||
// timestamp
|
||||
|
@ -25,7 +25,7 @@ type Version struct {
|
|||
}
|
||||
|
||||
// NewVersion returns a pointer to a Version payload.
|
||||
func NewVersion(magic config.NetMode, id uint32, ua string, c []capability.Capability) *Version {
|
||||
func NewVersion(magic netmode.Magic, id uint32, ua string, c []capability.Capability) *Version {
|
||||
return &Version{
|
||||
Magic: magic,
|
||||
Version: 0,
|
||||
|
@ -38,7 +38,7 @@ func NewVersion(magic config.NetMode, id uint32, ua string, c []capability.Capab
|
|||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (p *Version) DecodeBinary(br *io.BinReader) {
|
||||
p.Magic = config.NetMode(br.ReadU32LE())
|
||||
p.Magic = netmode.Magic(br.ReadU32LE())
|
||||
p.Version = br.ReadU32LE()
|
||||
p.Timestamp = br.ReadU32LE()
|
||||
p.Nonce = br.ReadU32LE()
|
||||
|
|
|
@ -3,14 +3,14 @@ package payload
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
||||
"github.com/nspcc-dev/neo-go/pkg/network/capability"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestVersionEncodeDecode(t *testing.T) {
|
||||
var magic config.NetMode = 56753
|
||||
var magic netmode.Magic = 56753
|
||||
var tcpPort uint16 = 3000
|
||||
var wsPort uint16 = 3001
|
||||
var id uint32 = 13337
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/consensus"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
|
@ -53,6 +54,9 @@ type (
|
|||
// id also known as the nonce of the server.
|
||||
id uint32
|
||||
|
||||
// Network's magic number for correct message decoding.
|
||||
network netmode.Magic
|
||||
|
||||
transport Transporter
|
||||
discovery Discoverer
|
||||
chain blockchainer.Blockchainer
|
||||
|
@ -95,6 +99,7 @@ func NewServer(config ServerConfig, chain blockchainer.Blockchainer, log *zap.Lo
|
|||
ServerConfig: config,
|
||||
chain: chain,
|
||||
id: randomID(),
|
||||
network: chain.GetConfig().Magic,
|
||||
quit: make(chan struct{}),
|
||||
register: make(chan Peer),
|
||||
unregister: make(chan peerDrop),
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
@ -38,7 +39,7 @@ type (
|
|||
// ModePrivNet docker private network.
|
||||
// ModeTestNet NEO test network.
|
||||
// ModeMainNet NEO main network.
|
||||
Net config.NetMode
|
||||
Net netmode.Magic
|
||||
|
||||
// Relay determines whether the server is forwarding its inventory.
|
||||
Relay bool
|
||||
|
|
|
@ -150,7 +150,7 @@ func (p *TCPPeer) handleConn() {
|
|||
if err == nil {
|
||||
r := io.NewBinReaderFromIO(p.conn)
|
||||
for {
|
||||
msg := &Message{}
|
||||
msg := &Message{Network: p.server.network}
|
||||
err = msg.Decode(r)
|
||||
|
||||
if err == payload.ErrTooManyHeaders {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
||||
|
@ -49,6 +50,7 @@ type Options struct {
|
|||
CACert string
|
||||
DialTimeout time.Duration
|
||||
RequestTimeout time.Duration
|
||||
Network netmode.Magic
|
||||
}
|
||||
|
||||
// cache stores cache values for the RPC client methods
|
||||
|
|
|
@ -5,13 +5,14 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
endpoint := "http://seed5.bridgeprotocol.io:10332"
|
||||
opts := client.Options{}
|
||||
opts := client.Options{Network: netmode.MainNet}
|
||||
|
||||
c, err := client.New(context.TODO(), endpoint, opts)
|
||||
if err != nil {
|
||||
|
|
|
@ -109,7 +109,7 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke
|
|||
emit.Opcode(w.BinWriter, opcode.ASSERT)
|
||||
|
||||
script := w.Bytes()
|
||||
tx := transaction.New(script, gas)
|
||||
tx := transaction.New(c.opts.Network, script, gas)
|
||||
tx.Sender = from
|
||||
tx.Cosigners = []transaction.Cosigner{
|
||||
{
|
||||
|
|
|
@ -72,7 +72,7 @@ func (c *Client) getBlock(params request.RawParams) (*block.Block, error) {
|
|||
return nil, err
|
||||
}
|
||||
r := io.NewBinReaderFromBuf(blockBytes)
|
||||
b = new(block.Block)
|
||||
b = block.New(c.opts.Network)
|
||||
b.DecodeBinary(r)
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
|
@ -98,6 +98,7 @@ func (c *Client) getBlockVerbose(params request.RawParams) (*result.Block, error
|
|||
resp = &result.Block{}
|
||||
err error
|
||||
)
|
||||
resp.Network = c.opts.Network
|
||||
if err = c.performRequest("getblock", params, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -133,6 +134,7 @@ func (c *Client) GetBlockHeader(hash util.Uint256) (*block.Header, error) {
|
|||
}
|
||||
r := io.NewBinReaderFromBuf(headerBytes)
|
||||
h = new(block.Header)
|
||||
h.Network = c.opts.Network
|
||||
h.DecodeBinary(r)
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
|
@ -247,7 +249,7 @@ func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tx, err := transaction.NewTransactionFromBytes(txBytes)
|
||||
tx, err := transaction.NewTransactionFromBytes(c.opts.Network, txBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -263,6 +265,7 @@ func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.Transactio
|
|||
resp = &result.TransactionOutputRaw{}
|
||||
err error
|
||||
)
|
||||
resp.Network = c.opts.Network
|
||||
if err = c.performRequest("getrawtransaction", params, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -421,7 +424,7 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys
|
|||
var txHash util.Uint256
|
||||
var err error
|
||||
|
||||
tx := transaction.New(script, sysfee)
|
||||
tx := transaction.New(c.opts.Network, script, sysfee)
|
||||
tx.SystemFee = sysfee
|
||||
|
||||
validUntilBlock, err := c.CalculateValidUntilBlock()
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -35,17 +36,17 @@ type rpcClientTestCase struct {
|
|||
check func(t *testing.T, c *Client, result interface{})
|
||||
}
|
||||
|
||||
const hexB1 = "00000000e862e7907fc987cd58ddb3abb754aeb8812c9377c45e737a036fe88a622c3b8f301f2e84a86b207270830e7929530ccb841a3df7379fe6f0ac8865b33316839501cdd0847201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c40ab634ce91590e77b246cee8b204e8a270268ee1ef32434cece73f425a7dbc90f1bed1dbe914edcaa2653167ad170ae10e16a9b2c6b7e0af1f711fb848fbb1b7f0c40232de6ad07ee3846bafa96302d37602349501a556df575e7df0743e45b076d6a0c6c6dd4cad3898f9e8848dd054abd303b229fd12984042f241f0e668f39a0fb0c408b4af43057df189a9d471010b5150bab442040403147c5e502bda38cde3ff8bce803f01245e07e2bfb95d57349c55dcc27e3710b82f2735d0f40eb4342908e330c40cda66f743d4ed8d856f5376953f9169581c668a9370245aef16202ebef9bb3f7f81234be62ec287d701ad7d8bf5042648019af9fe5baa0a8e05d279bfdb1d4c994130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb030057040000000000000002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c402d96d8fde4ba266f89bc71ef117361967e0d11ed84cd60942a27bc99994dc58adf36a0e74ce976aac657a87a3c19c38e8ca450c67420046b81d98c60fd8feb040c40b3c15d5d23e0403a36cf559caee2979ca6ef00fe255df0e5c3daac4da051016b41eba42668934cd3308359451bafdd5419d059179fd40859684a3b91388bf9d80c407ac048cf8540b091955a374a0f36dae560c92c0134886507a589edf58b9dfbb4e3dbd5450be34e269d2e5454eb14eb7d6280d6101b4529410f829d37634849be0c403bba4113a687ff8507c1753f8519557531cf9df51ecc20deeb2c2b003ec5a1f7588cdd50b99e40b4f8039bb56c5df7ec9e7d6ea4b02fe23792510da21c7557f394130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb0003000000abec5362f11e75b6e02e407bb98d63675d1438410000000000000000de6e0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d143841015d0300e87648170000000c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b523801fd08010c4063fb12aa9f3fb83f6324ea9c7ec11fa9e995b51140f480409d68cf4d625e598b0632d6610602984bfa2f5e5ea9bcc62a0e6d818dd271b38530c0d1b8a71b4e0c0c4013e091eac6f304668d647c5c032fd1020597ea5204545e21c38655a6343d58492118f1231ede91af848af7e1d987d1a8816966f5fc1a7821c6c6f62734267bde0c40daadd04a7a4141d96c58de2d373e672ca071e2b82138ef52df016ac522710385db2ac73743d2fe73061fa5d6cb0ff73a7ec7f0667e4c8bff6aa0d5783128d36e0c40dab85cd87d3f92be9532292bdc6f420b0ecbf2f877c70c6a9921ee0fc900dfc53998cf020a51fa9af3d0608f6a2b9048cea3c0b586485802bbd278b261eee8a494130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb"
|
||||
const hexB1 = "000000008aaab19c43c4ca2870c3e616b123f1b689866f44b138ae4d6a5352e54442fd56401107247de4e35599d1feffaf6e763972f738d2858b0a22ad06523867e4dcf921f7c1c67201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c400f01eb6371a135527ddb205a0dae1f69d2d324837cce128bead9033091883f9ce21e6d759a40f690746592b021d397f088e3b7b417fcef73cd1bfdc2800769520c4084f7ae5d9f58a09aa56eeb2f282744a59a82d17e3be0eb1c7f54e6e8df79620e2608191bac57280a836db2ec2a776d07e43f16bc76c47d348b0fcd09d56c7c320c402b95b4e39ec35162a640795ff223e92dec95390a072eb457f6a4323052f80731517e0df029e4a457204f777f5261c6a4a88d46d4c3abdec635a6eed580d6c77f0c40b9735745b1dd795a258c31d8e6fa87d5cfc2e9b3a4890d610d33bcf833b64c58b0c5cea17f3a7128f1065ed193e636971590f193f28bdd1eeebbbc1fe6e7cee594130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb030057040000000000000002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c40ae6fc04fe4b6c22218ca9617c98d607d9ec9b1faf8cfdc3391bec485ae76b11adc6cc6abeb31a50b536ea8073e674d62a5566fce5e0a0ceb0718cb971c1ae3d00c40603071b725a58d052cad7afd88e99b27baab931afd5bb50d16e224335aab450170aabe251d3c0c6ad3f31dd7e9b89b209baabe5a1e2fa588bd8118f9e2a6960f0c40d72afcf39e663dba2d70fb8c36a09d1a6a6ad0d2fd38c857a8e7dc71e2b98711324e0d2ec641fe6896ba63ba80d3ea341c1aad11e082fb188ee07e215b4031b10c409afb2808b60286a56343b7ffcef28bb2ab0c595603e7323b5e5b0b9c1c10edfa5c40754d921865cb6fd71668a206b37a1eb10c0029a9fcd3a856aed07742cd3f94130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb0003000000abec5362f11e75b6e02e407bb98d63675d1438410000000000000000de6e0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d143841015d0300e87648170000000c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b523801fd08010c408710e7b5d8ac6cd8d09d6fb35bf2dcce5f5fb38595ddb6d04a570bc925bc2c55a73cdf5f3cb5a1feb0acc4f26c8bbca6c43df3b4a98b8c3c2c809c2f096eb25a0c40c186c102cbf72313fd94df5077fc5bbefcd32227ed2159a47a46594877fa39f330d8223b45aa24aff005bebb5b2427a50c8c4de8618e7d7b00d73d836c44942e0c40a243b5b565bd4bc2f0bb112f7624f6b3514c12413c5a95230819face3f760f03fcb96b188f98038a3f251686b53a88d69744f4e4a985e6297003a80cdb169e800c404a951e61ac99d5ee31831d111754adb711b4a9060a9524fe383a90771843cdb096382674027a87f2a15a83bd77deb2b2ab1fe8b3de6e546293ef3df9b1129e2894130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb"
|
||||
|
||||
const hexTxMoveNeo = "0002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c402d96d8fde4ba266f89bc71ef117361967e0d11ed84cd60942a27bc99994dc58adf36a0e74ce976aac657a87a3c19c38e8ca450c67420046b81d98c60fd8feb040c40b3c15d5d23e0403a36cf559caee2979ca6ef00fe255df0e5c3daac4da051016b41eba42668934cd3308359451bafdd5419d059179fd40859684a3b91388bf9d80c407ac048cf8540b091955a374a0f36dae560c92c0134886507a589edf58b9dfbb4e3dbd5450be34e269d2e5454eb14eb7d6280d6101b4529410f829d37634849be0c403bba4113a687ff8507c1753f8519557531cf9df51ecc20deeb2c2b003ec5a1f7588cdd50b99e40b4f8039bb56c5df7ec9e7d6ea4b02fe23792510da21c7557f394130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb"
|
||||
const hexTxMoveNeo = "0002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c40ae6fc04fe4b6c22218ca9617c98d607d9ec9b1faf8cfdc3391bec485ae76b11adc6cc6abeb31a50b536ea8073e674d62a5566fce5e0a0ceb0718cb971c1ae3d00c40603071b725a58d052cad7afd88e99b27baab931afd5bb50d16e224335aab450170aabe251d3c0c6ad3f31dd7e9b89b209baabe5a1e2fa588bd8118f9e2a6960f0c40d72afcf39e663dba2d70fb8c36a09d1a6a6ad0d2fd38c857a8e7dc71e2b98711324e0d2ec641fe6896ba63ba80d3ea341c1aad11e082fb188ee07e215b4031b10c409afb2808b60286a56343b7ffcef28bb2ab0c595603e7323b5e5b0b9c1c10edfa5c40754d921865cb6fd71668a206b37a1eb10c0029a9fcd3a856aed07742cd3f94130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb"
|
||||
|
||||
const b1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"size":1681,"nextblockhash":"0xf2afe371a27c9dbac4f4a8ad8eba750898b7c04aa298e64fe9e488e947976045","confirmations":6,"hash":"0xbd178d8d4a28ec082c034f817ce2423221281a31e7e00014dbf732c4053033d2","version":0,"previousblockhash":"0x8f3b2c628ae86f037a735ec477932c81b8ae54b7abb3dd58cd87c97f90e762e8","merkleroot":"0x95831633b36588acf0e69f37f73d1a84cb0c5329790e837072206ba8842e1f30","time":1591366176001,"index":1,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DECrY0zpFZDneyRs7osgToonAmjuHvMkNM7Oc/Qlp9vJDxvtHb6RTtyqJlMWetFwrhDhapssa34K8fcR+4SPuxt/DEAjLeatB+44Rrr6ljAtN2AjSVAaVW31deffB0PkWwdtagxsbdTK04mPnohI3QVKvTA7Ip/RKYQELyQfDmaPOaD7DECLSvQwV98Ymp1HEBC1FQurRCBAQDFHxeUCvaOM3j/4vOgD8BJF4H4r+5XVc0nFXcwn43ELgvJzXQ9A60NCkI4zDEDNpm90PU7Y2Fb1N2lT+RaVgcZoqTcCRa7xYgLr75uz9/gSNL5i7Ch9cBrX2L9QQmSAGa+f5bqgqOBdJ5v9sdTJ","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"consensus_data":{"primary":0,"nonce":"0000000000000457"},"tx":[{"txid":"0x8af9ccb8e7e0f0a73e77b78dc52750e77c50f78b09ecc2f0669c0b459cc7dd89","size":575,"version":0,"nonce":2,"sender":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","sys_fee":"0","net_fee":"0.0087635","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x4138145d67638db97b402ee0b6751ef16253ecab","scopes":"CalledByEntry"}],"script":"Ahjd9QUMFDFuhRA5AZ0538LDfWw/7hn9WAmHDBSr7FNi8R51tuAuQHu5jWNnXRQ4QRPADAh0cmFuc2ZlcgwUiXcg2M129PAKv6N8Dt2InCCP3ptBYn1bUjg=","scripts":[{"invocation":"DEAtltj95Lomb4m8ce8Rc2GWfg0R7YTNYJQqJ7yZmU3Fit82oOdM6XaqxleoejwZw46MpFDGdCAEa4HZjGD9j+sEDECzwV1dI+BAOjbPVZyu4pecpu8A/iVd8OXD2qxNoFEBa0HrpCZok0zTMINZRRuv3VQZ0FkXn9QIWWhKO5E4i/nYDEB6wEjPhUCwkZVaN0oPNtrlYMksATSIZQelie31i537tOPb1UUL404mnS5UVOsU631igNYQG0UpQQ+CnTdjSEm+DEA7ukETpof/hQfBdT+FGVV1Mc+d9R7MIN7rLCsAPsWh91iM3VC5nkC0+AObtWxd9+yefW6ksC/iN5JRDaIcdVfz","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}]},{"txid":"0xe7cff9e4820e53232dae619a3e6f57a9430dc240b5ed7b5c0ea2cfee3e90c985","size":579,"version":0,"nonce":3,"sender":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","sys_fee":"0","net_fee":"0.0088035","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x4138145d67638db97b402ee0b6751ef16253ecab","scopes":"CalledByEntry"}],"script":"AwDodkgXAAAADBQxboUQOQGdOd/Cw31sP+4Z/VgJhwwUq+xTYvEedbbgLkB7uY1jZ10UOEETwAwIdHJhbnNmZXIMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1I4","scripts":[{"invocation":"DEBj+xKqnz+4P2Mk6px+wR+p6ZW1EUD0gECdaM9NYl5ZiwYy1mEGAphL+i9eXqm8xioObYGN0nGzhTDA0binG04MDEAT4JHqxvMEZo1kfFwDL9ECBZfqUgRUXiHDhlWmND1YSSEY8SMe3pGvhIr34dmH0aiBaWb1/Bp4IcbG9ic0JnveDEDardBKekFB2WxY3i03PmcsoHHiuCE471LfAWrFInEDhdsqxzdD0v5zBh+l1ssP9zp+x/BmfkyL/2qg1XgxKNNuDEDauFzYfT+SvpUyKSvcb0ILDsvy+HfHDGqZIe4PyQDfxTmYzwIKUfqa89Bgj2orkEjOo8C1hkhYArvSeLJh7uik","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}]}]}}`
|
||||
const b1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"size":1681,"nextblockhash":"0x45f62d72e37b074ecdc9f687222b0f91ec98d6d9af4429a2caa2e076a9196b0d","confirmations":6,"hash":"0x4f2c5539b0213ea444608cc217c5cb191255c1858ccd051ad9a36f08df26a288","version":0,"previousblockhash":"0x56fd4244e552536a4dae38b1446f8689b6f123b116e6c37028cac4439cb1aa8a","merkleroot":"0xf9dce467385206ad220a8b85d238f77239766eaffffed19955e3e47d24071140","time":1592472500001,"index":1,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DEAPAetjcaE1Un3bIFoNrh9p0tMkg3zOEovq2QMwkYg/nOIebXWaQPaQdGWSsCHTl/CI47e0F/zvc80b/cKAB2lSDECE965dn1igmqVu6y8oJ0SlmoLRfjvg6xx/VObo33liDiYIGRusVygKg22y7Cp3bQfkPxa8dsR9NIsPzQnVbHwyDEArlbTjnsNRYqZAeV/yI+kt7JU5CgcutFf2pDIwUvgHMVF+DfAp5KRXIE93f1JhxqSojUbUw6vexjWm7tWA1sd/DEC5c1dFsd15WiWMMdjm+ofVz8Lps6SJDWENM7z4M7ZMWLDFzqF/OnEo8QZe0ZPmNpcVkPGT8ovdHu67vB/m587l","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"consensus_data":{"primary":0,"nonce":"0000000000000457"},"tx":[{"txid":"0x7fb05b593cf4b1eb2d9a283c5488ca1bfe61191b5775bafa43b8647e7b20f22c","size":575,"version":0,"nonce":2,"sender":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","sys_fee":"0","net_fee":"0.0087635","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x4138145d67638db97b402ee0b6751ef16253ecab","scopes":"CalledByEntry"}],"script":"Ahjd9QUMFDFuhRA5AZ0538LDfWw/7hn9WAmHDBSr7FNi8R51tuAuQHu5jWNnXRQ4QRPADAh0cmFuc2ZlcgwUiXcg2M129PAKv6N8Dt2InCCP3ptBYn1bUjg=","scripts":[{"invocation":"DECub8BP5LbCIhjKlhfJjWB9nsmx+vjP3DORvsSFrnaxGtxsxqvrMaULU26oBz5nTWKlVm/OXgoM6wcYy5ccGuPQDEBgMHG3JaWNBSytev2I6ZsnuquTGv1btQ0W4iQzWqtFAXCqviUdPAxq0/Md1+m4myCbqr5aHi+liL2BGPnippYPDEDXKvzznmY9ui1w+4w2oJ0aamrQ0v04yFeo59xx4rmHETJODS7GQf5olrpjuoDT6jQcGq0R4IL7GI7gfiFbQDGxDECa+ygItgKGpWNDt//O8ouyqwxZVgPnMjteWwucHBDt+lxAdU2SGGXLb9cWaKIGs3oesQwAKan806hWrtB3Qs0/","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}]},{"txid":"0xb661d5e4d9e41c3059b068f8abb6f1566a47ec800879e34c0ebd2799781a2760","size":579,"version":0,"nonce":3,"sender":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","sys_fee":"0","net_fee":"0.0088035","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x4138145d67638db97b402ee0b6751ef16253ecab","scopes":"CalledByEntry"}],"script":"AwDodkgXAAAADBQxboUQOQGdOd/Cw31sP+4Z/VgJhwwUq+xTYvEedbbgLkB7uY1jZ10UOEETwAwIdHJhbnNmZXIMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1I4","scripts":[{"invocation":"DECHEOe12Kxs2NCdb7Nb8tzOX1+zhZXdttBKVwvJJbwsVac83188taH+sKzE8myLvKbEPfO0qYuMPCyAnC8JbrJaDEDBhsECy/cjE/2U31B3/Fu+/NMiJ+0hWaR6RllId/o58zDYIjtFqiSv8AW+u1skJ6UMjE3oYY59ewDXPYNsRJQuDECiQ7W1Zb1LwvC7ES92JPazUUwSQTxalSMIGfrOP3YPA/y5axiPmAOKPyUWhrU6iNaXRPTkqYXmKXADqAzbFp6ADEBKlR5hrJnV7jGDHREXVK23EbSpBgqVJP44OpB3GEPNsJY4JnQCeofyoVqDvXfesrKrH+iz3m5UYpPvPfmxEp4o","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}]}]}}`
|
||||
|
||||
const hexHeader1 = "00000000e862e7907fc987cd58ddb3abb754aeb8812c9377c45e737a036fe88a622c3b8f301f2e84a86b207270830e7929530ccb841a3df7379fe6f0ac8865b33316839501cdd0847201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c40ab634ce91590e77b246cee8b204e8a270268ee1ef32434cece73f425a7dbc90f1bed1dbe914edcaa2653167ad170ae10e16a9b2c6b7e0af1f711fb848fbb1b7f0c40232de6ad07ee3846bafa96302d37602349501a556df575e7df0743e45b076d6a0c6c6dd4cad3898f9e8848dd054abd303b229fd12984042f241f0e668f39a0fb0c408b4af43057df189a9d471010b5150bab442040403147c5e502bda38cde3ff8bce803f01245e07e2bfb95d57349c55dcc27e3710b82f2735d0f40eb4342908e330c40cda66f743d4ed8d856f5376953f9169581c668a9370245aef16202ebef9bb3f7f81234be62ec287d701ad7d8bf5042648019af9fe5baa0a8e05d279bfdb1d4c994130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb00"
|
||||
const hexHeader1 = "000000008aaab19c43c4ca2870c3e616b123f1b689866f44b138ae4d6a5352e54442fd56401107247de4e35599d1feffaf6e763972f738d2858b0a22ad06523867e4dcf921f7c1c67201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c400f01eb6371a135527ddb205a0dae1f69d2d324837cce128bead9033091883f9ce21e6d759a40f690746592b021d397f088e3b7b417fcef73cd1bfdc2800769520c4084f7ae5d9f58a09aa56eeb2f282744a59a82d17e3be0eb1c7f54e6e8df79620e2608191bac57280a836db2ec2a776d07e43f16bc76c47d348b0fcd09d56c7c320c402b95b4e39ec35162a640795ff223e92dec95390a072eb457f6a4323052f80731517e0df029e4a457204f777f5261c6a4a88d46d4c3abdec635a6eed580d6c77f0c40b9735745b1dd795a258c31d8e6fa87d5cfc2e9b3a4890d610d33bcf833b64c58b0c5cea17f3a7128f1065ed193e636971590f193f28bdd1eeebbbc1fe6e7cee594130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb00"
|
||||
|
||||
const header1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"hash":"0xbd178d8d4a28ec082c034f817ce2423221281a31e7e00014dbf732c4053033d2","size":518,"version":0,"previousblockhash":"0x8f3b2c628ae86f037a735ec477932c81b8ae54b7abb3dd58cd87c97f90e762e8","merkleroot":"0x95831633b36588acf0e69f37f73d1a84cb0c5329790e837072206ba8842e1f30","time":1591366176001,"index":1,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DECrY0zpFZDneyRs7osgToonAmjuHvMkNM7Oc/Qlp9vJDxvtHb6RTtyqJlMWetFwrhDhapssa34K8fcR+4SPuxt/DEAjLeatB+44Rrr6ljAtN2AjSVAaVW31deffB0PkWwdtagxsbdTK04mPnohI3QVKvTA7Ip/RKYQELyQfDmaPOaD7DECLSvQwV98Ymp1HEBC1FQurRCBAQDFHxeUCvaOM3j/4vOgD8BJF4H4r+5XVc0nFXcwn43ELgvJzXQ9A60NCkI4zDEDNpm90PU7Y2Fb1N2lT+RaVgcZoqTcCRa7xYgLr75uz9/gSNL5i7Ch9cBrX2L9QQmSAGa+f5bqgqOBdJ5v9sdTJ","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"confirmations":6,"nextblockhash":"0xf2afe371a27c9dbac4f4a8ad8eba750898b7c04aa298e64fe9e488e947976045"}}`
|
||||
const header1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"hash":"0x4f2c5539b0213ea444608cc217c5cb191255c1858ccd051ad9a36f08df26a288","size":518,"version":0,"previousblockhash":"0x56fd4244e552536a4dae38b1446f8689b6f123b116e6c37028cac4439cb1aa8a","merkleroot":"0xf9dce467385206ad220a8b85d238f77239766eaffffed19955e3e47d24071140","time":1592472500001,"index":1,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DEAPAetjcaE1Un3bIFoNrh9p0tMkg3zOEovq2QMwkYg/nOIebXWaQPaQdGWSsCHTl/CI47e0F/zvc80b/cKAB2lSDECE965dn1igmqVu6y8oJ0SlmoLRfjvg6xx/VObo33liDiYIGRusVygKg22y7Cp3bQfkPxa8dsR9NIsPzQnVbHwyDEArlbTjnsNRYqZAeV/yI+kt7JU5CgcutFf2pDIwUvgHMVF+DfAp5KRXIE93f1JhxqSojUbUw6vexjWm7tWA1sd/DEC5c1dFsd15WiWMMdjm+ofVz8Lps6SJDWENM7z4M7ZMWLDFzqF/OnEo8QZe0ZPmNpcVkPGT8ovdHu67vB/m587l","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"confirmations":6,"nextblockhash":"0x45f62d72e37b074ecdc9f687222b0f91ec98d6d9af4429a2caa2e076a9196b0d"}}`
|
||||
|
||||
const txMoveNeoVerbose = `{"id":5,"jsonrpc":"2.0","result":{"blockhash":"0xbd178d8d4a28ec082c034f817ce2423221281a31e7e00014dbf732c4053033d2","confirmations":6,"blocktime":1591366176001,"txid":"0x8af9ccb8e7e0f0a73e77b78dc52750e77c50f78b09ecc2f0669c0b459cc7dd89","size":575,"version":0,"nonce":2,"sender":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","sys_fee":"0","net_fee":"0.0087635","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x4138145d67638db97b402ee0b6751ef16253ecab","scopes":"CalledByEntry"}],"script":"Ahjd9QUMFDFuhRA5AZ0538LDfWw/7hn9WAmHDBSr7FNi8R51tuAuQHu5jWNnXRQ4QRPADAh0cmFuc2ZlcgwUiXcg2M129PAKv6N8Dt2InCCP3ptBYn1bUjg=","scripts":[{"invocation":"DEAtltj95Lomb4m8ce8Rc2GWfg0R7YTNYJQqJ7yZmU3Fit82oOdM6XaqxleoejwZw46MpFDGdCAEa4HZjGD9j+sEDECzwV1dI+BAOjbPVZyu4pecpu8A/iVd8OXD2qxNoFEBa0HrpCZok0zTMINZRRuv3VQZ0FkXn9QIWWhKO5E4i/nYDEB6wEjPhUCwkZVaN0oPNtrlYMksATSIZQelie31i537tOPb1UUL404mnS5UVOsU631igNYQG0UpQQ+CnTdjSEm+DEA7ukETpof/hQfBdT+FGVV1Mc+d9R7MIN7rLCsAPsWh91iM3VC5nkC0+AObtWxd9+yefW6ksC/iN5JRDaIcdVfz","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}]}}`
|
||||
const txMoveNeoVerbose = `{"id":5,"jsonrpc":"2.0","result":{"blockhash":"0x4f2c5539b0213ea444608cc217c5cb191255c1858ccd051ad9a36f08df26a288","confirmations":6,"blocktime":1592472500001,"txid":"0x7fb05b593cf4b1eb2d9a283c5488ca1bfe61191b5775bafa43b8647e7b20f22c","size":575,"version":0,"nonce":2,"sender":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","sys_fee":"0","net_fee":"0.0087635","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x4138145d67638db97b402ee0b6751ef16253ecab","scopes":"CalledByEntry"}],"script":"Ahjd9QUMFDFuhRA5AZ0538LDfWw/7hn9WAmHDBSr7FNi8R51tuAuQHu5jWNnXRQ4QRPADAh0cmFuc2ZlcgwUiXcg2M129PAKv6N8Dt2InCCP3ptBYn1bUjg=","scripts":[{"invocation":"DECub8BP5LbCIhjKlhfJjWB9nsmx+vjP3DORvsSFrnaxGtxsxqvrMaULU26oBz5nTWKlVm/OXgoM6wcYy5ccGuPQDEBgMHG3JaWNBSytev2I6ZsnuquTGv1btQ0W4iQzWqtFAXCqviUdPAxq0/Md1+m4myCbqr5aHi+liL2BGPnippYPDEDXKvzznmY9ui1w+4w2oJ0aamrQ0v04yFeo59xx4rmHETJODS7GQf5olrpjuoDT6jQcGq0R4IL7GI7gfiFbQDGxDECa+ygItgKGpWNDt//O8ouyqwxZVgPnMjteWwucHBDt+lxAdU2SGGXLb9cWaKIGs3oesQwAKan806hWrtB3Qs0/","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}]}}`
|
||||
|
||||
// getResultBlock1 returns data for block number 1 which is used by several tests.
|
||||
func getResultBlock1() *result.Block {
|
||||
|
@ -53,17 +54,17 @@ func getResultBlock1() *result.Block {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b := new(block.Block)
|
||||
b := block.New(netmode.UnitTestNet)
|
||||
err = testserdes.DecodeBinary(binB, b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b2Hash, err := util.Uint256DecodeStringLE("f2afe371a27c9dbac4f4a8ad8eba750898b7c04aa298e64fe9e488e947976045")
|
||||
b2Hash, err := util.Uint256DecodeStringLE("45f62d72e37b074ecdc9f687222b0f91ec98d6d9af4429a2caa2e076a9196b0d")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &result.Block{
|
||||
Block: b,
|
||||
Block: *b,
|
||||
BlockMetadata: result.BlockMetadata{
|
||||
Size: 1681,
|
||||
NextBlockHash: &b2Hash,
|
||||
|
@ -78,13 +79,12 @@ func getTxMoveNeo() *result.TransactionOutputRaw {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tx := new(transaction.Transaction)
|
||||
err = testserdes.DecodeBinary(txBin, tx)
|
||||
tx, err := transaction.NewTransactionFromBytes(netmode.UnitTestNet, txBin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &result.TransactionOutputRaw{
|
||||
Transaction: tx,
|
||||
Transaction: *tx,
|
||||
TransactionMetadata: result.TransactionMetadata{
|
||||
Timestamp: b1.Timestamp,
|
||||
Blockhash: b1.Block.Hash(),
|
||||
|
@ -154,7 +154,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + hexB1 + `"}`,
|
||||
result: func(c *Client) interface{} {
|
||||
b := getResultBlock1()
|
||||
return b.Block
|
||||
return &b.Block
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -179,7 +179,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + hexB1 + `"}`,
|
||||
result: func(c *Client) interface{} {
|
||||
b := getResultBlock1()
|
||||
return b.Block
|
||||
return &b.Block
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -448,7 +448,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + hexTxMoveNeo + `"}`,
|
||||
result: func(c *Client) interface{} {
|
||||
tx := getTxMoveNeo()
|
||||
return tx.Transaction
|
||||
return &tx.Transaction
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -619,7 +619,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
{
|
||||
name: "positive",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
return nil, c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0))
|
||||
return nil, c.SendRawTransaction(transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0))
|
||||
},
|
||||
serverResponse: `{"jsonrpc":"2.0","id":1,"result":true}`,
|
||||
result: func(c *Client) interface{} {
|
||||
|
@ -740,7 +740,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
|
|||
{
|
||||
name: "sendrawtransaction_bad_server_answer",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
return nil, c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0))
|
||||
return nil, c.SendRawTransaction(transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0))
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1066,7 +1066,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
|
|||
{
|
||||
name: "sendrawtransaction_unmarshalling_error",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
return nil, c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0))
|
||||
return nil, c.SendRawTransaction(transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0))
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1112,7 +1112,7 @@ func testRPCClient(t *testing.T, newClient func(context.Context, string, Options
|
|||
defer srv.Close()
|
||||
|
||||
endpoint := srv.URL
|
||||
opts := Options{}
|
||||
opts := Options{Network: netmode.UnitTestNet}
|
||||
c, err := newClient(context.TODO(), endpoint, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -1136,7 +1136,7 @@ func testRPCClient(t *testing.T, newClient func(context.Context, string, Options
|
|||
defer srv.Close()
|
||||
|
||||
endpoint := srv.URL
|
||||
opts := Options{}
|
||||
opts := Options{Network: netmode.UnitTestNet}
|
||||
c, err := newClient(context.TODO(), endpoint, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
@ -137,9 +137,9 @@ readloop:
|
|||
var val interface{}
|
||||
switch event {
|
||||
case response.BlockEventID:
|
||||
val = new(block.Block)
|
||||
val = block.New(c.opts.Network)
|
||||
case response.TransactionEventID:
|
||||
val = new(transaction.Transaction)
|
||||
val = &transaction.Transaction{Network: c.opts.Network}
|
||||
case response.NotificationEventID:
|
||||
val = new(result.NotificationEvent)
|
||||
case response.ExecutionEventID:
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -17,7 +18,7 @@ import (
|
|||
func TestWSClientClose(t *testing.T) {
|
||||
srv := initTestServer(t, "")
|
||||
defer srv.Close()
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
wsc.Close()
|
||||
}
|
||||
|
@ -42,7 +43,7 @@ func TestWSClientSubscription(t *testing.T) {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
srv := initTestServer(t, `{"jsonrpc": "2.0", "id": 1, "result": "55aaff00"}`)
|
||||
defer srv.Close()
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
id, err := f(wsc)
|
||||
require.NoError(t, err)
|
||||
|
@ -55,7 +56,7 @@ func TestWSClientSubscription(t *testing.T) {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
srv := initTestServer(t, `{"jsonrpc": "2.0", "id": 1, "error":{"code":-32602,"message":"Invalid Params"}}`)
|
||||
defer srv.Close()
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
_, err = f(wsc)
|
||||
require.Error(t, err)
|
||||
|
@ -104,7 +105,7 @@ func TestWSClientUnsubscription(t *testing.T) {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
srv := initTestServer(t, rc.response)
|
||||
defer srv.Close()
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
rc.code(t, wsc)
|
||||
})
|
||||
|
@ -117,8 +118,8 @@ func TestWSClientEvents(t *testing.T) {
|
|||
var events = []string{
|
||||
`{"jsonrpc":"2.0","method":"transaction_executed","params":[{"txid":"0xe1cd5e57e721d2a2e05fb1f08721b12057b25ab1dd7fd0f33ee1639932fdfad7","executions":[{"trigger":"Application","contract":"0x0000000000000000000000000000000000000000","vmstate":"HALT","gas_consumed":"2.291","stack":[],"notifications":[{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}]}},{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}}]}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"notification_from_execution","params":[{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}]}}]}`,
|
||||
`{"jsonrpc":"2.0","method":"transaction_added","params":[{"txid":"0x1c615d4043c98fc0e285c2f40cc3601cf4ebe1cf9d2b404dfc67c9cd085444ec","size":265,"version":0,"nonce":9,"sender":"NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN","sys_fee":"0","net_fee":"0.0036521","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x870958fd19ee3f6c7dc3c2df399d013910856e31","scopes":"CalledByEntry"}],"script":"AHsMFCBygnSvr8NvQ6Bx0yjPo+Yp2cuwDBQxboUQOQGdOd/Cw31sP+4Z/VgJhxPADAh0cmFuc2ZlcgwUdpFiJB7t+XwkgWUq3xug9b9XQxtBYn1bUjg=","scripts":[{"invocation":"DEA00C87l6Ig/+eWQOSCuIfsDkTcyV5xn14rQ7KZh/DJgiua8EmdkAlMatO6GR5DSj313TeNO3MxjPR8ny1tgBzI","verification":"DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ="}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"block_added","params":[{"hash":"0x765ea65b4de6addfee29b1c90ac922d1901c8d7ab7f2366da9a8ad3dd71ca703","version":0,"previousblockhash":"0xbdeed527a43ab72d5d8cecf1dc6ee142112ff8a8eaaaebc7206d3df3bf3c1169","merkleroot":"0xa1b321f59b127cddd23b0cd47fc9ec7920647d30d7ab23318a106597b9c9abad","time":1591366176006,"index":6,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DEDaH0tUaopg6WWWNRI013CTkYZrs1kKKQEzvAxFg38drGNR7jJQan4Lv2/LzD7AEiLM/oS8HUBxIh9MQy6/VptiDEDuWQYygBKopKQR5/ojqouiH+24GxFYHloofK2WH6NtKiCyBpVJpaFIYNnprjZA6iD5GR1gq3wq7d9D7dbavlWMDED1OR5559YvfMqpAFEdUw+J3hg/pRvEr3RL2oH3Y+FN3X+5U+abCQFmDUdS8kDVJpNE0LZLULEk0aMWrXJIbaFeDEABL3c/rvKu5K9Z4IO0Q+vmz0BNEvSdMpZsX0jywgPihEKWFaotNMgnNW1Vw74WEvZ6W3Jfb/Sbm5Wx9gMGpytx","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"consensus_data":{"primary":0,"nonce":"0000000000000457"},"tx":[{"txid":"0x1c615d4043c98fc0e285c2f40cc3601cf4ebe1cf9d2b404dfc67c9cd085444ec","size":265,"version":0,"nonce":9,"sender":"NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN","sys_fee":"0","net_fee":"0.0036521","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x870958fd19ee3f6c7dc3c2df399d013910856e31","scopes":"CalledByEntry"}],"script":"AHsMFCBygnSvr8NvQ6Bx0yjPo+Yp2cuwDBQxboUQOQGdOd/Cw31sP+4Z/VgJhxPADAh0cmFuc2ZlcgwUdpFiJB7t+XwkgWUq3xug9b9XQxtBYn1bUjg=","scripts":[{"invocation":"DEA00C87l6Ig/+eWQOSCuIfsDkTcyV5xn14rQ7KZh/DJgiua8EmdkAlMatO6GR5DSj313TeNO3MxjPR8ny1tgBzI","verification":"DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ="}]}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"transaction_executed","params":[{"txid":"0xf97a72b7722c109f909a8bc16c22368c5023d85828b09b127b237aace33cf099","executions":[{"trigger":"Application","contract":"0x0000000000000000000000000000000000000000","vmstate":"HALT","gas_consumed":"0.0604261","stack":[],"notifications":[{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteArray","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}]}},{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","state":{"type":"Array","value":[{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteArray","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}}]}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"block_added","params":[{"hash":"0x2d312f6379ead13cf62634c703091b750e7903728df2a3cf5bd96ce80b84a849","version":0,"previousblockhash":"0xb8237d34c156cac6be7b01578decf8ac8c99a62f0b6f774d622aad7be0fe189d","merkleroot":"0xf89169e89361692b71e671f13c088e84c5325015c413e8f89e7ba38efdb41287","time":1592472500006,"index":6,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DEDblVguNGXWbUswDvBfVJzBt76BJyJ0Ga6siquyjioGn4Dbr6zy1IvcLl3xN5akcejRy9e+Mr1qvpe/gkLgtW4QDEDRwPISZagMFjE/plXTnZ/gEU0IbBAAe23U29zVWteUmzRsPxF/MdzXvdffR9W0edkj17AmkWpn+5rqzH9aCOpLDECEvjgxZaRoAHEDNzp1REllLcGzMwrwSjudtzfgRglQL3g1BKerDx6cGHH73medRVkL9QVm4KzSxlywVtvhwBMrDEBuPKvzg5TtakFW2jr/bfmy1bn2FiLARlOySwaGdKRV93ozA5lVEIAvHbBlJtT4/5H8jHjbncXXMrP3OUHqebZz","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"consensus_data":{"primary":0,"nonce":"0000000000000457"},"tx":[{"txid":"0xf97a72b7722c109f909a8bc16c22368c5023d85828b09b127b237aace33cf099","size":265,"version":0,"nonce":9,"sender":"NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN","sys_fee":"0","net_fee":"0.0036521","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x870958fd19ee3f6c7dc3c2df399d013910856e31","scopes":"CalledByEntry"}],"script":"AHsMFCBygnSvr8NvQ6Bx0yjPo+Yp2cuwDBQxboUQOQGdOd/Cw31sP+4Z/VgJhxPADAh0cmFuc2ZlcgwU2gHvYphOfQUnXEpYeyAtoLP3X+ZBYn1bUjg=","scripts":[{"invocation":"DECwklSj3liZOJbktRtkVdUCu8U2LQlrU6Dv8NtMgd0xXbk5lXjc2p68xv6xtJXbJ4aoFMJZ9lkcNpGoeUCcaCet","verification":"DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ="}]}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"event_missed","params":[]}`,
|
||||
}
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
|
@ -138,7 +139,7 @@ func TestWSClientEvents(t *testing.T) {
|
|||
}
|
||||
}))
|
||||
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
for range events {
|
||||
select {
|
||||
|
@ -161,7 +162,7 @@ func TestWSExecutionVMStateCheck(t *testing.T) {
|
|||
// Will answer successfully if request slips through.
|
||||
srv := initTestServer(t, `{"jsonrpc": "2.0", "id": 1, "result": "55aaff00"}`)
|
||||
defer srv.Close()
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
filter := "NONE"
|
||||
_, err = wsc.SubscribeForTransactionExecutions(&filter)
|
||||
|
@ -291,7 +292,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
|
|||
}
|
||||
}))
|
||||
defer srv.Close()
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
c.clientCode(t, wsc)
|
||||
wsc.Close()
|
||||
|
@ -304,11 +305,11 @@ func TestNewWS(t *testing.T) {
|
|||
defer srv.Close()
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
_, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{})
|
||||
_, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{Network: netmode.UnitTestNet})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("bad URL", func(t *testing.T) {
|
||||
_, err := NewWS(context.TODO(), strings.Trim(srv.URL, "http://"), Options{})
|
||||
_, err := NewWS(context.TODO(), strings.Trim(srv.URL, "http://"), Options{Network: netmode.UnitTestNet})
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ type (
|
|||
// Block wrapper used for the representation of
|
||||
// block.Block / block.Base on the RPC Server.
|
||||
Block struct {
|
||||
*block.Block
|
||||
block.Block
|
||||
BlockMetadata
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ type (
|
|||
// NewBlock creates a new Block wrapper.
|
||||
func NewBlock(b *block.Block, chain blockchainer.Blockchainer) Block {
|
||||
res := Block{
|
||||
Block: b,
|
||||
Block: *b,
|
||||
BlockMetadata: BlockMetadata{
|
||||
Size: io.GetVarSize(b),
|
||||
Confirmations: chain.BlockHeight() - b.Index + 1,
|
||||
|
@ -72,16 +72,14 @@ func (b *Block) UnmarshalJSON(data []byte) error {
|
|||
// As block.Block and BlockMetadata are at the same level in json,
|
||||
// do unmarshalling separately for both structs.
|
||||
meta := new(BlockMetadata)
|
||||
base := new(block.Block)
|
||||
err := json.Unmarshal(data, meta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(data, base)
|
||||
err = json.Unmarshal(data, &b.Block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Block = base
|
||||
b.BlockMetadata = *meta
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
// TransactionOutputRaw is used as a wrapper to represents
|
||||
// a Transaction.
|
||||
type TransactionOutputRaw struct {
|
||||
*transaction.Transaction
|
||||
transaction.Transaction
|
||||
TransactionMetadata
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header,
|
|||
// confirmations formula
|
||||
confirmations := int(chain.BlockHeight() - header.Base.Index + 1)
|
||||
return TransactionOutputRaw{
|
||||
Transaction: tx,
|
||||
Transaction: *tx,
|
||||
TransactionMetadata: TransactionMetadata{
|
||||
Blockhash: header.Hash(),
|
||||
Confirmations: confirmations,
|
||||
|
@ -48,7 +48,7 @@ func (t TransactionOutputRaw) MarshalJSON() ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
txBytes, err := json.Marshal(t.Transaction)
|
||||
txBytes, err := json.Marshal(&t.Transaction)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -76,11 +76,5 @@ func (t *TransactionOutputRaw) UnmarshalJSON(data []byte) error {
|
|||
t.Confirmations = output.Confirmations
|
||||
t.Timestamp = output.Timestamp
|
||||
|
||||
transaction := new(transaction.Transaction)
|
||||
err = json.Unmarshal(data, transaction)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.Transaction = transaction
|
||||
return nil
|
||||
return json.Unmarshal(data, &t.Transaction)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||
|
@ -40,6 +41,7 @@ type (
|
|||
*http.Server
|
||||
chain blockchainer.Blockchainer
|
||||
config rpc.Config
|
||||
network netmode.Magic
|
||||
coreServer *network.Server
|
||||
log *zap.Logger
|
||||
https *http.Server
|
||||
|
@ -135,6 +137,7 @@ func New(chain blockchainer.Blockchainer, conf rpc.Config, coreServer *network.S
|
|||
Server: httpServer,
|
||||
chain: chain,
|
||||
config: conf,
|
||||
network: chain.GetConfig().Magic,
|
||||
coreServer: coreServer,
|
||||
log: log,
|
||||
https: tlsServer,
|
||||
|
@ -928,13 +931,13 @@ func (s *Server) submitBlock(reqParams request.Params) (interface{}, *response.E
|
|||
if err != nil {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
b := block.Block{}
|
||||
b := block.New(s.network)
|
||||
r := io.NewBinReaderFromBuf(blockBytes)
|
||||
b.DecodeBinary(r)
|
||||
if r.Err != nil {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
err = s.chain.AddBlock(&b)
|
||||
err = s.chain.AddBlock(b)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case core.ErrInvalidBlockIndex, core.ErrAlreadyExists:
|
||||
|
@ -955,7 +958,7 @@ func (s *Server) sendrawtransaction(reqParams request.Params) (interface{}, *res
|
|||
} else if byteTx, err := reqParams[0].GetBytesHex(); err != nil {
|
||||
return nil, response.ErrInvalidParams
|
||||
} else {
|
||||
tx, err := transaction.NewTransactionFromBytes(byteTx)
|
||||
tx, err := transaction.NewTransactionFromBytes(s.network, byteTx)
|
||||
if err != nil {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
|
@ -19,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
func getUnitTestChain(t *testing.T) (*core.Blockchain, config.Config, *zap.Logger) {
|
||||
net := config.ModeUnitTestNet
|
||||
net := netmode.UnitTestNet
|
||||
configPath := "../../../config"
|
||||
cfg, err := config.Load(configPath, net)
|
||||
require.NoError(t, err, "could not load config")
|
||||
|
@ -49,7 +50,7 @@ func getTestBlocks(t *testing.T) []*block.Block {
|
|||
blocks := make([]*block.Block, 0, int(nBlocks))
|
||||
for i := 0; i < int(nBlocks); i++ {
|
||||
_ = br.ReadU32LE()
|
||||
b := &block.Block{}
|
||||
b := block.New(netmode.UnitTestNet)
|
||||
b.DecodeBinary(br)
|
||||
require.Nil(t, br.Err)
|
||||
blocks = append(blocks, b)
|
||||
|
|
|
@ -51,17 +51,18 @@ type rpcTestCase struct {
|
|||
}
|
||||
|
||||
const testContractHash = "e65ff7b3a02d207b584a5c27057d4e9862ef01da"
|
||||
const deploymentTxHash = "5ce44eae362d3f81d440cb73cf4e4af71e69851bcd683b076aa08b7346d4e69b"
|
||||
|
||||
var rpcTestCases = map[string][]rpcTestCase{
|
||||
"getapplicationlog": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["9352fa8d351635bb151e7e5a3a923bfe4d8fb90f05b605ec00af95c2410b594d"]`,
|
||||
params: `["` + deploymentTxHash + `"]`,
|
||||
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)
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("9352fa8d351635bb151e7e5a3a923bfe4d8fb90f05b605ec00af95c2410b594d")
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE(deploymentTxHash)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedTxHash, res.TxHash)
|
||||
assert.Equal(t, 1, len(res.Executions))
|
||||
|
@ -316,7 +317,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
{
|
||||
name: "positive",
|
||||
params: "[3, 1]",
|
||||
result: func(e *executor) interface{} { return &result.Block{} },
|
||||
result: func(_ *executor) interface{} { return &result.Block{} },
|
||||
check: func(t *testing.T, e *executor, blockRes interface{}) {
|
||||
res, ok := blockRes.(*result.Block)
|
||||
require.True(t, ok)
|
||||
|
@ -483,7 +484,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"gettransactionheight": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["9352fa8d351635bb151e7e5a3a923bfe4d8fb90f05b605ec00af95c2410b594d"]`,
|
||||
params: `["` + deploymentTxHash + `"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
h := 0
|
||||
return &h
|
||||
|
@ -687,7 +688,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"sendrawtransaction": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["000a000000316e851039019d39dfc2c37d6c3fee19fd5809870000000000000000f2ad050000000000b00400000001316e851039019d39dfc2c37d6c3fee19fd580987015d0300e87648170000000c1420728274afafc36f43a071d328cfa3e629d9cbb00c14316e851039019d39dfc2c37d6c3fee19fd58098713c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c40df953141271169421cebab5d27a0163e294d7c7f2d0525b4498745344814fd3d6c5c591c9b1723d05d42856f409adb084cf67acc921cfafc629133a5eb5e7a7e290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
|
||||
params: `["000a000000316e851039019d39dfc2c37d6c3fee19fd5809870000000000000000f2ad050000000000b00400000001316e851039019d39dfc2c37d6c3fee19fd580987015d0300e87648170000000c1420728274afafc36f43a071d328cfa3e629d9cbb00c14316e851039019d39dfc2c37d6c3fee19fd58098713c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c409803db41e66a94e0bd6fdd3d7a7b1e106c1e2281c9782a231f32df036bb80c7f19155cdb9a52a45cf8d93ec9c1e8df69d6ee35625f352d1710c7cc6eee26003c290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
v := true
|
||||
return &v
|
||||
|
@ -825,7 +826,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
|||
|
||||
newTx := func() *transaction.Transaction {
|
||||
height := chain.BlockHeight()
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Nonce = height + 1
|
||||
tx.ValidUntilBlock = height + 10
|
||||
tx.Sender = acc0.PrivateKey().GetScriptHash()
|
||||
|
@ -886,11 +887,11 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
|||
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE())
|
||||
body := doRPCCall(rpc, httpSrv.URL, t)
|
||||
txOut := checkErrGetResult(t, body, false)
|
||||
actual := result.TransactionOutputRaw{}
|
||||
actual := result.TransactionOutputRaw{Transaction: transaction.Transaction{Network: testchain.Network()}}
|
||||
err := json.Unmarshal(txOut, &actual)
|
||||
require.NoErrorf(t, err, "could not parse response: %s", txOut)
|
||||
|
||||
assert.Equal(t, block.Transactions[0], actual.Transaction)
|
||||
assert.Equal(t, *block.Transactions[0], actual.Transaction)
|
||||
assert.Equal(t, 8, actual.Confirmations)
|
||||
assert.Equal(t, TXHash, actual.Transaction.Hash())
|
||||
})
|
||||
|
@ -955,7 +956,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
|||
expected = append(expected, tx.Hash())
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0)
|
||||
assert.NoError(t, mp.Add(tx, &FeerStub{}))
|
||||
expected = append(expected, tx.Hash())
|
||||
}
|
||||
|
@ -1004,6 +1005,7 @@ func newBlock(t *testing.T, bc blockchainer.Blockchainer, index uint32, primary
|
|||
Index: hdr.Index + index,
|
||||
NextConsensus: witness.ScriptHash(),
|
||||
Script: witness,
|
||||
Network: bc.GetConfig().Magic,
|
||||
},
|
||||
ConsensusData: block.ConsensusData{
|
||||
PrimaryIndex: primary,
|
||||
|
@ -1020,7 +1022,12 @@ func newBlock(t *testing.T, bc blockchainer.Blockchainer, index uint32, primary
|
|||
func (tc rpcTestCase) getResultPair(e *executor) (expected interface{}, res interface{}) {
|
||||
expected = tc.result(e)
|
||||
resVal := reflect.New(reflect.TypeOf(expected).Elem())
|
||||
return expected, resVal.Interface()
|
||||
res = resVal.Interface()
|
||||
switch r := res.(type) {
|
||||
case *result.Block:
|
||||
r.Network = testchain.Network()
|
||||
}
|
||||
return expected, res
|
||||
}
|
||||
|
||||
func checkErrGetResult(t *testing.T, body []byte, expectingFail bool) json.RawMessage {
|
||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
|
@ -24,7 +25,7 @@ type ParameterContext struct {
|
|||
// Type is a type of a verifiable item.
|
||||
Type string
|
||||
// Verifiable is an object which can be (de-)serialized.
|
||||
Verifiable io.Serializable
|
||||
Verifiable crypto.VerifiableDecodable
|
||||
// Items is a map from script hashes to context items.
|
||||
Items map[util.Uint160]*Item
|
||||
}
|
||||
|
@ -41,7 +42,7 @@ type sigWithIndex struct {
|
|||
}
|
||||
|
||||
// NewParameterContext returns ParameterContext with the specified type and item to sign.
|
||||
func NewParameterContext(typ string, verif io.Serializable) *ParameterContext {
|
||||
func NewParameterContext(typ string, verif crypto.VerifiableDecodable) *ParameterContext {
|
||||
return &ParameterContext{
|
||||
Type: typ,
|
||||
Verifiable: verif,
|
||||
|
@ -144,11 +145,7 @@ func (c *ParameterContext) getItemForContract(ctr *wallet.Contract) *Item {
|
|||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (c ParameterContext) MarshalJSON() ([]byte, error) {
|
||||
bw := io.NewBufBinWriter()
|
||||
c.Verifiable.EncodeBinary(bw.BinWriter)
|
||||
if bw.Err != nil {
|
||||
return nil, bw.Err
|
||||
}
|
||||
verif := c.Verifiable.GetSignedPart()
|
||||
items := make(map[string]json.RawMessage, len(c.Items))
|
||||
for u := range c.Items {
|
||||
data, err := json.Marshal(c.Items[u])
|
||||
|
@ -159,7 +156,7 @@ func (c ParameterContext) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
pc := ¶mContext{
|
||||
Type: c.Type,
|
||||
Hex: hex.EncodeToString(bw.Bytes()),
|
||||
Hex: hex.EncodeToString(verif),
|
||||
Items: items,
|
||||
}
|
||||
return json.Marshal(pc)
|
||||
|
@ -176,17 +173,16 @@ func (c *ParameterContext) UnmarshalJSON(data []byte) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var verif io.Serializable
|
||||
var verif crypto.VerifiableDecodable
|
||||
switch pc.Type {
|
||||
case "Neo.Core.ContractTransaction":
|
||||
verif = new(transaction.Transaction)
|
||||
default:
|
||||
return fmt.Errorf("unsupported type: %s", c.Type)
|
||||
}
|
||||
br := io.NewBinReaderFromBuf(data)
|
||||
verif.DecodeBinary(br)
|
||||
if br.Err != nil {
|
||||
return br.Err
|
||||
err = verif.DecodeSignedPart(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items := make(map[util.Uint160]*Item, len(pc.Items))
|
||||
for h := range pc.Items {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -165,7 +166,7 @@ func newParam(typ smartcontract.ParamType, name string) wallet.ContractParam {
|
|||
}
|
||||
|
||||
func getContractTx() *transaction.Transaction {
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||
tx.Attributes = make([]transaction.Attribute, 0)
|
||||
tx.Scripts = make([]transaction.Witness, 0)
|
||||
tx.Hash()
|
||||
|
|
Loading…
Reference in a new issue