Skip to content

Commit

Permalink
Merge 04670ef into merged_master (Bitcoin PR #20385)
Browse files Browse the repository at this point in the history
  • Loading branch information
apoelstra committed May 6, 2021
2 parents 74ec329 + 04670ef commit 00e1863
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
28 changes: 16 additions & 12 deletions test/functional/mempool_spend_coinbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,48 @@
"""

from test_framework.test_framework import BitcoinTestFramework
from test_framework.blocktools import create_raw_transaction
from test_framework.util import assert_equal, assert_raises_rpc_error
from test_framework.wallet import MiniWallet


class MempoolSpendCoinbaseTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1

def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
self.setup_clean_chain = True

def run_test(self):
wallet = MiniWallet(self.nodes[0])

wallet.generate(200)
chain_height = self.nodes[0].getblockcount()
assert_equal(chain_height, 200)
node0_address = self.nodes[0].getnewaddress()

# Coinbase at height chain_height-100+1 ok in mempool, should
# get mined. Coinbase at height chain_height-100+2 is
# is too immature to spend.
# too immature to spend.
b = [self.nodes[0].getblockhash(n) for n in range(101, 103)]
coinbase_txids = [self.nodes[0].getblock(h)['tx'][0] for h in b]
spends_raw = [create_raw_transaction(self.nodes[0], txid, node0_address, amount=49.99, fee=0.01) for txid in coinbase_txids]
utxo_101 = wallet.get_utxo(txid=coinbase_txids[0])
utxo_102 = wallet.get_utxo(txid=coinbase_txids[1])

spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])
spend_101_id = wallet.send_self_transfer(from_node=self.nodes[0], utxo_to_spend=utxo_101)["txid"]

# coinbase at height 102 should be too immature to spend
assert_raises_rpc_error(-26,"bad-txns-premature-spend-of-coinbase", self.nodes[0].sendrawtransaction, spends_raw[1])
assert_raises_rpc_error(-26,
"bad-txns-premature-spend-of-coinbase",
lambda: wallet.send_self_transfer(from_node=self.nodes[0], utxo_to_spend=utxo_102))

# mempool should have just spend_101:
assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ])
assert_equal(self.nodes[0].getrawmempool(), [spend_101_id])

# mine a block, spend_101 should get confirmed
self.nodes[0].generate(1)
assert_equal(set(self.nodes[0].getrawmempool()), set())

# ... and now height 102 can be spent:
spend_102_id = self.nodes[0].sendrawtransaction(spends_raw[1])
assert_equal(self.nodes[0].getrawmempool(), [ spend_102_id ])
spend_102_id = wallet.send_self_transfer(from_node=self.nodes[0], utxo_to_spend=utxo_102)["txid"]
assert_equal(self.nodes[0].getrawmempool(), [spend_102_id])


if __name__ == '__main__':
MempoolSpendCoinbaseTest().main()
17 changes: 14 additions & 3 deletions test/functional/test_framework/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,20 @@ def generate(self, num_blocks):
self._utxos.append({'txid': cb_tx['txid'], 'vout': 0, 'value': cb_tx['vout'][0]['value']})
return blocks

def get_utxo(self):
"""Return the last utxo. Can be used to get the change output immediately after a send_self_transfer"""
return self._utxos.pop()
def get_utxo(self, *, txid=''):
"""
Returns a utxo and marks it as spent (pops it from the internal list)
Args:
txid (string), optional: get the first utxo we find from a specific transaction
Note: Can be used to get the change output immediately after a send_self_transfer
"""
index = -1 # by default the last utxo
if txid:
utxo = next(filter(lambda utxo: txid == utxo['txid'], self._utxos))
index = self._utxos.index(utxo)
return self._utxos.pop(index)

def send_self_transfer(self, *, fee_rate=Decimal("0.003"), from_node, utxo_to_spend=None):
"""Create and send a tx with the specified fee_rate. Fee may be exact or at most one satoshi higher than needed."""
Expand Down

0 comments on commit 00e1863

Please sign in to comment.