forked from cerc-io/ipld-eth-server
Update dependencies
- uses newer version of go-ethereum required for go1.11
This commit is contained in:
+4
-4
@@ -53,7 +53,7 @@ func makeTestOutput(r *rpctest.Harness, t *testing.T,
|
||||
output := &wire.TxOut{PkScript: selfAddrScript, Value: 1e8}
|
||||
|
||||
// Next, create and broadcast a transaction paying to the output.
|
||||
fundTx, err := r.CreateTransaction([]*wire.TxOut{output}, 10)
|
||||
fundTx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@@ -88,7 +88,7 @@ func makeTestOutput(r *rpctest.Harness, t *testing.T,
|
||||
return key, utxo, selfAddrScript, nil
|
||||
}
|
||||
|
||||
// TestBIP0113Activation tests for proper adherance of the BIP 113 rule
|
||||
// TestBIP0113Activation tests for proper adherence of the BIP 113 rule
|
||||
// constraint which requires all transaction finality tests to use the MTP of
|
||||
// the last 11 blocks, rather than the timestamp of the block which includes
|
||||
// them.
|
||||
@@ -188,7 +188,7 @@ func TestBIP0113Activation(t *testing.T) {
|
||||
// At this point, the block height should be 103: we mined 101 blocks
|
||||
// to create a single mature output, then an additional block to create
|
||||
// a new output, and then mined a single block above to include our
|
||||
// transation.
|
||||
// transaction.
|
||||
assertChainHeight(r, t, 103)
|
||||
|
||||
// Next, mine enough blocks to ensure that the soft-fork becomes
|
||||
@@ -316,7 +316,7 @@ func createCSVOutput(r *rpctest.Harness, t *testing.T,
|
||||
|
||||
// Finally create a valid transaction which creates the output crafted
|
||||
// above.
|
||||
tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10)
|
||||
tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
+26
-11
@@ -45,12 +45,20 @@ func solveBlock(header *wire.BlockHeader, targetDifficulty *big.Int) bool {
|
||||
hdr.Nonce = i
|
||||
hash := hdr.BlockHash()
|
||||
if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 {
|
||||
results <- sbResult{true, i}
|
||||
return
|
||||
select {
|
||||
case results <- sbResult{true, i}:
|
||||
return
|
||||
case <-quit:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
results <- sbResult{false, 0}
|
||||
select {
|
||||
case results <- sbResult{false, 0}:
|
||||
case <-quit:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
startNonce := uint32(0)
|
||||
@@ -88,7 +96,8 @@ func standardCoinbaseScript(nextBlockHeight int32, extraNonce uint64) ([]byte, e
|
||||
// createCoinbaseTx returns a coinbase transaction paying an appropriate
|
||||
// subsidy based on the passed block height to the provided address.
|
||||
func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int32,
|
||||
addr btcutil.Address, net *chaincfg.Params) (*btcutil.Tx, error) {
|
||||
addr btcutil.Address, mineTo []wire.TxOut,
|
||||
net *chaincfg.Params) (*btcutil.Tx, error) {
|
||||
|
||||
// Create the script to pay to the provided payment address.
|
||||
pkScript, err := txscript.PayToAddrScript(addr)
|
||||
@@ -105,10 +114,16 @@ func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int32,
|
||||
SignatureScript: coinbaseScript,
|
||||
Sequence: wire.MaxTxInSequenceNum,
|
||||
})
|
||||
tx.AddTxOut(&wire.TxOut{
|
||||
Value: blockchain.CalcBlockSubsidy(nextBlockHeight, net),
|
||||
PkScript: pkScript,
|
||||
})
|
||||
if len(mineTo) == 0 {
|
||||
tx.AddTxOut(&wire.TxOut{
|
||||
Value: blockchain.CalcBlockSubsidy(nextBlockHeight, net),
|
||||
PkScript: pkScript,
|
||||
})
|
||||
} else {
|
||||
for i := range mineTo {
|
||||
tx.AddTxOut(&mineTo[i])
|
||||
}
|
||||
}
|
||||
return btcutil.NewTx(tx), nil
|
||||
}
|
||||
|
||||
@@ -118,8 +133,8 @@ func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int32,
|
||||
// second is used. Passing nil for the previous block results in a block that
|
||||
// builds off of the genesis block for the specified chain.
|
||||
func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx,
|
||||
blockVersion int32, blockTime time.Time,
|
||||
miningAddr btcutil.Address, net *chaincfg.Params) (*btcutil.Block, error) {
|
||||
blockVersion int32, blockTime time.Time, miningAddr btcutil.Address,
|
||||
mineTo []wire.TxOut, net *chaincfg.Params) (*btcutil.Block, error) {
|
||||
|
||||
var (
|
||||
prevHash *chainhash.Hash
|
||||
@@ -156,7 +171,7 @@ func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx,
|
||||
return nil, err
|
||||
}
|
||||
coinbaseTx, err := createCoinbaseTx(coinbaseScript, blockHeight,
|
||||
miningAddr, net)
|
||||
miningAddr, mineTo, net)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+86
-38
@@ -56,6 +56,7 @@ func (u *utxo) isMature(height int32) bool {
|
||||
type chainUpdate struct {
|
||||
blockHeight int32
|
||||
filteredTxns []*btcutil.Tx
|
||||
isConnect bool // True if connect, false if disconnect
|
||||
}
|
||||
|
||||
// undoEntry is functionally the opposite of a chainUpdate. An undoEntry is
|
||||
@@ -176,13 +177,14 @@ func (m *memWallet) SetRPCClient(rpcClient *rpcclient.Client) {
|
||||
}
|
||||
|
||||
// IngestBlock is a call-back which is to be triggered each time a new block is
|
||||
// connected to the main chain. Ingesting a block updates the wallet's internal
|
||||
// utxo state based on the outputs created and destroyed within each block.
|
||||
// connected to the main chain. It queues the update for the chain syncer,
|
||||
// calling the private version in sequential order.
|
||||
func (m *memWallet) IngestBlock(height int32, header *wire.BlockHeader, filteredTxns []*btcutil.Tx) {
|
||||
// Append this new chain update to the end of the queue of new chain
|
||||
// updates.
|
||||
m.chainMtx.Lock()
|
||||
m.chainUpdates = append(m.chainUpdates, &chainUpdate{height, filteredTxns})
|
||||
m.chainUpdates = append(m.chainUpdates, &chainUpdate{height,
|
||||
filteredTxns, true})
|
||||
m.chainMtx.Unlock()
|
||||
|
||||
// Launch a goroutine to signal the chainSyncer that a new update is
|
||||
@@ -193,6 +195,30 @@ func (m *memWallet) IngestBlock(height int32, header *wire.BlockHeader, filtered
|
||||
}()
|
||||
}
|
||||
|
||||
// ingestBlock updates the wallet's internal utxo state based on the outputs
|
||||
// created and destroyed within each block.
|
||||
func (m *memWallet) ingestBlock(update *chainUpdate) {
|
||||
// Update the latest synced height, then process each filtered
|
||||
// transaction in the block creating and destroying utxos within
|
||||
// the wallet as a result.
|
||||
m.currentHeight = update.blockHeight
|
||||
undo := &undoEntry{
|
||||
utxosDestroyed: make(map[wire.OutPoint]*utxo),
|
||||
}
|
||||
for _, tx := range update.filteredTxns {
|
||||
mtx := tx.MsgTx()
|
||||
isCoinbase := blockchain.IsCoinBaseTx(mtx)
|
||||
txHash := mtx.TxHash()
|
||||
m.evalOutputs(mtx.TxOut, &txHash, isCoinbase, undo)
|
||||
m.evalInputs(mtx.TxIn, undo)
|
||||
}
|
||||
|
||||
// Finally, record the undo entry for this block so we can
|
||||
// properly update our internal state in response to the block
|
||||
// being re-org'd from the main chain.
|
||||
m.reorgJournal[update.blockHeight] = undo
|
||||
}
|
||||
|
||||
// chainSyncer is a goroutine dedicated to processing new blocks in order to
|
||||
// keep the wallet's utxo state up to date.
|
||||
//
|
||||
@@ -209,26 +235,12 @@ func (m *memWallet) chainSyncer() {
|
||||
m.chainUpdates = m.chainUpdates[1:]
|
||||
m.chainMtx.Unlock()
|
||||
|
||||
// Update the latest synced height, then process each filtered
|
||||
// transaction in the block creating and destroying utxos within
|
||||
// the wallet as a result.
|
||||
m.Lock()
|
||||
m.currentHeight = update.blockHeight
|
||||
undo := &undoEntry{
|
||||
utxosDestroyed: make(map[wire.OutPoint]*utxo),
|
||||
if update.isConnect {
|
||||
m.ingestBlock(update)
|
||||
} else {
|
||||
m.unwindBlock(update)
|
||||
}
|
||||
for _, tx := range update.filteredTxns {
|
||||
mtx := tx.MsgTx()
|
||||
isCoinbase := blockchain.IsCoinBaseTx(mtx)
|
||||
txHash := mtx.TxHash()
|
||||
m.evalOutputs(mtx.TxOut, &txHash, isCoinbase, undo)
|
||||
m.evalInputs(mtx.TxIn, undo)
|
||||
}
|
||||
|
||||
// Finally, record the undo entry for this block so we can
|
||||
// properly update our internal state in response to the block
|
||||
// being re-org'd from the main chain.
|
||||
m.reorgJournal[update.blockHeight] = undo
|
||||
m.Unlock()
|
||||
}
|
||||
}
|
||||
@@ -285,13 +297,28 @@ func (m *memWallet) evalInputs(inputs []*wire.TxIn, undo *undoEntry) {
|
||||
}
|
||||
|
||||
// UnwindBlock is a call-back which is to be executed each time a block is
|
||||
// disconnected from the main chain. Unwinding a block undoes the effect that a
|
||||
// particular block had on the wallet's internal utxo state.
|
||||
// disconnected from the main chain. It queues the update for the chain syncer,
|
||||
// calling the private version in sequential order.
|
||||
func (m *memWallet) UnwindBlock(height int32, header *wire.BlockHeader) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
// Append this new chain update to the end of the queue of new chain
|
||||
// updates.
|
||||
m.chainMtx.Lock()
|
||||
m.chainUpdates = append(m.chainUpdates, &chainUpdate{height,
|
||||
nil, false})
|
||||
m.chainMtx.Unlock()
|
||||
|
||||
undo := m.reorgJournal[height]
|
||||
// Launch a goroutine to signal the chainSyncer that a new update is
|
||||
// available. We do this in a new goroutine in order to avoid blocking
|
||||
// the main loop of the rpc client.
|
||||
go func() {
|
||||
m.chainUpdateSignal <- struct{}{}
|
||||
}()
|
||||
}
|
||||
|
||||
// unwindBlock undoes the effect that a particular block had on the wallet's
|
||||
// internal utxo state.
|
||||
func (m *memWallet) unwindBlock(update *chainUpdate) {
|
||||
undo := m.reorgJournal[update.blockHeight]
|
||||
|
||||
for _, utxo := range undo.utxosCreated {
|
||||
delete(m.utxos, utxo)
|
||||
@@ -301,7 +328,7 @@ func (m *memWallet) UnwindBlock(height int32, header *wire.BlockHeader) {
|
||||
m.utxos[outPoint] = utxo
|
||||
}
|
||||
|
||||
delete(m.reorgJournal, height)
|
||||
delete(m.reorgJournal, update.blockHeight)
|
||||
}
|
||||
|
||||
// newAddress returns a new address from the wallet's hd key chain. It also
|
||||
@@ -347,12 +374,15 @@ func (m *memWallet) NewAddress() (btcutil.Address, error) {
|
||||
}
|
||||
|
||||
// fundTx attempts to fund a transaction sending amt bitcoin. The coins are
|
||||
// selected such that the final amount spent pays enough fees as dictated by
|
||||
// the passed fee rate. The passed fee rate should be expressed in
|
||||
// satoshis-per-byte.
|
||||
// selected such that the final amount spent pays enough fees as dictated by the
|
||||
// passed fee rate. The passed fee rate should be expressed in
|
||||
// satoshis-per-byte. The transaction being funded can optionally include a
|
||||
// change output indicated by the change boolean.
|
||||
//
|
||||
// NOTE: The memWallet's mutex must be held when this function is called.
|
||||
func (m *memWallet) fundTx(tx *wire.MsgTx, amt btcutil.Amount, feeRate btcutil.Amount) error {
|
||||
func (m *memWallet) fundTx(tx *wire.MsgTx, amt btcutil.Amount,
|
||||
feeRate btcutil.Amount, change bool) error {
|
||||
|
||||
const (
|
||||
// spendSize is the largest number of bytes of a sigScript
|
||||
// which spends a p2pkh output: OP_DATA_73 <sig> OP_DATA_33 <pubkey>
|
||||
@@ -388,10 +418,11 @@ func (m *memWallet) fundTx(tx *wire.MsgTx, amt btcutil.Amount, feeRate btcutil.A
|
||||
continue
|
||||
}
|
||||
|
||||
// If we have any change left over, then add an additional
|
||||
// output to the transaction reserved for change.
|
||||
// If we have any change left over and we should create a change
|
||||
// output, then add an additional output to the transaction
|
||||
// reserved for it.
|
||||
changeVal := amtSelected - amt - reqFee
|
||||
if changeVal > 0 {
|
||||
if changeVal > 0 && change {
|
||||
addr, err := m.newAddress()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -421,7 +452,21 @@ func (m *memWallet) fundTx(tx *wire.MsgTx, amt btcutil.Amount, feeRate btcutil.A
|
||||
func (m *memWallet) SendOutputs(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) (*chainhash.Hash, error) {
|
||||
|
||||
tx, err := m.CreateTransaction(outputs, feeRate)
|
||||
tx, err := m.CreateTransaction(outputs, feeRate, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m.rpc.SendRawTransaction(tx, true)
|
||||
}
|
||||
|
||||
// SendOutputsWithoutChange creates and sends a transaction that pays to the
|
||||
// specified outputs while observing the passed fee rate and ignoring a change
|
||||
// output. The passed fee rate should be expressed in sat/b.
|
||||
func (m *memWallet) SendOutputsWithoutChange(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) (*chainhash.Hash, error) {
|
||||
|
||||
tx, err := m.CreateTransaction(outputs, feeRate, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -431,10 +476,13 @@ func (m *memWallet) SendOutputs(outputs []*wire.TxOut,
|
||||
|
||||
// CreateTransaction returns a fully signed transaction paying to the specified
|
||||
// outputs while observing the desired fee rate. The passed fee rate should be
|
||||
// expressed in satoshis-per-byte.
|
||||
// expressed in satoshis-per-byte. The transaction being created can optionally
|
||||
// include a change output indicated by the change boolean.
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (m *memWallet) CreateTransaction(outputs []*wire.TxOut, feeRate btcutil.Amount) (*wire.MsgTx, error) {
|
||||
func (m *memWallet) CreateTransaction(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount, change bool) (*wire.MsgTx, error) {
|
||||
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
@@ -449,7 +497,7 @@ func (m *memWallet) CreateTransaction(outputs []*wire.TxOut, feeRate btcutil.Amo
|
||||
}
|
||||
|
||||
// Attempt to fund the transaction with spendable utxos.
|
||||
if err := m.fundTx(tx, outputAmt, feeRate); err != nil {
|
||||
if err := m.fundTx(tx, outputAmt, feeRate, change); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -44,7 +44,7 @@ type nodeConfig struct {
|
||||
func newConfig(prefix, certFile, keyFile string, extra []string) (*nodeConfig, error) {
|
||||
btcdPath, err := btcdExecutablePath()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
btcdPath = "btcd"
|
||||
}
|
||||
|
||||
a := &nodeConfig{
|
||||
@@ -115,10 +115,6 @@ func (n *nodeConfig) arguments() []string {
|
||||
args = append(args, fmt.Sprintf("--rpccert=%s", n.certFile))
|
||||
// --rpckey
|
||||
args = append(args, fmt.Sprintf("--rpckey=%s", n.keyFile))
|
||||
// --txindex
|
||||
args = append(args, "--txindex")
|
||||
// --addrindex
|
||||
args = append(args, "--addrindex")
|
||||
if n.dataDir != "" {
|
||||
// --datadir
|
||||
args = append(args, fmt.Sprintf("--datadir=%s", n.dataDir))
|
||||
|
||||
+41
-8
@@ -356,20 +356,32 @@ func (h *Harness) SendOutputs(targetOutputs []*wire.TxOut,
|
||||
return h.wallet.SendOutputs(targetOutputs, feeRate)
|
||||
}
|
||||
|
||||
// SendOutputsWithoutChange creates and sends a transaction that pays to the
|
||||
// specified outputs while observing the passed fee rate and ignoring a change
|
||||
// output. The passed fee rate should be expressed in sat/b.
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (h *Harness) SendOutputsWithoutChange(targetOutputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) (*chainhash.Hash, error) {
|
||||
|
||||
return h.wallet.SendOutputsWithoutChange(targetOutputs, feeRate)
|
||||
}
|
||||
|
||||
// CreateTransaction returns a fully signed transaction paying to the specified
|
||||
// outputs while observing the desired fee rate. The passed fee rate should be
|
||||
// expressed in satoshis-per-byte. Any unspent outputs selected as inputs for
|
||||
// the crafted transaction are marked as unspendable in order to avoid
|
||||
// potential double-spends by future calls to this method. If the created
|
||||
// transaction is cancelled for any reason then the selected inputs MUST be
|
||||
// freed via a call to UnlockOutputs. Otherwise, the locked inputs won't be
|
||||
// expressed in satoshis-per-byte. The transaction being created can optionally
|
||||
// include a change output indicated by the change boolean. Any unspent outputs
|
||||
// selected as inputs for the crafted transaction are marked as unspendable in
|
||||
// order to avoid potential double-spends by future calls to this method. If the
|
||||
// created transaction is cancelled for any reason then the selected inputs MUST
|
||||
// be freed via a call to UnlockOutputs. Otherwise, the locked inputs won't be
|
||||
// returned to the pool of spendable outputs.
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (h *Harness) CreateTransaction(targetOutputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) (*wire.MsgTx, error) {
|
||||
feeRate btcutil.Amount, change bool) (*wire.MsgTx, error) {
|
||||
|
||||
return h.wallet.CreateTransaction(targetOutputs, feeRate)
|
||||
return h.wallet.CreateTransaction(targetOutputs, feeRate, change)
|
||||
}
|
||||
|
||||
// UnlockOutputs unlocks any outputs which were previously marked as
|
||||
@@ -406,6 +418,27 @@ func (h *Harness) P2PAddress() string {
|
||||
// This function is safe for concurrent access.
|
||||
func (h *Harness) GenerateAndSubmitBlock(txns []*btcutil.Tx, blockVersion int32,
|
||||
blockTime time.Time) (*btcutil.Block, error) {
|
||||
return h.GenerateAndSubmitBlockWithCustomCoinbaseOutputs(txns,
|
||||
blockVersion, blockTime, []wire.TxOut{})
|
||||
}
|
||||
|
||||
// GenerateAndSubmitBlockWithCustomCoinbaseOutputs creates a block whose
|
||||
// contents include the passed coinbase outputs and transactions and submits
|
||||
// it to the running simnet node. For generating blocks with only a coinbase tx,
|
||||
// callers can simply pass nil instead of transactions to be mined.
|
||||
// Additionally, a custom block version can be set by the caller. A blockVersion
|
||||
// of -1 indicates that the current default block version should be used. An
|
||||
// uninitialized time.Time should be used for the blockTime parameter if one
|
||||
// doesn't wish to set a custom time. The mineTo list of outputs will be added
|
||||
// to the coinbase; this is not checked for correctness until the block is
|
||||
// submitted; thus, it is the caller's responsibility to ensure that the outputs
|
||||
// are correct. If the list is empty, the coinbase reward goes to the wallet
|
||||
// managed by the Harness.
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (h *Harness) GenerateAndSubmitBlockWithCustomCoinbaseOutputs(
|
||||
txns []*btcutil.Tx, blockVersion int32, blockTime time.Time,
|
||||
mineTo []wire.TxOut) (*btcutil.Block, error) {
|
||||
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
@@ -427,7 +460,7 @@ func (h *Harness) GenerateAndSubmitBlock(txns []*btcutil.Tx, blockVersion int32,
|
||||
|
||||
// Create a new block including the specified transactions
|
||||
newBlock, err := CreateBlock(prevBlock, txns, blockVersion,
|
||||
blockTime, h.wallet.coinbaseAddr, h.ActiveNet)
|
||||
blockTime, h.wallet.coinbaseAddr, mineTo, h.ActiveNet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+79
-3
@@ -206,7 +206,7 @@ func testJoinMempools(r *Harness, t *testing.T) {
|
||||
t.Fatalf("unable to generate pkscript to addr: %v", err)
|
||||
}
|
||||
output := wire.NewTxOut(5e8, addrScript)
|
||||
testTx, err := r.CreateTransaction([]*wire.TxOut{output}, 10)
|
||||
testTx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true)
|
||||
if err != nil {
|
||||
t.Fatalf("coinbase spend failed: %v", err)
|
||||
}
|
||||
@@ -340,7 +340,7 @@ func testGenerateAndSubmitBlock(r *Harness, t *testing.T) {
|
||||
const numTxns = 5
|
||||
txns := make([]*btcutil.Tx, 0, numTxns)
|
||||
for i := 0; i < numTxns; i++ {
|
||||
tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10)
|
||||
tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create tx: %v", err)
|
||||
}
|
||||
@@ -391,6 +391,81 @@ func testGenerateAndSubmitBlock(r *Harness, t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testGenerateAndSubmitBlockWithCustomCoinbaseOutputs(r *Harness,
|
||||
t *testing.T) {
|
||||
// Generate a few test spend transactions.
|
||||
addr, err := r.NewAddress()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to generate new address: %v", err)
|
||||
}
|
||||
pkScript, err := txscript.PayToAddrScript(addr)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create script: %v", err)
|
||||
}
|
||||
output := wire.NewTxOut(btcutil.SatoshiPerBitcoin, pkScript)
|
||||
|
||||
const numTxns = 5
|
||||
txns := make([]*btcutil.Tx, 0, numTxns)
|
||||
for i := 0; i < numTxns; i++ {
|
||||
tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create tx: %v", err)
|
||||
}
|
||||
|
||||
txns = append(txns, btcutil.NewTx(tx))
|
||||
}
|
||||
|
||||
// Now generate a block with the default block version, a zero'd out
|
||||
// time, and a burn output.
|
||||
block, err := r.GenerateAndSubmitBlockWithCustomCoinbaseOutputs(txns,
|
||||
-1, time.Time{}, []wire.TxOut{{
|
||||
Value: 0,
|
||||
PkScript: []byte{},
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatalf("unable to generate block: %v", err)
|
||||
}
|
||||
|
||||
// Ensure that all created transactions were included, and that the
|
||||
// block version was properly set to the default.
|
||||
numBlocksTxns := len(block.Transactions())
|
||||
if numBlocksTxns != numTxns+1 {
|
||||
t.Fatalf("block did not include all transactions: "+
|
||||
"expected %v, got %v", numTxns+1, numBlocksTxns)
|
||||
}
|
||||
blockVersion := block.MsgBlock().Header.Version
|
||||
if blockVersion != BlockVersion {
|
||||
t.Fatalf("block version is not default: expected %v, got %v",
|
||||
BlockVersion, blockVersion)
|
||||
}
|
||||
|
||||
// Next generate a block with a "non-standard" block version along with
|
||||
// time stamp a minute after the previous block's timestamp.
|
||||
timestamp := block.MsgBlock().Header.Timestamp.Add(time.Minute)
|
||||
targetBlockVersion := int32(1337)
|
||||
block, err = r.GenerateAndSubmitBlockWithCustomCoinbaseOutputs(nil,
|
||||
targetBlockVersion, timestamp, []wire.TxOut{{
|
||||
Value: 0,
|
||||
PkScript: []byte{},
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatalf("unable to generate block: %v", err)
|
||||
}
|
||||
|
||||
// Finally ensure that the desired block version and timestamp were set
|
||||
// properly.
|
||||
header := block.MsgBlock().Header
|
||||
blockVersion = header.Version
|
||||
if blockVersion != targetBlockVersion {
|
||||
t.Fatalf("block version mismatch: expected %v, got %v",
|
||||
targetBlockVersion, blockVersion)
|
||||
}
|
||||
if !timestamp.Equal(header.Timestamp) {
|
||||
t.Fatalf("header time stamp mismatch: expected %v, got %v",
|
||||
timestamp, header.Timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
func testMemWalletReorg(r *Harness, t *testing.T) {
|
||||
// Create a fresh harness, we'll be using the main harness to force a
|
||||
// re-org on this local harness.
|
||||
@@ -447,7 +522,7 @@ func testMemWalletLockedOutputs(r *Harness, t *testing.T) {
|
||||
}
|
||||
outputAmt := btcutil.Amount(50 * btcutil.SatoshiPerBitcoin)
|
||||
output := wire.NewTxOut(int64(outputAmt), pkScript)
|
||||
tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10)
|
||||
tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create transaction: %v", err)
|
||||
}
|
||||
@@ -478,6 +553,7 @@ var harnessTestCases = []HarnessTestCase{
|
||||
testJoinBlocks,
|
||||
testJoinMempools, // Depends on results of testJoinBlocks
|
||||
testGenerateAndSubmitBlock,
|
||||
testGenerateAndSubmitBlockWithCustomCoinbaseOutputs,
|
||||
testMemWalletReorg,
|
||||
testMemWalletLockedOutputs,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user