block/transaction: add network magic into the hash

We make it explicit in the appropriate Block/Transaction structures, not via a
singleton as C# node does. I think this approach has a bit more potential and
allows better packages reuse for different purposes.
This commit is contained in:
Roman Khimov 2020-06-18 12:00:51 +03:00
parent 8fda6a3407
commit b483c38593
39 changed files with 244 additions and 144 deletions

View file

@ -282,7 +282,7 @@ func restoreDB(ctx *cli.Context) error {
default: default:
} }
bytes, err := readBlock(reader) bytes, err := readBlock(reader)
block := &block.Block{} block := block.New(cfg.ProtocolConfiguration.Magic)
newReader := io.NewBinReaderFromBuf(bytes) newReader := io.NewBinReaderFromBuf(bytes)
block.DecodeBinary(newReader) block.DecodeBinary(newReader)
if err != nil { if err != nil {

View file

@ -78,7 +78,7 @@ func getTX(t *testing.B, wif *keys.WIF) *transaction.Transaction {
fromAddressHash, err := address.StringToUint160(fromAddress) fromAddressHash, err := address.StringToUint160(fromAddress)
require.NoError(t, err) require.NoError(t, err)
tx := transaction.New([]byte{0x51}, 1) tx := transaction.New(netmode.UnitTestNet, []byte{0x51}, 1)
tx.Version = 0 tx.Version = 0
tx.Sender = fromAddressHash tx.Sender = fromAddressHash
tx.Attributes = append(tx.Attributes, tx.Attributes = append(tx.Attributes,

View file

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/compiler" "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"
"github.com/nspcc-dev/neo-go/pkg/core/dao" "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/interop"
@ -80,7 +81,7 @@ func TestAppCall(t *testing.T) {
inner, err := compiler.Compile(strings.NewReader(srcInner)) inner, err := compiler.Compile(strings.NewReader(srcInner))
require.NoError(t, err) 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})) require.NoError(t, ic.DAO.PutContractState(&state.Contract{Script: inner}))
ih := hash.Hash160(inner) ih := hash.Hash160(inner)

View file

@ -6,6 +6,7 @@ import (
"github.com/nspcc-dev/dbft/block" "github.com/nspcc-dev/dbft/block"
"github.com/nspcc-dev/dbft/crypto" "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/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "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} b.Block.PrevHash = util.Uint256{9, 8, 7}
require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash()) 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) b.SetTransactions(txx)
require.Equal(t, txx, b.Transactions()) require.Equal(t, txx, b.Transactions())
} }

View file

