From d314f82db3eec265c802c4d27aa933ff497d68b9 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 25 Mar 2021 19:18:01 +0300 Subject: [PATCH] transaction: drop Network from Transaction We only need it when signing/verifying. --- cli/paramcontext/context.go | 7 +- cli/smartcontract/smart_contract.go | 2 +- cli/wallet/multisig.go | 2 +- cli/wallet/nep17.go | 4 +- cli/wallet/validator.go | 4 +- internal/testchain/address.go | 10 +- internal/testchain/transaction.go | 11 +- pkg/consensus/block_test.go | 3 +- pkg/consensus/consensus_test.go | 37 +++--- pkg/core/block/block.go | 4 +- pkg/core/block/block_test.go | 4 +- pkg/core/blockchain_test.go | 139 ++++++++++----------- pkg/core/dao/dao.go | 2 +- pkg/core/dao/dao_test.go | 2 +- pkg/core/helper_test.go | 34 ++--- pkg/core/interop/crypto/ecdsa_test.go | 24 ++-- pkg/core/interop_neo_test.go | 2 +- pkg/core/mempool/mem_pool_test.go | 45 ++++--- pkg/core/mempool/subscriptions_test.go | 3 +- pkg/core/native/notary.go | 5 +- pkg/core/native_designate_test.go | 6 +- pkg/core/native_name_service_test.go | 2 +- pkg/core/native_neo_test.go | 10 +- pkg/core/native_notary_test.go | 9 +- pkg/core/native_oracle_test.go | 6 +- pkg/core/notary_test.go | 20 +-- pkg/core/transaction/helper_test.go | 3 +- pkg/core/transaction/transaction.go | 52 +------- pkg/core/transaction/transaction_test.go | 16 ++- pkg/network/message.go | 2 +- pkg/network/message_test.go | 2 +- pkg/network/payload/notary_request.go | 4 +- pkg/network/payload/notary_request_test.go | 2 - pkg/network/server.go | 2 +- pkg/network/server_test.go | 4 +- pkg/rpc/client/nep17.go | 6 +- pkg/rpc/client/rpc.go | 9 +- pkg/rpc/client/rpc_test.go | 8 +- pkg/rpc/client/wsclient.go | 2 +- pkg/rpc/response/result/invoke.go | 38 +++--- pkg/rpc/response/result/invoke_test.go | 13 +- pkg/rpc/server/client_test.go | 28 ++--- pkg/rpc/server/server.go | 2 +- pkg/rpc/server/server_test.go | 16 +-- pkg/services/notary/node_test.go | 3 +- pkg/services/notary/notary.go | 12 +- pkg/services/notary/notary_test.go | 7 +- pkg/services/oracle/request.go | 6 +- pkg/services/oracle/response.go | 6 +- pkg/services/oracle/transaction.go | 8 +- pkg/smartcontract/context/context.go | 1 - pkg/smartcontract/context/context_test.go | 12 +- pkg/wallet/account.go | 9 +- scripts/gendump/main.go | 8 +- 54 files changed, 305 insertions(+), 373 deletions(-) diff --git a/cli/paramcontext/context.go b/cli/paramcontext/context.go index d9a0377c4..9df147fd0 100644 --- a/cli/paramcontext/context.go +++ b/cli/paramcontext/context.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" + "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/encoding/address" "github.com/nspcc-dev/neo-go/pkg/smartcontract/context" @@ -16,13 +17,13 @@ const validUntilBlockIncrement = 50 // InitAndSave creates incompletely signed transaction which can used // as input to `multisig sign`. -func InitAndSave(tx *transaction.Transaction, acc *wallet.Account, filename string) error { +func InitAndSave(net netmode.Magic, tx *transaction.Transaction, acc *wallet.Account, filename string) error { // avoid fast transaction expiration tx.ValidUntilBlock += validUntilBlockIncrement priv := acc.PrivateKey() pub := priv.PublicKey() - sign := priv.Sign(tx.GetSignedPart()) - scCtx := context.NewParameterContext("Neo.Core.ContractTransaction", tx.Network, tx) + sign := priv.SignHashable(uint32(net), tx) + scCtx := context.NewParameterContext("Neo.Core.ContractTransaction", net, tx) h, err := address.StringToUint160(acc.Address) if err != nil { return fmt.Errorf("invalid address: %s", acc.Address) diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 7fb687e0a..65be26b3d 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -596,7 +596,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error { if err != nil { return cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1) } - if err := paramcontext.InitAndSave(tx, acc, out); err != nil { + if err := paramcontext.InitAndSave(c.GetNetwork(), tx, acc, out); err != nil { return cli.NewExitError(err, 1) } fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE()) diff --git a/cli/wallet/multisig.go b/cli/wallet/multisig.go index 2a7955d28..0ff3d4349 100644 --- a/cli/wallet/multisig.go +++ b/cli/wallet/multisig.go @@ -52,7 +52,7 @@ func signStoredTransaction(ctx *cli.Context) error { } priv := acc.PrivateKey() - sign := priv.Sign(tx.GetSignedPart()) + sign := priv.SignHashable(uint32(c.Network), tx) if err := c.AddSignature(ch, acc.Contract, priv.PublicKey(), sign); err != nil { return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1) } diff --git a/cli/wallet/nep17.go b/cli/wallet/nep17.go index 86440c3e9..76096bb94 100644 --- a/cli/wallet/nep17.go +++ b/cli/wallet/nep17.go @@ -474,11 +474,11 @@ func signAndSendTransfer(ctx *cli.Context, c *client.Client, acc *wallet.Account } if outFile := ctx.String("out"); outFile != "" { - if err := paramcontext.InitAndSave(tx, acc, outFile); err != nil { + if err := paramcontext.InitAndSave(c.GetNetwork(), tx, acc, outFile); err != nil { return cli.NewExitError(err, 1) } } else { - _ = acc.SignTx(tx) + _ = acc.SignTx(c.GetNetwork(), tx) res, err := c.SendRawTransaction(tx) if err != nil { return cli.NewExitError(err, 1) diff --git a/cli/wallet/validator.go b/cli/wallet/validator.go index 80e9bbbea..0b6e3a28b 100644 --- a/cli/wallet/validator.go +++ b/cli/wallet/validator.go @@ -119,7 +119,7 @@ func handleCandidate(ctx *cli.Context, method string, sysGas int64) error { }) if err != nil { return cli.NewExitError(err, 1) - } else if err = acc.SignTx(tx); err != nil { + } else if err = acc.SignTx(c.GetNetwork(), tx); err != nil { return cli.NewExitError(fmt.Errorf("can't sign tx: %v", err), 1) } @@ -187,7 +187,7 @@ func handleVote(ctx *cli.Context) error { return cli.NewExitError(err, 1) } - if err = acc.SignTx(tx); err != nil { + if err = acc.SignTx(c.GetNetwork(), tx); err != nil { return cli.NewExitError(fmt.Errorf("can't sign tx: %v", err), 1) } diff --git a/internal/testchain/address.go b/internal/testchain/address.go index d031adab3..9be6f2371 100644 --- a/internal/testchain/address.go +++ b/internal/testchain/address.go @@ -127,11 +127,11 @@ func CommitteeAddress() string { } // Sign signs data by all consensus nodes and returns invocation script. -func Sign(data []byte) []byte { +func Sign(h hash.Hashable) []byte { buf := io.NewBufBinWriter() for i := 0; i < 3; i++ { pKey := PrivateKey(i) - sig := pKey.Sign(data) + sig := pKey.SignHashable(uint32(Network()), h) if len(sig) != 64 { panic("wrong signature length") } @@ -141,11 +141,11 @@ func Sign(data []byte) []byte { } // SignCommittee signs data by a majority of committee members. -func SignCommittee(data []byte) []byte { +func SignCommittee(h hash.Hashable) []byte { buf := io.NewBufBinWriter() for i := 0; i < CommitteeSize()/2+1; i++ { pKey := PrivateKey(i) - sig := pKey.Sign(data) + sig := pKey.SignHashable(uint32(Network()), h) if len(sig) != 64 { panic("wrong signature length") } @@ -176,6 +176,6 @@ func NewBlock(t *testing.T, bc blockchainer.Blockchainer, offset uint32, primary } b.RebuildMerkleRoot() - b.Script.InvocationScript = Sign(b.GetSignedPart()) + b.Script.InvocationScript = Sign(b) return b } diff --git a/internal/testchain/transaction.go b/internal/testchain/transaction.go index 13b0e9283..04363f7cd 100644 --- a/internal/testchain/transaction.go +++ b/internal/testchain/transaction.go @@ -8,12 +8,12 @@ import ( "github.com/nspcc-dev/neo-go/cli/smartcontract" "github.com/nspcc-dev/neo-go/pkg/compiler" "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/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/fee" "github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" + "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" @@ -38,7 +38,7 @@ func NewTransferFromOwner(bc blockchainer.Blockchainer, contractHash, to util.Ui } script := w.Bytes() - tx := transaction.New(netmode.UnitTestNet, script, 11000000) + tx := transaction.New(script, 11000000) tx.ValidUntilBlock = validUntil tx.Nonce = nonce tx.Signers = []transaction.Signer{{ @@ -100,7 +100,7 @@ func NewDeployTx(bc blockchainer.Blockchainer, name string, sender util.Uint160, return nil, util.Uint160{}, nil, buf.Err } - tx := transaction.New(Network(), buf.Bytes(), 100*native.GASFactor) + tx := transaction.New(buf.Bytes(), 100*native.GASFactor) tx.Signers = []transaction.Signer{{Account: sender}} h := state.CreateContractHash(tx.Sender(), ne.Checksum, name) @@ -119,16 +119,15 @@ func SignTxCommittee(bc blockchainer.Blockchainer, txs ...*transaction.Transacti return nil } -func signTxGeneric(bc blockchainer.Blockchainer, sign func([]byte) []byte, verif []byte, txs ...*transaction.Transaction) { +func signTxGeneric(bc blockchainer.Blockchainer, sign func(hash.Hashable) []byte, verif []byte, txs ...*transaction.Transaction) { for _, tx := range txs { size := io.GetVarSize(tx) netFee, sizeDelta := fee.Calculate(bc.GetPolicer().GetBaseExecFee(), verif) tx.NetworkFee += netFee size += sizeDelta tx.NetworkFee += int64(size) * bc.FeePerByte() - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{{ - InvocationScript: sign(data), + InvocationScript: sign(tx), VerificationScript: verif, }} } diff --git a/pkg/consensus/block_test.go b/pkg/consensus/block_test.go index efed586e3..af6d9826f 100644 --- a/pkg/consensus/block_test.go +++ b/pkg/consensus/block_test.go @@ -6,7 +6,6 @@ import ( "github.com/nspcc-dev/dbft/block" "github.com/nspcc-dev/dbft/crypto" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" @@ -43,7 +42,7 @@ func TestNeoBlock_Setters(t *testing.T) { b.Block.PrevHash = util.Uint256{9, 8, 7} require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash()) - txx := []block.Transaction{transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 1)} + txx := []block.Transaction{transaction.New([]byte{byte(opcode.PUSH1)}, 1)} b.SetTransactions(txx) require.Equal(t, txx, b.Transactions()) } diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index b448e4f56..747c47653 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -34,7 +34,7 @@ import ( func TestNewService(t *testing.T) { srv := newTestService(t) - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 100000) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 100000) tx.ValidUntilBlock = 1 addSender(t, tx) signTx(t, srv.Chain, tx) @@ -65,11 +65,11 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) - tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 21_000_000) + tx := transaction.New(w.Bytes(), 21_000_000) tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.NetworkFee = 10_000_000 tx.Signers = []transaction.Signer{{Scopes: transaction.Global, Account: acc.Contract.ScriptHash()}} - require.NoError(t, acc.SignTx(tx)) + require.NoError(t, acc.SignTx(netmode.UnitTestNet, tx)) require.NoError(t, bc.PoolTx(tx)) srv := newTestServiceWithChain(t, bc) @@ -80,11 +80,11 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 emit.AppCall(w.BinWriter, bc.GoverningTokenHash(), "registerCandidate", callflag.All, newPriv.PublicKey().Bytes()) require.NoError(t, w.Err) - tx = transaction.New(netmode.UnitTestNet, w.Bytes(), 1001_00000000) + tx = transaction.New(w.Bytes(), 1001_00000000) tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.NetworkFee = 20_000_000 tx.Signers = []transaction.Signer{{Scopes: transaction.Global, Account: newPriv.GetScriptHash()}} - require.NoError(t, newAcc.SignTx(tx)) + require.NoError(t, newAcc.SignTx(netmode.UnitTestNet, tx)) require.NoError(t, bc.PoolTx(tx)) srv.dbft.OnTimeout(timer.HV{Height: srv.dbft.Context.BlockIndex}) @@ -100,11 +100,11 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) - tx = transaction.New(netmode.UnitTestNet, w.Bytes(), 20_000_000) + tx = transaction.New(w.Bytes(), 20_000_000) tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.NetworkFee = 20_000_000 tx.Signers = []transaction.Signer{{Scopes: transaction.Global, Account: newPriv.GetScriptHash()}} - require.NoError(t, newAcc.SignTx(tx)) + require.NoError(t, newAcc.SignTx(netmode.UnitTestNet, tx)) require.NoError(t, bc.PoolTx(tx)) srv.dbft.OnTimeout(timer.HV{Height: srv.dbft.BlockIndex}) @@ -167,7 +167,7 @@ func TestService_GetVerified(t *testing.T) { srv.dbft.Start() var txs []*transaction.Transaction for i := 0; i < 4; i++ { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 100000) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 100000) tx.Nonce = 123 + uint32(i) tx.ValidUntilBlock = 1 txs = append(txs, tx) @@ -260,7 +260,7 @@ func TestService_getTx(t *testing.T) { srv := newTestService(t) t.Run("transaction in mempool", func(t *testing.T) { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = 1234 tx.ValidUntilBlock = 1 addSender(t, tx) @@ -277,7 +277,7 @@ func TestService_getTx(t *testing.T) { }) t.Run("transaction in local cache", func(t *testing.T) { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = 4321 tx.ValidUntilBlock = 1 h := tx.Hash() @@ -372,7 +372,7 @@ func TestVerifyBlock(t *testing.T) { require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("good pooled tx", func(t *testing.T) { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 100000) + tx := transaction.New([]byte{byte(opcode.RET)}, 100000) tx.ValidUntilBlock = 1 addSender(t, tx) signTx(t, srv.Chain, tx) @@ -381,7 +381,7 @@ func TestVerifyBlock(t *testing.T) { require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("good non-pooled tx", func(t *testing.T) { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 100000) + tx := transaction.New([]byte{byte(opcode.RET)}, 100000) tx.ValidUntilBlock = 1 addSender(t, tx) signTx(t, srv.Chain, tx) @@ -389,12 +389,12 @@ func TestVerifyBlock(t *testing.T) { require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("good conflicting tx", func(t *testing.T) { - tx1 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 100000) + tx1 := transaction.New([]byte{byte(opcode.RET)}, 100000) tx1.NetworkFee = 20_000_000 * native.GASFactor tx1.ValidUntilBlock = 1 addSender(t, tx1) signTx(t, srv.Chain, tx1) - tx2 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 100000) + tx2 := transaction.New([]byte{byte(opcode.RET)}, 100000) tx2.NetworkFee = 20_000_000 * native.GASFactor tx2.ValidUntilBlock = 1 addSender(t, tx2) @@ -412,7 +412,7 @@ func TestVerifyBlock(t *testing.T) { t.Run("bad big size", func(t *testing.T) { script := make([]byte, int(srv.ProtocolConfiguration.MaxBlockSize)) script[0] = byte(opcode.RET) - tx := transaction.New(netmode.UnitTestNet, script, 100000) + tx := transaction.New(script, 100000) tx.ValidUntilBlock = 1 addSender(t, tx) signTx(t, srv.Chain, tx) @@ -425,7 +425,7 @@ func TestVerifyBlock(t *testing.T) { require.False(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("bad tx", func(t *testing.T) { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 100000) + tx := transaction.New([]byte{byte(opcode.RET)}, 100000) tx.ValidUntilBlock = 1 addSender(t, tx) signTx(t, srv.Chain, tx) @@ -436,7 +436,7 @@ func TestVerifyBlock(t *testing.T) { t.Run("bad big sys fee", func(t *testing.T) { txes := make([]*transaction.Transaction, 2) for i := range txes { - txes[i] = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, srv.ProtocolConfiguration.MaxBlockSystemFee/2+1) + txes[i] = transaction.New([]byte{byte(opcode.RET)}, srv.ProtocolConfiguration.MaxBlockSystemFee/2+1) txes[i].ValidUntilBlock = 1 addSender(t, txes[i]) signTx(t, srv.Chain, txes[i]) @@ -547,11 +547,10 @@ func signTx(t *testing.T, bc blockchainer.Blockchainer, txs ...*transaction.Tran tx.NetworkFee += +netFee size += sizeDelta tx.NetworkFee += int64(size) * bc.FeePerByte() - data := tx.GetSignedPart() buf := io.NewBufBinWriter() for _, key := range privNetKeys { - signature := key.Sign(data) + signature := key.SignHashable(uint32(testchain.Network()), tx) emit.Bytes(buf.BinWriter, signature) } diff --git a/pkg/core/block/block.go b/pkg/core/block/block.go index 9291b3482..45b7651fc 100644 --- a/pkg/core/block/block.go +++ b/pkg/core/block/block.go @@ -136,7 +136,7 @@ func (b *Block) DecodeBinary(br *io.BinReader) { } txes := make([]*transaction.Transaction, contentsCount) for i := 0; i < int(contentsCount); i++ { - tx := &transaction.Transaction{Network: b.Network} + tx := &transaction.Transaction{} tx.DecodeBinary(br) txes[i] = tx } @@ -207,7 +207,7 @@ func (b *Block) UnmarshalJSON(data []byte) error { if len(auxb.Transactions) != 0 { b.Transactions = make([]*transaction.Transaction, 0, len(auxb.Transactions)) for _, txBytes := range auxb.Transactions { - tx := &transaction.Transaction{Network: b.Network} + tx := &transaction.Transaction{} err = tx.UnmarshalJSON(txBytes) if err != nil { return err diff --git a/pkg/core/block/block_test.go b/pkg/core/block/block_test.go index 65a8f1ec7..bad0c760f 100644 --- a/pkg/core/block/block_test.go +++ b/pkg/core/block/block_test.go @@ -93,7 +93,7 @@ func newDumbBlock() *Block { }, }, Transactions: []*transaction.Transaction{ - transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0), + transaction.New([]byte{byte(opcode.PUSH1)}, 0), }, } } @@ -260,7 +260,7 @@ func TestGetExpectedBlockSize(t *testing.T) { b.StateRootEnabled = stateRootEnabled b.Transactions = make([]*transaction.Transaction, 123) for i := range b.Transactions { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, int64(i)) + tx := transaction.New([]byte{byte(opcode.RET)}, int64(i)) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} tx.Scripts = []transaction.Witness{{}} b.Transactions[i] = tx diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index f5d77bfcf..0e993f179 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -161,7 +161,7 @@ func TestAddBlockStateRoot(t *testing.T) { func TestAddBadBlock(t *testing.T) { bc := newTestChain(t) // It has ValidUntilBlock == 0, which is wrong - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Signers = []transaction.Signer{{ Account: testchain.MultisigScriptHash(), Scopes: transaction.None, @@ -180,7 +180,7 @@ func TestAddBadBlock(t *testing.T) { bc.config.VerifyBlocks = false require.NoError(t, bc.AddBlock(b2)) - tx = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx = transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.ValidUntilBlock = 128 tx.Signers = []transaction.Signer{{ Account: testchain.MultisigScriptHash(), @@ -196,7 +196,7 @@ func TestAddBadBlock(t *testing.T) { func TestGetHeader(t *testing.T) { bc := newTestChain(t) - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.ValidUntilBlock = bc.BlockHeight() + 1 addSigners(neoOwner, tx) assert.Nil(t, testchain.SignTx(bc, tx)) @@ -263,7 +263,7 @@ func TestGetBlock(t *testing.T) { } func (bc *Blockchain) newTestTx(h util.Uint160, script []byte) *transaction.Transaction { - tx := transaction.New(testchain.Network(), script, 1_000_000) + tx := transaction.New(script, 1_000_000) tx.Nonce = rand.Uint32() tx.ValidUntilBlock = 100 tx.Signers = []transaction.Signer{{ @@ -333,12 +333,12 @@ func TestVerifyTx(t *testing.T) { t.Run("Expired", func(t *testing.T) { tx := bc.newTestTx(h, testScript) tx.ValidUntilBlock = 1 - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrTxExpired, tx) }) t.Run("BlockedAccount", func(t *testing.T) { tx := bc.newTestTx(accs[1].PrivateKey().GetScriptHash(), testScript) - require.NoError(t, accs[1].SignTx(tx)) + require.NoError(t, accs[1].SignTx(netmode.UnitTestNet, tx)) err := bc.VerifyTx(tx) require.True(t, errors.Is(err, ErrPolicy)) }) @@ -346,20 +346,20 @@ func TestVerifyTx(t *testing.T) { balance := bc.GetUtilityTokenBalance(h) tx := bc.newTestTx(h, testScript) tx.SystemFee = balance.Int64() + 1 - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInsufficientFunds, tx) }) t.Run("TooBigTx", func(t *testing.T) { script := make([]byte, transaction.MaxTransactionSize) tx := bc.newTestTx(h, script) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrTxTooBig, tx) }) t.Run("NetworkFee", func(t *testing.T) { t.Run("SmallNetworkFee", func(t *testing.T) { tx := bc.newTestTx(h, testScript) tx.NetworkFee = 1 - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrTxSmallNetworkFee, tx) }) t.Run("AlmostEnoughNetworkFee", func(t *testing.T) { @@ -368,7 +368,7 @@ func TestVerifyTx(t *testing.T) { expectedSize := io.GetVarSize(tx) + calcultedScriptSize calculatedNetFee := verificationNetFee + int64(expectedSize)*bc.FeePerByte() tx.NetworkFee = calculatedNetFee - 1 - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) require.Equal(t, expectedSize, io.GetVarSize(tx)) checkErr(t, ErrVerificationFailed, tx) }) @@ -378,7 +378,7 @@ func TestVerifyTx(t *testing.T) { expectedSize := io.GetVarSize(tx) + calcultedScriptSize calculatedNetFee := verificationNetFee + int64(expectedSize)*bc.FeePerByte() tx.NetworkFee = calculatedNetFee - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) require.Equal(t, expectedSize, io.GetVarSize(tx)) require.NoError(t, bc.VerifyTx(tx)) }) @@ -389,7 +389,7 @@ func TestVerifyTx(t *testing.T) { expectedSize += calculatedScriptSize expectedNetFee := verificationNetFee + int64(expectedSize)*bc.FeePerByte() tx.NetworkFee = expectedNetFee - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) actualSize := io.GetVarSize(tx) require.Equal(t, expectedSize, actualSize) interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, nil, tx) @@ -408,7 +408,7 @@ func TestVerifyTx(t *testing.T) { expectedSize := io.GetVarSize(tx) + calculatedScriptSize expectedNetFee := verificationNetFee + int64(expectedSize)*bc.FeePerByte() tx.NetworkFee = expectedNetFee - require.NoError(t, multisigAcc.SignTx(tx)) + require.NoError(t, multisigAcc.SignTx(netmode.UnitTestNet, tx)) actualSize := io.GetVarSize(tx) require.Equal(t, expectedSize, actualSize) interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, nil, tx) @@ -421,7 +421,7 @@ func TestVerifyTx(t *testing.T) { t.Run("InvalidTxScript", func(t *testing.T) { tx := bc.newTestTx(h, testScript) tx.Script = append(tx.Script, 0xff) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidScript, tx) }) t.Run("InvalidVerificationScript", func(t *testing.T) { @@ -432,7 +432,7 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.Global, }) tx.NetworkFee += 1000000 - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) tx.Scripts = append(tx.Scripts, transaction.Witness{ InvocationScript: []byte{}, VerificationScript: verif, @@ -447,7 +447,7 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.Global, }) tx.NetworkFee += 1000000 - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) tx.Scripts = append(tx.Scripts, transaction.Witness{ InvocationScript: []byte{byte(opcode.JMP), 3, 0xff}, VerificationScript: verif, @@ -458,24 +458,24 @@ func TestVerifyTx(t *testing.T) { balance := bc.GetUtilityTokenBalance(h).Int64() tx := bc.newTestTx(h, testScript) tx.NetworkFee = balance / 2 - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) require.NoError(t, bc.PoolTx(tx)) tx2 := bc.newTestTx(h, testScript) tx2.NetworkFee = balance / 2 - require.NoError(t, accs[0].SignTx(tx2)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx2)) err := bc.PoolTx(tx2) require.True(t, errors.Is(err, ErrMemPoolConflict)) }) t.Run("InvalidWitnessHash", func(t *testing.T) { tx := bc.newTestTx(h, testScript) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) tx.Scripts[0].VerificationScript = []byte{byte(opcode.PUSHT)} checkErr(t, ErrWitnessHashMismatch, tx) }) t.Run("InvalidWitnessSignature", func(t *testing.T) { tx := bc.newTestTx(h, testScript) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) tx.Scripts[0].InvocationScript[10] = ^tx.Scripts[0].InvocationScript[10] checkErr(t, ErrVerificationFailed, tx) }) @@ -485,13 +485,13 @@ func TestVerifyTx(t *testing.T) { Account: accs[3].PrivateKey().GetScriptHash(), Scopes: transaction.Global, }) - require.NoError(t, accs[0].SignTx(tx)) - require.NoError(t, accs[3].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) + require.NoError(t, accs[3].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrVerificationFailed, tx) }) t.Run("OldTX", func(t *testing.T) { tx := bc.newTestTx(h, testScript) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) b := bc.newBlock(tx) require.NoError(t, bc.AddBlock(b)) @@ -500,7 +500,7 @@ func TestVerifyTx(t *testing.T) { }) t.Run("MemPooledTX", func(t *testing.T) { tx := bc.newTestTx(h, testScript) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) require.NoError(t, bc.PoolTx(tx)) err := bc.PoolTx(tx) @@ -510,11 +510,11 @@ func TestVerifyTx(t *testing.T) { bc.memPool = mempool.New(1, 0, false) tx1 := bc.newTestTx(h, testScript) tx1.NetworkFee += 10000 // Give it more priority. - require.NoError(t, accs[0].SignTx(tx1)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx1)) require.NoError(t, bc.PoolTx(tx1)) tx2 := bc.newTestTx(h, testScript) - require.NoError(t, accs[0].SignTx(tx2)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx2)) err := bc.PoolTx(tx2) require.True(t, errors.Is(err, ErrOOM)) }) @@ -522,7 +522,7 @@ func TestVerifyTx(t *testing.T) { t.Run("InvalidHighPriority", func(t *testing.T) { tx := bc.newTestTx(h, testScript) tx.Attributes = append(tx.Attributes, transaction.Attribute{Type: transaction.HighPriority}) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidAttribute, tx) }) t.Run("ValidHighPriority", func(t *testing.T) { @@ -539,9 +539,8 @@ func TestVerifyTx(t *testing.T) { netFee, sizeDelta := fee.Calculate(bc.GetBaseExecFee(), rawScript) tx.NetworkFee += netFee tx.NetworkFee += int64(size+sizeDelta) * bc.FeePerByte() - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{{ - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: rawScript, }} require.NoError(t, bc.VerifyTx(tx)) @@ -583,14 +582,14 @@ func TestVerifyTx(t *testing.T) { t.Run("NoOracleNodes", func(t *testing.T) { tx := getOracleTx(t) - require.NoError(t, oracleAcc.SignTx(tx)) + require.NoError(t, oracleAcc.SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidAttribute, tx) }) - txSetOracle := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 0) // it's a hack, so we don't need a real script + txSetOracle := transaction.New([]byte{byte(opcode.RET)}, 0) // it's a hack, so we don't need a real script setSigner(txSetOracle, testchain.CommitteeScriptHash()) txSetOracle.Scripts = []transaction.Witness{{ - InvocationScript: testchain.SignCommittee(txSetOracle.GetSignedPart()), + InvocationScript: testchain.SignCommittee(txSetOracle), VerificationScript: testchain.CommitteeVerificationScript(), }} bl := block.New(netmode.UnitTestNet, bc.config.StateRootInHeader) @@ -604,7 +603,7 @@ func TestVerifyTx(t *testing.T) { t.Run("Valid", func(t *testing.T) { tx := getOracleTx(t) - require.NoError(t, oracleAcc.SignTx(tx)) + require.NoError(t, oracleAcc.SignTx(netmode.UnitTestNet, tx)) require.NoError(t, bc.VerifyTx(tx)) t.Run("NativeVerify", func(t *testing.T) { @@ -632,31 +631,31 @@ func TestVerifyTx(t *testing.T) { t.Run("InvalidRequestID", func(t *testing.T) { tx := getOracleTx(t) tx.Attributes[0].Value.(*transaction.OracleResponse).ID = 2 - require.NoError(t, oracleAcc.SignTx(tx)) + require.NoError(t, oracleAcc.SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidAttribute, tx) }) t.Run("InvalidScope", func(t *testing.T) { tx := getOracleTx(t) tx.Signers[0].Scopes = transaction.Global - require.NoError(t, oracleAcc.SignTx(tx)) + require.NoError(t, oracleAcc.SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidAttribute, tx) }) t.Run("InvalidScript", func(t *testing.T) { tx := getOracleTx(t) tx.Script = append(tx.Script, byte(opcode.NOP)) - require.NoError(t, oracleAcc.SignTx(tx)) + require.NoError(t, oracleAcc.SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidAttribute, tx) }) t.Run("InvalidSigner", func(t *testing.T) { tx := getOracleTx(t) tx.Signers[0].Account = accs[0].Contract.ScriptHash() - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidAttribute, tx) }) t.Run("SmallFee", func(t *testing.T) { tx := getOracleTx(t) tx.SystemFee = 0 - require.NoError(t, oracleAcc.SignTx(tx)) + require.NoError(t, oracleAcc.SignTx(netmode.UnitTestNet, tx)) checkErr(t, ErrInvalidAttribute, tx) }) }) @@ -675,9 +674,8 @@ func TestVerifyTx(t *testing.T) { netFee, sizeDelta := fee.Calculate(bc.GetBaseExecFee(), rawScript) tx.NetworkFee += netFee tx.NetworkFee += int64(size+sizeDelta) * bc.FeePerByte() - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{{ - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: rawScript, }} return tx @@ -713,9 +711,8 @@ func TestVerifyTx(t *testing.T) { netFee, sizeDelta := fee.Calculate(bc.GetBaseExecFee(), rawScript) tx.NetworkFee += netFee tx.NetworkFee += int64(size+sizeDelta) * bc.FeePerByte() - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{{ - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: rawScript, }} return tx @@ -753,9 +750,8 @@ func TestVerifyTx(t *testing.T) { netFee, sizeDelta := fee.Calculate(bc.GetBaseExecFee(), rawScript) tx.NetworkFee += netFee tx.NetworkFee += int64(size+sizeDelta) * bc.FeePerByte() - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{{ - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: rawScript, }} return tx @@ -769,14 +765,14 @@ func TestVerifyTx(t *testing.T) { bc.config.P2PSigExtensions = true t.Run("dummy on-chain conflict", func(t *testing.T) { tx := bc.newTestTx(h, testScript) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(netmode.UnitTestNet, tx)) dummyTx := transaction.NewTrimmedTX(tx.Hash()) dummyTx.Version = transaction.DummyVersion require.NoError(t, bc.dao.StoreAsTransaction(dummyTx, bc.blockHeight, nil)) require.True(t, errors.Is(bc.VerifyTx(tx), ErrHasConflicts)) }) t.Run("attribute on-chain conflict", func(t *testing.T) { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.ValidUntilBlock = 4242 tx.Signers = []transaction.Signer{{ Account: testchain.MultisigScriptHash(), @@ -798,10 +794,10 @@ func TestVerifyTx(t *testing.T) { t.Run("NotaryAssisted", func(t *testing.T) { notary, err := wallet.NewAccount() require.NoError(t, err) - txSetNotary := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 0) + txSetNotary := transaction.New([]byte{byte(opcode.RET)}, 0) setSigner(txSetNotary, testchain.CommitteeScriptHash()) txSetNotary.Scripts = []transaction.Witness{{ - InvocationScript: testchain.SignCommittee(txSetNotary.GetSignedPart()), + InvocationScript: testchain.SignCommittee(txSetNotary), VerificationScript: testchain.CommitteeVerificationScript(), }} bl := block.New(netmode.UnitTestNet, false) @@ -833,14 +829,13 @@ func TestVerifyTx(t *testing.T) { netFee, sizeDelta := fee.Calculate(bc.GetBaseExecFee(), rawScript) tx.NetworkFee += netFee tx.NetworkFee += int64(size+sizeDelta) * bc.FeePerByte() - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{ { - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: rawScript, }, { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().Sign(data)...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().SignHashable(uint32(testchain.Network()), tx)...), }, } return tx @@ -870,14 +865,13 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.None, }, } - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{ { - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: testchain.CommitteeVerificationScript(), }, { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().Sign(data)...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().SignHashable(uint32(testchain.Network()), tx)...), }, } require.Error(t, bc.VerifyTx(tx)) @@ -894,13 +888,12 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.None, }, } - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{ { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().Sign(data)...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().SignHashable(uint32(testchain.Network()), tx)...), }, { - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: testchain.CommitteeVerificationScript(), }, } @@ -918,14 +911,13 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.CalledByEntry, }, } - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{ { - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: testchain.CommitteeVerificationScript(), }, { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().Sign(data)...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().SignHashable(uint32(testchain.Network()), tx)...), }, } require.Error(t, bc.VerifyTx(tx)) @@ -938,10 +930,9 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.None, }, } - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{ { - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: testchain.CommitteeVerificationScript(), }, } @@ -959,16 +950,15 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.None, }, } - data := tx.GetSignedPart() acc, err := keys.NewPrivateKey() require.NoError(t, err) tx.Scripts = []transaction.Witness{ { - InvocationScript: testchain.SignCommittee(data), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: testchain.CommitteeVerificationScript(), }, { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.Sign(data)...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.SignHashable(uint32(testchain.Network()), tx)...), }, } require.Error(t, bc.VerifyTx(tx)) @@ -981,10 +971,9 @@ func TestVerifyTx(t *testing.T) { Scopes: transaction.None, }, } - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{ { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().Sign(data)...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notary.PrivateKey().SignHashable(uint32(testchain.Network()), tx)...), }, } require.Error(t, bc.VerifyTx(tx)) @@ -1039,7 +1028,7 @@ func TestVerifyTx(t *testing.T) { VerificationScript: []byte{}, }, { - InvocationScript: testchain.Sign(tx.GetSignedPart()), + InvocationScript: testchain.Sign(tx), VerificationScript: testchain.MultisigVerificationScript(), }, } @@ -1066,7 +1055,7 @@ func TestVerifyTx(t *testing.T) { VerificationScript: []byte{}, }, { - InvocationScript: testchain.Sign(tx.GetSignedPart()), + InvocationScript: testchain.Sign(tx), VerificationScript: testchain.MultisigVerificationScript(), }, } @@ -1165,7 +1154,7 @@ func TestIsTxStillRelevant(t *testing.T) { mp := bc.GetMemPool() newTx := func(t *testing.T) *transaction.Transaction { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 100) + tx := transaction.New([]byte{byte(opcode.RET)}, 100) tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.Signers = []transaction.Signer{{ Account: neoOwner, @@ -1299,13 +1288,13 @@ func TestHasBlock(t *testing.T) { func TestGetTransaction(t *testing.T) { bc := newTestChain(t) - tx1 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx1 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx1.ValidUntilBlock = 16 tx1.Signers = []transaction.Signer{{ Account: testchain.MultisigScriptHash(), Scopes: transaction.CalledByEntry, }} - tx2 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH2)}, 0) + tx2 := transaction.New([]byte{byte(opcode.PUSH2)}, 0) tx2.ValidUntilBlock = 16 tx2.Signers = []transaction.Signer{{ Account: testchain.MultisigScriptHash(), @@ -1407,7 +1396,7 @@ func TestSubscriptions(t *testing.T) { emit.Bytes(script.BinWriter, []byte("yay!")) emit.Syscall(script.BinWriter, interopnames.SystemRuntimeNotify) require.NoError(t, script.Err) - txGood1 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0) + txGood1 := transaction.New(script.Bytes(), 0) txGood1.Signers = []transaction.Signer{{Account: neoOwner}} txGood1.Nonce = 1 txGood1.ValidUntilBlock = 1024 @@ -1419,7 +1408,7 @@ func TestSubscriptions(t *testing.T) { emit.Syscall(script.BinWriter, interopnames.SystemRuntimeNotify) emit.Opcodes(script.BinWriter, opcode.THROW) require.NoError(t, script.Err) - txBad := transaction.New(netmode.UnitTestNet, script.Bytes(), 0) + txBad := transaction.New(script.Bytes(), 0) txBad.Signers = []transaction.Signer{{Account: neoOwner}} txBad.Nonce = 2 txBad.ValidUntilBlock = 1024 @@ -1429,7 +1418,7 @@ func TestSubscriptions(t *testing.T) { emit.Bytes(script.BinWriter, []byte("yay! yay! yay!")) emit.Syscall(script.BinWriter, interopnames.SystemRuntimeNotify) require.NoError(t, script.Err) - txGood2 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0) + txGood2 := transaction.New(script.Bytes(), 0) txGood2.Signers = []transaction.Signer{{Account: neoOwner}} txGood2.Nonce = 3 txGood2.ValidUntilBlock = 1024 diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index 85289656a..ae7f40fe5 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -448,7 +448,7 @@ func (dao *Simple) GetTransaction(hash util.Uint256) (*transaction.Transaction, var height = r.ReadU32LE() - tx := &transaction.Transaction{Network: dao.network} + tx := &transaction.Transaction{} tx.DecodeBinary(r) if r.Err != nil { return nil, 0, r.Err diff --git a/pkg/core/dao/dao_test.go b/pkg/core/dao/dao_test.go index e5eedbfcf..fe67ca597 100644 --- a/pkg/core/dao/dao_test.go +++ b/pkg/core/dao/dao_test.go @@ -152,7 +152,7 @@ func TestGetCurrentHeaderHeight_Store(t *testing.T) { func TestStoreAsTransaction(t *testing.T) { dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false) - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 1) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 1) hash := tx.Hash() err := dao.StoreAsTransaction(tx, 0, nil) require.NoError(t, err) diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index 21c46c920..8fac8554f 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -120,7 +120,7 @@ func newBlockCustom(cfg config.ProtocolConfiguration, f func(b *block.Block), f(b) b.RebuildMerkleRoot() - b.Script.InvocationScript = testchain.Sign(b.GetSignedPart()) + b.Script.InvocationScript = testchain.Sign(b) return b } @@ -221,7 +221,7 @@ func newDumbBlock() *block.Block { }, }, Transactions: []*transaction.Transaction{ - transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0), + transaction.New([]byte{byte(opcode.PUSH1)}, 0), }, } } @@ -267,7 +267,7 @@ func TestCreateBasicChain(t *testing.T) { AllowedGroups: nil, }} require.NoError(t, addNetworkFee(bc, txSendRaw, acc0)) - require.NoError(t, acc0.SignTx(txSendRaw)) + require.NoError(t, acc0.SignTx(testchain.Network(), txSendRaw)) bw := io.NewBufBinWriter() txSendRaw.EncodeBinary(bw.BinWriter) t.Logf("sendrawtransaction: %s", base64.StdEncoding.EncodeToString(bw.Bytes())) @@ -353,7 +353,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { txDeploy.Nonce = getNextNonce() txDeploy.ValidUntilBlock = validUntilBlock require.NoError(t, addNetworkFee(bc, txDeploy, acc0)) - require.NoError(t, acc0.SignTx(txDeploy)) + require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy)) b = bc.newBlock(txDeploy) require.NoError(t, bc.AddBlock(b)) checkTxHalt(t, bc, txDeploy.Hash()) @@ -364,12 +364,12 @@ func initBasicChain(t *testing.T, bc *Blockchain) { script := io.NewBufBinWriter() emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "testkey", "testvalue") - txInv := transaction.New(testchain.Network(), script.Bytes(), 1*native.GASFactor) + txInv := transaction.New(script.Bytes(), 1*native.GASFactor) txInv.Nonce = getNextNonce() txInv.ValidUntilBlock = validUntilBlock txInv.Signers = []transaction.Signer{{Account: priv0ScriptHash}} require.NoError(t, addNetworkFee(bc, txInv, acc0)) - require.NoError(t, acc0.SignTx(txInv)) + require.NoError(t, acc0.SignTx(testchain.Network(), txInv)) b = bc.newBlock(txInv) require.NoError(t, bc.AddBlock(b)) checkTxHalt(t, bc, txInv.Hash()) @@ -388,19 +388,19 @@ func initBasicChain(t *testing.T, bc *Blockchain) { }, } require.NoError(t, addNetworkFee(bc, txNeo0to1, acc0)) - require.NoError(t, acc0.SignTx(txNeo0to1)) + require.NoError(t, acc0.SignTx(testchain.Network(), txNeo0to1)) b = bc.newBlock(txNeo0to1) require.NoError(t, bc.AddBlock(b)) checkTxHalt(t, bc, txNeo0to1.Hash()) w := io.NewBufBinWriter() emit.AppCall(w.BinWriter, cHash, "init", callflag.All) - initTx := transaction.New(testchain.Network(), w.Bytes(), 1*native.GASFactor) + initTx := transaction.New(w.Bytes(), 1*native.GASFactor) initTx.Nonce = getNextNonce() initTx.ValidUntilBlock = validUntilBlock initTx.Signers = []transaction.Signer{{Account: priv0ScriptHash}} require.NoError(t, addNetworkFee(bc, initTx, acc0)) - require.NoError(t, acc0.SignTx(initTx)) + require.NoError(t, acc0.SignTx(testchain.Network(), initTx)) transferTx := newNEP17Transfer(cHash, cHash, priv0.GetScriptHash(), 1000) transferTx.Nonce = getNextNonce() transferTx.ValidUntilBlock = validUntilBlock @@ -413,7 +413,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { }, } require.NoError(t, addNetworkFee(bc, transferTx, acc0)) - require.NoError(t, acc0.SignTx(transferTx)) + require.NoError(t, acc0.SignTx(testchain.Network(), transferTx)) b = bc.newBlock(initTx, transferTx) require.NoError(t, bc.AddBlock(b)) @@ -433,7 +433,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { }, } require.NoError(t, addNetworkFee(bc, transferTx, acc0)) - require.NoError(t, acc0.SignTx(transferTx)) + require.NoError(t, acc0.SignTx(testchain.Network(), transferTx)) b = bc.newBlock(transferTx) require.NoError(t, bc.AddBlock(b)) @@ -445,7 +445,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { txDeploy2.Nonce = getNextNonce() txDeploy2.ValidUntilBlock = validUntilBlock require.NoError(t, addNetworkFee(bc, txDeploy2, acc0)) - require.NoError(t, acc0.SignTx(txDeploy2)) + require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy2)) b = bc.newBlock(txDeploy2) require.NoError(t, bc.AddBlock(b)) checkTxHalt(t, bc, txDeploy2.Hash()) @@ -462,7 +462,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { } require.NoError(t, addNetworkFee(bc, transferTx, acc0)) transferTx.SystemFee += 10_0000 - require.NoError(t, acc0.SignTx(transferTx)) + require.NoError(t, acc0.SignTx(testchain.Network(), transferTx)) b = bc.newBlock(transferTx) require.NoError(t, bc.AddBlock(b)) @@ -481,7 +481,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { txDeploy3.Nonce = getNextNonce() txDeploy3.ValidUntilBlock = validUntilBlock require.NoError(t, addNetworkFee(bc, txDeploy3, acc0)) - require.NoError(t, acc0.SignTx(txDeploy3)) + require.NoError(t, acc0.SignTx(testchain.Network(), txDeploy3)) b = bc.newBlock(txDeploy3) require.NoError(t, bc.AddBlock(b)) checkTxHalt(t, bc, txDeploy3.Hash()) @@ -499,7 +499,7 @@ func newNEP17Transfer(sc, from, to util.Uint160, amount int64, additionalArgs .. } script := w.Bytes() - return transaction.New(testchain.Network(), script, 11000000) + return transaction.New(script, 11000000) } func newDeployTx(t *testing.T, bc *Blockchain, sender util.Uint160, name, ctrName string, cfgName *string) (*transaction.Transaction, util.Uint160) { @@ -549,7 +549,7 @@ func prepareContractMethodInvokeGeneric(chain *Blockchain, sysfee int64, return nil, w.Err } script := w.Bytes() - tx := transaction.New(chain.GetConfig().Magic, script, sysfee) + tx := transaction.New(script, sysfee) tx.ValidUntilBlock = chain.blockHeight + 1 var err error switch s := signer.(type) { @@ -592,7 +592,7 @@ func signTxWithAccounts(chain *Blockchain, tx *transaction.Transaction, accs ... tx.NetworkFee += int64(size) * chain.FeePerByte() for _, acc := range accs { - if err := acc.SignTx(tx); err != nil { + if err := acc.SignTx(testchain.Network(), tx); err != nil { panic(err) } } diff --git a/pkg/core/interop/crypto/ecdsa_test.go b/pkg/core/interop/crypto/ecdsa_test.go index 01342ef70..0ee3ee436 100644 --- a/pkg/core/interop/crypto/ecdsa_test.go +++ b/pkg/core/interop/crypto/ecdsa_test.go @@ -11,6 +11,7 @@ import ( "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/transaction" + "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/util" @@ -21,7 +22,7 @@ import ( "github.com/stretchr/testify/require" ) -func initCHECKMULTISIG(msg []byte, n int) ([]stackitem.Item, []stackitem.Item, map[string]*keys.PublicKey, error) { +func initCHECKMULTISIG(msgHash util.Uint256, n int) ([]stackitem.Item, []stackitem.Item, map[string]*keys.PublicKey, error) { var err error keyMap := make(map[string]*keys.PublicKey) @@ -41,7 +42,7 @@ func initCHECKMULTISIG(msg []byte, n int) ([]stackitem.Item, []stackitem.Item, m sigs := make([]stackitem.Item, n) for i := range sigs { - sig := pkeys[i].Sign(msg) + sig := pkeys[i].SignHash(msgHash) sigs[i] = stackitem.NewByteArray(sig) } @@ -78,13 +79,13 @@ func initCheckMultisigVMNoArgs(container *transaction.Transaction) *vm.VM { } func initCHECKMULTISIGVM(t *testing.T, n int, ik, is []int) *vm.VM { - tx := transaction.New(netmode.UnitTestNet, []byte("NEO - An Open Network For Smart Economy"), 10) + tx := transaction.New([]byte("NEO - An Open Network For Smart Economy"), 10) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} tx.Scripts = []transaction.Witness{{}} v := initCheckMultisigVMNoArgs(tx) - pubs, sigs, _, err := initCHECKMULTISIG(tx.GetSignedPart(), n) + pubs, sigs, _, err := initCHECKMULTISIG(hash.NetSha256(uint32(netmode.UnitTestNet), tx), n) require.NoError(t, err) pubs = subSlice(pubs, ik) @@ -146,10 +147,10 @@ func testCurveCHECKMULTISIGBad(t *testing.T) { }) msg := []byte("NEO - An Open Network For Smart Economy") - pubs, sigs, _, err := initCHECKMULTISIG(msg, 1) + pubs, sigs, _, err := initCHECKMULTISIG(hash.Sha256(msg), 1) require.NoError(t, err) arr := stackitem.NewArray([]stackitem.Item{stackitem.NewArray(nil)}) - tx := transaction.New(netmode.UnitTestNet, []byte("NEO - An Open Network For Smart Economy"), 10) + tx := transaction.New([]byte("NEO - An Open Network For Smart Economy"), 10) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} tx.Scripts = []transaction.Witness{{}} @@ -199,29 +200,28 @@ func TestCheckSig(t *testing.T) { require.Equal(t, result, ic.VM.Estack().Pop().Value().(bool)) } - tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1) - msg := tx.GetSignedPart() + tx := transaction.New([]byte{0, 1, 2}, 1) ic.Container = tx t.Run("success", func(t *testing.T) { - sign := priv.Sign(msg) + sign := priv.SignHashable(uint32(netmode.UnitTestNet), tx) runCase(t, false, true, sign, priv.PublicKey().Bytes()) }) t.Run("missing argument", func(t *testing.T) { runCase(t, true, false) - sign := priv.Sign(msg) + sign := priv.SignHashable(uint32(netmode.UnitTestNet), tx) runCase(t, true, false, sign) }) t.Run("invalid signature", func(t *testing.T) { - sign := priv.Sign(msg) + sign := priv.SignHashable(uint32(netmode.UnitTestNet), tx) sign[0] = ^sign[0] runCase(t, false, false, sign, priv.PublicKey().Bytes()) }) t.Run("invalid public key", func(t *testing.T) { - sign := priv.Sign(msg) + sign := priv.SignHashable(uint32(netmode.UnitTestNet), tx) pub := priv.PublicKey().Bytes() pub[0] = 0xFF // invalid prefix runCase(t, true, false, sign, pub) diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index 8d2976960..6121058e8 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -262,7 +262,7 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.C func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) { script := []byte{byte(opcode.PUSH1), byte(opcode.RET)} - tx := transaction.New(netmode.UnitTestNet, script, 0) + tx := transaction.New(script, 0) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3, 4}}} tx.Scripts = []transaction.Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}} chain := newTestChain(t) diff --git a/pkg/core/mempool/mem_pool_test.go b/pkg/core/mempool/mem_pool_test.go index c7b79ef80..694ce8960 100644 --- a/pkg/core/mempool/mem_pool_test.go +++ b/pkg/core/mempool/mem_pool_test.go @@ -8,7 +8,6 @@ import ( "time" "github.com/nspcc-dev/neo-go/internal/random" - "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/network/payload" "github.com/nspcc-dev/neo-go/pkg/util" @@ -46,7 +45,7 @@ func (fs *FeerStub) P2PSigExtensionsEnabled() bool { func testMemPoolAddRemoveWithFeer(t *testing.T, fs Feer) { mp := New(10, 0, false) - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = 0 tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} _, ok := mp.TryGetValue(tx.Hash()) @@ -69,7 +68,7 @@ func TestMemPoolRemoveStale(t *testing.T) { mp := New(5, 0, false) txs := make([]*transaction.Transaction, 5) for i := range txs { - txs[i] = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + txs[i] = transaction.New([]byte{byte(opcode.PUSH1)}, 0) txs[i].Nonce = uint32(i) txs[i].Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} require.NoError(t, mp.Add(txs[i], &FeerStub{blockHeight: uint32(i)})) @@ -120,7 +119,7 @@ func TestOverCapacity(t *testing.T) { mp := New(mempoolSize, 0, false) for i := 0; i < mempoolSize; i++ { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = uint32(i) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} require.NoError(t, mp.Add(tx, fs)) @@ -134,7 +133,7 @@ func TestOverCapacity(t *testing.T) { bigScript[1] = byte(opcode.RET) // Fees are also prioritized. for i := 0; i < mempoolSize; i++ { - tx := transaction.New(netmode.UnitTestNet, bigScript, 0) + tx := transaction.New(bigScript, 0) tx.NetworkFee = 10000 tx.Nonce = txcnt tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} @@ -145,7 +144,7 @@ func TestOverCapacity(t *testing.T) { require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) } // Less prioritized txes are not allowed anymore. - tx := transaction.New(netmode.UnitTestNet, bigScript, 0) + tx := transaction.New(bigScript, 0) tx.NetworkFee = 100 tx.Nonce = txcnt tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} @@ -158,7 +157,7 @@ func TestOverCapacity(t *testing.T) { require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) // Low net fee, but higher per-byte fee is still a better combination. - tx = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx = transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = txcnt tx.NetworkFee = 7000 tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} @@ -171,7 +170,7 @@ func TestOverCapacity(t *testing.T) { // High priority always wins over low priority. for i := 0; i < mempoolSize; i++ { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.NetworkFee = 8000 tx.Nonce = txcnt tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} @@ -181,7 +180,7 @@ func TestOverCapacity(t *testing.T) { require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) } // Good luck with low priority now. - tx = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx = transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = txcnt tx.NetworkFee = 7000 tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} @@ -197,7 +196,7 @@ func TestGetVerified(t *testing.T) { txes := make([]*transaction.Transaction, 0, mempoolSize) for i := 0; i < mempoolSize; i++ { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = uint32(i) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} txes = append(txes, tx) @@ -222,7 +221,7 @@ func TestRemoveStale(t *testing.T) { txes1 := make([]*transaction.Transaction, 0, mempoolSize/2) txes2 := make([]*transaction.Transaction, 0, mempoolSize/2) for i := 0; i < mempoolSize; i++ { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = uint32(i) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} if i%2 == 0 { @@ -253,7 +252,7 @@ func TestMemPoolFees(t *testing.T) { mp := New(10, 0, false) fs := &FeerStub{balance: 10000000} sender0 := util.Uint160{1, 2, 3} - tx0 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx0 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx0.NetworkFee = fs.balance + 1 tx0.Signers = []transaction.Signer{{Account: sender0}} // insufficient funds to add transaction, and balance shouldn't be stored @@ -263,7 +262,7 @@ func TestMemPoolFees(t *testing.T) { balancePart := new(big.Int).Div(big.NewInt(fs.balance), big.NewInt(4)) // no problems with adding another transaction with lower fee - tx1 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx1 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx1.NetworkFee = balancePart.Int64() tx1.Signers = []transaction.Signer{{Account: sender0}} require.NoError(t, mp.Add(tx1, fs)) @@ -274,7 +273,7 @@ func TestMemPoolFees(t *testing.T) { }, mp.fees[sender0]) // balance shouldn't change after adding one more transaction - tx2 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx2 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx2.NetworkFee = new(big.Int).Sub(big.NewInt(fs.balance), balancePart).Int64() tx2.Signers = []transaction.Signer{{Account: sender0}} require.NoError(t, mp.Add(tx2, fs)) @@ -286,7 +285,7 @@ func TestMemPoolFees(t *testing.T) { }, mp.fees[sender0]) // can't add more transactions as we don't have enough GAS - tx3 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx3 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx3.NetworkFee = 1 tx3.Signers = []transaction.Signer{{Account: sender0}} require.Equal(t, false, mp.Verify(tx3, fs)) @@ -324,24 +323,24 @@ func TestMempoolItemsOrder(t *testing.T) { sender0 := util.Uint160{1, 2, 3} balance := big.NewInt(10000000) - tx1 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx1 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx1.NetworkFee = new(big.Int).Div(balance, big.NewInt(8)).Int64() tx1.Signers = []transaction.Signer{{Account: sender0}} tx1.Attributes = []transaction.Attribute{{Type: transaction.HighPriority}} item1 := item{txn: tx1} - tx2 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx2 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx2.NetworkFee = new(big.Int).Div(balance, big.NewInt(16)).Int64() tx2.Signers = []transaction.Signer{{Account: sender0}} tx2.Attributes = []transaction.Attribute{{Type: transaction.HighPriority}} item2 := item{txn: tx2} - tx3 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx3 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx3.NetworkFee = new(big.Int).Div(balance, big.NewInt(2)).Int64() tx3.Signers = []transaction.Signer{{Account: sender0}} item3 := item{txn: tx3} - tx4 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx4 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx4.NetworkFee = new(big.Int).Div(balance, big.NewInt(4)).Int64() tx4.Signers = []transaction.Signer{{Account: sender0}} item4 := item{txn: tx4} @@ -365,7 +364,7 @@ func TestMempoolAddRemoveOracleResponse(t *testing.T) { nonce := uint32(0) fs := &FeerStub{balance: 10000} newTx := func(netFee int64, id uint64) *transaction.Transaction { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.NetworkFee = netFee tx.Nonce = nonce nonce++ @@ -437,7 +436,7 @@ func TestMempoolAddRemoveConflicts(t *testing.T) { nonce uint32 = 1 ) getConflictsTx := func(netFee int64, hashes ...util.Uint256) *transaction.Transaction { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.NetworkFee = netFee tx.Nonce = nonce nonce++ @@ -535,7 +534,7 @@ func TestMempoolAddRemoveConflicts(t *testing.T) { assert.Equal(t, []util.Uint256{tx3.Hash(), tx2.Hash()}, mp.conflicts[tx1.Hash()]) // tx13 conflicts with tx2, but is not signed by tx2.Sender - tx13 := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx13 := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx13.NetworkFee = smallNetFee tx13.Nonce = uint32(random.Int(0, 1e4)) tx13.Signers = []transaction.Signer{{Account: util.Uint160{3, 2, 1}}} @@ -563,7 +562,7 @@ func TestMempoolAddWithDataGetData(t *testing.T) { } mp := New(10, 1, false) newTx := func(t *testing.T, netFee int64) *transaction.Transaction { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 0) + tx := transaction.New([]byte{byte(opcode.RET)}, 0) tx.Signers = []transaction.Signer{{}, {}} tx.NetworkFee = netFee nonce++ diff --git a/pkg/core/mempool/subscriptions_test.go b/pkg/core/mempool/subscriptions_test.go index 77b18141e..67557455f 100644 --- a/pkg/core/mempool/subscriptions_test.go +++ b/pkg/core/mempool/subscriptions_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" @@ -33,7 +32,7 @@ func TestSubscriptions(t *testing.T) { txs := make([]*transaction.Transaction, 4) for i := range txs { - txs[i] = transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + txs[i] = transaction.New([]byte{byte(opcode.PUSH1)}, 0) txs[i].Nonce = uint32(i) txs[i].Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} txs[i].NetworkFee = int64(i) diff --git a/pkg/core/native/notary.go b/pkg/core/native/notary.go index 34beafc4d..269051784 100644 --- a/pkg/core/native/notary.go +++ b/pkg/core/native/notary.go @@ -17,6 +17,7 @@ import ( "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/transaction" + "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" @@ -356,10 +357,10 @@ func (n *Notary) verify(ic *interop.Context, args []stackitem.Item) stackitem.It if err != nil { panic(fmt.Errorf("failed to get notary nodes: %w", err)) } - hash := tx.GetSignedHash().BytesBE() + shash := hash.NetSha256(uint32(ic.Network), tx) var verified bool for _, n := range notaries { - if n.Verify(sig, hash) { + if n.Verify(sig, shash[:]) { verified = true break } diff --git a/pkg/core/native_designate_test.go b/pkg/core/native_designate_test.go index c19794478..291457b05 100644 --- a/pkg/core/native_designate_test.go +++ b/pkg/core/native_designate_test.go @@ -33,7 +33,7 @@ func (bc *Blockchain) setNodesByRole(t *testing.T, ok bool, r noderoles.Role, no emit.Opcodes(w.BinWriter, opcode.PACK) emit.AppCallNoArgs(w.BinWriter, bc.contracts.Designate.Hash, "designateAsRole", callflag.All) require.NoError(t, w.Err) - tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 0) + tx := transaction.New(w.Bytes(), 0) tx.NetworkFee = 10_000_000 tx.SystemFee = 10_000_000 tx.ValidUntilBlock = 100 @@ -49,7 +49,7 @@ func (bc *Blockchain) setNodesByRole(t *testing.T, ok bool, r noderoles.Role, no } require.NoError(t, testchain.SignTx(bc, tx)) tx.Scripts = append(tx.Scripts, transaction.Witness{ - InvocationScript: testchain.SignCommittee(tx.GetSignedPart()), + InvocationScript: testchain.SignCommittee(tx), VerificationScript: testchain.CommitteeVerificationScript(), }) require.NoError(t, bc.AddBlock(bc.newBlock(tx))) @@ -114,7 +114,7 @@ func TestDesignate_DesignateAsRole(t *testing.T) { bc := newTestChain(t) des := bc.contracts.Designate - tx := transaction.New(netmode.UnitTestNet, []byte{}, 0) + tx := transaction.New([]byte{}, 0) bl := block.New(netmode.UnitTestNet, bc.config.StateRootInHeader) bl.Index = bc.BlockHeight() + 1 ic := bc.newInteropContext(trigger.OnPersist, bc.dao, bl, tx) diff --git a/pkg/core/native_name_service_test.go b/pkg/core/native_name_service_test.go index dc519aaa2..e79e559d4 100644 --- a/pkg/core/native_name_service_test.go +++ b/pkg/core/native_name_service_test.go @@ -329,7 +329,7 @@ func testTokensOf(t *testing.T, bc *Blockchain, signer *wallet.Account, result [ emit.Opcodes(w.BinWriter, opcode.PACK) require.NoError(t, w.Err) script := w.Bytes() - tx := transaction.New(bc.GetConfig().Magic, script, defaultNameServiceSysfee) + tx := transaction.New(script, defaultNameServiceSysfee) tx.ValidUntilBlock = bc.BlockHeight() + 1 signTxWithAccounts(bc, tx, signer) aers, err := persistBlock(bc, tx) diff --git a/pkg/core/native_neo_test.go b/pkg/core/native_neo_test.go index d86cd9e47..b085ba824 100644 --- a/pkg/core/native_neo_test.go +++ b/pkg/core/native_neo_test.go @@ -41,7 +41,7 @@ func TestNEO_Vote(t *testing.T) { bc := newTestChain(t) neo := bc.contracts.NEO - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) ic := bc.newInteropContext(trigger.Application, bc.dao, nil, tx) ic.SpawnVM() ic.Block = bc.newBlock(tx) @@ -85,7 +85,7 @@ func TestNEO_Vote(t *testing.T) { int64(1_000_000_000), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) - tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 1000_000_000) + tx := transaction.New(w.Bytes(), 1000_000_000) tx.ValidUntilBlock = bc.BlockHeight() + 1 setSigner(tx, testchain.MultisigScriptHash()) require.NoError(t, testchain.SignTx(bc, tx)) @@ -146,12 +146,12 @@ func TestNEO_Vote(t *testing.T) { h.BytesBE(), h.BytesBE(), int64(1), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) - tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 0) + tx := transaction.New(w.Bytes(), 0) tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.NetworkFee = 2_000_000 tx.SystemFee = 11_000_000 setSigner(tx, h) - require.NoError(t, accs[i].SignTx(tx)) + require.NoError(t, accs[i].SignTx(netmode.UnitTestNet, tx)) txs = append(txs, tx) } require.NoError(t, bc.AddBlock(bc.newBlock(txs...))) @@ -204,7 +204,7 @@ func TestNEO_CalculateBonus(t *testing.T) { bc := newTestChain(t) neo := bc.contracts.NEO - tx := transaction.New(netmode.UnitTestNet, []byte{}, 0) + tx := transaction.New([]byte{}, 0) ic := bc.newInteropContext(trigger.Application, bc.dao, nil, tx) ic.SpawnVM() ic.VM.LoadScript([]byte{byte(opcode.RET)}) diff --git a/pkg/core/native_notary_test.go b/pkg/core/native_notary_test.go index fc1294272..1eed3a19c 100644 --- a/pkg/core/native_notary_test.go +++ b/pkg/core/native_notary_test.go @@ -178,7 +178,7 @@ func TestNotaryContractPipeline(t *testing.T) { testchain.MultisigScriptHash(), acc.PrivateKey().PublicKey().GetScriptHash()) require.NoError(t, w.Err) script := w.Bytes() - withdrawTx := transaction.New(chain.GetConfig().Magic, script, 10000000) + withdrawTx := transaction.New(script, 10000000) withdrawTx.ValidUntilBlock = chain.blockHeight + 1 withdrawTx.NetworkFee = 10000000 withdrawTx.Signers = []transaction.Signer{ @@ -187,7 +187,7 @@ func TestNotaryContractPipeline(t *testing.T) { Scopes: transaction.None, }, } - err = acc.SignTx(withdrawTx) + err = acc.SignTx(chain.GetConfig().Magic, withdrawTx) require.NoError(t, err) b := chain.newBlock(withdrawTx) err = chain.AddBlock(b) @@ -291,13 +291,12 @@ func TestNotaryNodesReward(t *testing.T) { Scopes: transaction.None, }, } - data := tx.GetSignedPart() tx.Scripts = []transaction.Witness{ { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notaryNodes[0].Sign(data)...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, notaryNodes[0].SignHashable(uint32(testchain.Network()), tx)...), }, { - InvocationScript: testchain.Sign(data), + InvocationScript: testchain.Sign(tx), VerificationScript: testchain.MultisigVerificationScript(), }, } diff --git a/pkg/core/native_oracle_test.go b/pkg/core/native_oracle_test.go index f1191278d..496928428 100644 --- a/pkg/core/native_oracle_test.go +++ b/pkg/core/native_oracle_test.go @@ -148,7 +148,7 @@ func TestOracle_Request(t *testing.T) { require.NoError(t, err) pub := priv.PublicKey() - tx := transaction.New(netmode.UnitTestNet, []byte{}, 0) + tx := transaction.New([]byte{}, 0) bl := block.New(netmode.UnitTestNet, bc.config.StateRootInHeader) bl.Index = bc.BlockHeight() + 1 setSigner(tx, testchain.CommitteeScriptHash()) @@ -158,7 +158,7 @@ func TestOracle_Request(t *testing.T) { err = bc.contracts.Designate.DesignateAsRole(ic, noderoles.Oracle, keys.PublicKeys{pub}) require.NoError(t, err) - tx = transaction.New(netmode.UnitTestNet, orc.GetOracleResponseScript(), 0) + tx = transaction.New(orc.GetOracleResponseScript(), 0) ic.Tx = tx ic.Block = bc.newBlock(tx) @@ -208,7 +208,7 @@ func TestOracle_Request(t *testing.T) { _, err := orc.GetRequestInternal(bc.dao, reqID) // ensure ID is 1 require.NoError(t, err) - tx = transaction.New(netmode.UnitTestNet, orc.GetOracleResponseScript(), 0) + tx = transaction.New(orc.GetOracleResponseScript(), 0) tx.Attributes = []transaction.Attribute{{ Type: transaction.OracleResponseT, Value: &transaction.OracleResponse{ diff --git a/pkg/core/notary_test.go b/pkg/core/notary_test.go index c3ee363f0..001bf9ebc 100644 --- a/pkg/core/notary_test.go +++ b/pkg/core/notary_test.go @@ -48,7 +48,7 @@ func getTestNotary(t *testing.T, bc *Blockchain, walletPath, pass string, onTx f Log: zaptest.NewLogger(t), } mp := mempool.New(10, 1, true) - ntr, err := notary.NewNotary(cfg, mp, onTx) + ntr, err := notary.NewNotary(cfg, testchain.Network(), mp, onTx) require.NoError(t, err) w, err := wallet.NewWalletFromFile(path.Join(notaryModulePath, walletPath)) @@ -107,7 +107,7 @@ func TestNotary(t *testing.T) { bc.setNodesByRole(t, true, noderoles.P2PNotary, notaryNodes) createFallbackTx := func(requester *wallet.Account, mainTx *transaction.Transaction, nvbIncrement ...uint32) *transaction.Transaction { - fallback := transaction.New(testchain.Network(), []byte{byte(opcode.RET)}, 2000_0000) + fallback := transaction.New([]byte{byte(opcode.RET)}, 2000_0000) fallback.Nonce = nonce nonce++ fallback.SystemFee = 1_0000_0000 @@ -146,12 +146,12 @@ func TestNotary(t *testing.T) { VerificationScript: []byte{}, }, } - requester.SignTx(fallback) + requester.SignTx(testchain.Network(), fallback) return fallback } createStandardRequest := func(requesters []*wallet.Account, NVBincrements ...uint32) []*payload.P2PNotaryRequest { - mainTx := *transaction.New(testchain.Network(), []byte{byte(opcode.RET)}, 11000000) + mainTx := *transaction.New([]byte{byte(opcode.RET)}, 11000000) mainTx.Nonce = nonce nonce++ mainTx.SystemFee = 100000000 @@ -182,7 +182,7 @@ func TestNotary(t *testing.T) { for j := range requesters { scripts[j].VerificationScript = requesters[j].PrivateKey().PublicKey().GetVerificationScript() } - scripts[i].InvocationScript = append([]byte{byte(opcode.PUSHDATA1), 64}, requesters[i].PrivateKey().Sign(main.GetSignedPart())...) + scripts[i].InvocationScript = append([]byte{byte(opcode.PUSHDATA1), 64}, requesters[i].PrivateKey().SignHashable(uint32(testchain.Network()), main)...) main.Scripts = scripts _ = main.Size() // for size update test @@ -205,7 +205,7 @@ func TestNotary(t *testing.T) { return payloads } createMultisigRequest := func(m int, requesters []*wallet.Account) []*payload.P2PNotaryRequest { - mainTx := *transaction.New(testchain.Network(), []byte{byte(opcode.RET)}, 11000000) + mainTx := *transaction.New([]byte{byte(opcode.RET)}, 11000000) mainTx.Nonce = nonce nonce++ mainTx.SystemFee = 100000000 @@ -240,7 +240,7 @@ func TestNotary(t *testing.T) { main := &cp main.Scripts = []transaction.Witness{ { - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, requesters[i].PrivateKey().Sign(main.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, requesters[i].PrivateKey().SignHashable(uint32(testchain.Network()), main)...), VerificationScript: script, }, {}, // empty Notary witness @@ -272,7 +272,7 @@ func TestNotary(t *testing.T) { require.NoError(t, err) } require.Equal(t, transaction.Witness{ - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc1.PrivateKey().Sign(requests[0].MainTransaction.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc1.PrivateKey().SignHashable(uint32(testchain.Network()), requests[0].MainTransaction)...), VerificationScript: []byte{}, }, completedTx.Scripts[nKeys]) } else { @@ -289,7 +289,7 @@ func TestNotary(t *testing.T) { _, err := bc.verifyHashAgainstScript(completedTx.Signers[0].Account, &completedTx.Scripts[0], interopCtx, -1) require.NoError(t, err) require.Equal(t, transaction.Witness{ - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc1.PrivateKey().Sign(requests[0].MainTransaction.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc1.PrivateKey().SignHashable(uint32(testchain.Network()), requests[0].MainTransaction)...), VerificationScript: []byte{}, }, completedTx.Scripts[1]) // check that only nSigs out of nKeys signatures are presented in the invocation script @@ -312,7 +312,7 @@ func TestNotary(t *testing.T) { require.Equal(t, 2, len(completedTx.Signers)) require.Equal(t, 2, len(completedTx.Scripts)) require.Equal(t, transaction.Witness{ - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc1.PrivateKey().Sign(req.FallbackTransaction.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc1.PrivateKey().SignHashable(uint32(testchain.Network()), req.FallbackTransaction)...), VerificationScript: []byte{}, }, completedTx.Scripts[0]) diff --git a/pkg/core/transaction/helper_test.go b/pkg/core/transaction/helper_test.go index fddfa503d..13987a18c 100644 --- a/pkg/core/transaction/helper_test.go +++ b/pkg/core/transaction/helper_test.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "testing" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/stretchr/testify/assert" ) @@ -16,7 +15,7 @@ var ( func decodeTransaction(rawTX string, t *testing.T) *Transaction { b, err1 := base64.StdEncoding.DecodeString(rawTX) assert.Nil(t, err1) - tx, err := NewTransactionFromBytes(netmode.PrivNet, b) + tx, err := NewTransactionFromBytes(b) assert.NoError(t, err) return tx } diff --git a/pkg/core/transaction/transaction.go b/pkg/core/transaction/transaction.go index b2eb455e8..d49b8061d 100644 --- a/pkg/core/transaction/transaction.go +++ b/pkg/core/transaction/transaction.go @@ -7,7 +7,6 @@ import ( "math" "math/rand" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/io" @@ -66,20 +65,12 @@ type Transaction struct { // and invocation script. Scripts []Witness - // Network magic number. This one actually is not a part of the - // wire-representation of Transaction, but it's absolutely necessary - // for correct signing/verification. - Network netmode.Magic - // size is transaction's serialized size. size int // Hash of the transaction (double SHA256). hash util.Uint256 - // Hash of the transaction used to verify it (single SHA256). - verificationHash util.Uint256 - // Trimmed indicates this is a transaction from trimmed // data. Trimmed bool @@ -96,7 +87,7 @@ func NewTrimmedTX(hash util.Uint256) *Transaction { // New returns a new transaction to execute given script and pay given system // fee. -func New(network netmode.Magic, script []byte, gas int64) *Transaction { +func New(script []byte, gas int64) *Transaction { return &Transaction{ Version: 0, Nonce: rand.Uint32(), @@ -105,7 +96,6 @@ func New(network netmode.Magic, script []byte, gas int64) *Transaction { Attributes: []Attribute{}, Signers: []Signer{}, Scripts: []Witness{}, - Network: network, } } @@ -119,16 +109,6 @@ func (t *Transaction) Hash() util.Uint256 { return t.hash } -// GetSignedHash returns a hash of the transaction used to verify it. -func (t *Transaction) GetSignedHash() util.Uint256 { - if t.verificationHash.Equals(util.Uint256{}) { - if t.createHash() != nil { - panic("failed to compute hash!") - } - } - return t.verificationHash -} - // HasAttribute returns true iff t has an attribute of type typ. func (t *Transaction) HasAttribute(typ AttrType) bool { for i := range t.Attributes { @@ -229,32 +209,9 @@ func (t *Transaction) createHash() error { } t.hash = hash.Sha256(buf.Bytes()) - buf.Reset() - t.writeSignedPart(buf) - t.verificationHash = hash.Sha256(buf.Bytes()) return nil } -// GetSignedPart returns a part of the transaction which must be signed. -func (t *Transaction) GetSignedPart() []byte { - if t.hash.Equals(util.Uint256{}) { - if err := t.createHash(); err != nil { - panic(fmt.Errorf("failed to compute hash: %w", err)) - } - } - buf := io.NewBufBinWriter() - t.writeSignedPart(buf) - if buf.Err != nil { - return nil - } - return buf.Bytes() -} - -func (t *Transaction) writeSignedPart(buf *io.BufBinWriter) { - buf.WriteU32LE(uint32(t.Network)) - buf.WriteBytes(t.hash[:]) -} - // DecodeHashableFields decodes a part of transaction which should be hashed. func (t *Transaction) DecodeHashableFields(buf []byte) error { r := io.NewBinReaderFromBuf(buf) @@ -270,9 +227,6 @@ func (t *Transaction) DecodeHashableFields(buf []byte) error { t.Scripts = make([]Witness, 0) t.hash = hash.Sha256(buf) - b := io.NewBufBinWriter() - t.writeSignedPart(b) - t.verificationHash = hash.Sha256(b.Bytes()) return nil } @@ -287,8 +241,8 @@ func (t *Transaction) Bytes() []byte { } // NewTransactionFromBytes decodes byte array into *Transaction -func NewTransactionFromBytes(network netmode.Magic, b []byte) (*Transaction, error) { - tx := &Transaction{Network: network} +func NewTransactionFromBytes(b []byte) (*Transaction, error) { + tx := &Transaction{} r := io.NewBinReaderFromBuf(b) tx.DecodeBinary(r) if r.Err != nil { diff --git a/pkg/core/transaction/transaction_test.go b/pkg/core/transaction/transaction_test.go index d00344be1..62a46123c 100644 --- a/pkg/core/transaction/transaction_test.go +++ b/pkg/core/transaction/transaction_test.go @@ -10,7 +10,6 @@ import ( "github.com/nspcc-dev/neo-go/internal/random" "github.com/nspcc-dev/neo-go/internal/testserdes" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" @@ -70,7 +69,7 @@ func TestDecodeEncodeInvocationTX(t *testing.T) { func TestNew(t *testing.T) { script := []byte{0x51} - tx := New(netmode.UnitTestNet, script, 1) + tx := New(script, 1) tx.Signers = []Signer{{Account: util.Uint160{1, 2, 3}}} tx.Scripts = []Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}} assert.Equal(t, int64(1), tx.SystemFee) @@ -78,12 +77,12 @@ func TestNew(t *testing.T) { // Update hash fields to match tx2 that is gonna autoupdate them on decode. _ = tx.Hash() _ = tx.Size() - testserdes.EncodeDecodeBinary(t, tx, &Transaction{Network: netmode.UnitTestNet}) + testserdes.EncodeDecodeBinary(t, tx, &Transaction{}) } func TestNewTransactionFromBytes(t *testing.T) { script := []byte{0x51} - tx := New(netmode.UnitTestNet, script, 1) + tx := New(script, 1) tx.NetworkFee = 123 tx.Signers = []Signer{{Account: util.Uint160{1, 2, 3}}} tx.Scripts = []Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}} @@ -94,12 +93,12 @@ func TestNewTransactionFromBytes(t *testing.T) { tx.Hash() tx.FeePerByte() - tx1, err := NewTransactionFromBytes(netmode.UnitTestNet, data) + tx1, err := NewTransactionFromBytes(data) require.NoError(t, err) require.Equal(t, tx, tx1) data = append(data, 42) - _, err = NewTransactionFromBytes(netmode.UnitTestNet, data) + _, err = NewTransactionFromBytes(data) require.Error(t, err) } @@ -116,7 +115,7 @@ func TestDecodingTXWithNoScript(t *testing.T) { } func TestDecodingTxWithInvalidWitnessesNumber(t *testing.T) { - tx := New(netmode.UnitTestNet, []byte{byte(opcode.RET)}, 1) + tx := New([]byte{byte(opcode.RET)}, 1) tx.Signers = []Signer{{Account: util.Uint160{1, 2, 3}}} tx.Scripts = []Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}, {InvocationScript: []byte{}, VerificationScript: []byte{}}} data, err := testserdes.EncodeBinary(tx) @@ -151,7 +150,6 @@ func TestUnmarshalNeoFSTX(t *testing.T) { ] }`) tx := new(Transaction) - tx.Network = 56753 require.NoError(t, json.Unmarshal(txjson, tx)) } @@ -171,7 +169,7 @@ func TestMarshalUnmarshalJSONInvocationTX(t *testing.T) { } func TestTransaction_HasAttribute(t *testing.T) { - tx := New(netmode.UnitTestNet, []byte{1}, 0) + tx := New([]byte{1}, 0) require.False(t, tx.HasAttribute(HighPriority)) tx.Attributes = append(tx.Attributes, Attribute{Type: HighPriority}) require.True(t, tx.HasAttribute(HighPriority)) diff --git a/pkg/network/message.go b/pkg/network/message.go index 9c64cc802..83f7927d3 100644 --- a/pkg/network/message.go +++ b/pkg/network/message.go @@ -159,7 +159,7 @@ func (m *Message) decodePayload() error { case CMDHeaders: p = &payload.Headers{Network: m.Network, StateRootInHeader: m.StateRootInHeader} case CMDTX: - p = &transaction.Transaction{Network: m.Network} + p = &transaction.Transaction{} case CMDMerkleBlock: p = &payload.MerkleBlock{Network: m.Network} case CMDPing, CMDPong: diff --git a/pkg/network/message_test.go b/pkg/network/message_test.go index 64b538115..5a6379be3 100644 --- a/pkg/network/message_test.go +++ b/pkg/network/message_test.go @@ -302,7 +302,7 @@ func newDummyBlock(height uint32, txCount int) *block.Block { } func newDummyTx() *transaction.Transaction { - tx := transaction.New(netmode.UnitTestNet, random.Bytes(100), 123) + tx := transaction.New(random.Bytes(100), 123) tx.Signers = []transaction.Signer{{Account: random.Uint160()}} tx.Scripts = []transaction.Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}} tx.Size() diff --git a/pkg/network/payload/notary_request.go b/pkg/network/payload/notary_request.go index 8dcd5e1ad..8eb8e6444 100644 --- a/pkg/network/payload/notary_request.go +++ b/pkg/network/payload/notary_request.go @@ -94,8 +94,8 @@ func (r *P2PNotaryRequest) createHash() error { // DecodeBinaryUnsigned reads payload from w excluding signature. func (r *P2PNotaryRequest) decodeHashableFields(br *io.BinReader) { - r.MainTransaction = &transaction.Transaction{Network: r.Network} - r.FallbackTransaction = &transaction.Transaction{Network: r.Network} + r.MainTransaction = &transaction.Transaction{} + r.FallbackTransaction = &transaction.Transaction{} r.MainTransaction.DecodeBinary(br) r.FallbackTransaction.DecodeBinary(br) if br.Err == nil { diff --git a/pkg/network/payload/notary_request_test.go b/pkg/network/payload/notary_request_test.go index 7f82175cb..7261eecb5 100644 --- a/pkg/network/payload/notary_request_test.go +++ b/pkg/network/payload/notary_request_test.go @@ -144,7 +144,6 @@ func TestNotaryRequestIsValid(t *testing.T) { func TestNotaryRequestBytesFromBytes(t *testing.T) { mainTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}}, Script: []byte{0, 1, 2}, ValidUntilBlock: 123, @@ -157,7 +156,6 @@ func TestNotaryRequestBytesFromBytes(t *testing.T) { _ = mainTx.Hash() _ = mainTx.Size() fallbackTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Script: []byte{3, 2, 1}, ValidUntilBlock: 123, Attributes: []transaction.Attribute{ diff --git a/pkg/network/server.go b/pkg/network/server.go index e7272da9e..852055857 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -152,7 +152,7 @@ func newServerFromConstructors(config ServerConfig, chain blockchainer.Blockchai Chain: chain, Log: log, } - n, err := notary.NewNotary(cfg, s.notaryRequestPool, func(tx *transaction.Transaction) error { + n, err := notary.NewNotary(cfg, s.network, s.notaryRequestPool, func(tx *transaction.Transaction) error { if err := s.RelayTxn(tx); err != nil { return fmt.Errorf("can't relay completed notary transaction: hash %s, error: %w", tx.Hash().StringLE(), err) } diff --git a/pkg/network/server_test.go b/pkg/network/server_test.go index 9284b5134..bc5c2f2bf 100644 --- a/pkg/network/server_test.go +++ b/pkg/network/server_test.go @@ -518,7 +518,6 @@ func TestGetData(t *testing.T) { }) t.Run("p2pNotaryRequest", func(t *testing.T) { mainTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}}, Script: []byte{0, 1, 2}, ValidUntilBlock: 123, @@ -528,7 +527,6 @@ func TestGetData(t *testing.T) { mainTx.Size() mainTx.Hash() fallbackTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Script: []byte{1, 2, 3}, ValidUntilBlock: 123, Attributes: []transaction.Attribute{ @@ -720,7 +718,7 @@ func TestInv(t *testing.T) { }) }) t.Run("p2pNotaryRequest", func(t *testing.T) { - fallbackTx := transaction.New(netmode.UnitTestNet, random.Bytes(100), 123) + fallbackTx := transaction.New(random.Bytes(100), 123) fallbackTx.Signers = []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}} fallbackTx.Size() fallbackTx.Hash() diff --git a/pkg/rpc/client/nep17.go b/pkg/rpc/client/nep17.go index 62a61b1fe..f9ce80a7f 100644 --- a/pkg/rpc/client/nep17.go +++ b/pkg/rpc/client/nep17.go @@ -179,7 +179,7 @@ func (c *Client) CreateTxFromScript(script []byte, acc *wallet.Account, sysFee, if !c.initDone { return nil, errNetworkNotInitialized } - tx := transaction.New(c.GetNetwork(), script, sysFee) + tx := transaction.New(script, sysFee) tx.Signers = signers tx.ValidUntilBlock, err = c.CalculateValidUntilBlock() @@ -205,7 +205,7 @@ func (c *Client) TransferNEP17(acc *wallet.Account, to util.Uint160, token util. return util.Uint256{}, err } - if err := acc.SignTx(tx); err != nil { + if err := acc.SignTx(c.GetNetwork(), tx); err != nil { return util.Uint256{}, fmt.Errorf("can't sign tx: %w", err) } @@ -219,7 +219,7 @@ func (c *Client) MultiTransferNEP17(acc *wallet.Account, gas int64, recipients [ return util.Uint256{}, err } - if err := acc.SignTx(tx); err != nil { + if err := acc.SignTx(c.GetNetwork(), tx); err != nil { return util.Uint256{}, fmt.Errorf("can't sign tx: %w", err) } diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index dcec9177c..60fe1e872 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -336,7 +336,7 @@ func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction, if err = c.performRequest("getrawtransaction", params, &resp); err != nil { return nil, err } - tx, err := transaction.NewTransactionFromBytes(c.GetNetwork(), resp) + tx, err := transaction.NewTransactionFromBytes(resp) if err != nil { return nil, err } @@ -356,7 +356,6 @@ func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.Transactio if !c.initDone { return nil, errNetworkNotInitialized } - resp.Network = c.GetNetwork() if err = c.performRequest("getrawtransaction", params, resp); err != nil { return nil, err } @@ -529,7 +528,7 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys if err != nil { return txHash, fmt.Errorf("failed to create tx: %w", err) } - if err = acc.SignTx(tx); err != nil { + if err = acc.SignTx(c.GetNetwork(), tx); err != nil { return txHash, fmt.Errorf("failed to sign tx: %w", err) } txHash = tx.Hash() @@ -621,7 +620,7 @@ func (c *Client) SignAndPushP2PNotaryRequest(mainTx *transaction.Transaction, fa if int64(fallbackValidFor) > maxNVBDelta { return nil, fmt.Errorf("fallback transaction should be valid for not more than %d blocks", maxNVBDelta) } - fallbackTx := transaction.New(c.GetNetwork(), fallbackScript, fallbackSysFee) + fallbackTx := transaction.New(fallbackScript, fallbackSysFee) fallbackTx.Signers = signers fallbackTx.ValidUntilBlock = mainTx.ValidUntilBlock fallbackTx.Attributes = []transaction.Attribute{ @@ -655,7 +654,7 @@ func (c *Client) SignAndPushP2PNotaryRequest(mainTx *transaction.Transaction, fa VerificationScript: []byte{}, }, } - if err = acc.SignTx(fallbackTx); err != nil { + if err = acc.SignTx(c.GetNetwork(), fallbackTx); err != nil { return nil, fmt.Errorf("failed to sign fallback tx: %w", err) } fallbackHash := fallbackTx.Hash() diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index 7f48ea0b6..3368ae6f2 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -91,7 +91,7 @@ func getTxMoveNeo() *result.TransactionOutputRaw { if err != nil { panic(err) } - tx, err := transaction.NewTransactionFromBytes(netmode.UnitTestNet, txBin) + tx, err := transaction.NewTransactionFromBytes(txBin) if err != nil { panic(err) } @@ -939,7 +939,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ { name: "positive", invoke: func(c *Client) (interface{}, error) { - return c.SendRawTransaction(transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)) + return c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0)) }, serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"hash":"0x72159b0cf1221110daad6e1df6ef4ff03012173b63c86910bd7134deb659c875"}}`, result: func(c *Client) interface{} { @@ -1076,7 +1076,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{ { name: "sendrawtransaction_bad_server_answer", invoke: func(c *Client) (interface{}, error) { - return c.SendRawTransaction(transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)) + return c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0)) }, }, { @@ -1437,7 +1437,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{ { name: "sendrawtransaction_unmarshalling_error", invoke: func(c *Client) (interface{}, error) { - return c.SendRawTransaction(transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)) + return c.SendRawTransaction(transaction.New([]byte{byte(opcode.PUSH1)}, 0)) }, }, { diff --git a/pkg/rpc/client/wsclient.go b/pkg/rpc/client/wsclient.go index 7f79b6711..a1a34f964 100644 --- a/pkg/rpc/client/wsclient.go +++ b/pkg/rpc/client/wsclient.go @@ -141,7 +141,7 @@ readloop: case response.BlockEventID: val = block.New(c.GetNetwork(), c.StateRootInHeader()) case response.TransactionEventID: - val = &transaction.Transaction{Network: c.GetNetwork()} + val = &transaction.Transaction{} case response.NotificationEventID: val = new(state.NotificationEvent) case response.ExecutionEventID: diff --git a/pkg/rpc/response/result/invoke.go b/pkg/rpc/response/result/invoke.go index 76be179df..7b29cc239 100644 --- a/pkg/rpc/response/result/invoke.go +++ b/pkg/rpc/response/result/invoke.go @@ -2,25 +2,20 @@ package result import ( "encoding/json" - "errors" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) // Invoke represents code invocation result and is used by several RPC calls -// that invoke functions, scripts and generic bytecode. Transaction is -// represented in raw serialized format, use transaction.NewTransactionFromBytes -// or GetTransaction method to deserialize it. +// that invoke functions, scripts and generic bytecode. type Invoke struct { State string GasConsumed int64 Script []byte Stack []stackitem.Item FaultException string - // Transaction represents transaction bytes. Use GetTransaction method to decode it. - Transaction []byte + Transaction *transaction.Transaction } type invokeAux struct { @@ -52,25 +47,29 @@ func (r Invoke) MarshalJSON() ([]byte, error) { return nil, err } } - + var txbytes []byte + if r.Transaction != nil { + txbytes = r.Transaction.Bytes() + } return json.Marshal(&invokeAux{ GasConsumed: r.GasConsumed, Script: r.Script, State: r.State, Stack: st, FaultException: r.FaultException, - Transaction: r.Transaction, + Transaction: txbytes, }) } // UnmarshalJSON implements json.Unmarshaler. func (r *Invoke) UnmarshalJSON(data []byte) error { + var err error aux := new(invokeAux) - if err := json.Unmarshal(data, aux); err != nil { + if err = json.Unmarshal(data, aux); err != nil { return err } var arr []json.RawMessage - if err := json.Unmarshal(aux.Stack, &arr); err == nil { + if err = json.Unmarshal(aux.Stack, &arr); err == nil { st := make([]stackitem.Item, len(arr)) for i := range arr { st[i], err = stackitem.FromJSONWithTypes(arr[i]) @@ -82,18 +81,17 @@ func (r *Invoke) UnmarshalJSON(data []byte) error { r.Stack = st } } + var tx *transaction.Transaction + if len(aux.Transaction) != 0 { + tx, err = transaction.NewTransactionFromBytes(aux.Transaction) + if err != nil { + return err + } + } r.GasConsumed = aux.GasConsumed r.Script = aux.Script r.State = aux.State r.FaultException = aux.FaultException - r.Transaction = aux.Transaction + r.Transaction = tx return nil } - -// GetTransaction returns decoded transaction from Invoke.Transaction bytes. -func (r *Invoke) GetTransaction(magic netmode.Magic) (*transaction.Transaction, error) { - if r.Transaction == nil { - return nil, errors.New("empty transaction") - } - return transaction.NewTransactionFromBytes(magic, r.Transaction) -} diff --git a/pkg/rpc/response/result/invoke_test.go b/pkg/rpc/response/result/invoke_test.go index 247abd944..769b26620 100644 --- a/pkg/rpc/response/result/invoke_test.go +++ b/pkg/rpc/response/result/invoke_test.go @@ -6,19 +6,26 @@ import ( "math/big" "testing" + "github.com/nspcc-dev/neo-go/pkg/core/transaction" + "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/stretchr/testify/require" ) func TestInvoke_MarshalJSON(t *testing.T) { + tx := transaction.New([]byte{1, 2, 3, 4}, 0) + tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} + tx.Scripts = []transaction.Witness{transaction.Witness{InvocationScript: []byte{}, VerificationScript: []byte{}}} + _ = tx.Size() + tx.Hash() + result := &Invoke{ State: "HALT", GasConsumed: 237626000, Script: []byte{10}, Stack: []stackitem.Item{stackitem.NewBigInteger(big.NewInt(1))}, FaultException: "", - // Transaction represents transaction bytes. Use GetTransaction method to decode it. - Transaction: []byte{1, 2, 3, 4}, + Transaction: tx, } data, err := json.Marshal(result) @@ -30,7 +37,7 @@ func TestInvoke_MarshalJSON(t *testing.T) { "stack":[ {"type":"Integer","value":"1"} ], - "tx":"` + base64.StdEncoding.EncodeToString(result.Transaction) + `" + "tx":"` + base64.StdEncoding.EncodeToString(tx.Bytes()) + `" }` require.JSONEq(t, expected, string(data)) diff --git a/pkg/rpc/server/client_test.go b/pkg/rpc/server/client_test.go index c7c459a9e..41305f332 100644 --- a/pkg/rpc/server/client_test.go +++ b/pkg/rpc/server/client_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/nspcc-dev/neo-go/internal/testchain" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/fee" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -90,7 +89,7 @@ func TestAddNetworkFee(t *testing.T) { feePerByte := chain.FeePerByte() t.Run("Invalid", func(t *testing.T) { - tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) accs := getAccounts(t, 2) tx.Signers = []transaction.Signer{{ Account: accs[0].PrivateKey().GetScriptHash(), @@ -99,20 +98,20 @@ func TestAddNetworkFee(t *testing.T) { require.Error(t, c.AddNetworkFee(tx, extraFee, accs[0], accs[1])) }) t.Run("Simple", func(t *testing.T) { - tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) accs := getAccounts(t, 1) tx.Signers = []transaction.Signer{{ Account: accs[0].PrivateKey().GetScriptHash(), Scopes: transaction.CalledByEntry, }} require.NoError(t, c.AddNetworkFee(tx, 10, accs[0])) - require.NoError(t, accs[0].SignTx(tx)) + require.NoError(t, accs[0].SignTx(testchain.Network(), tx)) cFee, _ := fee.Calculate(chain.GetBaseExecFee(), accs[0].Contract.Script) require.Equal(t, int64(io.GetVarSize(tx))*feePerByte+cFee+extraFee, tx.NetworkFee) }) t.Run("Multi", func(t *testing.T) { - tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) accs := getAccounts(t, 4) pubs := keys.PublicKeys{accs[1].PrivateKey().PublicKey(), accs[2].PrivateKey().PublicKey(), accs[3].PrivateKey().PublicKey()} require.NoError(t, accs[1].ConvertMultisig(2, pubs)) @@ -128,9 +127,9 @@ func TestAddNetworkFee(t *testing.T) { }, } require.NoError(t, c.AddNetworkFee(tx, extraFee, accs[0], accs[1])) - require.NoError(t, accs[0].SignTx(tx)) - require.NoError(t, accs[1].SignTx(tx)) - require.NoError(t, accs[2].SignTx(tx)) + require.NoError(t, accs[0].SignTx(testchain.Network(), tx)) + require.NoError(t, accs[1].SignTx(testchain.Network(), tx)) + require.NoError(t, accs[2].SignTx(testchain.Network(), tx)) cFee, _ := fee.Calculate(chain.GetBaseExecFee(), accs[0].Contract.Script) cFeeM, _ := fee.Calculate(chain.GetBaseExecFee(), accs[1].Contract.Script) require.Equal(t, int64(io.GetVarSize(tx))*feePerByte+cFee+cFeeM+extraFee, tx.NetworkFee) @@ -145,7 +144,7 @@ func TestAddNetworkFee(t *testing.T) { acc1.Contract.Script, err = base64.StdEncoding.DecodeString(verifyContractAVM) newTx := func(t *testing.T) *transaction.Transaction { - tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) require.NoError(t, err) tx.ValidUntilBlock = chain.BlockHeight() + 10 return tx @@ -170,21 +169,21 @@ func TestAddNetworkFee(t *testing.T) { // check that network fee with extra value is enough tx1 := completeTx(t) - require.NoError(t, acc0.SignTx(tx1)) + require.NoError(t, acc0.SignTx(testchain.Network(), tx1)) tx1.Scripts = append(tx1.Scripts, transaction.Witness{}) require.NoError(t, chain.VerifyTx(tx1)) // check that network fee without extra value is enough tx2 := completeTx(t) tx2.NetworkFee -= extraFee - require.NoError(t, acc0.SignTx(tx2)) + require.NoError(t, acc0.SignTx(testchain.Network(), tx2)) tx2.Scripts = append(tx2.Scripts, transaction.Witness{}) require.NoError(t, chain.VerifyTx(tx2)) // check that we don't add unexpected extra GAS tx3 := completeTx(t) tx3.NetworkFee -= extraFee + 1 - require.NoError(t, acc0.SignTx(tx3)) + require.NoError(t, acc0.SignTx(testchain.Network(), tx3)) tx3.Scripts = append(tx3.Scripts, transaction.Witness{}) require.Error(t, chain.VerifyTx(tx3)) }) @@ -286,7 +285,6 @@ func TestSignAndPushP2PNotaryRequest(t *testing.T) { sender := testchain.PrivateKeyByID(0) // owner of the deposit in testchain acc := wallet.NewAccountFromPrivateKey(sender) expected := transaction.Transaction{ - Network: netmode.UnitTestNet, Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}}, Script: []byte{byte(opcode.RET)}, ValidUntilBlock: chain.BlockHeight() + 5, @@ -328,7 +326,7 @@ func TestSignAndPushP2PNotaryRequest(t *testing.T) { ntr := w.Accounts[0] ntr.Decrypt(notaryPass) req.FallbackTransaction.Scripts[0] = transaction.Witness{ - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, ntr.PrivateKey().Sign(req.FallbackTransaction.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, ntr.PrivateKey().SignHashable(uint32(testchain.Network()), req.FallbackTransaction)...), VerificationScript: []byte{}, } b := testchain.NewBlock(t, chain, 1, 0, req.FallbackTransaction) @@ -416,7 +414,7 @@ func TestCreateNEP17TransferTx(t *testing.T) { tx, err := c.CreateNEP17TransferTx(acc, util.Uint160{}, gasContractHash, 1000, 0, nil) require.NoError(t, err) - require.NoError(t, acc.SignTx(tx)) + require.NoError(t, acc.SignTx(testchain.Network(), tx)) require.NoError(t, chain.VerifyTx(tx)) v := chain.GetTestVM(trigger.Application, tx, nil) v.LoadScriptWithFlags(tx.Script, callflag.All) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index fc299e9ef..40a4b6bd9 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -1344,7 +1344,7 @@ func (s *Server) sendrawtransaction(reqParams request.Params) (interface{}, *res if err != nil { return nil, response.ErrInvalidParams } - tx, err := transaction.NewTransactionFromBytes(s.network, byteTx) + tx, err := transaction.NewTransactionFromBytes(byteTx) if err != nil { return nil, response.ErrInvalidParams } diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index a7317d519..97d83d50b 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -1076,7 +1076,6 @@ func TestSubmitNotaryRequest(t *testing.T) { t.Run("invalid request bytes", runCase(t, true, `"not-a-request"`)) t.Run("invalid request", func(t *testing.T) { mainTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}}, Script: []byte{byte(opcode.RET)}, ValidUntilBlock: 123, @@ -1087,7 +1086,6 @@ func TestSubmitNotaryRequest(t *testing.T) { }}, } fallbackTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Script: []byte{byte(opcode.RET)}, ValidUntilBlock: 123, Attributes: []transaction.Attribute{ @@ -1117,7 +1115,6 @@ func TestSubmitNotaryRequest(t *testing.T) { t.Run("valid request", func(t *testing.T) { sender := testchain.PrivateKeyByID(0) // owner of the deposit in testchain mainTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}}, Script: []byte{byte(opcode.RET)}, ValidUntilBlock: 123, @@ -1128,7 +1125,6 @@ func TestSubmitNotaryRequest(t *testing.T) { }}, } fallbackTx := &transaction.Transaction{ - Network: netmode.UnitTestNet, Script: []byte{byte(opcode.RET)}, ValidUntilBlock: 123, Attributes: []transaction.Attribute{ @@ -1143,7 +1139,7 @@ func TestSubmitNotaryRequest(t *testing.T) { NetworkFee: 2_0000_0000, } fallbackTx.Scripts = append(fallbackTx.Scripts, transaction.Witness{ - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, sender.Sign(fallbackTx.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, sender.SignHashable(uint32(testchain.Network()), fallbackTx)...), VerificationScript: sender.PublicKey().GetVerificationScript(), }) p := &payload.P2PNotaryRequest{ @@ -1152,7 +1148,7 @@ func TestSubmitNotaryRequest(t *testing.T) { FallbackTransaction: fallbackTx, } p.Witness = transaction.Witness{ - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, sender.Sign(p.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, sender.SignHashable(uint32(testchain.Network()), p)...), VerificationScript: sender.PublicKey().GetVerificationScript(), } bytes, err := p.Bytes() @@ -1314,12 +1310,12 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] newTx := func() *transaction.Transaction { height := chain.BlockHeight() - tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Nonce = height + 1 tx.ValidUntilBlock = height + 10 tx.Signers = []transaction.Signer{{Account: acc0.PrivateKey().GetScriptHash()}} addNetworkFee(tx) - require.NoError(t, acc0.SignTx(tx)) + require.NoError(t, acc0.SignTx(testchain.Network(), tx)) return tx } @@ -1417,7 +1413,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE()) body := doRPCCall(rpc, httpSrv.URL, t) txOut := checkErrGetResult(t, body, false) - actual := result.TransactionOutputRaw{Transaction: transaction.Transaction{Network: testchain.Network()}} + actual := result.TransactionOutputRaw{Transaction: transaction.Transaction{}} err := json.Unmarshal(txOut, &actual) require.NoErrorf(t, err, "could not parse response: %s", txOut) @@ -1486,7 +1482,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] expected = append(expected, tx.Hash()) } for i := 0; i < 5; i++ { - tx := transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} assert.NoError(t, mp.Add(tx, &FeerStub{})) expected = append(expected, tx.Hash()) diff --git a/pkg/services/notary/node_test.go b/pkg/services/notary/node_test.go index 99e20ee52..4c30f0b2c 100644 --- a/pkg/services/notary/node_test.go +++ b/pkg/services/notary/node_test.go @@ -5,6 +5,7 @@ import ( "github.com/nspcc-dev/neo-go/internal/fakechain" "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/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/mempool" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -27,7 +28,7 @@ func getTestNotary(t *testing.T, bc blockchainer.Blockchainer, walletPath, pass Chain: bc, Log: zaptest.NewLogger(t), } - ntr, err := NewNotary(cfg, mp, nil) + ntr, err := NewNotary(cfg, netmode.UnitTestNet, mp, nil) require.NoError(t, err) w, err := wallet.NewWalletFromFile(walletPath) diff --git a/pkg/services/notary/notary.go b/pkg/services/notary/notary.go index eb5b83cf3..66d2eb5eb 100644 --- a/pkg/services/notary/notary.go +++ b/pkg/services/notary/notary.go @@ -9,6 +9,7 @@ import ( "sync" "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/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/mempool" @@ -29,6 +30,8 @@ type ( Notary struct { Config Config + Network netmode.Magic + // onTransaction is a callback for completed transactions (mains or fallbacks) sending. onTransaction func(tx *transaction.Transaction) error @@ -81,7 +84,7 @@ type request struct { } // NewNotary returns new Notary module. -func NewNotary(cfg Config, mp *mempool.Pool, onTransaction func(tx *transaction.Transaction) error) (*Notary, error) { +func NewNotary(cfg Config, net netmode.Magic, mp *mempool.Pool, onTransaction func(tx *transaction.Transaction) error) (*Notary, error) { w := cfg.MainCfg.UnlockWallet wallet, err := wallet.NewWalletFromFile(w.Path) if err != nil { @@ -102,6 +105,7 @@ func NewNotary(cfg Config, mp *mempool.Pool, onTransaction func(tx *transaction. return &Notary{ requests: make(map[util.Uint256]*request), Config: cfg, + Network: net, wallet: wallet, onTransaction: onTransaction, mp: mp, @@ -203,7 +207,7 @@ func (n *Notary) OnNewRequest(payload *payload.P2PNotaryRequest) { r.sigs = make(map[*keys.PublicKey][]byte) } - hash := r.main.GetSignedHash().BytesBE() + hash := hash.NetSha256(uint32(n.Network), r.main).BytesBE() for _, pub := range pubs { if r.sigs[pub] != nil { continue // signature for this pub has already been added @@ -308,7 +312,7 @@ func (n *Notary) finalize(tx *transaction.Transaction) error { panic(errors.New("no available Notary account")) // unreachable code, because all callers of `finalize` check that acc != nil } notaryWitness := transaction.Witness{ - InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.PrivateKey().Sign(tx.GetSignedPart())...), + InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.PrivateKey().SignHashable(uint32(n.Network), tx)...), VerificationScript: []byte{}, } for i, signer := range tx.Signers { @@ -332,7 +336,7 @@ func updateTxSize(tx *transaction.Transaction) (*transaction.Transaction, error) if bw.Err != nil { return nil, fmt.Errorf("encode binary: %w", bw.Err) } - return transaction.NewTransactionFromBytes(tx.Network, tx.Bytes()) + return transaction.NewTransactionFromBytes(tx.Bytes()) } // verifyIncompleteWitnesses checks that tx either doesn't have all witnesses attached (in this case none of them diff --git a/pkg/services/notary/notary_test.go b/pkg/services/notary/notary_test.go index 15e14dce6..2d5f1b9fe 100644 --- a/pkg/services/notary/notary_test.go +++ b/pkg/services/notary/notary_test.go @@ -5,6 +5,7 @@ import ( "github.com/nspcc-dev/neo-go/internal/fakechain" "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/mempool" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" @@ -27,21 +28,21 @@ func TestWallet(t *testing.T) { } t.Run("unexisting wallet", func(t *testing.T) { cfg.MainCfg.UnlockWallet.Path = "./testdata/does_not_exists.json" - _, err := NewNotary(cfg, mempool.New(1, 1, true), nil) + _, err := NewNotary(cfg, netmode.UnitTestNet, mempool.New(1, 1, true), nil) require.Error(t, err) }) t.Run("bad password", func(t *testing.T) { cfg.MainCfg.UnlockWallet.Path = "./testdata/notary1.json" cfg.MainCfg.UnlockWallet.Password = "invalid" - _, err := NewNotary(cfg, mempool.New(1, 1, true), nil) + _, err := NewNotary(cfg, netmode.UnitTestNet, mempool.New(1, 1, true), nil) require.Error(t, err) }) t.Run("good", func(t *testing.T) { cfg.MainCfg.UnlockWallet.Path = "./testdata/notary1.json" cfg.MainCfg.UnlockWallet.Password = "one" - _, err := NewNotary(cfg, mempool.New(1, 1, true), nil) + _, err := NewNotary(cfg, netmode.UnitTestNet, mempool.New(1, 1, true), nil) require.NoError(t, err) }) } diff --git a/pkg/services/oracle/request.go b/pkg/services/oracle/request.go index 11546b338..067b3a574 100644 --- a/pkg/services/oracle/request.go +++ b/pkg/services/oracle/request.go @@ -164,12 +164,12 @@ func (o *Oracle) processRequest(priv *keys.PrivateKey, req request) error { incTx.request = req.Req incTx.tx = tx incTx.backupTx = backupTx - incTx.reverifyTx() + incTx.reverifyTx(o.Network) - txSig := priv.Sign(tx.GetSignedPart()) + txSig := priv.SignHashable(uint32(o.Network), tx) incTx.addResponse(priv.PublicKey(), txSig, false) - backupSig := priv.Sign(backupTx.GetSignedPart()) + backupSig := priv.SignHashable(uint32(o.Network), backupTx) incTx.addResponse(priv.PublicKey(), backupSig, true) readyTx, ready := incTx.finalize(o.getOracleNodes(), false) diff --git a/pkg/services/oracle/response.go b/pkg/services/oracle/response.go index de9a20e38..fea159b10 100644 --- a/pkg/services/oracle/response.go +++ b/pkg/services/oracle/response.go @@ -38,9 +38,9 @@ func (o *Oracle) AddResponse(pub *keys.PublicKey, reqID uint64, txSig []byte) { incTx.Lock() isBackup := false if incTx.tx != nil { - ok := pub.Verify(txSig, incTx.tx.GetSignedHash().BytesBE()) + ok := pub.VerifyHashable(txSig, uint32(o.Network), incTx.tx) if !ok { - ok = pub.Verify(txSig, incTx.backupTx.GetSignedHash().BytesBE()) + ok = pub.VerifyHashable(txSig, uint32(o.Network), incTx.backupTx) if !ok { o.Log.Debug("invalid response signature", zap.String("pub", hex.EncodeToString(pub.Bytes()))) @@ -82,7 +82,7 @@ func readResponse(rc gio.ReadCloser, limit int) ([]byte, error) { // CreateResponseTx creates unsigned oracle response transaction. func (o *Oracle) CreateResponseTx(gasForResponse int64, height uint32, resp *transaction.OracleResponse) (*transaction.Transaction, error) { - tx := transaction.New(o.Network, o.oracleResponse, 0) + tx := transaction.New(o.oracleResponse, 0) tx.Nonce = uint32(resp.ID) tx.ValidUntilBlock = height + transaction.MaxValidUntilBlockIncrement tx.Attributes = []transaction.Attribute{{ diff --git a/pkg/services/oracle/transaction.go b/pkg/services/oracle/transaction.go index 7a803c83e..6e38b8416 100644 --- a/pkg/services/oracle/transaction.go +++ b/pkg/services/oracle/transaction.go @@ -4,8 +4,10 @@ import ( "sync" "time" + "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/transaction" + "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" @@ -50,9 +52,9 @@ func newIncompleteTx() *incompleteTx { } } -func (t *incompleteTx) reverifyTx() { - txHash := t.tx.GetSignedHash() - backupHash := t.backupTx.GetSignedHash() +func (t *incompleteTx) reverifyTx(net netmode.Magic) { + txHash := hash.NetSha256(uint32(net), t.tx) + backupHash := hash.NetSha256(uint32(net), t.backupTx) for pub, sig := range t.sigs { if !sig.ok { sig.ok = sig.pub.Verify(sig.sig, txHash.BytesBE()) diff --git a/pkg/smartcontract/context/context.go b/pkg/smartcontract/context/context.go index ddb810012..e5c3cafc5 100644 --- a/pkg/smartcontract/context/context.go +++ b/pkg/smartcontract/context/context.go @@ -190,7 +190,6 @@ func (c *ParameterContext) UnmarshalJSON(data []byte) error { switch pc.Type { case "Neo.Core.ContractTransaction": tx := new(transaction.Transaction) - tx.Network = netmode.Magic(pc.Net) verif = tx default: return fmt.Errorf("unsupported type: %s", c.Type) diff --git a/pkg/smartcontract/context/context_test.go b/pkg/smartcontract/context/context_test.go index 58c232ea6..a2db41f53 100644 --- a/pkg/smartcontract/context/context_test.go +++ b/pkg/smartcontract/context/context_test.go @@ -24,7 +24,7 @@ func TestParameterContext_AddSignatureSimpleContract(t *testing.T) { priv, err := keys.NewPrivateKey() require.NoError(t, err) pub := priv.PublicKey() - sig := priv.Sign(tx.GetSignedPart()) + sig := priv.SignHashable(uint32(netmode.UnitTestNet), tx) t.Run("invalid contract", func(t *testing.T) { c := NewParameterContext("Neo.Core.ContractTransaction", netmode.UnitTestNet, tx) @@ -91,15 +91,14 @@ func TestParameterContext_AddSignatureMultisig(t *testing.T) { newParam(smartcontract.SignatureType, "parameter2"), }, } - data := tx.GetSignedPart() priv, err := keys.NewPrivateKey() require.NoError(t, err) - sig := priv.Sign(data) + sig := priv.SignHashable(uint32(c.Network), tx) require.Error(t, c.AddSignature(ctr.ScriptHash(), ctr, priv.PublicKey(), sig)) indices := []int{2, 3, 0} // random order for _, i := range indices { - sig := privs[i].Sign(data) + sig := privs[i].SignHashable(uint32(c.Network), tx) require.NoError(t, c.AddSignature(ctr.ScriptHash(), ctr, pubs[i], sig)) require.Error(t, c.AddSignature(ctr.ScriptHash(), ctr, pubs[i], sig)) @@ -132,8 +131,7 @@ func TestParameterContext_MarshalJSON(t *testing.T) { require.NoError(t, err) tx := getContractTx() - data := tx.GetSignedPart() - sign := priv.Sign(data) + sign := priv.SignHashable(uint32(netmode.UnitTestNet), tx) expected := &ParameterContext{ Type: "Neo.Core.ContractTransaction", @@ -192,7 +190,7 @@ func newParam(typ smartcontract.ParamType, name string) wallet.ContractParam { } func getContractTx() *transaction.Transaction { - tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) + tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx.Attributes = make([]transaction.Attribute, 0) tx.Scripts = make([]transaction.Witness, 0) tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} diff --git a/pkg/wallet/account.go b/pkg/wallet/account.go index e15e3f024..66393f9ab 100644 --- a/pkg/wallet/account.go +++ b/pkg/wallet/account.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" + "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -94,7 +95,7 @@ func NewAccount() (*Account, error) { } // SignTx signs transaction t and updates it's Witnesses. -func (a *Account) SignTx(t *transaction.Transaction) error { +func (a *Account) SignTx(net netmode.Magic, t *transaction.Transaction) error { if a.privateKey == nil { return errors.New("account is not unlocked") } @@ -102,11 +103,7 @@ func (a *Account) SignTx(t *transaction.Transaction) error { t.Scripts = append(t.Scripts, transaction.Witness{}) return nil } - data := t.GetSignedPart() - if data == nil { - return errors.New("failed to get transaction's signed part") - } - sign := a.privateKey.Sign(data) + sign := a.privateKey.SignHashable(uint32(net), t) verif := a.GetVerificationScript() invoc := append([]byte{byte(opcode.PUSHDATA1), 64}, sign...) diff --git a/scripts/gendump/main.go b/scripts/gendump/main.go index 0c1f1df64..663d04f91 100644 --- a/scripts/gendump/main.go +++ b/scripts/gendump/main.go @@ -79,7 +79,7 @@ func main() { handleError("can't create deploy tx", err) tx.NetworkFee = 10_000_000 tx.ValidUntilBlock = bc.BlockHeight() + 1 - handleError("can't sign deploy tx", acc.SignTx(tx)) + handleError("can't sign deploy tx", acc.SignTx(netmode.UnitTestNet, tx)) lastBlock = addBlock(bc, lastBlock, valScript, tx) key := make([]byte, 10) @@ -99,7 +99,7 @@ func main() { emit.AppCall(w.BinWriter, contractHash, "put", callflag.All, key, value) handleError("can't create transaction", w.Err) - tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 4_000_000) + tx := transaction.New(w.Bytes(), 4_000_000) tx.ValidUntilBlock = i + 1 tx.NetworkFee = 4_000_000 tx.Nonce = nonce @@ -107,7 +107,7 @@ func main() { Account: h, Scopes: transaction.CalledByEntry, }} - handleError("can't sign tx", acc.SignTx(tx)) + handleError("can't sign tx", acc.SignTx(netmode.UnitTestNet, tx)) txs[j] = tx } @@ -179,6 +179,6 @@ func newBlock(bc *core.Blockchain, lastBlock *block.Block, script []byte, txs .. b.PrevStateRoot = sr.Root } b.RebuildMerkleRoot() - b.Script.InvocationScript = testchain.Sign(b.GetSignedPart()) + b.Script.InvocationScript = testchain.Sign(b) return b, nil }