diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 9aeeeb516..996c30e78 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -258,7 +258,7 @@ func (s *service) verifyBlock(b block.Block) bool { func (s *service) processBlock(b block.Block) { bb := &b.(*neoBlock).Block - bb.Script = s.getBlockWitness(bb) + bb.Script = *(s.getBlockWitness(bb)) if err := s.Chain.AddBlock(bb); err != nil { s.log.Warnf("error on add block: %v", err) diff --git a/pkg/consensus/payload_test.go b/pkg/consensus/payload_test.go index c6312c006..26c2c4b42 100644 --- a/pkg/consensus/payload_test.go +++ b/pkg/consensus/payload_test.go @@ -339,10 +339,10 @@ func newMinerTx(nonce uint32) *transaction.Transaction { Data: &transaction.MinerTX{ Nonce: rand.Uint32(), }, - Attributes: []*transaction.Attribute{}, - Inputs: []*transaction.Input{}, - Outputs: []*transaction.Output{}, - Scripts: []*transaction.Witness{}, + Attributes: []transaction.Attribute{}, + Inputs: []transaction.Input{}, + Outputs: []transaction.Output{}, + Scripts: []transaction.Witness{}, Trimmed: false, } } diff --git a/pkg/core/block.go b/pkg/core/block.go index ff4266276..e1e898ed7 100644 --- a/pkg/core/block.go +++ b/pkg/core/block.go @@ -91,7 +91,6 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) { var padding uint8 br.ReadLE(&padding) - block.Script = &transaction.Witness{} block.Script.DecodeBinary(br) lenTX := br.ReadVarUint() diff --git a/pkg/core/block_base.go b/pkg/core/block_base.go index 7ca235ae2..77ec7d61d 100644 --- a/pkg/core/block_base.go +++ b/pkg/core/block_base.go @@ -38,7 +38,7 @@ type BlockBase struct { _ uint8 // Script used to validate the block - Script *transaction.Witness `json:"script"` + Script transaction.Witness `json:"script"` // Hash of this block, created when binary encoded (double SHA256). hash util.Uint256 @@ -80,7 +80,6 @@ func (b *BlockBase) DecodeBinary(br *io.BinReader) { return } - b.Script = &transaction.Witness{} b.Script.DecodeBinary(br) } diff --git a/pkg/core/block_test.go b/pkg/core/block_test.go index b39e486c4..594041158 100644 --- a/pkg/core/block_test.go +++ b/pkg/core/block_test.go @@ -87,7 +87,7 @@ func newDumbBlock() *Block { Index: 1, ConsensusData: 1111, NextConsensus: hash.Hash160([]byte("a")), - Script: &transaction.Witness{ + Script: transaction.Witness{ VerificationScript: []byte{0x51}, // PUSH1 InvocationScript: []byte{0x61}, // NOP }, diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 9a12d911c..6544ebc4b 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -945,7 +945,7 @@ func (bc *Blockchain) References(t *transaction.Transaction) map[transaction.Inp tx = nil } else if tx != nil { for _, in := range inputs { - references[*in] = tx.Outputs[in.PrevIndex] + references[*in] = &tx.Outputs[in.PrevIndex] } } else { references = nil @@ -1243,8 +1243,9 @@ func (bc *Blockchain) GetValidators(txes ...*transaction.Transaction) ([]*keys.P // group inputs by the same previous hash and iterate through inputs group := make(map[util.Uint256][]*transaction.Input) - for _, input := range tx.Inputs { - group[input.PrevHash] = append(group[input.PrevHash], input) + for i := range tx.Inputs { + hash := tx.Inputs[i].PrevHash + group[hash] = append(group[hash], &tx.Inputs[i]) } for hash, inputs := range group { @@ -1360,7 +1361,7 @@ func (bc *Blockchain) GetScriptHashesForVerifying(t *transaction.Transaction) ([ } hashes := make(map[util.Uint160]bool) for _, i := range t.Inputs { - h := references[*i].ScriptHash + h := references[i].ScriptHash if _, ok := hashes[h]; !ok { hashes[h] = true } @@ -1486,7 +1487,7 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *Block sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) }) interopCtx := newInteropContext(trigger.Verification, bc, bc.store, block, t) for i := 0; i < len(hashes); i++ { - err := bc.verifyHashAgainstScript(hashes[i], witnesses[i], t.VerificationHash(), interopCtx) + err := bc.verifyHashAgainstScript(hashes[i], &witnesses[i], t.VerificationHash(), interopCtx) if err != nil { numStr := fmt.Sprintf("witness #%d", i) return errors.Wrap(err, numStr) @@ -1505,7 +1506,7 @@ func (bc *Blockchain) verifyBlockWitnesses(block *Block, prevHeader *Header) err hash = prevHeader.NextConsensus } interopCtx := newInteropContext(trigger.Verification, bc, bc.store, nil, nil) - return bc.verifyHashAgainstScript(hash, block.Script, block.VerificationHash(), interopCtx) + return bc.verifyHashAgainstScript(hash, &block.Script, block.VerificationHash(), interopCtx) } func hashAndIndexToBytes(h util.Uint256, index uint32) []byte { diff --git a/pkg/core/header_test.go b/pkg/core/header_test.go index 81cd2a242..ed35c6f73 100644 --- a/pkg/core/header_test.go +++ b/pkg/core/header_test.go @@ -20,7 +20,7 @@ func TestHeaderEncodeDecode(t *testing.T) { Index: 3445, ConsensusData: 394949, NextConsensus: util.Uint160{}, - Script: &transaction.Witness{ + Script: transaction.Witness{ InvocationScript: []byte{0x10}, VerificationScript: []byte{0x11}, }, diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index 43b8d96ab..132dc5087 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -55,7 +55,7 @@ func newBlock(index uint32, txs ...*transaction.Transaction) *Block { vlen-(vlen-1)/3, validators, ) - witness := &transaction.Witness{ + witness := transaction.Witness{ VerificationScript: valScript, } b := &Block{ diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index c7bea1c0f..da688b9cc 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -89,8 +89,8 @@ func (ic *interopContext) txGetAttributes(v *vm.VM) error { return errors.New("too many attributes") } attrs := make([]vm.StackItem, 0, len(tx.Attributes)) - for _, attr := range tx.Attributes { - attrs = append(attrs, vm.NewInteropItem(attr)) + for i := range tx.Attributes { + attrs = append(attrs, vm.NewInteropItem(&tx.Attributes[i])) } v.Estack().PushVal(attrs) return nil @@ -107,8 +107,8 @@ func (ic *interopContext) txGetInputs(v *vm.VM) error { return errors.New("too many inputs") } inputs := make([]vm.StackItem, 0, len(tx.Inputs)) - for _, input := range tx.Inputs { - inputs = append(inputs, vm.NewInteropItem(input)) + for i := range tx.Inputs { + inputs = append(inputs, vm.NewInteropItem(&tx.Inputs[i])) } v.Estack().PushVal(inputs) return nil @@ -125,8 +125,8 @@ func (ic *interopContext) txGetOutputs(v *vm.VM) error { return errors.New("too many outputs") } outputs := make([]vm.StackItem, 0, len(tx.Outputs)) - for _, output := range tx.Outputs { - outputs = append(outputs, vm.NewInteropItem(output)) + for i := range tx.Outputs { + outputs = append(outputs, vm.NewInteropItem(&tx.Outputs[i])) } v.Estack().PushVal(outputs) return nil @@ -146,7 +146,7 @@ func (ic *interopContext) txGetReferences(v *vm.VM) error { stackrefs := make([]vm.StackItem, 0, len(refs)) for _, k := range tx.Inputs { - tio := txInOut{*k, *refs[*k]} + tio := txInOut{k, *refs[k]} stackrefs = append(stackrefs, vm.NewInteropItem(tio)) } v.Estack().PushVal(stackrefs) @@ -190,8 +190,8 @@ func (ic *interopContext) txGetWitnesses(v *vm.VM) error { return errors.New("too many outputs") } scripts := make([]vm.StackItem, 0, len(tx.Scripts)) - for _, script := range tx.Scripts { - scripts = append(scripts, vm.NewInteropItem(script)) + for i := range tx.Scripts { + scripts = append(scripts, vm.NewInteropItem(&tx.Scripts[i])) } v.Estack().PushVal(scripts) return nil diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index 331f593bf..c1c378cd9 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -92,7 +92,7 @@ func TestTxGetInputs(t *testing.T) { err := context.txGetInputs(v) require.NoError(t, err) value := v.Estack().Pop().Value().([]vm.StackItem) - require.Equal(t, tx.Inputs[0], value[0].Value().(*transaction.Input)) + require.Equal(t, tx.Inputs[0], *value[0].Value().(*transaction.Input)) } func TestTxGetOutputs(t *testing.T) { @@ -101,7 +101,7 @@ func TestTxGetOutputs(t *testing.T) { err := context.txGetOutputs(v) require.NoError(t, err) value := v.Estack().Pop().Value().([]vm.StackItem) - require.Equal(t, tx.Outputs[0], value[0].Value().(*transaction.Output)) + require.Equal(t, tx.Outputs[0], *value[0].Value().(*transaction.Output)) } func TestTxGetType(t *testing.T) { @@ -115,16 +115,16 @@ func TestTxGetType(t *testing.T) { func TestPopInputFromVM(t *testing.T) { v, tx, _ := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Inputs[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0])) input, err := popInputFromVM(v) require.NoError(t, err) - require.Equal(t, tx.Inputs[0], input) + require.Equal(t, tx.Inputs[0], *input) } func TestInputGetHash(t *testing.T) { v, tx, context := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Inputs[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0])) err := context.inputGetHash(v) require.NoError(t, err) @@ -134,7 +134,7 @@ func TestInputGetHash(t *testing.T) { func TestInputGetIndex(t *testing.T) { v, tx, context := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Inputs[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0])) err := context.inputGetIndex(v) require.NoError(t, err) @@ -144,16 +144,16 @@ func TestInputGetIndex(t *testing.T) { func TestPopOutputFromVM(t *testing.T) { v, tx, _ := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0])) output, err := popOutputFromVM(v) require.NoError(t, err) - require.Equal(t, tx.Outputs[0], output) + require.Equal(t, tx.Outputs[0], *output) } func TestOutputGetAssetID(t *testing.T) { v, tx, context := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0])) err := context.outputGetAssetID(v) require.NoError(t, err) @@ -163,7 +163,7 @@ func TestOutputGetAssetID(t *testing.T) { func TestOutputGetScriptHash(t *testing.T) { v, tx, context := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0])) err := context.outputGetScriptHash(v) require.NoError(t, err) @@ -173,7 +173,7 @@ func TestOutputGetScriptHash(t *testing.T) { func TestOutputGetValue(t *testing.T) { v, tx, context := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Outputs[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0])) err := context.outputGetValue(v) require.NoError(t, err) @@ -183,7 +183,7 @@ func TestOutputGetValue(t *testing.T) { func TestAttrGetData(t *testing.T) { v, tx, context := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Attributes[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Attributes[0])) err := context.attrGetData(v) require.NoError(t, err) @@ -193,7 +193,7 @@ func TestAttrGetData(t *testing.T) { func TestAttrGetUsage(t *testing.T) { v, tx, context := createVMAndTX(t) - v.Estack().PushVal(vm.NewInteropItem(tx.Attributes[0])) + v.Estack().PushVal(vm.NewInteropItem(&tx.Attributes[0])) err := context.attrGetUsage(v) require.NoError(t, err) @@ -397,17 +397,17 @@ func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interopCont tx := newMinerTX() bytes := make([]byte, 1) - attributes := append(tx.Attributes, &transaction.Attribute{ + attributes := append(tx.Attributes, transaction.Attribute{ Usage: transaction.Description, Data: bytes, }) - inputs := append(tx.Inputs, &transaction.Input{ + inputs := append(tx.Inputs, transaction.Input{ PrevHash: randomUint256(), PrevIndex: 1, }) - outputs := append(tx.Outputs, &transaction.Output{ + outputs := append(tx.Outputs, transaction.Output{ AssetID: randomUint256(), Amount: 10, ScriptHash: randomUint160(), diff --git a/pkg/core/mem_pool.go b/pkg/core/mem_pool.go index 52611dc74..d9e489c0f 100644 --- a/pkg/core/mem_pool.go +++ b/pkg/core/mem_pool.go @@ -288,7 +288,9 @@ func (mp MemPool) Verify(tx *transaction.Transaction) bool { inputs := make([]*transaction.Input, 0) for _, item := range mp.GetVerifiedTransactions() { if tx.Hash().Equals(item.Hash()) { - inputs = append(inputs, item.Inputs...) + for i := range item.Inputs { + inputs = append(inputs, &item.Inputs[i]) + } } } diff --git a/pkg/core/transaction/invocation.go b/pkg/core/transaction/invocation.go index 50ad3c78f..cf60cb403 100644 --- a/pkg/core/transaction/invocation.go +++ b/pkg/core/transaction/invocation.go @@ -26,10 +26,10 @@ func NewInvocationTX(script []byte, gas util.Fixed8) *Transaction { Gas: gas, Version: 1, }, - Attributes: []*Attribute{}, - Inputs: []*Input{}, - Outputs: []*Output{}, - Scripts: []*Witness{}, + Attributes: []Attribute{}, + Inputs: []Input{}, + Outputs: []Output{}, + Scripts: []Witness{}, } } diff --git a/pkg/core/transaction/transaction.go b/pkg/core/transaction/transaction.go index 36443ec3b..305a577d2 100644 --- a/pkg/core/transaction/transaction.go +++ b/pkg/core/transaction/transaction.go @@ -27,18 +27,18 @@ type Transaction struct { Data TXer `json:"-"` // Transaction attributes. - Attributes []*Attribute `json:"attributes"` + Attributes []Attribute `json:"attributes"` // The inputs of the transaction. - Inputs []*Input `json:"vin"` + Inputs []Input `json:"vin"` // The outputs of the transaction. - Outputs []*Output `json:"vout"` + Outputs []Output `json:"vout"` // The scripts that comes with this transaction. // Scripts exist out of the verification script // and invocation script. - Scripts []*Witness `json:"scripts"` + Scripts []Witness `json:"scripts"` // Hash of the transaction (double SHA256). hash util.Uint256 @@ -82,12 +82,12 @@ func (t *Transaction) VerificationHash() util.Uint256 { // AddOutput adds the given output to the transaction outputs. func (t *Transaction) AddOutput(out *Output) { - t.Outputs = append(t.Outputs, out) + t.Outputs = append(t.Outputs, *out) } // AddInput adds the given input to the transaction inputs. func (t *Transaction) AddInput(in *Input) { - t.Inputs = append(t.Inputs, in) + t.Inputs = append(t.Inputs, *in) } // DecodeBinary implements Serializable interface. @@ -187,8 +187,9 @@ func (t *Transaction) createHash() error { // GroupInputsByPrevHash groups all TX inputs by their previous hash. func (t *Transaction) GroupInputsByPrevHash() map[util.Uint256][]*Input { m := make(map[util.Uint256][]*Input) - for _, in := range t.Inputs { - m[in.PrevHash] = append(m[in.PrevHash], in) + for i := range t.Inputs { + hash := t.Inputs[i].PrevHash + m[hash] = append(m[hash], &t.Inputs[i]) } return m } @@ -196,8 +197,9 @@ func (t *Transaction) GroupInputsByPrevHash() map[util.Uint256][]*Input { // GroupOutputByAssetID groups all TX outputs by their assetID. func (t Transaction) GroupOutputByAssetID() map[util.Uint256][]*Output { m := make(map[util.Uint256][]*Output) - for _, out := range t.Outputs { - m[out.AssetID] = append(m[out.AssetID], out) + for i := range t.Outputs { + hash := t.Outputs[i].AssetID + m[hash] = append(m[hash], &t.Outputs[i]) } return m } diff --git a/pkg/core/util.go b/pkg/core/util.go index 05ba10bdd..8da60beab 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -31,7 +31,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { Index: 0, ConsensusData: 2083236893, NextConsensus: nextConsensus, - Script: &transaction.Witness{ + Script: transaction.Witness{ InvocationScript: []byte{}, VerificationScript: []byte{byte(opcode.PUSHT)}, }, @@ -56,25 +56,25 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { Data: &transaction.MinerTX{ Nonce: 2083236893, }, - Attributes: []*transaction.Attribute{}, - Inputs: []*transaction.Input{}, - Outputs: []*transaction.Output{}, - Scripts: []*transaction.Witness{}, + Attributes: []transaction.Attribute{}, + Inputs: []transaction.Input{}, + Outputs: []transaction.Output{}, + Scripts: []transaction.Witness{}, }, governingTX, utilityTX, { Type: transaction.IssueType, Data: &transaction.IssueTX{}, // no fields. - Inputs: []*transaction.Input{}, - Outputs: []*transaction.Output{ + Inputs: []transaction.Input{}, + Outputs: []transaction.Output{ { AssetID: governingTX.Hash(), Amount: governingTX.Data.(*transaction.RegisterTX).Amount, ScriptHash: scriptOut, }, }, - Scripts: []*transaction.Witness{ + Scripts: []transaction.Witness{ { InvocationScript: []byte{}, VerificationScript: []byte{byte(opcode.PUSHT)}, @@ -105,10 +105,10 @@ func governingTokenTX() *transaction.Transaction { tx := &transaction.Transaction{ Type: transaction.RegisterType, Data: registerTX, - Attributes: []*transaction.Attribute{}, - Inputs: []*transaction.Input{}, - Outputs: []*transaction.Output{}, - Scripts: []*transaction.Witness{}, + Attributes: []transaction.Attribute{}, + Inputs: []transaction.Input{}, + Outputs: []transaction.Output{}, + Scripts: []transaction.Witness{}, } return tx @@ -127,10 +127,10 @@ func utilityTokenTX() *transaction.Transaction { tx := &transaction.Transaction{ Type: transaction.RegisterType, Data: registerTX, - Attributes: []*transaction.Attribute{}, - Inputs: []*transaction.Input{}, - Outputs: []*transaction.Output{}, - Scripts: []*transaction.Witness{}, + Attributes: []transaction.Attribute{}, + Inputs: []transaction.Input{}, + Outputs: []transaction.Output{}, + Scripts: []transaction.Witness{}, } return tx diff --git a/pkg/network/payload/headers_test.go b/pkg/network/payload/headers_test.go index 78d7644c5..44c2b001f 100644 --- a/pkg/network/payload/headers_test.go +++ b/pkg/network/payload/headers_test.go @@ -16,7 +16,7 @@ func TestHeadersEncodeDecode(t *testing.T) { BlockBase: core.BlockBase{ Version: 0, Index: 1, - Script: &transaction.Witness{ + Script: transaction.Witness{ InvocationScript: []byte{0x0}, VerificationScript: []byte{0x1}, }, @@ -25,7 +25,7 @@ func TestHeadersEncodeDecode(t *testing.T) { BlockBase: core.BlockBase{ Version: 0, Index: 2, - Script: &transaction.Witness{ + Script: transaction.Witness{ InvocationScript: []byte{0x0}, VerificationScript: []byte{0x1}, }, @@ -34,7 +34,7 @@ func TestHeadersEncodeDecode(t *testing.T) { BlockBase: core.BlockBase{ Version: 0, Index: 3, - Script: &transaction.Witness{ + Script: transaction.Witness{ InvocationScript: []byte{0x0}, VerificationScript: []byte{0x1}, }, diff --git a/pkg/rpc/txBuilder.go b/pkg/rpc/txBuilder.go index 71036e341..4ce978b58 100644 --- a/pkg/rpc/txBuilder.go +++ b/pkg/rpc/txBuilder.go @@ -39,7 +39,7 @@ func CreateRawContractTransaction(params ContractTxParams) (*transaction.Transac return nil, errs.Wrapf(err, "Failed to take script hash from address: %v", address) } tx.Attributes = append(tx.Attributes, - &transaction.Attribute{ + transaction.Attribute{ Usage: transaction.Script, Data: fromAddressHash.BytesBE(), }) @@ -87,7 +87,7 @@ func SignTx(tx *transaction.Transaction, wif *keys.WIF) error { return errs.Wrap(err, "failed to create invocation script") } witness.VerificationScript = wif.PrivateKey.PublicKey().GetVerificationScript() - tx.Scripts = append(tx.Scripts, &witness) + tx.Scripts = append(tx.Scripts, witness) tx.Hash() return nil