From a2b69a84f4d795ce80f00dea2a2407995abac5fb Mon Sep 17 00:00:00 2001 From: Svarog Date: Tue, 19 Mar 2019 12:28:24 +0200 Subject: [PATCH] [NOD-48] Make wire.NewMsgTx recieve all paramaters that go into MsgTx, and compute what can be computed. (#216) * [NOD-48] Update wire.NewMsgTx to recieve all fields in msgTx * [NOD-48] Fix all compilation errors resulting from modification of wire.NewMsgTx * [NOD-48] Calculate payloadHash iff subnetworkID is not native * [NOD-48] Update all places the instantiate wire.MsgTx to use wire.NewMsgTx * [NOD-48] Remove 'wire.' calls inside wire package * [NOD-48] Made newMsgTx with all parameters private, and added a few public functions that take various arguments for all common use-cases * [NOD-48] Explicitly pass SubnetworkIDNative instead of nil to newMsgTx * [NOD-48] Remove option to pass nil to newMsgTx --- blockdag/dag_test.go | 117 ++++----------- blockdag/external_dag_test.go | 86 +++++------ blockdag/fees.go | 8 +- blockdag/fullblocktests/generate.go | 17 +-- blockdag/indexers/txindex_test.go | 8 +- blockdag/test_utils.go | 36 ++--- blockdag/utxoset_test.go | 49 ++----- blockdag/validate_test.go | 15 +- dagconfig/genesis.go | 52 +++---- database/testdata/generator.go | 72 +++++---- integration/rpctest/blockgen.go | 13 +- integration/rpctest/memwallet.go | 2 +- mempool/estimatefee_test.go | 6 +- mempool/mempool_test.go | 122 +++++++-------- mempool/policy_test.go | 144 ++++++------------ mining/mining.go | 11 +- mining/mining_test.go | 70 ++++----- mining/policy_test.go | 9 +- peer/peer_test.go | 2 +- server/rpc/rpcserver.go | 5 +- txscript/engine_test.go | 188 +++++++++++------------- txscript/example_test.go | 9 +- txscript/reference_test.go | 9 +- txscript/script.go | 2 + txscript/sign_test.go | 75 +++++----- util/coinset/coins.go | 6 +- util/testtools/testtools.go | 15 +- wire/bench_test.go | 71 +++++---- wire/message_test.go | 2 +- wire/msgblock_test.go | 30 ++-- wire/msgtx.go | 81 +++++++--- wire/msgtx_test.go | 220 +++++++++++++--------------- 32 files changed, 677 insertions(+), 875 deletions(-) diff --git a/blockdag/dag_test.go b/blockdag/dag_test.go index 31a4a6426..a077bd447 100644 --- a/blockdag/dag_test.go +++ b/blockdag/dag_test.go @@ -244,11 +244,7 @@ func TestCalcSequenceLock(t *testing.T) { // Create a utxo view with a fake utxo for the inputs used in the // transactions created below. This utxo is added such that it has an // age of 4 blocks. - msgTx := wire.NewMsgTx(wire.TxVersion) - msgTx.TxOut = []*wire.TxOut{{ - PkScript: nil, - Value: 10, - }} + msgTx := wire.NewNativeMsgTx(wire.TxVersion, nil, []*wire.TxOut{{PkScript: nil, Value: 10}}) targetTx := util.NewTx(msgTx) utxoSet := NewFullUTXOSet() utxoSet.AddTx(targetTx.MsgTx(), int32(numBlocksToGenerate)-4) @@ -278,12 +274,7 @@ func TestCalcSequenceLock(t *testing.T) { // Add an additional transaction which will serve as our unconfirmed // output. - unConfTx := wire.NewMsgTx(wire.TxVersion) - unConfTx.TxOut = []*wire.TxOut{{ - PkScript: nil, - Value: 5, - }} - + unConfTx := wire.NewNativeMsgTx(wire.TxVersion, nil, []*wire.TxOut{{PkScript: nil, Value: 5}}) unConfUtxo := wire.OutPoint{ TxID: unConfTx.TxID(), Index: 0, @@ -303,14 +294,7 @@ func TestCalcSequenceLock(t *testing.T) { // This sequence number has the high bit set, so sequence locks // should be disabled. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: utxo, - Sequence: wire.MaxTxInSequenceNum, - }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{PreviousOutPoint: utxo, Sequence: wire.MaxTxInSequenceNum}}, nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: -1, @@ -324,14 +308,7 @@ func TestCalcSequenceLock(t *testing.T) { // seconds lock-time should be just before the median time of // the targeted block. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: utxo, - Sequence: LockTimeToSequence(true, 2), - }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{PreviousOutPoint: utxo, Sequence: LockTimeToSequence(true, 2)}}, nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: medianTime - 1, @@ -343,14 +320,7 @@ func TestCalcSequenceLock(t *testing.T) { // seconds after the median past time of the last block in the // chain. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: utxo, - Sequence: LockTimeToSequence(true, 1024), - }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{PreviousOutPoint: utxo, Sequence: LockTimeToSequence(true, 1024)}}, nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: medianTime + 1023, @@ -364,9 +334,8 @@ func TestCalcSequenceLock(t *testing.T) { // bit set. So the first lock should be selected as it's the // latest lock that isn't disabled. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ + tx: wire.NewNativeMsgTx(1, + []*wire.TxIn{{ PreviousOutPoint: utxo, Sequence: LockTimeToSequence(true, 2560), }, { @@ -377,8 +346,7 @@ func TestCalcSequenceLock(t *testing.T) { Sequence: LockTimeToSequence(false, 5) | wire.SequenceLockTimeDisabled, }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: medianTime + (5 << wire.SequenceLockTimeGranularity) - 1, @@ -390,14 +358,7 @@ func TestCalcSequenceLock(t *testing.T) { // sequence lock should have a value of -1 for seconds, but a // height of 2 meaning it can be included at height 3. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: utxo, - Sequence: LockTimeToSequence(false, 3), - }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{PreviousOutPoint: utxo, Sequence: LockTimeToSequence(false, 3)}}, nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: -1, @@ -408,17 +369,13 @@ func TestCalcSequenceLock(t *testing.T) { // seconds. The selected sequence lock value for seconds should // be the time further in the future. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: utxo, - Sequence: LockTimeToSequence(true, 5120), - }, { - PreviousOutPoint: utxo, - Sequence: LockTimeToSequence(true, 2560), - }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{ + PreviousOutPoint: utxo, + Sequence: LockTimeToSequence(true, 5120), + }, { + PreviousOutPoint: utxo, + Sequence: LockTimeToSequence(true, 2560), + }}, nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: medianTime + (10 << wire.SequenceLockTimeGranularity) - 1, @@ -430,17 +387,15 @@ func TestCalcSequenceLock(t *testing.T) { // be the height further in the future, so a height of 10 // indicating it can be included at height 11. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ + tx: wire.NewNativeMsgTx(1, + []*wire.TxIn{{ PreviousOutPoint: utxo, Sequence: LockTimeToSequence(false, 1), }, { PreviousOutPoint: utxo, Sequence: LockTimeToSequence(false, 11), }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: -1, @@ -451,9 +406,8 @@ func TestCalcSequenceLock(t *testing.T) { // based, and the other two are block based. The lock lying // further into the future for both inputs should be chosen. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ + tx: wire.NewNativeMsgTx(1, + []*wire.TxIn{{ PreviousOutPoint: utxo, Sequence: LockTimeToSequence(true, 2560), }, { @@ -466,8 +420,7 @@ func TestCalcSequenceLock(t *testing.T) { PreviousOutPoint: utxo, Sequence: LockTimeToSequence(false, 9), }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + nil), utxoSet: utxoSet, want: &SequenceLock{ Seconds: medianTime + (13 << wire.SequenceLockTimeGranularity) - 1, @@ -481,14 +434,7 @@ func TestCalcSequenceLock(t *testing.T) { // *next* block height, indicating it can be included 2 blocks // after that. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: unConfUtxo, - Sequence: LockTimeToSequence(false, 2), - }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{PreviousOutPoint: unConfUtxo, Sequence: LockTimeToSequence(false, 2)}}, nil), utxoSet: utxoSet, mempool: true, want: &SequenceLock{ @@ -500,14 +446,7 @@ func TestCalcSequenceLock(t *testing.T) { // a time based lock, so the lock time should be based off the // MTP of the *next* block. { - tx: &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: unConfUtxo, - Sequence: LockTimeToSequence(true, 1024), - }}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{PreviousOutPoint: unConfUtxo, Sequence: LockTimeToSequence(true, 1024)}}, nil), utxoSet: utxoSet, mempool: true, want: &SequenceLock{ @@ -1245,11 +1184,13 @@ func TestValidateFeeTransaction(t *testing.T) { }, } - block5FeeTx := wire.NewMsgTx(1) + txIns := []*wire.TxIn{} + txOuts := []*wire.TxOut{} for hash := range feeInOuts { - block5FeeTx.AddTxIn(feeInOuts[hash].txIn) - block5FeeTx.AddTxOut(feeInOuts[hash].txOut) + txIns = append(txIns, feeInOuts[hash].txIn) + txOuts = append(txOuts, feeInOuts[hash].txOut) } + block5FeeTx := wire.NewNativeMsgTx(1, txIns, txOuts) sortedBlock5FeeTx := txsort.Sort(block5FeeTx) block5Txs := []*wire.MsgTx{cb5, sortedBlock5FeeTx} diff --git a/blockdag/external_dag_test.go b/blockdag/external_dag_test.go index 6cc2ddaac..ec6f74a2a 100644 --- a/blockdag/external_dag_test.go +++ b/blockdag/external_dag_test.go @@ -195,27 +195,27 @@ func TestChainedTransactions(t *testing.T) { } cbTx := block1.Transactions[0] - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ PreviousOutPoint: wire.OutPoint{TxID: cbTx.TxID(), Index: 0}, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, - }) - tx.AddTxOut(&wire.TxOut{ + } + txOut := &wire.TxOut{ PkScript: blockdag.OpTrueScript, Value: uint64(1), - }) + } + tx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) - chainedTx := wire.NewMsgTx(wire.TxVersion) - chainedTx.AddTxIn(&wire.TxIn{ + chainedTxIn := &wire.TxIn{ PreviousOutPoint: wire.OutPoint{TxID: tx.TxID(), Index: 0}, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, - }) - chainedTx.AddTxOut(&wire.TxOut{ + } + chainedTxOut := &wire.TxOut{ PkScript: blockdag.OpTrueScript, Value: uint64(1), - }) + } + chainedTx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{chainedTxIn}, []*wire.TxOut{chainedTxOut}) block2, err := mining.PrepareBlockForTest(dag, ¶ms, []daghash.Hash{block1.BlockHash()}, []*wire.MsgTx{tx, chainedTx}, true, 1) if err != nil { @@ -237,16 +237,16 @@ func TestChainedTransactions(t *testing.T) { t.Errorf("ProcessBlock: block2 got unexpectedly orphaned") } - nonChainedTx := wire.NewMsgTx(wire.TxVersion) - nonChainedTx.AddTxIn(&wire.TxIn{ + nonChainedTxIn := &wire.TxIn{ PreviousOutPoint: wire.OutPoint{TxID: cbTx.TxID(), Index: 0}, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, - }) - nonChainedTx.AddTxOut(&wire.TxOut{ + } + nonChainedTxOut := &wire.TxOut{ PkScript: blockdag.OpTrueScript, Value: uint64(1), - }) + } + nonChainedTx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{nonChainedTxIn}, []*wire.TxOut{nonChainedTxOut}) block3, err := mining.PrepareBlockForTest(dag, ¶ms, []daghash.Hash{block1.BlockHash()}, []*wire.MsgTx{nonChainedTx}, false, 1) if err != nil { @@ -299,31 +299,25 @@ func TestGasLimit(t *testing.T) { cbTxValue := fundsBlock.Transactions[0].TxOut[0].Value cbTxID := fundsBlock.Transactions[0].TxID() - tx1 := wire.NewMsgTx(wire.TxVersion) - tx1.AddTxIn(&wire.TxIn{ + tx1In := &wire.TxIn{ PreviousOutPoint: *wire.NewOutPoint(&cbTxID, 0), Sequence: wire.MaxTxInSequenceNum, - }) - tx1.AddTxOut(&wire.TxOut{ + } + tx1Out := &wire.TxOut{ Value: cbTxValue, PkScript: blockdag.OpTrueScript, - }) - tx1.SubnetworkID = *subnetworkID - tx1.Gas = 10000 - tx1.PayloadHash = daghash.DoubleHashP(tx1.Payload) + } + tx1 := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{tx1In}, []*wire.TxOut{tx1Out}, subnetworkID, 10000, []byte{}) - tx2 := wire.NewMsgTx(wire.TxVersion) - tx2.AddTxIn(&wire.TxIn{ + tx2In := &wire.TxIn{ PreviousOutPoint: *wire.NewOutPoint(&cbTxID, 1), Sequence: wire.MaxTxInSequenceNum, - }) - tx2.AddTxOut(&wire.TxOut{ + } + tx2Out := &wire.TxOut{ Value: cbTxValue, PkScript: blockdag.OpTrueScript, - }) - tx2.SubnetworkID = *subnetworkID - tx2.Gas = 10000 - tx2.PayloadHash = daghash.DoubleHashP(tx2.Payload) + } + tx2 := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{tx2In}, []*wire.TxOut{tx2Out}, subnetworkID, 10000, []byte{}) // Here we check that we can't process a block that has transactions that exceed the gas limit overLimitBlock, err := mining.PrepareBlockForTest(dag, ¶ms, dag.TipHashes(), []*wire.MsgTx{tx1, tx2}, true, 1) @@ -344,18 +338,16 @@ func TestGasLimit(t *testing.T) { t.Fatalf("ProcessBlock: overLimitBlock got unexpectedly orphan") } - overflowGasTx := wire.NewMsgTx(wire.TxVersion) - overflowGasTx.AddTxIn(&wire.TxIn{ + overflowGasTxIn := &wire.TxIn{ PreviousOutPoint: *wire.NewOutPoint(&cbTxID, 1), Sequence: wire.MaxTxInSequenceNum, - }) - overflowGasTx.AddTxOut(&wire.TxOut{ + } + overflowGasTxOut := &wire.TxOut{ Value: cbTxValue, PkScript: blockdag.OpTrueScript, - }) - overflowGasTx.SubnetworkID = *subnetworkID - overflowGasTx.Gas = math.MaxUint64 - overflowGasTx.PayloadHash = daghash.DoubleHashP(overflowGasTx.Payload) + } + overflowGasTx := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{overflowGasTxIn}, []*wire.TxOut{overflowGasTxOut}, + subnetworkID, math.MaxUint64, []byte{}) // Here we check that we can't process a block that its transactions' gas overflows uint64 overflowGasBlock, err := mining.PrepareBlockForTest(dag, ¶ms, dag.TipHashes(), []*wire.MsgTx{tx1, overflowGasTx}, true, 1) @@ -376,19 +368,17 @@ func TestGasLimit(t *testing.T) { t.Fatalf("ProcessBlock: overLimitBlock got unexpectedly orphan") } - nonExistentSubnetwork := subnetworkid.SubnetworkID{123} - nonExistentSubnetworkTx := wire.NewMsgTx(wire.TxVersion) - nonExistentSubnetworkTx.AddTxIn(&wire.TxIn{ + nonExistentSubnetwork := &subnetworkid.SubnetworkID{123} + nonExistentSubnetworkTxIn := &wire.TxIn{ PreviousOutPoint: *wire.NewOutPoint(&cbTxID, 0), Sequence: wire.MaxTxInSequenceNum, - }) - nonExistentSubnetworkTx.AddTxOut(&wire.TxOut{ + } + nonExistentSubnetworkTxOut := &wire.TxOut{ Value: cbTxValue, PkScript: blockdag.OpTrueScript, - }) - nonExistentSubnetworkTx.SubnetworkID = nonExistentSubnetwork - nonExistentSubnetworkTx.Gas = 1 - nonExistentSubnetworkTx.PayloadHash = daghash.DoubleHashP(nonExistentSubnetworkTx.Payload) + } + nonExistentSubnetworkTx := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{nonExistentSubnetworkTxIn}, + []*wire.TxOut{nonExistentSubnetworkTxOut}, nonExistentSubnetwork, 1, []byte{}) nonExistentSubnetworkBlock, err := mining.PrepareBlockForTest(dag, ¶ms, dag.TipHashes(), []*wire.MsgTx{nonExistentSubnetworkTx, overflowGasTx}, true, 1) if err != nil { diff --git a/blockdag/fees.go b/blockdag/fees.go index 17eb5a570..04a881a85 100644 --- a/blockdag/fees.go +++ b/blockdag/fees.go @@ -144,18 +144,20 @@ func (node *blockNode) buildFeeTransaction(dag *BlockDAG, txsAcceptanceData Mult return nil, err } - feeTx := wire.NewMsgTx(wire.TxVersion) + txIns := []*wire.TxIn{} + txOuts := []*wire.TxOut{} for _, blue := range node.blues { txIn, txOut, err := feeInputAndOutputForBlueBlock(blue, txsAcceptanceData, bluesFeeData) if err != nil { return nil, err } - feeTx.AddTxIn(txIn) + txIns = append(txIns, txIn) if txOut != nil { - feeTx.AddTxOut(txOut) + txOuts = append(txOuts, txOut) } } + feeTx := wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts) return txsort.Sort(feeTx), nil } diff --git a/blockdag/fullblocktests/generate.go b/blockdag/fullblocktests/generate.go index e6c2a85b1..7ed229dce 100644 --- a/blockdag/fullblocktests/generate.go +++ b/blockdag/fullblocktests/generate.go @@ -282,20 +282,19 @@ func (g *testGenerator) createCoinbaseTx(blockHeight int32) *wire.MsgTx { panic(err) } - tx := wire.NewMsgTx(1) - tx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ // Coinbase transactions have no inputs, so previous outpoint is // zero hash and max index. PreviousOutPoint: *wire.NewOutPoint(&daghash.TxID{}, wire.MaxPrevOutIndex), Sequence: wire.MaxTxInSequenceNum, SignatureScript: coinbaseScript, - }) - tx.AddTxOut(&wire.TxOut{ + } + txOut := &wire.TxOut{ Value: blockdag.CalcBlockSubsidy(blockHeight, g.params), PkScript: opTrueScript, - }) - return tx + } + return wire.NewNativeMsgTx(1, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) } // calcHashMerkleRoot creates a merkle tree from the slice of transactions and @@ -436,12 +435,12 @@ func additionalTx(tx *wire.MsgTx) func(*wire.MsgBlock) { // script which avoids the need to track addresses and signature scripts in the // tests. func createSpendTx(spend *spendableOut, fee util.Amount) *wire.MsgTx { - spendTx := wire.NewMsgTx(1) - spendTx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ PreviousOutPoint: spend.prevOut, Sequence: wire.MaxTxInSequenceNum, SignatureScript: nil, - }) + } + spendTx := wire.NewNativeMsgTx(1, []*wire.TxIn{txIn}, nil) spendTx.AddTxOut(wire.NewTxOut(uint64(spend.amount-fee), opTrueScript)) spendTx.AddTxOut(wire.NewTxOut(0, uniqueOpReturnScript())) diff --git a/blockdag/indexers/txindex_test.go b/blockdag/indexers/txindex_test.go index c0ca0cf6c..0e58336d4 100644 --- a/blockdag/indexers/txindex_test.go +++ b/blockdag/indexers/txindex_test.go @@ -15,17 +15,15 @@ import ( ) func createTransaction(value uint64, originTx *wire.MsgTx, outputIndex uint32) *wire.MsgTx { - tx := wire.NewMsgTx(wire.TxVersion) - - tx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ PreviousOutPoint: wire.OutPoint{ TxID: originTx.TxID(), Index: outputIndex, }, Sequence: wire.MaxTxInSequenceNum, - }) + } txOut := wire.NewTxOut(value, blockdag.OpTrueScript) - tx.AddTxOut(txOut) + tx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) return tx } diff --git a/blockdag/test_utils.go b/blockdag/test_utils.go index adf0d375c..d5f3b2623 100644 --- a/blockdag/test_utils.go +++ b/blockdag/test_utils.go @@ -109,41 +109,35 @@ func DAGSetup(dbName string, config Config) (*BlockDAG, func(), error) { var OpTrueScript = []byte{txscript.OpTrue} type txSubnetworkData struct { - subnetworkID subnetworkid.SubnetworkID + subnetworkID *subnetworkid.SubnetworkID Gas uint64 Payload []byte } func createTxForTest(numInputs uint32, numOutputs uint32, outputValue uint64, subnetworkData *txSubnetworkData) *wire.MsgTx { - tx := wire.NewMsgTx(wire.TxVersion) + txIns := []*wire.TxIn{} + txOuts := []*wire.TxOut{} for i := uint32(0); i < numInputs; i++ { - tx.AddTxIn(&wire.TxIn{ + txIns = append(txIns, &wire.TxIn{ PreviousOutPoint: *wire.NewOutPoint(&daghash.TxID{}, i), SignatureScript: []byte{}, Sequence: wire.MaxTxInSequenceNum, }) } + for i := uint32(0); i < numOutputs; i++ { - tx.AddTxOut(&wire.TxOut{ + txOuts = append(txOuts, &wire.TxOut{ PkScript: OpTrueScript, Value: outputValue, }) } if subnetworkData != nil { - tx.SubnetworkID = subnetworkData.subnetworkID - tx.Gas = subnetworkData.Gas - tx.Payload = subnetworkData.Payload - if !subnetworkData.subnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) { - tx.PayloadHash = daghash.DoubleHashP(tx.Payload) - } - } else { - tx.SubnetworkID = *subnetworkid.SubnetworkIDNative - tx.Gas = 0 - tx.Payload = []byte{} + return wire.NewSubnetworkMsgTx(wire.TxVersion, txIns, txOuts, subnetworkData.subnetworkID, subnetworkData.Gas, subnetworkData.Payload) } - return tx + + return wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts) } // createCoinbaseTxForTest returns a coinbase transaction with the requested number of @@ -158,15 +152,17 @@ func createCoinbaseTxForTest(blockHeight int32, numOutputs uint32, extraNonce in return nil, err } - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIns := []*wire.TxIn{&wire.TxIn{ // Coinbase transactions have no inputs, so previous outpoint is // zero hash and max index. PreviousOutPoint: *wire.NewOutPoint(&daghash.TxID{}, wire.MaxPrevOutIndex), SignatureScript: coinbaseScript, Sequence: wire.MaxTxInSequenceNum, - }) + }} + + txOuts := []*wire.TxOut{} + totalInput := CalcBlockSubsidy(blockHeight, params) amountPerOutput := totalInput / uint64(numOutputs) remainder := totalInput - amountPerOutput*uint64(numOutputs) @@ -177,13 +173,13 @@ func createCoinbaseTxForTest(blockHeight int32, numOutputs uint32, extraNonce in if i == numOutputs-1 { amount = amountPerOutput + remainder } - tx.AddTxOut(&wire.TxOut{ + txOuts = append(txOuts, &wire.TxOut{ PkScript: OpTrueScript, Value: amount, }) } - return tx, nil + return wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts), nil } // SetVirtualForTest replaces the dag's virtual block. This function is used for test purposes only diff --git a/blockdag/utxoset_test.go b/blockdag/utxoset_test.go index 8e6361da9..0b8c78e6f 100644 --- a/blockdag/utxoset_test.go +++ b/blockdag/utxoset_test.go @@ -7,7 +7,6 @@ import ( "github.com/daglabs/btcd/dagconfig" "github.com/daglabs/btcd/dagconfig/daghash" - "github.com/daglabs/btcd/util/subnetworkid" "github.com/daglabs/btcd/wire" ) @@ -361,9 +360,7 @@ func TestFullUTXOSet(t *testing.T) { // Test fullUTXOSet addTx txIn0 := &wire.TxIn{SignatureScript: []byte{}, PreviousOutPoint: wire.OutPoint{TxID: *txID0, Index: 0}, Sequence: 0} - transaction0 := wire.NewMsgTx(1) - transaction0.TxIn = []*wire.TxIn{txIn0} - transaction0.TxOut = []*wire.TxOut{txOut0} + transaction0 := wire.NewNativeMsgTx(1, []*wire.TxIn{txIn0}, []*wire.TxOut{txOut0}) if ok = emptySet.AddTx(transaction0, 0); ok { t.Errorf("addTx unexpectedly succeeded") } @@ -638,9 +635,7 @@ func TestDiffUTXOSet_addTx(t *testing.T) { txIn0 := &wire.TxIn{SignatureScript: []byte{}, PreviousOutPoint: wire.OutPoint{TxID: *txID0, Index: math.MaxUint32}, Sequence: 0} txOut0 := &wire.TxOut{PkScript: []byte{0}, Value: 10} utxoEntry0 := NewUTXOEntry(txOut0, true, 0) - transaction0 := wire.NewMsgTx(1) - transaction0.TxIn = []*wire.TxIn{txIn0} - transaction0.TxOut = []*wire.TxOut{txOut0} + transaction0 := wire.NewNativeMsgTx(1, []*wire.TxIn{txIn0}, []*wire.TxOut{txOut0}) // transaction1 spends transaction0 id1 := transaction0.TxID() @@ -648,9 +643,7 @@ func TestDiffUTXOSet_addTx(t *testing.T) { txIn1 := &wire.TxIn{SignatureScript: []byte{}, PreviousOutPoint: wire.OutPoint{TxID: id1, Index: 0}, Sequence: 0} txOut1 := &wire.TxOut{PkScript: []byte{1}, Value: 20} utxoEntry1 := NewUTXOEntry(txOut1, false, 1) - transaction1 := wire.NewMsgTx(1) - transaction1.TxIn = []*wire.TxIn{txIn1} - transaction1.TxOut = []*wire.TxOut{txOut1} + transaction1 := wire.NewNativeMsgTx(1, []*wire.TxIn{txIn1}, []*wire.TxOut{txOut1}) // transaction2 spends transaction1 id2 := transaction1.TxID() @@ -658,9 +651,7 @@ func TestDiffUTXOSet_addTx(t *testing.T) { txIn2 := &wire.TxIn{SignatureScript: []byte{}, PreviousOutPoint: wire.OutPoint{TxID: id2, Index: 0}, Sequence: 0} txOut2 := &wire.TxOut{PkScript: []byte{2}, Value: 30} utxoEntry2 := NewUTXOEntry(txOut2, false, 2) - transaction2 := wire.NewMsgTx(1) - transaction2.TxIn = []*wire.TxIn{txIn2} - transaction2.TxOut = []*wire.TxOut{txOut2} + transaction2 := wire.NewNativeMsgTx(1, []*wire.TxIn{txIn2}, []*wire.TxOut{txOut2}) // outpoint3 is the outpoint for transaction2 id3 := transaction2.TxID() @@ -807,16 +798,16 @@ func TestDiffFromTx(t *testing.T) { fus.AddTx(cbTx, 1) node := &blockNode{height: 2} //Fake node cbOutpoint := wire.OutPoint{TxID: cbTx.TxID(), Index: 0} - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIns := []*wire.TxIn{&wire.TxIn{ PreviousOutPoint: cbOutpoint, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, - }) - tx.AddTxOut(&wire.TxOut{ + }} + txOuts := []*wire.TxOut{&wire.TxOut{ PkScript: OpTrueScript, Value: uint64(1), - }) + }} + tx := wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts) diff, err := fus.diffFromTx(tx, node) if err != nil { t.Errorf("diffFromTx: %v", err) @@ -834,16 +825,16 @@ func TestDiffFromTx(t *testing.T) { } //Test that we get an error if we don't have the outpoint inside the utxo set - invalidTx := wire.NewMsgTx(wire.TxVersion) - invalidTx.AddTxIn(&wire.TxIn{ + invalidTxIns := []*wire.TxIn{&wire.TxIn{ PreviousOutPoint: wire.OutPoint{TxID: daghash.TxID{}, Index: 0}, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, - }) - invalidTx.AddTxOut(&wire.TxOut{ + }} + invalidTxOuts := []*wire.TxOut{&wire.TxOut{ PkScript: OpTrueScript, Value: uint64(1), - }) + }} + invalidTx := wire.NewNativeMsgTx(wire.TxVersion, invalidTxIns, invalidTxOuts) _, err = fus.diffFromTx(invalidTx, node) if err == nil { t.Errorf("diffFromTx: expected an error but got ") @@ -929,16 +920,8 @@ func TestUTXOSetAddEntry(t *testing.T) { } func TestUTXOSetRemoveTxOuts(t *testing.T) { - tx0 := &wire.MsgTx{ - TxOut: []*wire.TxOut{{ - PkScript: []byte{1}, Value: 10}}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - } - tx1 := &wire.MsgTx{ - TxOut: []*wire.TxOut{{ - PkScript: []byte{2}, Value: 20}}, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - } + tx0 := wire.NewNativeMsgTx(1, nil, []*wire.TxOut{{PkScript: []byte{1}, Value: 10}}) + tx1 := wire.NewNativeMsgTx(1, nil, []*wire.TxOut{{PkScript: []byte{2}, Value: 20}}) hash0 := tx0.TxID() hash1 := tx1.TxID() outPoint0 := wire.NewOutPoint(&hash0, 0) diff --git a/blockdag/validate_test.go b/blockdag/validate_test.go index 59969a2e5..8a491795c 100644 --- a/blockdag/validate_test.go +++ b/blockdag/validate_test.go @@ -472,8 +472,7 @@ func TestCheckBlockSanity(t *testing.T) { func TestCheckSerializedHeight(t *testing.T) { // Create an empty coinbase template to be used in the tests below. coinbaseOutpoint := wire.NewOutPoint(&daghash.TxID{}, math.MaxUint32) - coinbaseTx := wire.NewMsgTx(1) - coinbaseTx.AddTxIn(wire.NewTxIn(coinbaseOutpoint, nil)) + coinbaseTx := wire.NewNativeMsgTx(1, []*wire.TxIn{wire.NewTxIn(coinbaseOutpoint, nil)}, nil) // Expected rule errors. missingHeightError := RuleError{ @@ -671,32 +670,32 @@ func TestCheckTransactionSanity(t *testing.T) { ruleError(ErrDuplicateTxInputs, "")}, {"non-zero gas in DAGCoin", 1, 1, 0, *subnetworkid.SubnetworkIDNative, - &txSubnetworkData{*subnetworkid.SubnetworkIDNative, 1, []byte{}}, + &txSubnetworkData{subnetworkid.SubnetworkIDNative, 1, []byte{}}, nil, ruleError(ErrInvalidGas, "")}, {"non-zero gas in subnetwork registry", 1, 1, 0, *subnetworkid.SubnetworkIDNative, - &txSubnetworkData{*subnetworkid.SubnetworkIDNative, 1, []byte{}}, + &txSubnetworkData{subnetworkid.SubnetworkIDNative, 1, []byte{}}, nil, ruleError(ErrInvalidGas, "")}, {"non-zero payload in DAGCoin", 1, 1, 0, *subnetworkid.SubnetworkIDNative, - &txSubnetworkData{*subnetworkid.SubnetworkIDNative, 0, []byte{1}}, + &txSubnetworkData{subnetworkid.SubnetworkIDNative, 0, []byte{1}}, nil, ruleError(ErrInvalidPayload, "")}, {"payload in subnetwork registry isn't 8 bytes", 1, 1, 0, *subnetworkid.SubnetworkIDNative, - &txSubnetworkData{*subnetworkid.SubnetworkIDNative, 0, []byte{1, 2, 3, 4, 5, 6, 7}}, + &txSubnetworkData{subnetworkid.SubnetworkIDNative, 0, []byte{1, 2, 3, 4, 5, 6, 7}}, nil, ruleError(ErrInvalidPayload, "")}, {"payload in other subnetwork isn't 0 bytes", 1, 1, 0, subnetworkid.SubnetworkID{123}, - &txSubnetworkData{subnetworkid.SubnetworkID{234}, 0, []byte{1}}, + &txSubnetworkData{&subnetworkid.SubnetworkID{234}, 0, []byte{1}}, nil, ruleError(ErrInvalidPayload, "")}, {"invalid payload hash", 1, 1, 0, subnetworkid.SubnetworkID{123}, - &txSubnetworkData{subnetworkid.SubnetworkID{123}, 0, []byte{1}}, + &txSubnetworkData{&subnetworkid.SubnetworkID{123}, 0, []byte{1}}, func(tx *wire.MsgTx) { tx.PayloadHash = &daghash.Hash{} }, diff --git a/dagconfig/genesis.go b/dagconfig/genesis.go index ff80156d3..e7d29f184 100644 --- a/dagconfig/genesis.go +++ b/dagconfig/genesis.go @@ -9,38 +9,34 @@ import ( "time" "github.com/daglabs/btcd/dagconfig/daghash" - "github.com/daglabs/btcd/util/subnetworkid" "github.com/daglabs/btcd/wire" ) +var genesisTxIns = []*wire.TxIn{ + { + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID{}, + Index: 0xffffffff, + }, + SignatureScript: []byte{ + 0x00, 0x00, 0x0b, 0x2f, 0x50, 0x32, 0x53, 0x48, + 0x2f, 0x62, 0x74, 0x63, 0x64, 0x2f, + }, + Sequence: math.MaxUint64, + }, +} +var genesisTxOuts = []*wire.TxOut{ + { + Value: 0x12a05f200, + PkScript: []byte{ + 0x51, + }, + }, +} + // genesisCoinbaseTx is the coinbase transaction for the genesis blocks for // the main network, regression test network, and test network (version 3). -var genesisCoinbaseTx = wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID{}, - Index: 0xffffffff, - }, - SignatureScript: []byte{ - 0x00, 0x00, 0x0b, 0x2f, 0x50, 0x32, 0x53, 0x48, - 0x2f, 0x62, 0x74, 0x63, 0x64, 0x2f, - }, - Sequence: math.MaxUint64, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0x12a05f200, - PkScript: []byte{ - 0x51, - }, - }, - }, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, -} +var genesisCoinbaseTx = wire.NewNativeMsgTx(1, genesisTxIns, genesisTxOuts) // genesisHash is the hash of the first block in the block chain for the main // network (genesis block). @@ -72,7 +68,7 @@ var genesisBlock = wire.MsgBlock{ Bits: 0x207fffff, Nonce: 0, }, - Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, + Transactions: []*wire.MsgTx{genesisCoinbaseTx}, } // regTestGenesisHash is the hash of the first block in the block chain for the diff --git a/database/testdata/generator.go b/database/testdata/generator.go index 3589d64fd..c285ff971 100644 --- a/database/testdata/generator.go +++ b/database/testdata/generator.go @@ -103,48 +103,44 @@ func printUsage() { os.Exit(1) } -var genesisCoinbaseTx = wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.Hash{}, - Index: 0xffffffff, - }, - SignatureScript: []byte{ - 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */ - 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */ - 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */ - 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */ - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */ - 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */ - 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/ - 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */ - 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ - 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ - }, - Sequence: 0xffffffff, +var genesisCoinbaseTxIns = []*wire.TxIn{ + { + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID{}, + Index: 0xffffffff, }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0x12a05f200, - PkScript: []byte{ - 0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */ - 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */ - 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */ - 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */ - 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */ - 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */ - 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */ - 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */ - 0x1d, 0x5f, 0xac, /* |._.| */ - }, + SignatureScript: []byte{ + 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */ + 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */ + 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */ + 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */ + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */ + 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */ + 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/ + 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */ + 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ + 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ }, + Sequence: 0xffffffff, }, - LockTime: 0, - SubnetworkID: subnetworkid.SubnetworkIDNative, } +var genesisCoinbaseTxOuts = []*wire.TxOut{ + { + Value: 0x12a05f200, + PkScript: []byte{ + 0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */ + 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */ + 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */ + 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */ + 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */ + 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */ + 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */ + 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */ + 0x1d, 0x5f, 0xac, /* |._.| */ + }, + }, +} +var genesisCoinbaseTx = wire.NewMsgTx(1, genesisCoinbaseTxIns, genesisCoinbaseTxOuts, nil, 0, nil) var genesisMerkleRoot = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy. 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, diff --git a/integration/rpctest/blockgen.go b/integration/rpctest/blockgen.go index fed668cde..5f9648865 100644 --- a/integration/rpctest/blockgen.go +++ b/integration/rpctest/blockgen.go @@ -105,26 +105,27 @@ func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int32, return nil, err } - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIns := []*wire.TxIn{&wire.TxIn{ // Coinbase transactions have no inputs, so previous outpoint is // zero hash and max index. PreviousOutPoint: *wire.NewOutPoint(&daghash.TxID{}, wire.MaxPrevOutIndex), SignatureScript: coinbaseScript, Sequence: wire.MaxTxInSequenceNum, - }) + }} + txOuts := []*wire.TxOut{} if len(mineTo) == 0 { - tx.AddTxOut(&wire.TxOut{ + txOuts = append(txOuts, &wire.TxOut{ Value: blockdag.CalcBlockSubsidy(nextBlockHeight, net), PkScript: pkScript, }) } else { for i := range mineTo { - tx.AddTxOut(&mineTo[i]) + txOuts = append(txOuts, &mineTo[i]) } } - return util.NewTx(tx), nil + + return util.NewTx(wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts)), nil } // CreateBlock creates a new block building from the previous block with a diff --git a/integration/rpctest/memwallet.go b/integration/rpctest/memwallet.go index 689add6ca..625433e74 100644 --- a/integration/rpctest/memwallet.go +++ b/integration/rpctest/memwallet.go @@ -464,7 +464,7 @@ func (m *memWallet) CreateTransaction(outputs []*wire.TxOut, feeRate util.Amount m.Lock() defer m.Unlock() - tx := wire.NewMsgTx(wire.TxVersion) + tx := wire.NewNativeMsgTx(wire.TxVersion, nil, nil) // Tally up the total amount to be sent in order to perform coin // selection shortly below. diff --git a/mempool/estimatefee_test.go b/mempool/estimatefee_test.go index 63b64de77..c11152556 100644 --- a/mempool/estimatefee_test.go +++ b/mempool/estimatefee_test.go @@ -12,7 +12,6 @@ import ( "github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/mining" "github.com/daglabs/btcd/util" - "github.com/daglabs/btcd/util/subnetworkid" "github.com/daglabs/btcd/wire" ) @@ -51,10 +50,7 @@ func (eft *estimateFeeTester) testTx(fee util.Amount) *TxDesc { eft.version++ return &TxDesc{ TxDesc: mining.TxDesc{ - Tx: util.NewTx(&wire.MsgTx{ - Version: eft.version, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }), + Tx: util.NewTx(wire.NewNativeMsgTx(eft.version, nil, nil)), Height: eft.height, Fee: uint64(fee), }, diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 8e85174bd..b52faed61 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -130,15 +130,16 @@ func (p *poolHarness) CreateCoinbaseTx(blockHeight int32, numOutputs uint32) (*u return nil, err } - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIns := []*wire.TxIn{&wire.TxIn{ // Coinbase transactions have no inputs, so previous outpoint is // zero hash and max index. PreviousOutPoint: *wire.NewOutPoint(&daghash.TxID{}, wire.MaxPrevOutIndex), SignatureScript: coinbaseScript, Sequence: wire.MaxTxInSequenceNum, - }) + }} + + txOuts := []*wire.TxOut{} totalInput := blockdag.CalcBlockSubsidy(blockHeight, p.chainParams) amountPerOutput := totalInput / uint64(numOutputs) remainder := totalInput - amountPerOutput*uint64(numOutputs) @@ -149,13 +150,13 @@ func (p *poolHarness) CreateCoinbaseTx(blockHeight int32, numOutputs uint32) (*u if i == numOutputs-1 { amount = amountPerOutput + remainder } - tx.AddTxOut(&wire.TxOut{ + txOuts = append(txOuts, &wire.TxOut{ PkScript: p.payScript, Value: amount, }) } - return util.NewTx(tx), nil + return util.NewTx(wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts)), nil } // CreateSignedTxForSubnetwork creates a new signed transaction that consumes the provided @@ -172,19 +173,16 @@ func (p *poolHarness) CreateSignedTxForSubnetwork(inputs []spendableOutpoint, nu amountPerOutput := uint64(totalInput) / uint64(numOutputs) remainder := uint64(totalInput) - amountPerOutput*uint64(numOutputs) - tx := wire.NewMsgTx(wire.TxVersion) - tx.SubnetworkID = *subnetworkID - tx.Gas = gas - if !subnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) { - tx.PayloadHash = daghash.DoubleHashP(tx.Payload) - } + txIns := []*wire.TxIn{} for _, input := range inputs { - tx.AddTxIn(&wire.TxIn{ + txIns = append(txIns, &wire.TxIn{ PreviousOutPoint: input.outPoint, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, }) } + + txOuts := []*wire.TxOut{} for i := uint32(0); i < numOutputs; i++ { // Ensure the final output accounts for any remainder that might // be left from splitting the input amount. @@ -192,12 +190,14 @@ func (p *poolHarness) CreateSignedTxForSubnetwork(inputs []spendableOutpoint, nu if i == numOutputs-1 { amount = amountPerOutput + remainder } - tx.AddTxOut(&wire.TxOut{ + txOuts = append(txOuts, &wire.TxOut{ PkScript: p.payScript, Value: amount, }) } + tx := wire.NewSubnetworkMsgTx(wire.TxVersion, txIns, txOuts, subnetworkID, gas, []byte{}) + // Sign the new transaction. for i := range tx.TxIn { sigScript, err := txscript.SignatureScript(tx, i, p.payScript, @@ -231,16 +231,16 @@ func (p *poolHarness) CreateTxChain(firstOutput spendableOutpoint, numTxns uint3 // Create the transaction using the previous transaction output // and paying the full amount to the payment address associated // with the harness. - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ PreviousOutPoint: prevOutPoint, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, - }) - tx.AddTxOut(&wire.TxOut{ + } + txOut := &wire.TxOut{ PkScript: p.payScript, Value: uint64(spendableAmount), - }) + } + tx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) // Sign the new transaction. sigScript, err := txscript.SignatureScript(tx, 0, p.payScript, @@ -441,19 +441,21 @@ func testPoolMembership(tc *testContext, tx *util.Tx, inOrphanPool, inTxPool boo } func (p *poolHarness) createTx(outpoint spendableOutpoint, fee uint64, numOutputs int64) (*util.Tx, error) { - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIns := []*wire.TxIn{&wire.TxIn{ PreviousOutPoint: outpoint.outPoint, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, - }) + }} + + txOuts := []*wire.TxOut{} amountPerOutput := (uint64(outpoint.amount) - fee) / uint64(numOutputs) for i := int64(0); i < numOutputs; i++ { - tx.AddTxOut(&wire.TxOut{ + txOuts = append(txOuts, &wire.TxOut{ PkScript: p.payScript, Value: amountPerOutput, }) } + tx := wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts) // Sign the new transaction. sigScript, err := txscript.SignatureScript(tx, 0, p.payScript, @@ -621,32 +623,19 @@ func TestProcessTransaction(t *testing.T) { if err != nil { t.Fatalf("PayToAddrScript: unexpected error: %v", err) } - - p2shTx := util.NewTx(&wire.MsgTx{ - Version: 1, - TxOut: []*wire.TxOut{{ - Value: 5000000000, - PkScript: p2shPKScript, - }}, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }) + p2shTx := util.NewTx(wire.NewNativeMsgTx(1, nil, []*wire.TxOut{{Value: 5000000000, PkScript: p2shPKScript}})) harness.txPool.mpUTXOSet.AddTx(p2shTx.MsgTx(), curHeight+1) - nonStdSigScriptTx := util.NewTx(&wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: wire.OutPoint{TxID: *p2shTx.ID(), Index: 0}, - SignatureScript: wrappedP2SHNonStdSigScript, - Sequence: wire.MaxTxInSequenceNum, - }}, - TxOut: []*wire.TxOut{{ - Value: 5000000000, - PkScript: dummyPkScript, - }}, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }) + txIns := []*wire.TxIn{{ + PreviousOutPoint: wire.OutPoint{TxID: *p2shTx.ID(), Index: 0}, + SignatureScript: wrappedP2SHNonStdSigScript, + Sequence: wire.MaxTxInSequenceNum, + }} + txOuts := []*wire.TxOut{{ + Value: 5000000000, + PkScript: dummyPkScript, + }} + nonStdSigScriptTx := util.NewTx(wire.NewNativeMsgTx(1, txIns, txOuts)) _, err = harness.txPool.ProcessTransaction(nonStdSigScriptTx, true, false, 0) if err == nil { t.Errorf("ProcessTransaction: expected an error, not nil") @@ -681,17 +670,12 @@ func TestProcessTransaction(t *testing.T) { harness.txPool.cfg.Policy.AcceptNonStd = false //Checks that a transaction with no outputs will not get rejected - noOutsTx := util.NewTx(&wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: dummyPrevOut, - SignatureScript: dummySigScript, - Sequence: wire.MaxTxInSequenceNum, - }}, - TxOut: []*wire.TxOut{}, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }) + noOutsTx := util.NewTx(wire.NewNativeMsgTx(1, []*wire.TxIn{{ + PreviousOutPoint: dummyPrevOut, + SignatureScript: dummySigScript, + Sequence: wire.MaxTxInSequenceNum, + }}, + nil)) _, err = harness.txPool.ProcessTransaction(noOutsTx, true, false, 0) if err != nil { t.Errorf("ProcessTransaction: %v", err) @@ -750,20 +734,16 @@ func TestProcessTransaction(t *testing.T) { } harness.txPool.cfg.Policy.DisableRelayPriority = true - tx = util.NewTx(&wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: spendableOuts[5].outPoint, - SignatureScript: []byte{02, 01}, //Unparsable script - Sequence: wire.MaxTxInSequenceNum, - }}, - TxOut: []*wire.TxOut{{ - Value: 1, - PkScript: dummyPkScript, - }}, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }) + txIns = []*wire.TxIn{{ + PreviousOutPoint: spendableOuts[5].outPoint, + SignatureScript: []byte{02, 01}, //Unparsable script + Sequence: wire.MaxTxInSequenceNum, + }} + txOuts = []*wire.TxOut{{ + Value: 1, + PkScript: dummyPkScript, + }} + tx = util.NewTx(wire.NewNativeMsgTx(1, txIns, txOuts)) _, err = harness.txPool.ProcessTransaction(tx, true, false, 0) fmt.Println(err) if err == nil { diff --git a/mempool/policy_test.go b/mempool/policy_test.go index 2aaf04978..af05826d7 100644 --- a/mempool/policy_test.go +++ b/mempool/policy_test.go @@ -306,159 +306,109 @@ func TestCheckTransactionStandard(t *testing.T) { tests := []struct { name string - tx wire.MsgTx + tx *wire.MsgTx height int32 isStandard bool code wire.RejectCode }{ { - name: "Typical pay-to-pubkey-hash transaction", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{&dummyTxIn}, - TxOut: []*wire.TxOut{&dummyTxOut}, - LockTime: 0, - }, + name: "Typical pay-to-pubkey-hash transaction", + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{&dummyTxIn}, []*wire.TxOut{&dummyTxOut}), height: 300000, isStandard: true, }, { - name: "Transaction version too high", - tx: wire.MsgTx{ - Version: wire.TxVersion + 1, - TxIn: []*wire.TxIn{&dummyTxIn}, - TxOut: []*wire.TxOut{&dummyTxOut}, - LockTime: 0, - }, + name: "Transaction version too high", + tx: wire.NewNativeMsgTx(wire.TxVersion+1, []*wire.TxIn{&dummyTxIn}, []*wire.TxOut{&dummyTxOut}), height: 300000, isStandard: false, code: wire.RejectNonstandard, }, { name: "Transaction is not finalized", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: dummyPrevOut, - SignatureScript: dummySigScript, - Sequence: 0, - }}, - TxOut: []*wire.TxOut{&dummyTxOut}, - LockTime: 300001, - }, + tx: wire.NewNativeMsgTxWithLocktime(1, []*wire.TxIn{{ + PreviousOutPoint: dummyPrevOut, + SignatureScript: dummySigScript, + Sequence: 0, + }}, []*wire.TxOut{&dummyTxOut}, 300001), height: 300000, isStandard: false, code: wire.RejectNonstandard, }, { name: "Transaction size is too large", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{&dummyTxIn}, - TxOut: []*wire.TxOut{{ - Value: 0, - PkScript: bytes.Repeat([]byte{0x00}, - MaxStandardTxSize+1), - }}, - LockTime: 0, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{&dummyTxIn}, []*wire.TxOut{{ + Value: 0, + PkScript: bytes.Repeat([]byte{0x00}, + MaxStandardTxSize+1), + }}), height: 300000, isStandard: false, code: wire.RejectNonstandard, }, { name: "Signature script size is too large", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: dummyPrevOut, - SignatureScript: bytes.Repeat([]byte{0x00}, - maxStandardSigScriptSize+1), - Sequence: wire.MaxTxInSequenceNum, - }}, - TxOut: []*wire.TxOut{&dummyTxOut}, - LockTime: 0, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{ + PreviousOutPoint: dummyPrevOut, + SignatureScript: bytes.Repeat([]byte{0x00}, + maxStandardSigScriptSize+1), + Sequence: wire.MaxTxInSequenceNum, + }}, []*wire.TxOut{&dummyTxOut}), height: 300000, isStandard: false, code: wire.RejectNonstandard, }, { name: "Signature script that does more than push data", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: dummyPrevOut, - SignatureScript: []byte{ - txscript.OpCheckSigVerify}, - Sequence: wire.MaxTxInSequenceNum, - }}, - TxOut: []*wire.TxOut{&dummyTxOut}, - LockTime: 0, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{{ + PreviousOutPoint: dummyPrevOut, + SignatureScript: []byte{ + txscript.OpCheckSigVerify}, + Sequence: wire.MaxTxInSequenceNum, + }}, []*wire.TxOut{&dummyTxOut}), height: 300000, isStandard: false, code: wire.RejectNonstandard, }, { name: "Valid but non standard public key script", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{&dummyTxIn}, - TxOut: []*wire.TxOut{{ - Value: 100000000, - PkScript: []byte{txscript.OpTrue}, - }}, - LockTime: 0, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{&dummyTxIn}, []*wire.TxOut{{ + Value: 100000000, + PkScript: []byte{txscript.OpTrue}, + }}), height: 300000, isStandard: false, code: wire.RejectNonstandard, }, { name: "More than one nulldata output", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{&dummyTxIn}, - TxOut: []*wire.TxOut{{ - Value: 0, - PkScript: []byte{txscript.OpReturn}, - }, { - Value: 0, - PkScript: []byte{txscript.OpReturn}, - }}, - LockTime: 0, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{&dummyTxIn}, []*wire.TxOut{{ + Value: 0, + PkScript: []byte{txscript.OpReturn}, + }, { + Value: 0, + PkScript: []byte{txscript.OpReturn}, + }}), height: 300000, isStandard: false, code: wire.RejectNonstandard, }, { name: "Dust output", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{&dummyTxIn}, - TxOut: []*wire.TxOut{{ - Value: 0, - PkScript: dummyPkScript, - }}, - LockTime: 0, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{&dummyTxIn}, []*wire.TxOut{{ + Value: 0, + PkScript: dummyPkScript, + }}), height: 300000, isStandard: false, code: wire.RejectDust, }, { name: "One nulldata output with 0 amount (standard)", - tx: wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{&dummyTxIn}, - TxOut: []*wire.TxOut{{ - Value: 0, - PkScript: []byte{txscript.OpReturn}, - }}, - LockTime: 0, - }, + tx: wire.NewNativeMsgTx(1, []*wire.TxIn{&dummyTxIn}, []*wire.TxOut{{ + Value: 0, + PkScript: []byte{txscript.OpReturn}, + }}), height: 300000, isStandard: true, }, @@ -467,7 +417,7 @@ func TestCheckTransactionStandard(t *testing.T) { pastMedianTime := time.Now() for _, test := range tests { // Ensure standardness is as expected. - err := checkTransactionStandard(util.NewTx(&test.tx), + err := checkTransactionStandard(util.NewTx(test.tx), test.height, pastMedianTime, &Policy{MinRelayTxFee: DefaultMinRelayTxFee, MaxTxVersion: 1}) if err == nil && test.isStandard { // Test passes since function returned standard for a diff --git a/mining/mining.go b/mining/mining.go index b0cf8c31f..812eacf22 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -245,20 +245,19 @@ func CreateCoinbaseTx(params *dagconfig.Params, coinbaseScript []byte, nextBlock } } - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ // Coinbase transactions have no inputs, so previous outpoint is // zero hash and max index. PreviousOutPoint: *wire.NewOutPoint(&daghash.TxID{}, wire.MaxPrevOutIndex), SignatureScript: coinbaseScript, Sequence: wire.MaxTxInSequenceNum, - }) - tx.AddTxOut(&wire.TxOut{ + } + txOut := &wire.TxOut{ Value: blockdag.CalcBlockSubsidy(nextBlockHeight, params), PkScript: pkScript, - }) - return util.NewTx(tx), nil + } + return util.NewTx(wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut})), nil } // MinimumMedianTime returns the minimum allowed timestamp for a block building diff --git a/mining/mining_test.go b/mining/mining_test.go index 91360e7f1..4f02fcf44 100644 --- a/mining/mining_test.go +++ b/mining/mining_test.go @@ -198,87 +198,81 @@ func TestNewBlockTemplate(t *testing.T) { template1CbTx := template1.Block.Transactions[0] // tx is a regular transaction, and should not be filtered by the miner - tx := wire.NewMsgTx(wire.TxVersion) - tx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ PreviousOutPoint: wire.OutPoint{ TxID: template1CbTx.TxID(), Index: 0, }, Sequence: wire.MaxTxInSequenceNum, - }) - tx.AddTxOut(&wire.TxOut{ + } + txOut := &wire.TxOut{ PkScript: pkScript, Value: 1, - }) + } + tx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) // We want to check that the miner filters non finalized transactions - nonFinalizedTx := wire.NewMsgTx(wire.TxVersion) - nonFinalizedTx.LockTime = uint64(dag.Height() + 2) - nonFinalizedTx.AddTxIn(&wire.TxIn{ + txIn = &wire.TxIn{ PreviousOutPoint: wire.OutPoint{ TxID: template1CbTx.TxID(), Index: 1, }, Sequence: 0, - }) - nonFinalizedTx.AddTxOut(&wire.TxOut{ + } + txOut = &wire.TxOut{ PkScript: pkScript, Value: 1, - }) + } + nonFinalizedTx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) + nonFinalizedTx.LockTime = uint64(dag.Height() + 2) - existingSubnetwork := subnetworkid.SubnetworkID{0xff} - nonExistingSubnetwork := subnetworkid.SubnetworkID{0xfe} + existingSubnetwork := &subnetworkid.SubnetworkID{0xff} + nonExistingSubnetwork := &subnetworkid.SubnetworkID{0xfe} // We want to check that the miner filters transactions with non-existing subnetwork id. (It should first push it to the priority queue, and then ignore it) - nonExistingSubnetworkTx := wire.NewMsgTx(wire.TxVersion) - nonExistingSubnetworkTx.SubnetworkID = nonExistingSubnetwork - nonExistingSubnetworkTx.Gas = 1 - nonExistingSubnetworkTx.PayloadHash = daghash.DoubleHashP(nonExistingSubnetworkTx.Payload) - nonExistingSubnetworkTx.AddTxIn(&wire.TxIn{ + txIn = &wire.TxIn{ PreviousOutPoint: wire.OutPoint{ TxID: template1CbTx.TxID(), Index: 2, }, Sequence: 0, - }) - nonExistingSubnetworkTx.AddTxOut(&wire.TxOut{ + } + txOut = &wire.TxOut{ PkScript: pkScript, Value: 1, - }) + } + nonExistingSubnetworkTx := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}, + nonExistingSubnetwork, 1, []byte{}) // We want to check that the miner doesn't filters transactions that do not exceed the subnetwork gas limit - subnetworkTx1 := wire.NewMsgTx(wire.TxVersion) - subnetworkTx1.SubnetworkID = existingSubnetwork - subnetworkTx1.Gas = 1 - subnetworkTx1.PayloadHash = daghash.DoubleHashP(subnetworkTx1.Payload) - subnetworkTx1.AddTxIn(&wire.TxIn{ + txIn = &wire.TxIn{ PreviousOutPoint: wire.OutPoint{ TxID: template1CbTx.TxID(), Index: 3, }, Sequence: 0, - }) - subnetworkTx1.AddTxOut(&wire.TxOut{ + } + txOut = &wire.TxOut{ PkScript: pkScript, Value: 1, - }) + } + subnetworkTx1 := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}, existingSubnetwork, 1, []byte{}) // We want to check that the miner filters transactions that exceed the subnetwork gas limit. (It should first push it to the priority queue, and then ignore it) - subnetworkTx2 := wire.NewMsgTx(wire.TxVersion) - subnetworkTx2.SubnetworkID = existingSubnetwork - subnetworkTx2.Gas = 100 // Subnetwork gas limit is 90 - subnetworkTx2.PayloadHash = daghash.DoubleHashP(subnetworkTx2.Payload) - subnetworkTx2.AddTxIn(&wire.TxIn{ + txIn = &wire.TxIn{ PreviousOutPoint: wire.OutPoint{ TxID: template1CbTx.TxID(), Index: 4, }, Sequence: 0, - }) - subnetworkTx2.AddTxOut(&wire.TxOut{ + } + txOut = &wire.TxOut{ PkScript: pkScript, Value: 1, - }) + } + subnetworkTx2 := wire.NewSubnetworkMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}, existingSubnetwork, + 100, // Subnetwork gas limit is 90 + []byte{}) txSource.txDescs = []*TxDesc{ { @@ -345,7 +339,7 @@ func TestNewBlockTemplate(t *testing.T) { // Here we define nonExistingSubnetwork to be non-exist, and existingSubnetwork to have a gas limit of 90 gasLimitPatch := monkey.Patch((*blockdag.SubnetworkStore).GasLimit, func(_ *blockdag.SubnetworkStore, subnetworkID *subnetworkid.SubnetworkID) (uint64, error) { - if *subnetworkID == nonExistingSubnetwork { + if subnetworkID.IsEqual(nonExistingSubnetwork) { return 0, errors.New("not found") } return 90, nil diff --git a/mining/policy_test.go b/mining/policy_test.go index bdb50f936..dd62a54b6 100644 --- a/mining/policy_test.go +++ b/mining/policy_test.go @@ -83,10 +83,7 @@ func createTransaction(value uint64, originTx *wire.MsgTx, originTxoutputIndex u return privKey, true, nil } - tx := wire.NewMsgTx(wire.TxVersion) - - tx.AddTxIn(createTxIn(originTx, originTxoutputIndex)) - + txIn := createTxIn(originTx, originTxoutputIndex) pkScript, err := txscript.PayToAddrScript(addr) if err != nil { fmt.Println(err) @@ -94,7 +91,9 @@ func createTransaction(value uint64, originTx *wire.MsgTx, originTxoutputIndex u } txOut := wire.NewTxOut(value, pkScript) - tx.AddTxOut(txOut) + + tx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) + if sigScript == nil { sigScript, err = txscript.SignTxOutput(&dagconfig.MainNetParams, tx, 0, originTx.TxOut[0].PkScript, txscript.SigHashAll, diff --git a/peer/peer_test.go b/peer/peer_test.go index d97f1e25b..fc5178c82 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -502,7 +502,7 @@ func TestPeerListeners(t *testing.T) { }, { "OnTx", - wire.NewMsgTx(wire.TxVersion), + wire.NewNativeMsgTx(wire.TxVersion, nil, nil), }, { "OnBlock", diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index 3c16c30e0..fa420d0ba 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -544,9 +544,9 @@ func handleCreateRawTransaction(s *Server, cmd interface{}, closeChan <-chan str } } + txIns := []*wire.TxIn{} // Add all transaction inputs to a new transaction after performing // some validity checks. - mtx := wire.NewMsgTx(wire.TxVersion) for _, input := range c.Inputs { txID, err := daghash.NewTxIDFromStr(input.TxID) if err != nil { @@ -558,8 +558,9 @@ func handleCreateRawTransaction(s *Server, cmd interface{}, closeChan <-chan str if c.LockTime != nil && *c.LockTime != 0 { txIn.Sequence = wire.MaxTxInSequenceNum - 1 } - mtx.AddTxIn(txIn) + txIns = append(txIns, txIn) } + mtx := wire.NewNativeMsgTx(wire.TxVersion, txIns, nil) // Add all transaction outputs to the transaction after performing // some validity checks. diff --git a/txscript/engine_test.go b/txscript/engine_test.go index 442d63d97..ebae8a78a 100644 --- a/txscript/engine_test.go +++ b/txscript/engine_test.go @@ -25,33 +25,30 @@ func TestBadPC(t *testing.T) { } // tx with almost empty scripts. - tx := &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID([32]byte{ - 0xc9, 0x97, 0xa5, 0xe5, - 0x6e, 0x10, 0x41, 0x02, - 0xfa, 0x20, 0x9c, 0x6a, - 0x85, 0x2d, 0xd9, 0x06, - 0x60, 0xa2, 0x0b, 0x2d, - 0x9c, 0x35, 0x24, 0x23, - 0xed, 0xce, 0x25, 0x85, - 0x7f, 0xcd, 0x37, 0x04, - }), - Index: 0, - }, - SignatureScript: mustParseShortForm(""), - Sequence: 4294967295, + txIns := []*wire.TxIn{ + { + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID([32]byte{ + 0xc9, 0x97, 0xa5, 0xe5, + 0x6e, 0x10, 0x41, 0x02, + 0xfa, 0x20, 0x9c, 0x6a, + 0x85, 0x2d, 0xd9, 0x06, + 0x60, 0xa2, 0x0b, 0x2d, + 0x9c, 0x35, 0x24, 0x23, + 0xed, 0xce, 0x25, 0x85, + 0x7f, 0xcd, 0x37, 0x04, + }), + Index: 0, }, + SignatureScript: mustParseShortForm(""), + Sequence: 4294967295, }, - TxOut: []*wire.TxOut{{ - Value: 1000000000, - PkScript: nil, - }}, - LockTime: 0, } + txOuts := []*wire.TxOut{{ + Value: 1000000000, + PkScript: nil, + }} + tx := wire.NewNativeMsgTx(1, txIns, txOuts) pkScript := mustParseShortForm("NOP") for _, test := range tests { @@ -99,31 +96,29 @@ func TestCheckErrorCondition(t *testing.T) { for i, test := range tests { func() { - tx := &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID([32]byte{ - 0xc9, 0x97, 0xa5, 0xe5, - 0x6e, 0x10, 0x41, 0x02, - 0xfa, 0x20, 0x9c, 0x6a, - 0x85, 0x2d, 0xd9, 0x06, - 0x60, 0xa2, 0x0b, 0x2d, - 0x9c, 0x35, 0x24, 0x23, - 0xed, 0xce, 0x25, 0x85, - 0x7f, 0xcd, 0x37, 0x04, - }), - Index: 0, - }, - SignatureScript: nil, - Sequence: 4294967295, - }}, - TxOut: []*wire.TxOut{{ - Value: 1000000000, - PkScript: nil, - }}, - LockTime: 0, - } + txIns := []*wire.TxIn{{ + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID([32]byte{ + 0xc9, 0x97, 0xa5, 0xe5, + 0x6e, 0x10, 0x41, 0x02, + 0xfa, 0x20, 0x9c, 0x6a, + 0x85, 0x2d, 0xd9, 0x06, + 0x60, 0xa2, 0x0b, 0x2d, + 0x9c, 0x35, 0x24, 0x23, + 0xed, 0xce, 0x25, 0x85, + 0x7f, 0xcd, 0x37, 0x04, + }), + Index: 0, + }, + SignatureScript: nil, + Sequence: 4294967295, + }} + txOuts := []*wire.TxOut{{ + Value: 1000000000, + PkScript: nil, + }} + tx := wire.NewNativeMsgTx(1, txIns, txOuts) + pkScript := mustParseShortForm(test.script) vm, err := NewEngine(pkScript, tx, 0, 0, nil) @@ -396,31 +391,29 @@ func TestDisasmPC(t *testing.T) { t.Parallel() // tx with almost empty scripts. - tx := &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID([32]byte{ - 0xc9, 0x97, 0xa5, 0xe5, - 0x6e, 0x10, 0x41, 0x02, - 0xfa, 0x20, 0x9c, 0x6a, - 0x85, 0x2d, 0xd9, 0x06, - 0x60, 0xa2, 0x0b, 0x2d, - 0x9c, 0x35, 0x24, 0x23, - 0xed, 0xce, 0x25, 0x85, - 0x7f, 0xcd, 0x37, 0x04, - }), - Index: 0, - }, - SignatureScript: mustParseShortForm("OP_2"), - Sequence: 4294967295, - }}, - TxOut: []*wire.TxOut{{ - Value: 1000000000, - PkScript: nil, - }}, - LockTime: 0, - } + txIns := []*wire.TxIn{{ + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID([32]byte{ + 0xc9, 0x97, 0xa5, 0xe5, + 0x6e, 0x10, 0x41, 0x02, + 0xfa, 0x20, 0x9c, 0x6a, + 0x85, 0x2d, 0xd9, 0x06, + 0x60, 0xa2, 0x0b, 0x2d, + 0x9c, 0x35, 0x24, 0x23, + 0xed, 0xce, 0x25, 0x85, + 0x7f, 0xcd, 0x37, 0x04, + }), + Index: 0, + }, + SignatureScript: mustParseShortForm("OP_2"), + Sequence: 4294967295, + }} + txOuts := []*wire.TxOut{{ + Value: 1000000000, + PkScript: nil, + }} + tx := wire.NewNativeMsgTx(1, txIns, txOuts) + pkScript := mustParseShortForm("OP_DROP NOP TRUE") vm, err := NewEngine(pkScript, tx, 0, 0, nil) @@ -458,31 +451,28 @@ func TestDisasmScript(t *testing.T) { t.Parallel() // tx with almost empty scripts. - tx := &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{{ - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID([32]byte{ - 0xc9, 0x97, 0xa5, 0xe5, - 0x6e, 0x10, 0x41, 0x02, - 0xfa, 0x20, 0x9c, 0x6a, - 0x85, 0x2d, 0xd9, 0x06, - 0x60, 0xa2, 0x0b, 0x2d, - 0x9c, 0x35, 0x24, 0x23, - 0xed, 0xce, 0x25, 0x85, - 0x7f, 0xcd, 0x37, 0x04, - }), - Index: 0, - }, - SignatureScript: mustParseShortForm("OP_2"), - Sequence: 4294967295, - }}, - TxOut: []*wire.TxOut{{ - Value: 1000000000, - PkScript: nil, - }}, - LockTime: 0, - } + txIns := []*wire.TxIn{{ + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID([32]byte{ + 0xc9, 0x97, 0xa5, 0xe5, + 0x6e, 0x10, 0x41, 0x02, + 0xfa, 0x20, 0x9c, 0x6a, + 0x85, 0x2d, 0xd9, 0x06, + 0x60, 0xa2, 0x0b, 0x2d, + 0x9c, 0x35, 0x24, 0x23, + 0xed, 0xce, 0x25, 0x85, + 0x7f, 0xcd, 0x37, 0x04, + }), + Index: 0, + }, + SignatureScript: mustParseShortForm("OP_2"), + Sequence: 4294967295, + }} + txOuts := []*wire.TxOut{{ + Value: 1000000000, + PkScript: nil, + }} + tx := wire.NewNativeMsgTx(1, txIns, txOuts) pkScript := mustParseShortForm("OP_DROP NOP TRUE") vm, err := NewEngine(pkScript, tx, 0, 0, nil) diff --git a/txscript/example_test.go b/txscript/example_test.go index 0e57146af..9f0d465e1 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -100,33 +100,30 @@ func ExampleSignTxOutput() { // For this example, create a fake transaction that represents what // would ordinarily be the real transaction that is being spent. It // contains a single output that pays to address in the amount of 1 BTC. - originTx := wire.NewMsgTx(wire.TxVersion) prevOut := wire.NewOutPoint(&daghash.TxID{}, ^uint32(0)) txIn := wire.NewTxIn(prevOut, []byte{txscript.Op0, txscript.Op0}) - originTx.AddTxIn(txIn) pkScript, err := txscript.PayToAddrScript(addr) if err != nil { fmt.Println(err) return } txOut := wire.NewTxOut(100000000, pkScript) - originTx.AddTxOut(txOut) + originTx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) originTxID := originTx.TxID() // Create the transaction to redeem the fake transaction. - redeemTx := wire.NewMsgTx(wire.TxVersion) // Add the input(s) the redeeming transaction will spend. There is no // signature script at this point since it hasn't been created or signed // yet, hence nil is provided for it. prevOut = wire.NewOutPoint(&originTxID, 0) txIn = wire.NewTxIn(prevOut, nil) - redeemTx.AddTxIn(txIn) // Ordinarily this would contain that actual destination of the funds, // but for this example don't bother. txOut = wire.NewTxOut(0, nil) - redeemTx.AddTxOut(txOut) + + redeemTx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) // Sign the redeeming transaction. lookupKey := func(a util.Address) (*btcec.PrivateKey, bool, error) { diff --git a/txscript/reference_test.go b/txscript/reference_test.go index 979838a5b..1badca872 100644 --- a/txscript/reference_test.go +++ b/txscript/reference_test.go @@ -215,22 +215,17 @@ func parseExpectedResult(expected string) ([]ErrorCode, error) { // createSpendTx generates a basic spending transaction given the passed // signature and public key scripts. func createSpendingTx(sigScript, pkScript []byte) *wire.MsgTx { - coinbaseTx := wire.NewMsgTx(wire.TxVersion) outPoint := wire.NewOutPoint(&daghash.TxID{}, ^uint32(0)) txIn := wire.NewTxIn(outPoint, []byte{Op0, Op0}) txOut := wire.NewTxOut(0, pkScript) - coinbaseTx.AddTxIn(txIn) - coinbaseTx.AddTxOut(txOut) + coinbaseTx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) - spendingTx := wire.NewMsgTx(wire.TxVersion) coinbaseTxID := coinbaseTx.TxID() outPoint = wire.NewOutPoint(&coinbaseTxID, 0) txIn = wire.NewTxIn(outPoint, sigScript) txOut = wire.NewTxOut(0, nil) - - spendingTx.AddTxIn(txIn) - spendingTx.AddTxOut(txOut) + spendingTx := wire.NewNativeMsgTx(wire.TxVersion, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}) return spendingTx } diff --git a/txscript/script.go b/txscript/script.go index ea8dac4a5..3d6143d9d 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -256,6 +256,8 @@ func shallowCopyTx(tx *wire.MsgTx) wire.MsgTx { // for the copied inputs and outputs and point the final slice of // pointers into the contiguous arrays. This avoids a lot of small // allocations. + // Specifically avoid using wire.NewMsgTx() to prevent correcting errors by + // auto-generating various fields. txCopy := wire.MsgTx{ Version: tx.Version, TxIn: make([]*wire.TxIn, len(tx.TxIn)), diff --git a/txscript/sign_test.go b/txscript/sign_test.go index 74c166601..72644bc89 100644 --- a/txscript/sign_test.go +++ b/txscript/sign_test.go @@ -13,7 +13,6 @@ import ( "github.com/daglabs/btcd/dagconfig" "github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/util" - "github.com/daglabs/btcd/util/subnetworkid" "github.com/daglabs/btcd/wire" ) @@ -100,45 +99,41 @@ func TestSignTxOutput(t *testing.T) { SigHashNone | SigHashAnyOneCanPay, SigHashSingle | SigHashAnyOneCanPay, } - tx := &wire.MsgTx{ - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID{}, - Index: 0, - }, - Sequence: 4294967295, - }, - { - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID{}, - Index: 1, - }, - Sequence: 4294967295, - }, - { - PreviousOutPoint: wire.OutPoint{ - TxID: daghash.TxID{}, - Index: 2, - }, - Sequence: 4294967295, + txIns := []*wire.TxIn{ + { + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID{}, + Index: 0, }, + Sequence: 4294967295, }, - TxOut: []*wire.TxOut{ - { - Value: 1, - }, - { - Value: 2, - }, - { - Value: 3, + { + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID{}, + Index: 1, }, + Sequence: 4294967295, + }, + { + PreviousOutPoint: wire.OutPoint{ + TxID: daghash.TxID{}, + Index: 2, + }, + Sequence: 4294967295, }, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, } + txOuts := []*wire.TxOut{ + { + Value: 1, + }, + { + Value: 2, + }, + { + Value: 3, + }, + } + tx := wire.NewNativeMsgTx(1, txIns, txOuts) // Pay to Pubkey Hash (uncompressed) for _, hashType := range hashTypes { @@ -1622,15 +1617,13 @@ func TestSignatureScript(t *testing.T) { nexttest: for i := range sigScriptTests { - tx := wire.NewMsgTx(wire.TxVersion) - - output := wire.NewTxOut(500, []byte{OpReturn}) - tx.AddTxOut(output) + txOuts := []*wire.TxOut{wire.NewTxOut(500, []byte{OpReturn})} + txIns := []*wire.TxIn{} for range sigScriptTests[i].inputs { - txin := wire.NewTxIn(coinbaseOutPoint, nil) - tx.AddTxIn(txin) + txIns = append(txIns, wire.NewTxIn(coinbaseOutPoint, nil)) } + tx := wire.NewNativeMsgTx(wire.TxVersion, txIns, txOuts) var script []byte var err error diff --git a/util/coinset/coins.go b/util/coinset/coins.go index b57dc9904..e39206a56 100644 --- a/util/coinset/coins.go +++ b/util/coinset/coins.go @@ -126,11 +126,10 @@ func (cs *CoinSet) removeElement(e *list.Element) Coin { // NewMsgTxWithInputCoins takes the coins in the CoinSet and makes them // the inputs to a new wire.MsgTx which is returned. func NewMsgTxWithInputCoins(txVersion int32, inputCoins Coins) *wire.MsgTx { - msgTx := wire.NewMsgTx(txVersion) coins := inputCoins.Coins() - msgTx.TxIn = make([]*wire.TxIn, len(coins)) + txIn := make([]*wire.TxIn, len(coins)) for i, coin := range coins { - msgTx.TxIn[i] = &wire.TxIn{ + txIn[i] = &wire.TxIn{ PreviousOutPoint: wire.OutPoint{ TxID: *coin.ID(), Index: coin.Index(), @@ -139,6 +138,7 @@ func NewMsgTxWithInputCoins(txVersion int32, inputCoins Coins) *wire.MsgTx { Sequence: wire.MaxTxInSequenceNum, } } + msgTx := wire.NewNativeMsgTx(txVersion, txIn, nil) return msgTx } diff --git a/util/testtools/testtools.go b/util/testtools/testtools.go index 8ffdaf5c7..cccd88dea 100644 --- a/util/testtools/testtools.go +++ b/util/testtools/testtools.go @@ -1,7 +1,6 @@ package testtools import ( - "encoding/binary" "fmt" "github.com/daglabs/btcd/dagconfig" @@ -55,19 +54,15 @@ func RegisterSubnetworkForTest(dag *blockdag.BlockDAG, params *dagconfig.Params, fundsBlockCbTxID := fundsBlockCbTx.TxID() // Create a block with a valid subnetwork registry transaction - registryTx := wire.NewMsgTx(wire.TxVersion) - registryTx.AddTxIn(&wire.TxIn{ + txIn := &wire.TxIn{ PreviousOutPoint: *wire.NewOutPoint(&fundsBlockCbTxID, 0), Sequence: wire.MaxTxInSequenceNum, - }) - registryTx.AddTxOut(&wire.TxOut{ + } + txOut := &wire.TxOut{ PkScript: blockdag.OpTrueScript, Value: fundsBlockCbTx.TxOut[0].Value, - }) - registryTx.SubnetworkID = *subnetworkid.SubnetworkIDRegistry - registryTx.Payload = make([]byte, 8) - binary.LittleEndian.PutUint64(registryTx.Payload, gasLimit) - registryTx.PayloadHash = daghash.DoubleHashP(registryTx.Payload) + } + registryTx := wire.NewRegistryMsgTx(1, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}, gasLimit) // Add it to the DAG registryBlock, err := buildNextBlock([]daghash.Hash{*fundsBlock.Hash()}, []*wire.MsgTx{registryTx}) diff --git a/wire/bench_test.go b/wire/bench_test.go index 0b181da2d..30faf7641 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -19,47 +19,44 @@ import ( // genesisCoinbaseTx is the coinbase transaction for the genesis blocks for // the main network, regression test network, and test network (version 3). -var genesisCoinbaseTx = MsgTx{ - Version: 1, - TxIn: []*TxIn{ - { - PreviousOutPoint: OutPoint{ - TxID: daghash.TxID{}, - Index: 0xffffffff, - }, - SignatureScript: []byte{ - 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */ - 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */ - 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */ - 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */ - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */ - 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */ - 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/ - 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */ - 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ - 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ - }, - Sequence: math.MaxUint64, +var genesisCoinbaseTxIns = []*TxIn{ + { + PreviousOutPoint: OutPoint{ + TxID: daghash.TxID{}, + Index: 0xffffffff, }, - }, - TxOut: []*TxOut{ - { - Value: 0x12a05f200, - PkScript: []byte{ - 0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */ - 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */ - 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */ - 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */ - 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */ - 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */ - 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */ - 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */ - 0x1d, 0x5f, 0xac, /* |._.| */ - }, + SignatureScript: []byte{ + 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */ + 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */ + 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */ + 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */ + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */ + 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */ + 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/ + 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */ + 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ + 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ }, + Sequence: math.MaxUint64, }, - LockTime: 0, } +var genesisCoinbaseTxOuts = []*TxOut{ + { + Value: 0x12a05f200, + PkScript: []byte{ + 0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */ + 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */ + 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */ + 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */ + 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */ + 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */ + 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */ + 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */ + 0x1d, 0x5f, 0xac, /* |._.| */ + }, + }, +} +var genesisCoinbaseTx = NewNativeMsgTx(1, genesisCoinbaseTxIns, genesisCoinbaseTxOuts) // BenchmarkWriteVarInt1 performs a benchmark on how long it takes to write // a single byte variable length integer. diff --git a/wire/message_test.go b/wire/message_test.go index 54d8572ff..6ef325032 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -57,7 +57,7 @@ func TestMessage(t *testing.T) { msgInv := NewMsgInv() msgGetData := NewMsgGetData() msgNotFound := NewMsgNotFound() - msgTx := NewMsgTx(1) + msgTx := NewNativeMsgTx(1, nil, nil) msgPing := NewMsgPing(123123) msgPong := NewMsgPong(123123) msgGetHeaders := NewMsgGetHeaders() diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index 9dd3a5d07..c9543fb72 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -90,27 +90,27 @@ func TestBlockHash(t *testing.T) { func TestConvertToPartial(t *testing.T) { transactions := []struct { - subnetworkID subnetworkid.SubnetworkID + subnetworkID *subnetworkid.SubnetworkID payload []byte expectedPayloadLength int }{ { - subnetworkID: *subnetworkid.SubnetworkIDNative, + subnetworkID: subnetworkid.SubnetworkIDNative, payload: []byte{}, expectedPayloadLength: 0, }, { - subnetworkID: *subnetworkid.SubnetworkIDRegistry, + subnetworkID: subnetworkid.SubnetworkIDRegistry, payload: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, expectedPayloadLength: 0, }, { - subnetworkID: subnetworkid.SubnetworkID{123}, + subnetworkID: &subnetworkid.SubnetworkID{123}, payload: []byte{0x01}, expectedPayloadLength: 1, }, { - subnetworkID: subnetworkid.SubnetworkID{234}, + subnetworkID: &subnetworkid.SubnetworkID{234}, payload: []byte{0x02}, expectedPayloadLength: 0, }, @@ -119,11 +119,7 @@ func TestConvertToPartial(t *testing.T) { block := MsgBlock{} payload := []byte{1} for _, transaction := range transactions { - block.Transactions = append(block.Transactions, &MsgTx{ - SubnetworkID: transaction.subnetworkID, - Payload: payload, - PayloadHash: daghash.DoubleHashP(payload), - }) + block.Transactions = append(block.Transactions, NewSubnetworkMsgTx(1, nil, nil, transaction.subnetworkID, 0, payload)) } block.ConvertToPartial(&subnetworkid.SubnetworkID{123}) @@ -131,7 +127,7 @@ func TestConvertToPartial(t *testing.T) { for _, transaction := range transactions { var subnetworkTx *MsgTx for _, tx := range block.Transactions { - if tx.SubnetworkID.IsEqual(&transaction.subnetworkID) { + if tx.SubnetworkID.IsEqual(transaction.subnetworkID) { subnetworkTx = tx } } @@ -507,9 +503,8 @@ var blockOne = MsgBlock{ Nonce: 0x9962e301, // 2573394689 }, Transactions: []*MsgTx{ - { - Version: 1, - TxIn: []*TxIn{ + NewNativeMsgTx(1, + []*TxIn{ { PreviousOutPoint: OutPoint{ TxID: daghash.TxID{}, @@ -521,7 +516,7 @@ var blockOne = MsgBlock{ Sequence: math.MaxUint64, }, }, - TxOut: []*TxOut{ + []*TxOut{ { Value: 0x12a05f200, PkScript: []byte{ @@ -538,10 +533,7 @@ var blockOne = MsgBlock{ 0xac, // OP_CHECKSIG }, }, - }, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, - }, + }), }, } diff --git a/wire/msgtx.go b/wire/msgtx.go index 52fd57091..02f8ed7b3 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -685,7 +685,7 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err if !msg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) { if msg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDRegistry) && msg.Gas != 0 { - str := fmt.Sprintf("Transactions from subnetwork %s should have 0 gas", msg.SubnetworkID) + str := "Transactions from registry subnetwork should have 0 gas" return messageError("MsgTx.BtcEncode", str) } @@ -709,13 +709,13 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err return err } } else if msg.Payload != nil { - str := fmt.Sprintf("Transactions from subnetwork %s should have payload", msg.SubnetworkID) + str := "Transactions from native subnetwork should have payload" return messageError("MsgTx.BtcEncode", str) } else if msg.PayloadHash != nil { - str := fmt.Sprintf("Transactions from subnetwork %s should have payload hash", msg.SubnetworkID) + str := "Transactions from native subnetwork should have payload hash" return messageError("MsgTx.BtcEncode", str) } else if msg.Gas != 0 { - str := fmt.Sprintf("Transactions from subnetwork %s should have 0 gas", msg.SubnetworkID) + str := "Transactions from native subnetwork should have 0 gas" return messageError("MsgTx.BtcEncode", str) } @@ -848,27 +848,68 @@ func (msg *MsgTx) IsSubnetworkCompatible(subnetworkID *subnetworkid.SubnetworkID subnetworkID.IsEqual(&msg.SubnetworkID) } -// NewMsgTx returns a new bitcoin tx message that conforms to the Message -// interface. The return instance has a default version of TxVersion and there -// are no transaction inputs or outputs. Also, the lock time is set to zero -// to indicate the transaction is valid immediately as opposed to some time in -// future. -func NewMsgTx(version int32) *MsgTx { +// newMsgTx returns a new tx message that conforms to the Message interface. +// +// All fields except version and gas has default values if nil is passed: +// txIn, txOut - empty arrays +// payload - an empty payload +// +// The payload hash is calculated automatically according to provided payload. +// Also, the lock time is set to zero to indicate the transaction is valid +// immediately as opposed to some time in future. +func newMsgTx(version int32, txIn []*TxIn, txOut []*TxOut, subnetworkID *subnetworkid.SubnetworkID, + gas uint64, payload []byte, lockTime uint64) *MsgTx { + + if txIn == nil { + txIn = make([]*TxIn, 0, defaultTxInOutAlloc) + } + + if txOut == nil { + txOut = make([]*TxOut, 0, defaultTxInOutAlloc) + } + + var payloadHash *daghash.Hash + if !subnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) { + payloadHash = daghash.DoubleHashP(payload) + } + return &MsgTx{ Version: version, - TxIn: make([]*TxIn, 0, defaultTxInOutAlloc), - TxOut: make([]*TxOut, 0, defaultTxInOutAlloc), - SubnetworkID: *subnetworkid.SubnetworkIDNative, + TxIn: txIn, + TxOut: txOut, + SubnetworkID: *subnetworkID, + Gas: gas, + PayloadHash: payloadHash, + Payload: payload, + LockTime: lockTime, } } -func newRegistryMsgTx(version int32, gasLimit uint64) *MsgTx { - tx := NewMsgTx(version) - tx.SubnetworkID = *subnetworkid.SubnetworkIDRegistry - tx.Payload = make([]byte, 8) - tx.PayloadHash = daghash.DoubleHashP(tx.Payload) - binary.LittleEndian.PutUint64(tx.Payload, gasLimit) - return tx +// NewNativeMsgTx returns a new tx message in the native subnetwork +func NewNativeMsgTx(version int32, txIn []*TxIn, txOut []*TxOut) *MsgTx { + return newMsgTx(version, txIn, txOut, subnetworkid.SubnetworkIDNative, 0, nil, 0) +} + +// NewSubnetworkMsgTx returns a new tx message in the specified subnetwork with specified gas and payload +func NewSubnetworkMsgTx(version int32, txIn []*TxIn, txOut []*TxOut, subnetworkID *subnetworkid.SubnetworkID, + gas uint64, payload []byte) *MsgTx { + + return newMsgTx(version, txIn, txOut, subnetworkID, gas, payload, 0) +} + +// NewNativeMsgTxWithLocktime returns a new tx message in the native subnetwork with a locktime. +// +// See newMsgTx for further documntation of the parameters +func NewNativeMsgTxWithLocktime(version int32, txIn []*TxIn, txOut []*TxOut, locktime uint64) *MsgTx { + return newMsgTx(version, txIn, txOut, subnetworkid.SubnetworkIDNative, 0, nil, locktime) +} + +// NewRegistryMsgTx creates a new MsgTx that registers a new subnetwork +func NewRegistryMsgTx(version int32, txIn []*TxIn, txOut []*TxOut, gasLimit uint64) *MsgTx { + payload := make([]byte, 8) + binary.LittleEndian.PutUint64(payload, gasLimit) + + return NewSubnetworkMsgTx(version, txIn, txOut, subnetworkid.SubnetworkIDRegistry, 0, payload) } // readOutPoint reads the next sequence of bytes from r as an OutPoint. diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index e002aac7f..3bdf3f118 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -30,7 +30,7 @@ func TestTx(t *testing.T) { // Ensure the command is expected value. wantCmd := "tx" - msg := NewMsgTx(1) + msg := NewNativeMsgTx(1, nil, nil) if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgAddr: wrong command - got %v want %v", cmd, wantCmd) @@ -137,8 +137,7 @@ func TestTxHashAndID(t *testing.T) { } // First transaction from block 113875. - tx1 := NewMsgTx(1) - txIn := TxIn{ + txIn := &TxIn{ PreviousOutPoint: OutPoint{ TxID: daghash.TxID{}, Index: 0xffffffff, @@ -146,7 +145,7 @@ func TestTxHashAndID(t *testing.T) { SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}, Sequence: math.MaxUint64, } - txOut := TxOut{ + txOut := &TxOut{ Value: 5000000000, PkScript: []byte{ 0x41, // OP_DATA_65 @@ -162,9 +161,7 @@ func TestTxHashAndID(t *testing.T) { 0xac, // OP_CHECKSIG }, } - tx1.AddTxIn(&txIn) - tx1.AddTxOut(&txOut) - tx1.LockTime = 0 + tx1 := NewNativeMsgTx(1, []*TxIn{txIn}, []*TxOut{txOut}) // Ensure the hash produced is expected. tx1Hash := tx1.TxHash() @@ -194,49 +191,41 @@ func TestTxHashAndID(t *testing.T) { return } payload := []byte{1, 2, 3} - tx2 := &MsgTx{ - Version: 1, - TxIn: []*TxIn{ - { - PreviousOutPoint: OutPoint{ - Index: 0, - TxID: daghash.TxID{1, 2, 3}, - }, - SignatureScript: []byte{ - 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xDA, 0x0D, 0xC6, 0xAE, 0xCE, 0xFE, 0x1E, 0x06, 0xEF, 0xDF, - 0x05, 0x77, 0x37, 0x57, 0xDE, 0xB1, 0x68, 0x82, 0x09, 0x30, 0xE3, 0xB0, 0xD0, 0x3F, 0x46, 0xF5, - 0xFC, 0xF1, 0x50, 0xBF, 0x99, 0x0C, 0x02, 0x21, 0x00, 0xD2, 0x5B, 0x5C, 0x87, 0x04, 0x00, 0x76, - 0xE4, 0xF2, 0x53, 0xF8, 0x26, 0x2E, 0x76, 0x3E, 0x2D, 0xD5, 0x1E, 0x7F, 0xF0, 0xBE, 0x15, 0x77, - 0x27, 0xC4, 0xBC, 0x42, 0x80, 0x7F, 0x17, 0xBD, 0x39, 0x01, 0x41, 0x04, 0xE6, 0xC2, 0x6E, 0xF6, - 0x7D, 0xC6, 0x10, 0xD2, 0xCD, 0x19, 0x24, 0x84, 0x78, 0x9A, 0x6C, 0xF9, 0xAE, 0xA9, 0x93, 0x0B, - 0x94, 0x4B, 0x7E, 0x2D, 0xB5, 0x34, 0x2B, 0x9D, 0x9E, 0x5B, 0x9F, 0xF7, 0x9A, 0xFF, 0x9A, 0x2E, - 0xE1, 0x97, 0x8D, 0xD7, 0xFD, 0x01, 0xDF, 0xC5, 0x22, 0xEE, 0x02, 0x28, 0x3D, 0x3B, 0x06, 0xA9, - 0xD0, 0x3A, 0xCF, 0x80, 0x96, 0x96, 0x8D, 0x7D, 0xBB, 0x0F, 0x91, 0x78, - }, - Sequence: math.MaxUint64, + txIns := []*TxIn{&TxIn{ + PreviousOutPoint: OutPoint{ + Index: 0, + TxID: daghash.TxID{1, 2, 3}, + }, + SignatureScript: []byte{ + 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xDA, 0x0D, 0xC6, 0xAE, 0xCE, 0xFE, 0x1E, 0x06, 0xEF, 0xDF, + 0x05, 0x77, 0x37, 0x57, 0xDE, 0xB1, 0x68, 0x82, 0x09, 0x30, 0xE3, 0xB0, 0xD0, 0x3F, 0x46, 0xF5, + 0xFC, 0xF1, 0x50, 0xBF, 0x99, 0x0C, 0x02, 0x21, 0x00, 0xD2, 0x5B, 0x5C, 0x87, 0x04, 0x00, 0x76, + 0xE4, 0xF2, 0x53, 0xF8, 0x26, 0x2E, 0x76, 0x3E, 0x2D, 0xD5, 0x1E, 0x7F, 0xF0, 0xBE, 0x15, 0x77, + 0x27, 0xC4, 0xBC, 0x42, 0x80, 0x7F, 0x17, 0xBD, 0x39, 0x01, 0x41, 0x04, 0xE6, 0xC2, 0x6E, 0xF6, + 0x7D, 0xC6, 0x10, 0xD2, 0xCD, 0x19, 0x24, 0x84, 0x78, 0x9A, 0x6C, 0xF9, 0xAE, 0xA9, 0x93, 0x0B, + 0x94, 0x4B, 0x7E, 0x2D, 0xB5, 0x34, 0x2B, 0x9D, 0x9E, 0x5B, 0x9F, 0xF7, 0x9A, 0xFF, 0x9A, 0x2E, + 0xE1, 0x97, 0x8D, 0xD7, 0xFD, 0x01, 0xDF, 0xC5, 0x22, 0xEE, 0x02, 0x28, 0x3D, 0x3B, 0x06, 0xA9, + 0xD0, 0x3A, 0xCF, 0x80, 0x96, 0x96, 0x8D, 0x7D, 0xBB, 0x0F, 0x91, 0x78, + }, + Sequence: math.MaxUint64, + }} + txOuts := []*TxOut{ + { + Value: 244623243, + PkScript: []byte{ + 0x76, 0xA9, 0x14, 0xBA, 0xDE, 0xEC, 0xFD, 0xEF, 0x05, 0x07, 0x24, 0x7F, 0xC8, 0xF7, 0x42, 0x41, + 0xD7, 0x3B, 0xC0, 0x39, 0x97, 0x2D, 0x7B, 0x88, 0xAC, }, }, - TxOut: []*TxOut{ - { - Value: 244623243, - PkScript: []byte{ - 0x76, 0xA9, 0x14, 0xBA, 0xDE, 0xEC, 0xFD, 0xEF, 0x05, 0x07, 0x24, 0x7F, 0xC8, 0xF7, 0x42, 0x41, - 0xD7, 0x3B, 0xC0, 0x39, 0x97, 0x2D, 0x7B, 0x88, 0xAC, - }, - }, - { - Value: 44602432, - PkScript: []byte{ - 0x76, 0xA9, 0x14, 0xC1, 0x09, 0x32, 0x48, 0x3F, 0xEC, 0x93, 0xED, 0x51, 0xF5, 0xFE, 0x95, 0xE7, - 0x25, 0x59, 0xF2, 0xCC, 0x70, 0x43, 0xF9, 0x88, 0xAC, - }, + { + Value: 44602432, + PkScript: []byte{ + 0x76, 0xA9, 0x14, 0xC1, 0x09, 0x32, 0x48, 0x3F, 0xEC, 0x93, 0xED, 0x51, 0xF5, 0xFE, 0x95, 0xE7, + 0x25, 0x59, 0xF2, 0xCC, 0x70, 0x43, 0xF9, 0x88, 0xAC, }, }, - LockTime: 0, - SubnetworkID: subnetworkid.SubnetworkID{1, 2, 3}, - Payload: payload, - PayloadHash: daghash.DoubleHashP(payload), } + tx2 := NewSubnetworkMsgTx(1, txIns, txOuts, &subnetworkid.SubnetworkID{1, 2, 3}, 0, payload) // Ensure the hash produced is expected. tx2Hash := tx2.TxHash() @@ -268,8 +257,7 @@ func TestTxHashAndID(t *testing.T) { // of transaction inputs and outputs and protocol versions. func TestTxWire(t *testing.T) { // Empty tx message. - noTx := NewMsgTx(1) - noTx.Version = 1 + noTx := NewNativeMsgTx(1, nil, nil) noTxEncoded := []byte{ 0x01, 0x00, 0x00, 0x00, // Version 0x00, // Varint for number of input transactions @@ -398,8 +386,7 @@ func TestTxWireErrors(t *testing.T) { // TestTxSerialize tests MsgTx serialize and deserialize. func TestTxSerialize(t *testing.T) { - noTx := NewMsgTx(1) - noTx.Version = 1 + noTx := NewNativeMsgTx(1, nil, nil) noTxEncoded := []byte{ 0x01, 0x00, 0x00, 0x00, // Version 0x00, // Varint for number of input transactions @@ -410,7 +397,7 @@ func TestTxSerialize(t *testing.T) { 0x00, 0x00, 0x00, 0x00, // Sub Network ID } - registryTx := newRegistryMsgTx(1, 16) + registryTx := NewRegistryMsgTx(1, nil, nil, 16) registryTxEncoded := []byte{ 0x01, 0x00, 0x00, 0x00, // Version 0x00, // Varint for number of input transactions @@ -420,19 +407,15 @@ func TestTxSerialize(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas - 0x7e, 0xf0, 0xca, 0x62, 0x6b, 0xbb, 0x05, 0x8d, - 0xd4, 0x43, 0xbb, 0x78, 0xe3, 0x3b, 0x88, 0x8b, - 0xde, 0xc8, 0x29, 0x5c, 0x96, 0xe5, 0x1f, 0x55, - 0x45, 0xf9, 0x63, 0x70, 0x87, 0x0c, 0x10, 0xb9, // Payload hash + 0x77, 0x56, 0x36, 0xb4, 0x89, 0x32, 0xe9, 0xa8, + 0xbb, 0x67, 0xe6, 0x54, 0x84, 0x36, 0x93, 0x8d, + 0x9f, 0xc5, 0x62, 0x49, 0x79, 0x5c, 0x0d, 0x0a, + 0x86, 0xaf, 0x7c, 0x5d, 0x54, 0x45, 0x4c, 0x4b, // Payload hash 0x08, // Payload length varint 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Payload / Gas limit } - subnetworkTx := NewMsgTx(1) - subnetworkTx.SubnetworkID = subnetworkid.SubnetworkID{0xff} - subnetworkTx.Gas = 5 - subnetworkTx.Payload = []byte{0, 1, 2} - subnetworkTx.PayloadHash = daghash.DoubleHashP(subnetworkTx.Payload) + subnetworkTx := NewSubnetworkMsgTx(1, nil, nil, &subnetworkid.SubnetworkID{0xff}, 5, []byte{0, 1, 2}) subnetworkTxEncoded := []byte{ 0x01, 0x00, 0x00, 0x00, // Version @@ -452,6 +435,7 @@ func TestTxSerialize(t *testing.T) { } tests := []struct { + name string in *MsgTx // Message to encode out *MsgTx // Expected decoded message buf []byte // Serialized data @@ -459,6 +443,7 @@ func TestTxSerialize(t *testing.T) { }{ // No transactions. { + "noTx", noTx, noTx, noTxEncoded, @@ -467,6 +452,7 @@ func TestTxSerialize(t *testing.T) { // Registry Transaction. { + "registryTx", registryTx, registryTx, registryTxEncoded, @@ -475,6 +461,7 @@ func TestTxSerialize(t *testing.T) { // Sub Network Transaction. { + "subnetworkTx", subnetworkTx, subnetworkTx, subnetworkTxEncoded, @@ -483,6 +470,7 @@ func TestTxSerialize(t *testing.T) { // Multiple transactions. { + "multiTx", multiTx, multiTx, multiTxEncoded, @@ -496,11 +484,11 @@ func TestTxSerialize(t *testing.T) { var buf bytes.Buffer err := test.in.Serialize(&buf) if err != nil { - t.Errorf("Serialize #%d error %v", i, err) + t.Errorf("Serialize %s: error %v", test.name, err) continue } if !bytes.Equal(buf.Bytes(), test.buf) { - t.Errorf("Serialize #%d\n got: %s want: %s", i, + t.Errorf("Serialize %s:\n got: %s want: %s", test.name, spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) continue } @@ -598,24 +586,21 @@ func TestTxSerializeErrors(t *testing.T) { } } - registryTx := NewMsgTx(1) - registryTx.SubnetworkID = *subnetworkid.SubnetworkIDRegistry - registryTx.Gas = 1 + registryTx := NewSubnetworkMsgTx(1, nil, nil, subnetworkid.SubnetworkIDRegistry, 1, nil) w := bytes.NewBuffer(make([]byte, 0, registryTx.SerializeSize())) err := registryTx.Serialize(w) - str := fmt.Sprintf("Transactions from subnetwork %v should have 0 gas", subnetworkid.SubnetworkIDRegistry) + str := "Transactions from registry subnetwork should have 0 gas" expectedErr := messageError("MsgTx.BtcEncode", str) if err == nil || err.Error() != expectedErr.Error() { t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err) } - nativeTx := NewMsgTx(1) - nativeTx.Gas = 1 + nativeTx := NewSubnetworkMsgTx(1, nil, nil, subnetworkid.SubnetworkIDNative, 1, nil) w = bytes.NewBuffer(make([]byte, 0, registryTx.SerializeSize())) err = nativeTx.Serialize(w) - str = fmt.Sprintf("Transactions from subnetwork %v should have 0 gas", subnetworkid.SubnetworkIDNative) + str = "Transactions from native subnetwork should have 0 gas" expectedErr = messageError("MsgTx.BtcEncode", str) if err == nil || err.Error() != expectedErr.Error() { t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err) @@ -627,7 +612,7 @@ func TestTxSerializeErrors(t *testing.T) { w = bytes.NewBuffer(make([]byte, 0, registryTx.SerializeSize())) err = nativeTx.Serialize(w) - str = fmt.Sprintf("Transactions from subnetwork %v should have payload", subnetworkid.SubnetworkIDNative) + str = "Transactions from native subnetwork should have payload" expectedErr = messageError("MsgTx.BtcEncode", str) if err == nil || err.Error() != expectedErr.Error() { t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err) @@ -754,8 +739,7 @@ func TestTxOverflowErrors(t *testing.T) { // various transactions is accurate. func TestTxSerializeSize(t *testing.T) { // Empty tx message. - noTx := NewMsgTx(1) - noTx.Version = 1 + noTx := NewNativeMsgTx(1, nil, nil) tests := []struct { in *MsgTx // Tx to encode @@ -780,7 +764,7 @@ func TestTxSerializeSize(t *testing.T) { } func TestIsSubnetworkCompatible(t *testing.T) { - testTx := MsgTx{SubnetworkID: subnetworkid.SubnetworkID{123}} + testTx := NewSubnetworkMsgTx(1, nil, nil, &subnetworkid.SubnetworkID{123}, 0, []byte{}) tests := []struct { name string subnetworkID *subnetworkid.SubnetworkID @@ -887,57 +871,53 @@ func underlyingArrayAddress(buf []byte) uint64 { } // multiTx is a MsgTx with an input and output and used in various tests. -var multiTx = &MsgTx{ - Version: 1, - TxIn: []*TxIn{ - { - PreviousOutPoint: OutPoint{ - TxID: daghash.TxID{}, - Index: 0xffffffff, - }, - SignatureScript: []byte{ - 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, - }, - Sequence: math.MaxUint64, +var multiTxIns = []*TxIn{ + { + PreviousOutPoint: OutPoint{ + TxID: daghash.TxID{}, + Index: 0xffffffff, }, + SignatureScript: []byte{ + 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, + }, + Sequence: math.MaxUint64, }, - TxOut: []*TxOut{ - { - Value: 0x12a05f200, - PkScript: []byte{ - 0x41, // OP_DATA_65 - 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, - 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, - 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, - 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, - 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, - 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, - 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, - 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, - 0xa6, // 65-byte signature - 0xac, // OP_CHECKSIG - }, - }, - { - Value: 0x5f5e100, - PkScript: []byte{ - 0x41, // OP_DATA_65 - 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, - 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, - 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, - 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, - 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, - 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, - 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, - 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, - 0xa6, // 65-byte signature - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - SubnetworkID: *subnetworkid.SubnetworkIDNative, } +var multiTxOuts = []*TxOut{ + { + Value: 0x12a05f200, + PkScript: []byte{ + 0x41, // OP_DATA_65 + 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, + 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, + 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, + 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, + 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, + 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, + 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, + 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, + 0xa6, // 65-byte signature + 0xac, // OP_CHECKSIG + }, + }, + { + Value: 0x5f5e100, + PkScript: []byte{ + 0x41, // OP_DATA_65 + 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, + 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, + 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, + 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, + 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, + 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, + 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, + 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, + 0xa6, // 65-byte signature + 0xac, // OP_CHECKSIG + }, + }, +} +var multiTx = NewNativeMsgTx(1, multiTxIns, multiTxOuts) // multiTxEncoded is the wire encoded bytes for multiTx using protocol version // 60002 and is used in the various tests.