diff --git a/cli/server/server.go b/cli/server/server.go index 061dc0734..be46edd2d 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -282,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 { diff --git a/integration/performance_test.go b/integration/performance_test.go index f139cd83a..89aa27df3 100644 --- a/integration/performance_test.go +++ b/integration/performance_test.go @@ -78,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, diff --git a/pkg/compiler/interop_test.go b/pkg/compiler/interop_test.go index 9bc60d0b7..646670244 100644 --- a/pkg/compiler/interop_test.go +++ b/pkg/compiler/interop_test.go @@ -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) diff --git a/pkg/consensus/block_test.go b/pkg/consensus/block_test.go index 312da1199..62f6bebe7 100644 --- a/pkg/consensus/block_test.go +++ b/pkg/consensus/block_test.go @@ -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()) } diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 23a74c34a..289ee5f89 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -9,6 +9,7 @@ import ( "github.com/nspcc-dev/dbft/block" "github.com/nspcc-dev/dbft/crypto" "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" @@ -60,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. @@ -100,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 { @@ -127,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), @@ -459,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 diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index e03a60c55..d59ac3825 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -24,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) @@ -41,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) @@ -55,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) @@ -122,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) @@ -139,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() diff --git a/pkg/core/block/block.go b/pkg/core/block/block.go index 54d88fa31..1fa2c8436 100644 --- a/pkg/core/block/block.go +++ b/pkg/core/block/block.go @@ -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. diff --git a/pkg/core/block/block_base.go b/pkg/core/block/block_base.go index 11caa2351..0b5af8c95 100644 --- a/pkg/core/block/block_base.go +++ b/pkg/core/block/block_base.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" + "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" @@ -37,6 +38,11 @@ type Base struct { // 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 @@ -102,6 +108,7 @@ func (b *Base) EncodeBinary(bw *io.BinWriter) { // 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) diff --git a/pkg/core/block/block_test.go b/pkg/core/block/block_test.go index 01a8d7b73..0d64ff80b 100644 --- a/pkg/core/block/block_test.go +++ b/pkg/core/block/block_test.go @@ -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), }, } } diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index f0db627c4..fdf1a97f8 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -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{}), diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index e01dde741..1e34150ea 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -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 diff --git a/pkg/core/dao/cacheddao_test.go b/pkg/core/dao/cacheddao_test.go index bd79af520..ceee31b6c 100644 --- a/pkg/core/dao/cacheddao_test.go +++ b/pkg/core/dao/cacheddao_test.go @@ -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) diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index 0166f3f30..23b88ca54 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -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 diff --git a/pkg/core/dao/dao_test.go b/pkg/core/dao/dao_test.go index 44b10e221..7c7f2ab78 100644 --- a/pkg/core/dao/dao_test.go +++ b/pkg/core/dao/dao_test.go @@ -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) diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index 414c480dd..c4ff4f4b6 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -10,7 +10,6 @@ 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/storage" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -35,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", netmode.UnitTestNet) + 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) @@ -60,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), @@ -103,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 @@ -124,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")), @@ -140,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), }, } } @@ -241,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 @@ -255,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 @@ -286,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 @@ -376,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 { diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index 063ab2775..f1451de6c 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -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 } diff --git a/pkg/core/interops_test.go b/pkg/core/interops_test.go index 168edf1a9..4c811363b 100644 --- a/pkg/core/interops_test.go +++ b/pkg/core/interops_test.go @@ -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)) } diff --git a/pkg/core/mempool/mem_pool_test.go b/pkg/core/mempool/mem_pool_test.go index 969652c11..2df37ad9d 100644 --- a/pkg/core/mempool/mem_pool_test.go +++ b/pkg/core/mempool/mem_pool_test.go @@ -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{})) diff --git a/pkg/core/native_contract_test.go b/pkg/core/native_contract_test.go index 855803125..2d9d901aa 100644 --- a/pkg/core/native_contract_test.go +++ b/pkg/core/native_contract_test.go @@ -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)) diff --git a/pkg/core/transaction/helper_test.go b/pkg/core/transaction/helper_test.go index 6cbd5e61c..cdfba61ff 100644 --- a/pkg/core/transaction/helper_test.go +++ b/pkg/core/transaction/helper_test.go @@ -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 } diff --git a/pkg/core/transaction/transaction.go b/pkg/core/transaction/transaction.go index 79d25a4b5..ce4f1a46a 100644 --- a/pkg/core/transaction/transaction.go +++ b/pkg/core/transaction/transaction.go @@ -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, } } @@ -203,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 @@ -229,6 +239,7 @@ func (t *Transaction) GetSignedPart() []byte { // 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 @@ -239,7 +250,7 @@ func (t *Transaction) DecodeSignedPart(buf []byte) error { return errors.New("additional data after the signed part") } t.Scripts = make([]Witness, 0) - _ = t.createHash() + t.updateHashes(buf) return nil } @@ -254,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 { diff --git a/pkg/core/transaction/transaction_test.go b/pkg/core/transaction/transaction_test.go index bbc082d18..b7cbd81d0 100644 --- a/pkg/core/transaction/transaction_test.go +++ b/pkg/core/transaction/transaction_test.go @@ -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) { diff --git a/pkg/core/util.go b/pkg/core/util.go index 52362bc9d..de081004f 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -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{ diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index e9a12d9fa..9d5002742 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -21,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 := "2b8a21dfaf989dc1a5f2694517aefdbda1dd340f3cf177187d73e038a58ad2bb" + expect := "dba446947a90b2862ef050703b44828ad8b02d11978f8ef59bd3e1c97aabf6e5" assert.Equal(t, expect, block.Hash().StringLE()) } diff --git a/pkg/internal/testchain/network.go b/pkg/internal/testchain/network.go new file mode 100644 index 000000000..17863c1c4 --- /dev/null +++ b/pkg/internal/testchain/network.go @@ -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 +} diff --git a/pkg/network/message.go b/pkg/network/message.go index 98bd89320..a4eeea882 100644 --- a/pkg/network/message.go +++ b/pkg/network/message.go @@ -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 @@ -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, @@ -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: diff --git a/pkg/network/payload/headers.go b/pkg/network/payload/headers.go index b8abe8162..31550a3df 100644 --- a/pkg/network/payload/headers.go +++ b/pkg/network/payload/headers.go @@ -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 } diff --git a/pkg/network/server.go b/pkg/network/server.go index cb95b5600..befc08ef4 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -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), diff --git a/pkg/network/tcp_peer.go b/pkg/network/tcp_peer.go index a6bd9bb41..29cd71d94 100644 --- a/pkg/network/tcp_peer.go +++ b/pkg/network/tcp_peer.go @@ -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 { diff --git a/pkg/rpc/client/nep5.go b/pkg/rpc/client/nep5.go index b00622468..0b6bd44a2 100644 --- a/pkg/rpc/client/nep5.go +++ b/pkg/rpc/client/nep5.go @@ -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{ { diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index cb80a67ef..d4e9ce2cc 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -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() diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index 7828c518e..bdfd08d67 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -36,17 +36,17 @@ type rpcClientTestCase struct { check func(t *testing.T, c *Client, result interface{}) } -const hexB1 = "0000000001748928bdff7ddcdf774b9221cf424b36d9140a24543907085ec80c9dc864037389fb7ab018e8d4873a57c43b8dce453ad54d3732e2d263236844cae38a3dc6c1cbb6c67201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c4090b975d9935a8472f531a41fba40b2fe6f798f345acfaf2e9a8af339487319a5a4c750a21c97de6a17dcdcb6ec213cc02de8d41a21790db887cecb64b2713f9a0c400fe916268762c8cc946e89652736a4bbfcc06453afae15ed3cffd6b8727840e4726aa33c1068c049a34f30e49f707945c28eb0ceea3b8c0599be9b5d2cad8cb80c40671375afb758c79a4096837785e720b3f8a61bb2252410a5123c8dbf99b8c78654722843e6620c6bc57ffc55234f9e76c523aba021cf735f2b95f329193830aa0c40d56010a228b258b4be146a90198c8822b68bf96c0aa6712df8220f79c76059f0e5d3dacfbf70dfb40a4d57e8c88af2ad6b6056c7a7274c29ed860117d4eb558294130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb030057040000000000000002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c402d96d8fde4ba266f89bc71ef117361967e0d11ed84cd60942a27bc99994dc58adf36a0e74ce976aac657a87a3c19c38e8ca450c67420046b81d98c60fd8feb040c40b3c15d5d23e0403a36cf559caee2979ca6ef00fe255df0e5c3daac4da051016b41eba42668934cd3308359451bafdd5419d059179fd40859684a3b91388bf9d80c407ac048cf8540b091955a374a0f36dae560c92c0134886507a589edf58b9dfbb4e3dbd5450be34e269d2e5454eb14eb7d6280d6101b4529410f829d37634849be0c403bba4113a687ff8507c1753f8519557531cf9df51ecc20deeb2c2b003ec5a1f7588cdd50b99e40b4f8039bb56c5df7ec9e7d6ea4b02fe23792510da21c7557f394130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb0003000000abec5362f11e75b6e02e407bb98d63675d1438410000000000000000de6e0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d143841015d0300e87648170000000c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b523801fd08010c4063fb12aa9f3fb83f6324ea9c7ec11fa9e995b51140f480409d68cf4d625e598b0632d6610602984bfa2f5e5ea9bcc62a0e6d818dd271b38530c0d1b8a71b4e0c0c4013e091eac6f304668d647c5c032fd1020597ea5204545e21c38655a6343d58492118f1231ede91af848af7e1d987d1a8816966f5fc1a7821c6c6f62734267bde0c40daadd04a7a4141d96c58de2d373e672ca071e2b82138ef52df016ac522710385db2ac73743d2fe73061fa5d6cb0ff73a7ec7f0667e4c8bff6aa0d5783128d36e0c40dab85cd87d3f92be9532292bdc6f420b0ecbf2f877c70c6a9921ee0fc900dfc53998cf020a51fa9af3d0608f6a2b9048cea3c0b586485802bbd278b261eee8a494130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb" +const hexB1 = "000000008aaab19c43c4ca2870c3e616b123f1b689866f44b138ae4d6a5352e54442fd56401107247de4e35599d1feffaf6e763972f738d2858b0a22ad06523867e4dcf921f7c1c67201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c400f01eb6371a135527ddb205a0dae1f69d2d324837cce128bead9033091883f9ce21e6d759a40f690746592b021d397f088e3b7b417fcef73cd1bfdc2800769520c4084f7ae5d9f58a09aa56eeb2f282744a59a82d17e3be0eb1c7f54e6e8df79620e2608191bac57280a836db2ec2a776d07e43f16bc76c47d348b0fcd09d56c7c320c402b95b4e39ec35162a640795ff223e92dec95390a072eb457f6a4323052f80731517e0df029e4a457204f777f5261c6a4a88d46d4c3abdec635a6eed580d6c77f0c40b9735745b1dd795a258c31d8e6fa87d5cfc2e9b3a4890d610d33bcf833b64c58b0c5cea17f3a7128f1065ed193e636971590f193f28bdd1eeebbbc1fe6e7cee594130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb030057040000000000000002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c40ae6fc04fe4b6c22218ca9617c98d607d9ec9b1faf8cfdc3391bec485ae76b11adc6cc6abeb31a50b536ea8073e674d62a5566fce5e0a0ceb0718cb971c1ae3d00c40603071b725a58d052cad7afd88e99b27baab931afd5bb50d16e224335aab450170aabe251d3c0c6ad3f31dd7e9b89b209baabe5a1e2fa588bd8118f9e2a6960f0c40d72afcf39e663dba2d70fb8c36a09d1a6a6ad0d2fd38c857a8e7dc71e2b98711324e0d2ec641fe6896ba63ba80d3ea341c1aad11e082fb188ee07e215b4031b10c409afb2808b60286a56343b7ffcef28bb2ab0c595603e7323b5e5b0b9c1c10edfa5c40754d921865cb6fd71668a206b37a1eb10c0029a9fcd3a856aed07742cd3f94130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb0003000000abec5362f11e75b6e02e407bb98d63675d1438410000000000000000de6e0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d143841015d0300e87648170000000c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b523801fd08010c408710e7b5d8ac6cd8d09d6fb35bf2dcce5f5fb38595ddb6d04a570bc925bc2c55a73cdf5f3cb5a1feb0acc4f26c8bbca6c43df3b4a98b8c3c2c809c2f096eb25a0c40c186c102cbf72313fd94df5077fc5bbefcd32227ed2159a47a46594877fa39f330d8223b45aa24aff005bebb5b2427a50c8c4de8618e7d7b00d73d836c44942e0c40a243b5b565bd4bc2f0bb112f7624f6b3514c12413c5a95230819face3f760f03fcb96b188f98038a3f251686b53a88d69744f4e4a985e6297003a80cdb169e800c404a951e61ac99d5ee31831d111754adb711b4a9060a9524fe383a90771843cdb096382674027a87f2a15a83bd77deb2b2ab1fe8b3de6e546293ef3df9b1129e2894130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb" -const hexTxMoveNeo = "0002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c402d96d8fde4ba266f89bc71ef117361967e0d11ed84cd60942a27bc99994dc58adf36a0e74ce976aac657a87a3c19c38e8ca450c67420046b81d98c60fd8feb040c40b3c15d5d23e0403a36cf559caee2979ca6ef00fe255df0e5c3daac4da051016b41eba42668934cd3308359451bafdd5419d059179fd40859684a3b91388bf9d80c407ac048cf8540b091955a374a0f36dae560c92c0134886507a589edf58b9dfbb4e3dbd5450be34e269d2e5454eb14eb7d6280d6101b4529410f829d37634849be0c403bba4113a687ff8507c1753f8519557531cf9df51ecc20deeb2c2b003ec5a1f7588cdd50b99e40b4f8039bb56c5df7ec9e7d6ea4b02fe23792510da21c7557f394130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb" +const hexTxMoveNeo = "0002000000abec5362f11e75b6e02e407bb98d63675d14384100000000000000003e5f0d0000000000b00400000001abec5362f11e75b6e02e407bb98d63675d14384101590218ddf5050c14316e851039019d39dfc2c37d6c3fee19fd5809870c14abec5362f11e75b6e02e407bb98d63675d14384113c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801fd08010c40ae6fc04fe4b6c22218ca9617c98d607d9ec9b1faf8cfdc3391bec485ae76b11adc6cc6abeb31a50b536ea8073e674d62a5566fce5e0a0ceb0718cb971c1ae3d00c40603071b725a58d052cad7afd88e99b27baab931afd5bb50d16e224335aab450170aabe251d3c0c6ad3f31dd7e9b89b209baabe5a1e2fa588bd8118f9e2a6960f0c40d72afcf39e663dba2d70fb8c36a09d1a6a6ad0d2fd38c857a8e7dc71e2b98711324e0d2ec641fe6896ba63ba80d3ea341c1aad11e082fb188ee07e215b4031b10c409afb2808b60286a56343b7ffcef28bb2ab0c595603e7323b5e5b0b9c1c10edfa5c40754d921865cb6fd71668a206b37a1eb10c0029a9fcd3a856aed07742cd3f94130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb" -const b1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"size":1681,"nextblockhash":"0x9cdc200c0efda77466e36427a056656ba0301428bba8514115bfac7bb325cd6b","confirmations":6,"hash":"0x007d285c78ee9d8c904156edecb6c027ac3a84dc1222f43ed0fa8459a4f8bd24","version":0,"previousblockhash":"0x0364c89d0cc85e08073954240a14d9364b42cf21924b77dfdc7dffbd28897401","merkleroot":"0xc63d8ae3ca44682363d2e232374dd53a45ce8d3bc4573a87d4e818b07afb8973","time":1592471768001,"index":1,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DECQuXXZk1qEcvUxpB+6QLL+b3mPNFrPry6aivM5SHMZpaTHUKIcl95qF9zctuwhPMAt6NQaIXkNuIfOy2SycT+aDEAP6RYmh2LIzJRuiWUnNqS7/MBkU6+uFe08/9a4cnhA5HJqozwQaMBJo08w5J9weUXCjrDO6juMBZm+m10srYy4DEBnE3Wvt1jHmkCWg3eF5yCz+KYbsiUkEKUSPI2/mbjHhlRyKEPmYgxrxX/8VSNPnnbFI6ugIc9zXyuV8ykZODCqDEDVYBCiKLJYtL4UapAZjIgitov5bAqmcS34Ig95x2BZ8OXT2s+/cN+0Ck1X6MiK8q1rYFbHpydMKe2GARfU61WC","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 = "0000000001748928bdff7ddcdf774b9221cf424b36d9140a24543907085ec80c9dc864037389fb7ab018e8d4873a57c43b8dce453ad54d3732e2d263236844cae38a3dc6c1cbb6c67201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c4090b975d9935a8472f531a41fba40b2fe6f798f345acfaf2e9a8af339487319a5a4c750a21c97de6a17dcdcb6ec213cc02de8d41a21790db887cecb64b2713f9a0c400fe916268762c8cc946e89652736a4bbfcc06453afae15ed3cffd6b8727840e4726aa33c1068c049a34f30e49f707945c28eb0ceea3b8c0599be9b5d2cad8cb80c40671375afb758c79a4096837785e720b3f8a61bb2252410a5123c8dbf99b8c78654722843e6620c6bc57ffc55234f9e76c523aba021cf735f2b95f329193830aa0c40d56010a228b258b4be146a90198c8822b68bf96c0aa6712df8220f79c76059f0e5d3dacfbf70dfb40a4d57e8c88af2ad6b6056c7a7274c29ed860117d4eb558294130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb00" +const hexHeader1 = "000000008aaab19c43c4ca2870c3e616b123f1b689866f44b138ae4d6a5352e54442fd56401107247de4e35599d1feffaf6e763972f738d2858b0a22ad06523867e4dcf921f7c1c67201000001000000abec5362f11e75b6e02e407bb98d63675d14384101fd08010c400f01eb6371a135527ddb205a0dae1f69d2d324837cce128bead9033091883f9ce21e6d759a40f690746592b021d397f088e3b7b417fcef73cd1bfdc2800769520c4084f7ae5d9f58a09aa56eeb2f282744a59a82d17e3be0eb1c7f54e6e8df79620e2608191bac57280a836db2ec2a776d07e43f16bc76c47d348b0fcd09d56c7c320c402b95b4e39ec35162a640795ff223e92dec95390a072eb457f6a4323052f80731517e0df029e4a457204f777f5261c6a4a88d46d4c3abdec635a6eed580d6c77f0c40b9735745b1dd795a258c31d8e6fa87d5cfc2e9b3a4890d610d33bcf833b64c58b0c5cea17f3a7128f1065ed193e636971590f193f28bdd1eeebbbc1fe6e7cee594130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb00" -const header1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"hash":"0x007d285c78ee9d8c904156edecb6c027ac3a84dc1222f43ed0fa8459a4f8bd24","size":518,"version":0,"previousblockhash":"0x0364c89d0cc85e08073954240a14d9364b42cf21924b77dfdc7dffbd28897401","merkleroot":"0xc63d8ae3ca44682363d2e232374dd53a45ce8d3bc4573a87d4e818b07afb8973","time":1592471768001,"index":1,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DECQuXXZk1qEcvUxpB+6QLL+b3mPNFrPry6aivM5SHMZpaTHUKIcl95qF9zctuwhPMAt6NQaIXkNuIfOy2SycT+aDEAP6RYmh2LIzJRuiWUnNqS7/MBkU6+uFe08/9a4cnhA5HJqozwQaMBJo08w5J9weUXCjrDO6juMBZm+m10srYy4DEBnE3Wvt1jHmkCWg3eF5yCz+KYbsiUkEKUSPI2/mbjHhlRyKEPmYgxrxX/8VSNPnnbFI6ugIc9zXyuV8ykZODCqDEDVYBCiKLJYtL4UapAZjIgitov5bAqmcS34Ig95x2BZ8OXT2s+/cN+0Ck1X6MiK8q1rYFbHpydMKe2GARfU61WC","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"confirmations":6,"nextblockhash":"0x9cdc200c0efda77466e36427a056656ba0301428bba8514115bfac7bb325cd6b"}}` +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":"0x007d285c78ee9d8c904156edecb6c027ac3a84dc1222f43ed0fa8459a4f8bd24","confirmations":6,"blocktime":1592471768001,"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 { @@ -54,12 +54,12 @@ 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("9cdc200c0efda77466e36427a056656ba0301428bba8514115bfac7bb325cd6b") + b2Hash, err := util.Uint256DecodeStringLE("45f62d72e37b074ecdc9f687222b0f91ec98d6d9af4429a2caa2e076a9196b0d") if err != nil { panic(err) } @@ -79,8 +79,7 @@ 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) } @@ -620,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{} { @@ -741,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)) }, }, { @@ -1067,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)) }, }, { diff --git a/pkg/rpc/client/wsclient.go b/pkg/rpc/client/wsclient.go index 3f469a86a..4ce50b3a1 100644 --- a/pkg/rpc/client/wsclient.go +++ b/pkg/rpc/client/wsclient.go @@ -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: diff --git a/pkg/rpc/client/wsclient_test.go b/pkg/rpc/client/wsclient_test.go index a69c09cdd..17693093e 100644 --- a/pkg/rpc/client/wsclient_test.go +++ b/pkg/rpc/client/wsclient_test.go @@ -118,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) { diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 55db4fd97..8139833ab 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -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 } diff --git a/pkg/rpc/server/server_helper_test.go b/pkg/rpc/server/server_helper_test.go index 3f16f12cf..813b46839 100644 --- a/pkg/rpc/server/server_helper_test.go +++ b/pkg/rpc/server/server_helper_test.go @@ -50,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) diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 2e4810ef0..f08d397cd 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -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,7 +887,7 @@ 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) @@ -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 { diff --git a/pkg/rpc/server/testdata/testblocks.acc b/pkg/rpc/server/testdata/testblocks.acc index 8caa29c3c..2a6c5f910 100644 Binary files a/pkg/rpc/server/testdata/testblocks.acc and b/pkg/rpc/server/testdata/testblocks.acc differ diff --git a/pkg/smartcontract/context/context_test.go b/pkg/smartcontract/context/context_test.go index ecd26e3e1..30271ac6d 100644 --- a/pkg/smartcontract/context/context_test.go +++ b/pkg/smartcontract/context/context_test.go @@ -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()