@ -9,6 +9,7 @@ import (
"github.com/nspcc-dev/dbft/block" "github.com/nspcc-dev/dbft/block"
"github.com/nspcc-dev/dbft/crypto" "github.com/nspcc-dev/dbft/crypto"
"github.com/nspcc-dev/dbft/payload" "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" 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/blockchainer"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -60,6 +61,7 @@ type service struct {
blockEvents chan *coreb.Block blockEvents chan *coreb.Block
lastProposal []util.Uint256 lastProposal []util.Uint256
wallet *wallet.Wallet wallet *wallet.Wallet
network netmode.Magic
} }
// Config is a configuration for consensus services. // Config is a configuration for consensus services.
@ -100,6 +102,7 @@ func NewService(cfg Config) (Service, error) {
transactions: make(chan *transaction.Transaction, 100), transactions: make(chan *transaction.Transaction, 100),
blockEvents: make(chan *coreb.Block, 1), blockEvents: make(chan *coreb.Block, 1),
network: cfg.Chain.GetConfig().Magic,
} }
if cfg.Wallet == nil { if cfg.Wallet == nil {
@ -127,7 +130,7 @@ func NewService(cfg Config) (Service, error) {
dbft.WithVerifyBlock(srv.verifyBlock), dbft.WithVerifyBlock(srv.verifyBlock),
dbft.WithGetBlock(srv.getBlock), dbft.WithGetBlock(srv.getBlock),
dbft.WithWatchOnly(func() bool { return false }), dbft.WithWatchOnly(func() bool { return false }),
dbft.WithNewBlockFromContext(newBlockFromContext), dbft.WithNewBlockFromContext(srv.newBlockFromContext),
dbft.WithCurrentHeight(cfg.Chain.BlockHeight), dbft.WithCurrentHeight(cfg.Chain.BlockHeight),
dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash), dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash),
dbft.WithGetValidators(srv.getValidators), dbft.WithGetValidators(srv.getValidators),
@ -459,12 +462,13 @@ func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) {
return return
} }
func newBlockFromContext(ctx *dbft.Context) block.Block { func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
block := new(neoBlock) block := new(neoBlock)
if ctx.TransactionHashes == nil { if ctx.TransactionHashes == nil {
return nil return nil
} }
block.Block.Network = s.network
block.Block.Timestamp = ctx.Timestamp / 1000000 block.Block.Timestamp = ctx.Timestamp / 1000000
block.Block.Index = ctx.BlockIndex block.Block.Index = ctx.BlockIndex
block.Block.NextConsensus = ctx.NextConsensus block.Block.NextConsensus = ctx.NextConsensus

View file

@ -24,7 +24,7 @@ import (
func TestNewService(t *testing.T) { func TestNewService(t *testing.T) {
srv := newTestService(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 tx.ValidUntilBlock = 1
addSender(t, tx) addSender(t, tx)
signTx(t, srv.Chain.FeePerByte(), tx) signTx(t, srv.Chain.FeePerByte(), tx)
@ -41,7 +41,7 @@ func TestService_GetVerified(t *testing.T) {
srv := newTestService(t) srv := newTestService(t)
var txs []*transaction.Transaction var txs []*transaction.Transaction
for i := 0; i < 4; i++ { 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.Nonce = 123 + uint32(i)
tx.ValidUntilBlock = 1 tx.ValidUntilBlock = 1
txs = append(txs, tx) txs = append(txs, tx)
@ -55,7 +55,7 @@ func TestService_GetVerified(t *testing.T) {
p := new(Payload) p := new(Payload)
p.message = &message{} p.message = &message{}
p.SetType(payload.PrepareRequestType) 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 tx.Nonce = 999
p.SetPayload(&prepareRequest{transactionHashes: hashes}) p.SetPayload(&prepareRequest{transactionHashes: hashes})
p.SetValidatorIndex(1) p.SetValidatorIndex(1)
@ -122,7 +122,7 @@ func TestService_getTx(t *testing.T) {
srv := newTestService(t) srv := newTestService(t)
t.Run("transaction in mempool", func(t *testing.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.Nonce = 1234
tx.ValidUntilBlock = 1 tx.ValidUntilBlock = 1
addSender(t, tx) addSender(t, tx)
@ -139,7 +139,7 @@ func TestService_getTx(t *testing.T) {
}) })
t.Run("transaction in local cache", func(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.Nonce = 4321
tx.ValidUntilBlock = 1 tx.ValidUntilBlock = 1
h := tx.Hash() h := tx.Hash()

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"github.com/Workiva/go-datastructures/queue" "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/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -26,12 +27,18 @@ type Block struct {
Trimmed bool Trimmed bool
} }
// auxBlock is used for JSON i/o. // auxBlockOut is used for JSON i/o.
type auxBlock struct { type auxBlockOut struct {
ConsensusData ConsensusData `json:"consensus_data"` ConsensusData ConsensusData `json:"consensus_data"`
Transactions []*transaction.Transaction `json:"tx"` 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. // Header returns the Header of the Block.
func (b *Block) Header() *Header { func (b *Block) Header() *Header {
return &Header{ return &Header{
@ -88,8 +95,11 @@ func (b *Block) Verify() error {
// This is commonly used to create a block from stored data. // This is commonly used to create a block from stored data.
// Blocks created from trimmed data will have their Trimmed field // Blocks created from trimmed data will have their Trimmed field
// set to true. // set to true.
func NewBlockFromTrimmedBytes(b []byte) (*Block, error) { func NewBlockFromTrimmedBytes(network netmode.Magic, b []byte) (*Block, error) {
block := &Block{ block := &Block{
Base: Base{
Network: network,
},
Trimmed: true, Trimmed: true,
} }
@ -117,6 +127,15 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
return block, br.Err 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 // Trim returns a subset of the block data to save up space
// in storage. // in storage.
// Notice that only the hashes of the transactions are stored. // 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) b.ConsensusData.DecodeBinary(br)
txes := make([]*transaction.Transaction, contentsCount-1) txes := make([]*transaction.Transaction, contentsCount-1)
for i := 0; i < int(contentsCount)-1; i++ { for i := 0; i < int(contentsCount)-1; i++ {
tx := new(transaction.Transaction) tx := &transaction.Transaction{Network: b.Network}
tx.DecodeBinary(br) tx.DecodeBinary(br)
txes[i] = tx txes[i] = tx
} }
@ -192,7 +211,7 @@ func (b *Block) Compare(item queue.Item) int {
// MarshalJSON implements json.Marshaler interface. // MarshalJSON implements json.Marshaler interface.
func (b Block) MarshalJSON() ([]byte, error) { func (b Block) MarshalJSON() ([]byte, error) {
auxb, err := json.Marshal(auxBlock{ auxb, err := json.Marshal(auxBlockOut{
ConsensusData: b.ConsensusData, ConsensusData: b.ConsensusData,
Transactions: b.Transactions, Transactions: b.Transactions,
}) })
@ -217,18 +236,26 @@ func (b Block) MarshalJSON() ([]byte, error) {
func (b *Block) UnmarshalJSON(data []byte) error { func (b *Block) UnmarshalJSON(data []byte) error {
// As Base and auxb are at the same level in json, // As Base and auxb are at the same level in json,
// do unmarshalling separately for both structs. // do unmarshalling separately for both structs.
auxb := new(auxBlock) auxb := new(auxBlockIn)
err := json.Unmarshal(data, auxb) err := json.Unmarshal(data, auxb)
if err != nil { if err != nil {
return err return err
} }
base := new(Base) err = json.Unmarshal(data, &b.Base)
err = json.Unmarshal(data, base)
if err != nil { if err != nil {
return err return err
} }
b.Base = *base if len(auxb.Transactions) != 0 {
b.Transactions = auxb.Transactions 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 b.ConsensusData = auxb.ConsensusData
// Some tests rely on hash presence and we're usually precomputing // Some tests rely on hash presence and we're usually precomputing
// other hashes upon deserialization. // other hashes upon deserialization.

View file

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "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/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "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/encoding/address"
@ -37,6 +38,11 @@ type Base struct {
// Script used to validate the block // Script used to validate the block
Script transaction.Witness 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 of this block, created when binary encoded (double SHA256).
hash util.Uint256 hash util.Uint256
@ -102,6 +108,7 @@ func (b *Base) EncodeBinary(bw *io.BinWriter) {
// GetSignedPart returns serialized hashable data of the block. // GetSignedPart returns serialized hashable data of the block.
func (b *Base) GetSignedPart() []byte { func (b *Base) GetSignedPart() []byte {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
buf.WriteU32LE(uint32(b.Network))
// No error can occure while encoding hashable fields. // No error can occure while encoding hashable fields.
b.encodeHashableFields(buf.BinWriter) b.encodeHashableFields(buf.BinWriter)

View file

@ -3,6 +3,7 @@ package block
import ( import (
"testing" "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/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
@ -85,7 +86,7 @@ func newDumbBlock() *Block {
Nonce: 1111, Nonce: 1111,
}, },
Transactions: []*transaction.Transaction{ Transactions: []*transaction.Transaction{
transaction.New([]byte{byte(opcode.PUSH1)}, 0), transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0),
}, },
} }
} }

View file

@ -170,7 +170,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L
} }
bc := &Blockchain{ bc := &Blockchain{
config: cfg, config: cfg,
dao: dao.NewSimple(s), dao: dao.NewSimple(s, cfg.Magic),
headersOp: make(chan headersOpFunc), headersOp: make(chan headersOpFunc),
headersOpDone: make(chan struct{}), headersOpDone: make(chan struct{}),
stopCh: make(chan struct{}), stopCh: make(chan struct{}),

View file

@ -4,6 +4,7 @@ import (
"testing" "testing"
"time" "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/block"
"github.com/nspcc-dev/neo-go/pkg/core/state" "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/core/storage"
@ -102,7 +103,7 @@ func TestScriptFromWitness(t *testing.T) {
func TestGetHeader(t *testing.T) { func TestGetHeader(t *testing.T) {
bc := newTestChain(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 tx.ValidUntilBlock = bc.BlockHeight() + 1
assert.Nil(t, addSender(tx)) assert.Nil(t, addSender(tx))
assert.Nil(t, signTx(bc, tx)) assert.Nil(t, signTx(bc, tx))
@ -267,7 +268,7 @@ func TestSubscriptions(t *testing.T) {
emit.Bytes(script.BinWriter, []byte("yay!")) emit.Bytes(script.BinWriter, []byte("yay!"))
emit.Syscall(script.BinWriter, "System.Runtime.Notify") emit.Syscall(script.BinWriter, "System.Runtime.Notify")
require.NoError(t, script.Err) require.NoError(t, script.Err)
txGood1 := transaction.New(script.Bytes(), 0) txGood1 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
txGood1.Sender = neoOwner txGood1.Sender = neoOwner
txGood1.Nonce = 1 txGood1.Nonce = 1
txGood1.ValidUntilBlock = 100500 txGood1.ValidUntilBlock = 100500
@ -279,7 +280,7 @@ func TestSubscriptions(t *testing.T) {
emit.Syscall(script.BinWriter, "System.Runtime.Notify") emit.Syscall(script.BinWriter, "System.Runtime.Notify")
emit.Opcode(script.BinWriter, opcode.THROW) emit.Opcode(script.BinWriter, opcode.THROW)
require.NoError(t, script.Err) require.NoError(t, script.Err)
txBad := transaction.New(script.Bytes(), 0) txBad := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
txBad.Sender = neoOwner txBad.Sender = neoOwner
txBad.Nonce = 2 txBad.Nonce = 2
txBad.ValidUntilBlock = 100500 txBad.ValidUntilBlock = 100500
@ -289,7 +290,7 @@ func TestSubscriptions(t *testing.T) {
emit.Bytes(script.BinWriter, []byte("yay! yay! yay!")) emit.Bytes(script.BinWriter, []byte("yay! yay! yay!"))
emit.Syscall(script.BinWriter, "System.Runtime.Notify") emit.Syscall(script.BinWriter, "System.Runtime.Notify")
require.NoError(t, script.Err) require.NoError(t, script.Err)
txGood2 := transaction.New(script.Bytes(), 0) txGood2 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
txGood2.Sender = neoOwner txGood2.Sender = neoOwner
txGood2.Nonce = 3 txGood2.Nonce = 3
txGood2.ValidUntilBlock = 100500 txGood2.ValidUntilBlock = 100500

View file

@ -3,6 +3,7 @@ package dao
import ( import (
"testing" "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/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
@ -16,7 +17,7 @@ import (
func TestCachedDaoAccounts(t *testing.T) { func TestCachedDaoAccounts(t *testing.T) {
store := storage.NewMemoryStore() store := storage.NewMemoryStore()
// Persistent DAO to check for backing storage. // Persistent DAO to check for backing storage.
pdao := NewSimple(store) pdao := NewSimple(store, netmode.UnitTestNet)
// Cached DAO. // Cached DAO.
cdao := NewCached(pdao) cdao := NewCached(pdao)
@ -52,7 +53,7 @@ func TestCachedDaoAccounts(t *testing.T) {
func TestCachedDaoContracts(t *testing.T) { func TestCachedDaoContracts(t *testing.T) {
store := storage.NewMemoryStore() store := storage.NewMemoryStore()
pdao := NewSimple(store) pdao := NewSimple(store, netmode.UnitTestNet)
dao := NewCached(pdao) dao := NewCached(pdao)
script := []byte{0xde, 0xad, 0xbe, 0xef} script := []byte{0xde, 0xad, 0xbe, 0xef}
@ -97,7 +98,7 @@ func TestCachedDaoContracts(t *testing.T) {
func TestCachedCachedDao(t *testing.T) { func TestCachedCachedDao(t *testing.T) {
store := storage.NewMemoryStore() store := storage.NewMemoryStore()
// Persistent DAO to check for backing storage. // Persistent DAO to check for backing storage.
pdao := NewSimple(store) pdao := NewSimple(store, netmode.UnitTestNet)
assert.NotEqual(t, store, pdao.Store) assert.NotEqual(t, store, pdao.Store)
// Cached DAO. // Cached DAO.
cdao := NewCached(pdao) cdao := NewCached(pdao)

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"sort" "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/block"
"github.com/nspcc-dev/neo-go/pkg/core/state" "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/core/storage"
@ -58,12 +59,13 @@ type DAO interface {
// Simple is memCached wrapper around DB, simple DAO implementation. // Simple is memCached wrapper around DB, simple DAO implementation.
type Simple struct { type Simple struct {
Store *storage.MemCachedStore Store *storage.MemCachedStore
network netmode.Magic
} }
// NewSimple creates new simple dao using provided backend store. // NewSimple creates new simple dao using provided backend store.
func NewSimple(backend storage.Store) *Simple { func NewSimple(backend storage.Store, network netmode.Magic) *Simple {
return &Simple{Store: storage.NewMemCachedStore(backend)} return &Simple{Store: storage.NewMemCachedStore(backend), network: network}
} }
// GetBatch returns currently accumulated DB changeset. // 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 // GetWrapped returns new DAO instance with another layer of wrapped
// MemCachedStore around the current DAO Store. // MemCachedStore around the current DAO Store.
func (dao *Simple) GetWrapped() DAO { func (dao *Simple) GetWrapped() DAO {
return NewSimple(dao.Store) return NewSimple(dao.Store, dao.network)
} }
// GetAndDecode performs get operation and decoding with serializable structures. // 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 return nil, err
} }
block, err := block.NewBlockFromTrimmedBytes(b) block, err := block.NewBlockFromTrimmedBytes(dao.network, b)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -455,7 +457,7 @@ func (dao *Simple) GetTransaction(hash util.Uint256) (*transaction.Transaction,
var height = r.ReadU32LE() var height = r.ReadU32LE()
tx := &transaction.Transaction{} tx := &transaction.Transaction{Network: dao.network}
tx.DecodeBinary(r) tx.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
return nil, 0, r.Err return nil, 0, r.Err

View file

@ -3,6 +3,7 @@ package dao
import ( import (
"testing" "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/block"
"github.com/nspcc-dev/neo-go/pkg/core/state" "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/core/storage"
@ -15,7 +16,7 @@ import (
) )
func TestPutGetAndDecode(t *testing.T) { func TestPutGetAndDecode(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
serializable := &TestSerializable{field: random.String(4)} serializable := &TestSerializable{field: random.String(4)}
hash := []byte{1} hash := []byte{1}
err := dao.Put(serializable, hash) err := dao.Put(serializable, hash)
@ -40,7 +41,7 @@ func (t *TestSerializable) DecodeBinary(reader *io.BinReader) {
} }
func TestGetAccountStateOrNew_New(t *testing.T) { func TestGetAccountStateOrNew_New(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint160() hash := random.Uint160()
createdAccount, err := dao.GetAccountStateOrNew(hash) createdAccount, err := dao.GetAccountStateOrNew(hash)
require.NoError(t, err) require.NoError(t, err)
@ -48,7 +49,7 @@ func TestGetAccountStateOrNew_New(t *testing.T) {
} }
func TestPutAndGetAccountStateOrNew(t *testing.T) { func TestPutAndGetAccountStateOrNew(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint160() hash := random.Uint160()
accountState := &state.Account{ScriptHash: hash} accountState := &state.Account{ScriptHash: hash}
err := dao.PutAccountState(accountState) err := dao.PutAccountState(accountState)
@ -59,7 +60,7 @@ func TestPutAndGetAccountStateOrNew(t *testing.T) {
} }
func TestPutAndGetContractState(t *testing.T) { func TestPutAndGetContractState(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
contractState := &state.Contract{Script: []byte{}} contractState := &state.Contract{Script: []byte{}}
hash := contractState.ScriptHash() hash := contractState.ScriptHash()
err := dao.PutContractState(contractState) err := dao.PutContractState(contractState)
@ -70,7 +71,7 @@ func TestPutAndGetContractState(t *testing.T) {
} }
func TestDeleteContractState(t *testing.T) { func TestDeleteContractState(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
contractState := &state.Contract{Script: []byte{}} contractState := &state.Contract{Script: []byte{}}
hash := contractState.ScriptHash() hash := contractState.ScriptHash()
err := dao.PutContractState(contractState) err := dao.PutContractState(contractState)
@ -83,7 +84,7 @@ func TestDeleteContractState(t *testing.T) {
} }
func TestSimple_GetNextContractID(t *testing.T) { func TestSimple_GetNextContractID(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
id, err := dao.GetNextContractID() id, err := dao.GetNextContractID()
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, 0, id) require.EqualValues(t, 0, id)
@ -94,7 +95,7 @@ func TestSimple_GetNextContractID(t *testing.T) {
} }
func TestPutGetAppExecResult(t *testing.T) { func TestPutGetAppExecResult(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint256() hash := random.Uint256()
appExecResult := &state.AppExecResult{ appExecResult := &state.AppExecResult{
TxHash: hash, TxHash: hash,
@ -109,7 +110,7 @@ func TestPutGetAppExecResult(t *testing.T) {
} }
func TestPutGetStorageItem(t *testing.T) { func TestPutGetStorageItem(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint160() hash := random.Uint160()
key := []byte{0} key := []byte{0}
storageItem := &state.StorageItem{Value: []uint8{}} storageItem := &state.StorageItem{Value: []uint8{}}
@ -120,7 +121,7 @@ func TestPutGetStorageItem(t *testing.T) {
} }
func TestDeleteStorageItem(t *testing.T) { func TestDeleteStorageItem(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint160() hash := random.Uint160()
key := []byte{0} key := []byte{0}
storageItem := &state.StorageItem{Value: []uint8{}} storageItem := &state.StorageItem{Value: []uint8{}}
@ -133,7 +134,7 @@ func TestDeleteStorageItem(t *testing.T) {
} }
func TestGetBlock_NotExists(t *testing.T) { func TestGetBlock_NotExists(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint256() hash := random.Uint256()
block, err := dao.GetBlock(hash) block, err := dao.GetBlock(hash)
require.Error(t, err) require.Error(t, err)
@ -141,7 +142,7 @@ func TestGetBlock_NotExists(t *testing.T) {
} }
func TestPutGetBlock(t *testing.T) { func TestPutGetBlock(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
b := &block.Block{ b := &block.Block{
Base: block.Base{ Base: block.Base{
Script: transaction.Witness{ Script: transaction.Witness{
@ -159,14 +160,14 @@ func TestPutGetBlock(t *testing.T) {
} }
func TestGetVersion_NoVersion(t *testing.T) { func TestGetVersion_NoVersion(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
version, err := dao.GetVersion() version, err := dao.GetVersion()
require.Error(t, err) require.Error(t, err)
require.Equal(t, "", version) require.Equal(t, "", version)
} }
func TestGetVersion(t *testing.T) { func TestGetVersion(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
err := dao.PutVersion("testVersion") err := dao.PutVersion("testVersion")
require.NoError(t, err) require.NoError(t, err)
version, err := dao.GetVersion() version, err := dao.GetVersion()
@ -175,14 +176,14 @@ func TestGetVersion(t *testing.T) {
} }
func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) { func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
height, err := dao.GetCurrentBlockHeight() height, err := dao.GetCurrentBlockHeight()
require.Error(t, err) require.Error(t, err)
require.Equal(t, uint32(0), height) require.Equal(t, uint32(0), height)
} }
func TestGetCurrentHeaderHeight_Store(t *testing.T) { func TestGetCurrentHeaderHeight_Store(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
b := &block.Block{ b := &block.Block{
Base: block.Base{ Base: block.Base{
Script: transaction.Witness{ Script: transaction.Witness{
@ -199,8 +200,8 @@ func TestGetCurrentHeaderHeight_Store(t *testing.T) {
} }
func TestStoreAsTransaction(t *testing.T) { func TestStoreAsTransaction(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 1) tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 1)
hash := tx.Hash() hash := tx.Hash()
err := dao.StoreAsTransaction(tx, 0) err := dao.StoreAsTransaction(tx, 0)
require.NoError(t, err) require.NoError(t, err)

View file

@ -10,7 +10,6 @@ import (
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/config" "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/block"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "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 // newTestChain should be called before newBlock invocation to properly setup
// global state. // global state.
func newTestChain(t *testing.T) *Blockchain { func newTestChain(t *testing.T) *Blockchain {
unitTestNetCfg, err := config.Load("../../config", netmode.UnitTestNet) unitTestNetCfg, err := config.Load("../../config", testchain.Network())
require.NoError(t, err) require.NoError(t, err)
chain, err := NewBlockchain(storage.NewMemoryStore(), unitTestNetCfg.ProtocolConfiguration, zaptest.NewLogger(t)) chain, err := NewBlockchain(storage.NewMemoryStore(), unitTestNetCfg.ProtocolConfiguration, zaptest.NewLogger(t))
require.NoError(t, err) require.NoError(t, err)
@ -60,6 +59,7 @@ func newBlock(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256,
} }
b := &block.Block{ b := &block.Block{
Base: block.Base{ Base: block.Base{
Network: testchain.Network(),
Version: 0, Version: 0,
PrevHash: prev, PrevHash: prev,
Timestamp: uint64(time.Now().UTC().Unix())*1000 + uint64(index), 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)) b, err := hex.DecodeString(data["raw"].(string))
require.NoError(t, err) require.NoError(t, err)
block := &block.Block{} block := block.New(testchain.Network())
require.NoError(t, testserdes.DecodeBinary(b, block)) require.NoError(t, testserdes.DecodeBinary(b, block))
return block return block
@ -124,6 +124,7 @@ func getBlockData(i int) (map[string]interface{}, error) {
func newDumbBlock() *block.Block { func newDumbBlock() *block.Block {
return &block.Block{ return &block.Block{
Base: block.Base{ Base: block.Base{
Network: testchain.Network(),
Version: 0, Version: 0,
PrevHash: hash.Sha256([]byte("a")), PrevHash: hash.Sha256([]byte("a")),
MerkleRoot: hash.Sha256([]byte("b")), MerkleRoot: hash.Sha256([]byte("b")),
@ -140,7 +141,7 @@ func newDumbBlock() *block.Block {
Nonce: 1111, Nonce: 1111,
}, },
Transactions: []*transaction.Transaction{ 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() txScript := script.Bytes()
invFee := util.Fixed8FromFloat(100) invFee := util.Fixed8FromFloat(100)
txDeploy := transaction.New(txScript, invFee) txDeploy := transaction.New(testchain.Network(), txScript, invFee)
txDeploy.Nonce = getNextNonce() txDeploy.Nonce = getNextNonce()
txDeploy.ValidUntilBlock = validUntilBlock txDeploy.ValidUntilBlock = validUntilBlock
txDeploy.Sender = priv0ScriptHash txDeploy.Sender = priv0ScriptHash
@ -255,7 +256,7 @@ func TestCreateBasicChain(t *testing.T) {
script = io.NewBufBinWriter() script = io.NewBufBinWriter()
emit.AppCallWithOperationAndArgs(script.BinWriter, hash.Hash160(avm), "Put", "testkey", "testvalue") 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.Nonce = getNextNonce()
txInv.ValidUntilBlock = validUntilBlock txInv.ValidUntilBlock = validUntilBlock
txInv.Sender = priv0ScriptHash txInv.Sender = priv0ScriptHash
@ -286,7 +287,7 @@ func TestCreateBasicChain(t *testing.T) {
sh := hash.Hash160(avm) sh := hash.Hash160(avm)
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.AppCallWithOperationAndArgs(w.BinWriter, sh, "init") emit.AppCallWithOperationAndArgs(w.BinWriter, sh, "init")
initTx := transaction.New(w.Bytes(), 0) initTx := transaction.New(testchain.Network(), w.Bytes(), 0)
initTx.Nonce = getNextNonce() initTx.Nonce = getNextNonce()
initTx.ValidUntilBlock = validUntilBlock initTx.ValidUntilBlock = validUntilBlock
initTx.Sender = priv0ScriptHash initTx.Sender = priv0ScriptHash
@ -376,7 +377,7 @@ func newNEP5Transfer(sc, from, to util.Uint160, amount int64) *transaction.Trans
emit.Opcode(w.BinWriter, opcode.ASSERT) emit.Opcode(w.BinWriter, opcode.ASSERT)
script := w.Bytes() script := w.Bytes()
return transaction.New(script, 0) return transaction.New(testchain.Network(), script, 0)
} }
func addSender(txs ...*transaction.Transaction) error { func addSender(txs ...*transaction.Transaction) error {

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"testing" "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/block"
"github.com/nspcc-dev/neo-go/pkg/core/dao" "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/interop"
@ -143,7 +144,7 @@ func TestECDSAVerify(t *testing.T) {
chain := newTestChain(t) chain := newTestChain(t)
defer chain.Close() 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{}) { runCase := func(t *testing.T, isErr bool, result interface{}, args ...interface{}) {
v := vm.New() v := vm.New()
for i := range args { for i := range args {
@ -177,14 +178,14 @@ func TestECDSAVerify(t *testing.T) {
}) })
t.Run("signed interop item", func(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() msg := tx.GetSignedPart()
sign := priv.Sign(msg) sign := priv.Sign(msg)
runCase(t, false, true, sign, priv.PublicKey().Bytes(), stackitem.NewInterop(tx)) runCase(t, false, true, sign, priv.PublicKey().Bytes(), stackitem.NewInterop(tx))
}) })
t.Run("signed script container", func(t *testing.T) { 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() msg := tx.GetSignedPart()
sign := priv.Sign(msg) sign := priv.Sign(msg)
ic.Container = tx ic.Container = tx
@ -218,7 +219,7 @@ func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
v := vm.New() v := vm.New()
chain := newTestChain(t) chain := newTestChain(t)
context := chain.newInteropContext(trigger.Application, context := chain.newInteropContext(trigger.Application,
dao.NewSimple(storage.NewMemoryStore()), nil, nil) dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil)
return v, context, chain return v, context, chain
} }
@ -232,7 +233,7 @@ func createVMAndBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Bl
v := vm.New() v := vm.New()
block := newDumbBlock() block := newDumbBlock()
chain := newTestChain(t) 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 return v, block, context, chain
} }
@ -259,7 +260,7 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.C
} }
chain := newTestChain(t) 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 return v, contractState, context, chain
} }
@ -271,14 +272,14 @@ func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interop.Context
require.NoError(t, err) require.NoError(t, err)
chain := newTestChain(t) 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 return v, accountState, context, chain
} }
func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) { func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
v := vm.New() v := vm.New()
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)} script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
tx := transaction.New(script, 0) tx := transaction.New(netmode.UnitTestNet, script, 0)
bytes := make([]byte, 1) bytes := make([]byte, 1)
attributes := append(tx.Attributes, transaction.Attribute{ attributes := append(tx.Attributes, transaction.Attribute{
@ -288,6 +289,6 @@ func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Con
tx.Attributes = attributes tx.Attributes = attributes
chain := newTestChain(t) 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 return v, tx, context, chain
} }

View file

@ -5,6 +5,7 @@ import (
"runtime" "runtime"
"testing" "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/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "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) v.Estack().PushVal(value)
chain := newTestChain(t) chain := newTestChain(t)
defer chain.Close() 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)) require.Error(t, f(context, v))
} }

View file

@ -4,6 +4,7 @@ import (
"sort" "sort"
"testing" "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/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "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) { func testMemPoolAddRemoveWithFeer(t *testing.T, fs Feer) {
mp := NewMemPool(10) mp := NewMemPool(10)
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
tx.Nonce = 0 tx.Nonce = 0
_, ok := mp.TryGetValue(tx.Hash()) _, ok := mp.TryGetValue(tx.Hash())
require.Equal(t, false, ok) require.Equal(t, false, ok)
@ -61,7 +62,7 @@ func TestOverCapacity(t *testing.T) {
mp := NewMemPool(mempoolSize) mp := NewMemPool(mempoolSize)
for i := 0; i < mempoolSize; i++ { 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) tx.Nonce = uint32(i)
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
} }
@ -71,7 +72,7 @@ func TestOverCapacity(t *testing.T) {
// Fees are also prioritized. // Fees are also prioritized.
for i := 0; i < mempoolSize; i++ { 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{ tx.Attributes = append(tx.Attributes, transaction.Attribute{
Usage: transaction.Hash1, Usage: transaction.Hash1,
Data: util.Uint256{1, 2, 3, 4}.BytesBE(), 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))) require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes)))
} }
// Less prioritized txes are not allowed anymore. // 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{ tx.Attributes = append(tx.Attributes, transaction.Attribute{
Usage: transaction.Hash1, Usage: transaction.Hash1,
Data: util.Uint256{1, 2, 3, 4}.BytesBE(), 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))) require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes)))
// Low net fee, but higher per-byte fee is still a better combination. // 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.Nonce = txcnt
tx.NetworkFee = util.Fixed8FromFloat(0.00007) tx.NetworkFee = util.Fixed8FromFloat(0.00007)
txcnt++ txcnt++
@ -111,7 +112,7 @@ func TestOverCapacity(t *testing.T) {
// High priority always wins over low priority. // High priority always wins over low priority.
fs.lowPriority = false fs.lowPriority = false
for i := 0; i < mempoolSize; i++ { 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 tx.Nonce = txcnt
txcnt++ txcnt++
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
@ -120,7 +121,7 @@ func TestOverCapacity(t *testing.T) {
} }
// Good luck with low priority now. // Good luck with low priority now.
fs.lowPriority = true fs.lowPriority = true
tx = transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
tx.Nonce = txcnt tx.Nonce = txcnt
require.Error(t, mp.Add(tx, fs)) require.Error(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
@ -134,7 +135,7 @@ func TestGetVerified(t *testing.T) {
txes := make([]*transaction.Transaction, 0, mempoolSize) txes := make([]*transaction.Transaction, 0, mempoolSize)
for i := 0; i < mempoolSize; i++ { 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) tx.Nonce = uint32(i)
txes = append(txes, tx) txes = append(txes, tx)
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
@ -158,7 +159,7 @@ func TestRemoveStale(t *testing.T) {
txes1 := make([]*transaction.Transaction, 0, mempoolSize/2) txes1 := make([]*transaction.Transaction, 0, mempoolSize/2)
txes2 := make([]*transaction.Transaction, 0, mempoolSize/2) txes2 := make([]*transaction.Transaction, 0, mempoolSize/2)
for i := 0; i < mempoolSize; i++ { 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) tx.Nonce = uint32(i)
if i%2 == 0 { if i%2 == 0 {
txes1 = append(txes1, tx) txes1 = append(txes1, tx)
@ -187,7 +188,7 @@ func TestRemoveStale(t *testing.T) {
func TestMemPoolFees(t *testing.T) { func TestMemPoolFees(t *testing.T) {
mp := NewMemPool(10) mp := NewMemPool(10)
sender0 := util.Uint160{1, 2, 3} 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.NetworkFee = util.Fixed8FromInt64(11000)
tx0.Sender = sender0 tx0.Sender = sender0
// insufficient funds to add transaction, but balance should be stored // insufficient funds to add transaction, but balance should be stored
@ -200,7 +201,7 @@ func TestMemPoolFees(t *testing.T) {
}, mp.fees[sender0]) }, mp.fees[sender0])
// no problems with adding another transaction with lower fee // 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.NetworkFee = util.Fixed8FromInt64(7000)
tx1.Sender = sender0 tx1.Sender = sender0
require.NoError(t, mp.Add(tx1, &FeerStub{})) require.NoError(t, mp.Add(tx1, &FeerStub{}))
@ -211,7 +212,7 @@ func TestMemPoolFees(t *testing.T) {
}, mp.fees[sender0]) }, mp.fees[sender0])
// balance shouldn't change after adding one more transaction // 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.NetworkFee = util.Fixed8FromFloat(3000)
tx2.Sender = sender0 tx2.Sender = sender0
require.NoError(t, mp.Add(tx2, &FeerStub{})) require.NoError(t, mp.Add(tx2, &FeerStub{}))
@ -223,7 +224,7 @@ func TestMemPoolFees(t *testing.T) {
}, mp.fees[sender0]) }, mp.fees[sender0])
// can't add more transactions as we don't have enough GAS // 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.NetworkFee = util.Fixed8FromFloat(0.5)
tx3.Sender = sender0 tx3.Sender = sender0
require.Equal(t, false, mp.Verify(tx3, &FeerStub{})) require.Equal(t, false, mp.Verify(tx3, &FeerStub{}))

View file

@ -92,7 +92,7 @@ func TestNativeContract_Invoke(t *testing.T) {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28)) emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28))
script := w.Bytes() script := w.Bytes()
tx := transaction.New(script, 0) tx := transaction.New(chain.GetConfig().Magic, script, 0)
validUntil := chain.blockHeight + 1 validUntil := chain.blockHeight + 1
tx.ValidUntilBlock = validUntil tx.ValidUntilBlock = validUntil
require.NoError(t, addSender(tx)) require.NoError(t, addSender(tx))

View file

@ -4,6 +4,7 @@ import (
"encoding/hex" "encoding/hex"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -16,7 +17,7 @@ var (
func decodeTransaction(rawTX string, t *testing.T) *Transaction { func decodeTransaction(rawTX string, t *testing.T) *Transaction {
b, err1 := hex.DecodeString(rawTX) b, err1 := hex.DecodeString(rawTX)
assert.Nil(t, err1) assert.Nil(t, err1)
tx, err := NewTransactionFromBytes(b) tx, err := NewTransactionFromBytes(netmode.UnitTestNet, b)
assert.NoError(t, err) assert.NoError(t, err)
return tx return tx
} }

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"math/rand" "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/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -58,6 +59,11 @@ type Transaction struct {
// and invocation script. // and invocation script.
Scripts []Witness 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 of the transaction (double SHA256).
hash util.Uint256 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 // New returns a new transaction to execute given script and pay given system
// fee. // fee.
func New(script []byte, gas util.Fixed8) *Transaction { func New(network netmode.Magic, script []byte, gas util.Fixed8) *Transaction {
return &Transaction{ return &Transaction{
Version: 0, Version: 0,
Nonce: rand.Uint32(), Nonce: rand.Uint32(),
@ -89,6 +95,7 @@ func New(script []byte, gas util.Fixed8) *Transaction {
Attributes: []Attribute{}, Attributes: []Attribute{},
Cosigners: []Cosigner{}, Cosigners: []Cosigner{},
Scripts: []Witness{}, Scripts: []Witness{},
Network: network,
} }
} }
@ -203,22 +210,25 @@ func (t *Transaction) encodeHashableFields(bw *io.BinWriter) {
// createHash creates the hash of the transaction. // createHash creates the hash of the transaction.
func (t *Transaction) createHash() error { func (t *Transaction) createHash() error {
buf := io.NewBufBinWriter() b := t.GetSignedPart()
t.encodeHashableFields(buf.BinWriter) if b == nil {
if buf.Err != nil { return errors.New("failed to serialize hashable data")
return buf.Err
} }
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.verificationHash = hash.Sha256(b)
t.hash = hash.Sha256(t.verificationHash.BytesBE()) t.hash = hash.Sha256(t.verificationHash.BytesBE())
return nil
} }
// GetSignedPart returns a part of the transaction which must be signed. // GetSignedPart returns a part of the transaction which must be signed.
func (t *Transaction) GetSignedPart() []byte { func (t *Transaction) GetSignedPart() []byte {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
buf.WriteU32LE(uint32(t.Network))
t.encodeHashableFields(buf.BinWriter) t.encodeHashableFields(buf.BinWriter)
if buf.Err != nil { if buf.Err != nil {
return nil return nil
@ -229,6 +239,7 @@ func (t *Transaction) GetSignedPart() []byte {
// DecodeSignedPart decodes a part of transaction from GetSignedPart data. // DecodeSignedPart decodes a part of transaction from GetSignedPart data.
func (t *Transaction) DecodeSignedPart(buf []byte) error { func (t *Transaction) DecodeSignedPart(buf []byte) error {
r := io.NewBinReaderFromBuf(buf) r := io.NewBinReaderFromBuf(buf)
t.Network = netmode.Magic(r.ReadU32LE())
t.decodeHashableFields(r) t.decodeHashableFields(r)
if r.Err != nil { if r.Err != nil {
return r.Err return r.Err
@ -239,7 +250,7 @@ func (t *Transaction) DecodeSignedPart(buf []byte) error {
return errors.New("additional data after the signed part") return errors.New("additional data after the signed part")
} }
t.Scripts = make([]Witness, 0) t.Scripts = make([]Witness, 0)
_ = t.createHash() t.updateHashes(buf)
return nil return nil
} }
@ -254,8 +265,8 @@ func (t *Transaction) Bytes() []byte {
} }
// NewTransactionFromBytes decodes byte array into *Transaction // NewTransactionFromBytes decodes byte array into *Transaction
func NewTransactionFromBytes(b []byte) (*Transaction, error) { func NewTransactionFromBytes(network netmode.Magic, b []byte) (*Transaction, error) {
tx := &Transaction{} tx := &Transaction{Network: network}
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
tx.DecodeBinary(r) tx.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {

View file

@ -4,6 +4,7 @@ import (
"encoding/hex" "encoding/hex"
"testing" "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/internal/testserdes"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -63,12 +64,12 @@ func TestDecodeEncodeInvocationTX(t *testing.T) {
func TestNew(t *testing.T) { func TestNew(t *testing.T) {
script := []byte{0x51} script := []byte{0x51}
tx := New(script, 1) tx := New(netmode.UnitTestNet, script, 1)
assert.Equal(t, util.Fixed8(1), tx.SystemFee) assert.Equal(t, util.Fixed8(1), tx.SystemFee)
assert.Equal(t, script, tx.Script) assert.Equal(t, script, tx.Script)
// Update hash fields to match tx2 that is gonna autoupdate them on decode. // Update hash fields to match tx2 that is gonna autoupdate them on decode.
_ = tx.Hash() _ = tx.Hash()
testserdes.EncodeDecodeBinary(t, tx, new(Transaction)) testserdes.EncodeDecodeBinary(t, tx, &Transaction{Network: netmode.UnitTestNet})
} }
func TestEncodingTXWithNoScript(t *testing.T) { func TestEncodingTXWithNoScript(t *testing.T) {

View file

@ -4,6 +4,7 @@ import (
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/config" "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/block"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "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/crypto/hash"
@ -53,12 +54,13 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
InvocationScript: []byte{}, InvocationScript: []byte{},
VerificationScript: []byte{byte(opcode.PUSH1)}, VerificationScript: []byte{byte(opcode.PUSH1)},
}, },
Network: cfg.Magic,
} }
b := &block.Block{ b := &block.Block{
Base: base, Base: base,
Transactions: []*transaction.Transaction{ Transactions: []*transaction.Transaction{
deployNativeContracts(), deployNativeContracts(cfg.Magic),
}, },
ConsensusData: block.ConsensusData{ ConsensusData: block.ConsensusData{
PrimaryIndex: 0, PrimaryIndex: 0,
@ -73,11 +75,11 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
return b, nil return b, nil
} }
func deployNativeContracts() *transaction.Transaction { func deployNativeContracts(magic netmode.Magic) *transaction.Transaction {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
emit.Syscall(buf.BinWriter, "Neo.Native.Deploy") emit.Syscall(buf.BinWriter, "Neo.Native.Deploy")
script := buf.Bytes() script := buf.Bytes()
tx := transaction.New(script, 0) tx := transaction.New(magic, script, 0)
tx.Nonce = 0 tx.Nonce = 0
tx.Sender = hash.Hash160([]byte{byte(opcode.PUSH1)}) tx.Sender = hash.Hash160([]byte{byte(opcode.PUSH1)})
tx.Scripts = []transaction.Witness{ tx.Scripts = []transaction.Witness{

View file

@ -21,7 +21,7 @@ func TestGenesisBlockMainNet(t *testing.T) {
// have been changed. Consequently, hash of the genesis block has been changed. // have been changed. Consequently, hash of the genesis block has been changed.
// Update expected genesis block hash for better times. // Update expected genesis block hash for better times.
// Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf" // Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf"
expect := "2b8a21dfaf989dc1a5f2694517aefdbda1dd340f3cf177187d73e038a58ad2bb" expect := "dba446947a90b2862ef050703b44828ad8b02d11978f8ef59bd3e1c97aabf6e5"
assert.Equal(t, expect, block.Hash().StringLE()) assert.Equal(t, expect, block.Hash().StringLE())
} }

View 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
}

View file

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "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/consensus"
"github.com/nspcc-dev/neo-go/pkg/core/block" "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/core/transaction"
@ -33,6 +34,10 @@ type Message struct {
// Compressed message payload. // Compressed message payload.
compressedPayload []byte 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 // MessageFlag represents compression level of message payload
@ -83,7 +88,8 @@ const (
CMDAlert CommandType = 0x40 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 { func NewMessage(cmd CommandType, p payload.Payload) *Message {
return &Message{ return &Message{
Command: cmd, Command: cmd,
@ -135,7 +141,7 @@ func (m *Message) decodePayload() error {
case CMDAddr: case CMDAddr:
p = &payload.AddressList{} p = &payload.AddressList{}
case CMDBlock: case CMDBlock:
p = &block.Block{} p = block.New(m.Network)
case CMDConsensus: case CMDConsensus:
p = &consensus.Payload{} p = &consensus.Payload{}
case CMDGetBlocks: case CMDGetBlocks:
@ -145,9 +151,9 @@ func (m *Message) decodePayload() error {
case CMDGetBlockData: case CMDGetBlockData:
p = &payload.GetBlockData{} p = &payload.GetBlockData{}
case CMDHeaders: case CMDHeaders:
p = &payload.Headers{} p = &payload.Headers{Network: m.Network}
case CMDTX: case CMDTX:
p = &transaction.Transaction{} p = &transaction.Transaction{Network: m.Network}
case CMDMerkleBlock: case CMDMerkleBlock:
p = &payload.MerkleBlock{} p = &payload.MerkleBlock{}
case CMDPing, CMDPong: case CMDPing, CMDPong:

View file

@ -1,6 +1,7 @@
package payload package payload
import ( 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/core/block"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -8,7 +9,8 @@ import (
// Headers payload. // Headers payload.
type Headers struct { type Headers struct {
Hdrs []*block.Header Hdrs []*block.Header
Network netmode.Magic
} }
// Users can at most request 2k header. // 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++ { for i := 0; i < int(lenHeaders); i++ {
header := &block.Header{} header := &block.Header{}
header.Network = p.Network
header.DecodeBinary(br) header.DecodeBinary(br)
p.Hdrs[i] = header p.Hdrs[i] = header
} }

View file

@ -10,6 +10,7 @@ import (
"sync" "sync"
"time" "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/consensus"
"github.com/nspcc-dev/neo-go/pkg/core" "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/block"
@ -53,6 +54,9 @@ type (
// id also known as the nonce of the server. // id also known as the nonce of the server.
id uint32 id uint32
// Network's magic number for correct message decoding.
network netmode.Magic
transport Transporter transport Transporter
discovery Discoverer discovery Discoverer
chain blockchainer.Blockchainer chain blockchainer.Blockchainer
@ -95,6 +99,7 @@ func NewServer(config ServerConfig, chain blockchainer.Blockchainer, log *zap.Lo
ServerConfig: config, ServerConfig: config,
chain: chain, chain: chain,
id: randomID(), id: randomID(),
network: chain.GetConfig().Magic,
quit: make(chan struct{}), quit: make(chan struct{}),
register: make(chan Peer), register: make(chan Peer),
unregister: make(chan peerDrop), unregister: make(chan peerDrop),

View file

@ -150,7 +150,7 @@ func (p *TCPPeer) handleConn() {
if err == nil { if err == nil {
r := io.NewBinReaderFromIO(p.conn) r := io.NewBinReaderFromIO(p.conn)
for { for {
msg := &Message{} msg := &Message{Network: p.server.network}
err = msg.Decode(r) err = msg.Decode(r)
if err == payload.ErrTooManyHeaders { if err == payload.ErrTooManyHeaders {

View file

@ -109,7 +109,7 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke
emit.Opcode(w.BinWriter, opcode.ASSERT) emit.Opcode(w.BinWriter, opcode.ASSERT)
script := w.Bytes() script := w.Bytes()
tx := transaction.New(script, gas) tx := transaction.New(c.opts.Network, script, gas)
tx.Sender = from tx.Sender = from
tx.Cosigners = []transaction.Cosigner{ tx.Cosigners = []transaction.Cosigner{
{ {

View file

@ -72,7 +72,7 @@ func (c *Client) getBlock(params request.RawParams) (*block.Block, error) {
return nil, err return nil, err
} }
r := io.NewBinReaderFromBuf(blockBytes) r := io.NewBinReaderFromBuf(blockBytes)
b = new(block.Block) b = block.New(c.opts.Network)
b.DecodeBinary(r) b.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
return nil, r.Err return nil, r.Err
@ -98,6 +98,7 @@ func (c *Client) getBlockVerbose(params request.RawParams) (*result.Block, error
resp = &result.Block{} resp = &result.Block{}
err error err error
) )
resp.Network = c.opts.Network
if err = c.performRequest("getblock", params, resp); err != nil { if err = c.performRequest("getblock", params, resp); err != nil {
return nil, err return nil, err
} }
@ -133,6 +134,7 @@ func (c *Client) GetBlockHeader(hash util.Uint256) (*block.Header, error) {
} }
r := io.NewBinReaderFromBuf(headerBytes) r := io.NewBinReaderFromBuf(headerBytes)
h = new(block.Header) h = new(block.Header)
h.Network = c.opts.Network
h.DecodeBinary(r) h.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
return nil, r.Err return nil, r.Err
@ -247,7 +249,7 @@ func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction,
if err != nil { if err != nil {
return nil, err return nil, err
} }
tx, err := transaction.NewTransactionFromBytes(txBytes) tx, err := transaction.NewTransactionFromBytes(c.opts.Network, txBytes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -263,6 +265,7 @@ func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.Transactio
resp = &result.TransactionOutputRaw{} resp = &result.TransactionOutputRaw{}
err error err error
) )
resp.Network = c.opts.Network
if err = c.performRequest("getrawtransaction", params, resp); err != nil { if err = c.performRequest("getrawtransaction", params, resp); err != nil {
return nil, err return nil, err
} }
@ -421,7 +424,7 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys
var txHash util.Uint256 var txHash util.Uint256
var err error var err error
tx := transaction.New(script, sysfee) tx := transaction.New(c.opts.Network, script, sysfee)
tx.SystemFee = sysfee tx.SystemFee = sysfee
validUntilBlock, err := c.CalculateValidUntilBlock() validUntilBlock, err := c.CalculateValidUntilBlock()

View file

@ -36,17 +36,17 @@ type rpcClientTestCase struct {
check func(t *testing.T, c *Client, result interface{}) 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. // getResultBlock1 returns data for block number 1 which is used by several tests.
func getResultBlock1() *result.Block { func getResultBlock1() *result.Block {
@ -54,12 +54,12 @@ func getResultBlock1() *result.Block {
if err != nil { if err != nil {
panic(err) panic(err)
} }
b := new(block.Block) b := block.New(netmode.UnitTestNet)
err = testserdes.DecodeBinary(binB, b) err = testserdes.DecodeBinary(binB, b)
if err != nil { if err != nil {
panic(err) panic(err)
} }
b2Hash, err := util.Uint256DecodeStringLE("9cdc200c0efda77466e36427a056656ba0301428bba8514115bfac7bb325cd6b") b2Hash, err := util.Uint256DecodeStringLE("45f62d72e37b074ecdc9f687222b0f91ec98d6d9af4429a2caa2e076a9196b0d")
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -79,8 +79,7 @@ func getTxMoveNeo() *result.TransactionOutputRaw {
if err != nil { if err != nil {
panic(err) panic(err)
} }
tx := new(transaction.Transaction) tx, err := transaction.NewTransactionFromBytes(netmode.UnitTestNet, txBin)
err = testserdes.DecodeBinary(txBin, tx)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -620,7 +619,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{ {
name: "positive", name: "positive",
invoke: func(c *Client) (interface{}, 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))
}, },
serverResponse: `{"jsonrpc":"2.0","id":1,"result":true}`, serverResponse: `{"jsonrpc":"2.0","id":1,"result":true}`,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {
@ -741,7 +740,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{ {
name: "sendrawtransaction_bad_server_answer", name: "sendrawtransaction_bad_server_answer",
invoke: func(c *Client) (interface{}, 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))
}, },
}, },
{ {
@ -1067,7 +1066,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{ {
name: "sendrawtransaction_unmarshalling_error", name: "sendrawtransaction_unmarshalling_error",
invoke: func(c *Client) (interface{}, 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))
}, },
}, },
{ {

View file

@ -137,9 +137,9 @@ readloop:
var val interface{} var val interface{}
switch event { switch event {
case response.BlockEventID: case response.BlockEventID:
val = new(block.Block) val = block.New(c.opts.Network)
case response.TransactionEventID: case response.TransactionEventID:
val = new(transaction.Transaction) val = &transaction.Transaction{Network: c.opts.Network}
case response.NotificationEventID: case response.NotificationEventID:
val = new(result.NotificationEvent) val = new(result.NotificationEvent)
case response.ExecutionEventID: case response.ExecutionEventID:

View file

@ -118,8 +118,8 @@ func TestWSClientEvents(t *testing.T) {
var events = []string{ 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":"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":"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":"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":"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":"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":[]}`, `{"jsonrpc":"2.0","method":"event_missed","params":[]}`,
} }
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {

View file

@ -13,6 +13,7 @@ import (
"time" "time"
"github.com/gorilla/websocket" "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"
"github.com/nspcc-dev/neo-go/pkg/core/block" "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/blockchainer"
@ -40,6 +41,7 @@ type (
*http.Server *http.Server
chain blockchainer.Blockchainer chain blockchainer.Blockchainer
config rpc.Config config rpc.Config
network netmode.Magic
coreServer *network.Server coreServer *network.Server
log *zap.Logger log *zap.Logger
https *http.Server https *http.Server
@ -135,6 +137,7 @@ func New(chain blockchainer.Blockchainer, conf rpc.Config, coreServer *network.S
Server: httpServer, Server: httpServer,
chain: chain, chain: chain,
config: conf, config: conf,
network: chain.GetConfig().Magic,
coreServer: coreServer, coreServer: coreServer,
log: log, log: log,
https: tlsServer, https: tlsServer,
@ -928,13 +931,13 @@ func (s *Server) submitBlock(reqParams request.Params) (interface{}, *response.E
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
} }
b := block.Block{} b := block.New(s.network)
r := io.NewBinReaderFromBuf(blockBytes) r := io.NewBinReaderFromBuf(blockBytes)
b.DecodeBinary(r) b.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
} }
err = s.chain.AddBlock(&b) err = s.chain.AddBlock(b)
if err != nil { if err != nil {
switch err { switch err {
case core.ErrInvalidBlockIndex, core.ErrAlreadyExists: 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 { } else if byteTx, err := reqParams[0].GetBytesHex(); err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
} else { } else {
tx, err := transaction.NewTransactionFromBytes(byteTx) tx, err := transaction.NewTransactionFromBytes(s.network, byteTx)
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
} }

View file

@ -50,7 +50,7 @@ func getTestBlocks(t *testing.T) []*block.Block {
blocks := make([]*block.Block, 0, int(nBlocks)) blocks := make([]*block.Block, 0, int(nBlocks))
for i := 0; i < int(nBlocks); i++ { for i := 0; i < int(nBlocks); i++ {
_ = br.ReadU32LE() _ = br.ReadU32LE()
b := &block.Block{} b := block.New(netmode.UnitTestNet)
b.DecodeBinary(br) b.DecodeBinary(br)
require.Nil(t, br.Err) require.Nil(t, br.Err)
blocks = append(blocks, b) blocks = append(blocks, b)

View file

@ -51,17 +51,18 @@ type rpcTestCase struct {
} }
const testContractHash = "e65ff7b3a02d207b584a5c27057d4e9862ef01da" const testContractHash = "e65ff7b3a02d207b584a5c27057d4e9862ef01da"
const deploymentTxHash = "5ce44eae362d3f81d440cb73cf4e4af71e69851bcd683b076aa08b7346d4e69b"
var rpcTestCases = map[string][]rpcTestCase{ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": { "getapplicationlog": {
{ {
name: "positive", name: "positive",
params: `["9352fa8d351635bb151e7e5a3a923bfe4d8fb90f05b605ec00af95c2410b594d"]`, params: `["` + deploymentTxHash + `"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} }, result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) { check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog) res, ok := acc.(*result.ApplicationLog)
require.True(t, ok) require.True(t, ok)
expectedTxHash, err := util.Uint256DecodeStringLE("9352fa8d351635bb151e7e5a3a923bfe4d8fb90f05b605ec00af95c2410b594d") expectedTxHash, err := util.Uint256DecodeStringLE(deploymentTxHash)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, expectedTxHash, res.TxHash) assert.Equal(t, expectedTxHash, res.TxHash)
assert.Equal(t, 1, len(res.Executions)) assert.Equal(t, 1, len(res.Executions))
@ -316,7 +317,7 @@ var rpcTestCases = map[string][]rpcTestCase{
{ {
name: "positive", name: "positive",
params: "[3, 1]", 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{}) { check: func(t *testing.T, e *executor, blockRes interface{}) {
res, ok := blockRes.(*result.Block) res, ok := blockRes.(*result.Block)
require.True(t, ok) require.True(t, ok)
@ -483,7 +484,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"gettransactionheight": { "gettransactionheight": {
{ {
name: "positive", name: "positive",
params: `["9352fa8d351635bb151e7e5a3a923bfe4d8fb90f05b605ec00af95c2410b594d"]`, params: `["` + deploymentTxHash + `"]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} {
h := 0 h := 0
return &h return &h
@ -687,7 +688,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"sendrawtransaction": { "sendrawtransaction": {
{ {
name: "positive", name: "positive",
params: `["000a000000316e851039019d39dfc2c37d6c3fee19fd5809870000000000000000f2ad050000000000b00400000001316e851039019d39dfc2c37d6c3fee19fd580987015d0300e87648170000000c1420728274afafc36f43a071d328cfa3e629d9cbb00c14316e851039019d39dfc2c37d6c3fee19fd58098713c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c40df953141271169421cebab5d27a0163e294d7c7f2d0525b4498745344814fd3d6c5c591c9b1723d05d42856f409adb084cf67acc921cfafc629133a5eb5e7a7e290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`, params: `["000a000000316e851039019d39dfc2c37d6c3fee19fd5809870000000000000000f2ad050000000000b00400000001316e851039019d39dfc2c37d6c3fee19fd580987015d0300e87648170000000c1420728274afafc36f43a071d328cfa3e629d9cbb00c14316e851039019d39dfc2c37d6c3fee19fd58098713c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c409803db41e66a94e0bd6fdd3d7a7b1e106c1e2281c9782a231f32df036bb80c7f19155cdb9a52a45cf8d93ec9c1e8df69d6ee35625f352d1710c7cc6eee26003c290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} {
v := true v := true
return &v return &v
@ -825,7 +826,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
newTx := func() *transaction.Transaction { newTx := func() *transaction.Transaction {
height := chain.BlockHeight() 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.Nonce = height + 1
tx.ValidUntilBlock = height + 10 tx.ValidUntilBlock = height + 10
tx.Sender = acc0.PrivateKey().GetScriptHash() 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()) rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE())
body := doRPCCall(rpc, httpSrv.URL, t) body := doRPCCall(rpc, httpSrv.URL, t)
txOut := checkErrGetResult(t, body, false) txOut := checkErrGetResult(t, body, false)
actual := result.TransactionOutputRaw{} actual := result.TransactionOutputRaw{Transaction: transaction.Transaction{Network: testchain.Network()}}
err := json.Unmarshal(txOut, &actual) err := json.Unmarshal(txOut, &actual)
require.NoErrorf(t, err, "could not parse response: %s", txOut) 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()) expected = append(expected, tx.Hash())
} }
for i := 0; i < 5; i++ { 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{})) assert.NoError(t, mp.Add(tx, &FeerStub{}))
expected = append(expected, tx.Hash()) expected = append(expected, tx.Hash())
} }
@ -1004,6 +1005,7 @@ func newBlock(t *testing.T, bc blockchainer.Blockchainer, index uint32, primary
Index: hdr.Index + index, Index: hdr.Index + index,
NextConsensus: witness.ScriptHash(), NextConsensus: witness.ScriptHash(),
Script: witness, Script: witness,
Network: bc.GetConfig().Magic,
}, },
ConsensusData: block.ConsensusData{ ConsensusData: block.ConsensusData{
PrimaryIndex: primary, 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{}) { func (tc rpcTestCase) getResultPair(e *executor) (expected interface{}, res interface{}) {
expected = tc.result(e) expected = tc.result(e)
resVal := reflect.New(reflect.TypeOf(expected).Elem()) 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 { func checkErrGetResult(t *testing.T, body []byte, expectingFail bool) json.RawMessage {

Binary file not shown.

View file

@ -4,6 +4,7 @@ import (
"encoding/hex" "encoding/hex"
"testing" "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"
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto" "github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "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 { 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.Attributes = make([]transaction.Attribute, 0)
tx.Scripts = make([]transaction.Witness, 0) tx.Scripts = make([]transaction.Witness, 0)
tx.Hash() tx.Hash()