[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
This commit is contained in:
Svarog 2019-03-19 12:28:24 +02:00 committed by Evgeny Khirin
parent 122520b9a5
commit a2b69a84f4
32 changed files with 677 additions and 875 deletions

View File

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

View File

@ -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, &params, []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, &params, []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, &params, 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, &params, 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, &params, dag.TipHashes(), []*wire.MsgTx{nonExistentSubnetworkTx, overflowGasTx}, true, 1)
if err != nil {

View File

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

View File

@ -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()))

View File

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

View File

@ -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

View File

@ -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 <nil>")
@ -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)

View File

@ -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{}
},

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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.

View File

@ -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),
},

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -502,7 +502,7 @@ func TestPeerListeners(t *testing.T) {
},
{
"OnTx",
wire.NewMsgTx(wire.TxVersion),
wire.NewNativeMsgTx(wire.TxVersion, nil, nil),
},
{
"OnBlock",

View File

@ -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.

View File

@ -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)

View File

@ -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) {

View File

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

View File

@ -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)),

View File

@ -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

View File

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

View File

@ -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})

View File

@ -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.

View File

@ -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()

View File

@ -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,
},
}),
},
}

View File

@ -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 <nil> payload", msg.SubnetworkID)
str := "Transactions from native subnetwork should have <nil> payload"
return messageError("MsgTx.BtcEncode", str)
} else if msg.PayloadHash != nil {
str := fmt.Sprintf("Transactions from subnetwork %s should have <nil> payload hash", msg.SubnetworkID)
str := "Transactions from native subnetwork should have <nil> 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.

View File

@ -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 <nil> payload", subnetworkid.SubnetworkIDNative)
str = "Transactions from native subnetwork should have <nil> 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.