@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
""" Test the RBF code. """
from copy import deepcopy
from decimal import Decimal
from test_framework . blocktools import COINBASE_MATURITY
@ -84,10 +85,11 @@ class ReplaceByFeeTest(BitcoinTestFramework):
self . skip_if_no_wallet ( )
def run_test ( self ) :
make_utxo ( self . nodes [ 0 ] , 1 * COIN )
# Ensure nodes are synced
self . sync_all ( )
self . wallet = MiniWallet ( self . nodes [ 0 ] )
# the pre-mined test framework chain contains coinbase outputs to the
# MiniWallet's default address ADDRESS_BCRT1_P2WSH_OP_TRUE in blocks
# 76-100 (see method BitcoinTestFramework._initialize_chain())
self . wallet . scan_blocks ( start = 76 , num = 2 )
self . log . info ( " Running test simple doublespend... " )
self . test_simple_doublespend ( )
@ -129,24 +131,17 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_simple_doublespend ( self ) :
""" Simple doublespend """
tx0_outpoint = make_utxo ( self . nodes [ 0 ] , int ( 1.1 * COIN ) )
# make_utxo may have generated a bunch of blocks, so we need to sync
# before we can spend the coins generated, or else the resulting
# transactions might not be accepted by our peers.
self . sync_all ( )
# we use MiniWallet to create a transaction template with inputs correctly set,
# and modify the output (amount, scriptPubKey) according to our needs
tx_template = self . wallet . create_self_transfer ( from_node = self . nodes [ 0 ] ) [ ' tx ' ]
tx1a = CTransaction ( )
tx1a . vin = [ CTxIn ( tx0_outpoint , nSequence = 0 ) ]
tx1a = deepcopy ( tx_template )
tx1a . vout = [ CTxOut ( 1 * COIN , DUMMY_P2WPKH_SCRIPT ) ]
tx1a_hex = tx1a . serialize ( ) . hex ( )
tx1a_txid = self . nodes [ 0 ] . sendrawtransaction ( tx1a_hex , 0 )
self . sync_all ( )
# Should fail because we haven't changed the fee
tx1b = CTransaction ( )
tx1b . vin = [ CTxIn ( tx0_outpoint , nSequence = 0 ) ]
tx1b = deepcopy ( tx_template )
tx1b . vout = [ CTxOut ( 1 * COIN , DUMMY_2_P2WPKH_SCRIPT ) ]
tx1b_hex = tx1b . serialize ( ) . hex ( )
@ -154,9 +149,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert_raises_rpc_error ( - 26 , " insufficient fee " , self . nodes [ 0 ] . sendrawtransaction , tx1b_hex , 0 )
# Extra 0.1 BTC fee
tx1b = CTransaction ( )
tx1b . vin = [ CTxIn ( tx0_outpoint , nSequence = 0 ) ]
tx1b . vout = [ CTxOut ( int ( 0.9 * COIN ) , DUMMY_P2WPKH_SCRIPT ) ]
tx1b . vout [ 0 ] . nValue - = int ( 0.1 * COIN )
tx1b_hex = tx1b . serialize ( ) . hex ( )
# Works when enabled
tx1b_txid = self . nodes [ 0 ] . sendrawtransaction ( tx1b_hex , 0 )
@ -574,12 +567,10 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert_equal ( json1 [ " vin " ] [ 0 ] [ " sequence " ] , 4294967294 )
def test_no_inherited_signaling ( self ) :
wallet = MiniWallet ( self . nodes [ 0 ] )
wallet . scan_blocks ( start = 76 , num = 1 )
confirmed_utxo = wallet . get_utxo ( )
confirmed_utxo = self . wallet . get_utxo ( )
# Create an explicitly opt-in parent transaction
optin_parent_tx = wallet . send_self_transfer (
optin_parent_tx = self . wallet . send_self_transfer (
from_node = self . nodes [ 0 ] ,
utxo_to_spend = confirmed_utxo ,
sequence = BIP125_SEQUENCE_NUMBER ,
@ -587,7 +578,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
)
assert_equal ( True , self . nodes [ 0 ] . getmempoolentry ( optin_parent_tx [ ' txid ' ] ) [ ' bip125-replaceable ' ] )
replacement_parent_tx = wallet . create_self_transfer (
replacement_parent_tx = self . wallet . create_self_transfer (
from_node = self . nodes [ 0 ] ,
utxo_to_spend = confirmed_utxo ,
sequence = BIP125_SEQUENCE_NUMBER ,
@ -601,8 +592,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert_equal ( res [ ' allowed ' ] , True )
# Create an opt-out child tx spending the opt-in parent
parent_utxo = wallet . get_utxo ( txid = optin_parent_tx [ ' txid ' ] )
optout_child_tx = wallet . send_self_transfer (
parent_utxo = self . wallet . get_utxo ( txid = optin_parent_tx [ ' txid ' ] )
optout_child_tx = self . wallet . send_self_transfer (
from_node = self . nodes [ 0 ] ,
utxo_to_spend = parent_utxo ,
sequence = 0xffffffff ,
@ -612,7 +603,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Reports true due to inheritance
assert_equal ( True , self . nodes [ 0 ] . getmempoolentry ( optout_child_tx [ ' txid ' ] ) [ ' bip125-replaceable ' ] )
replacement_child_tx = wallet . create_self_transfer (
replacement_child_tx = self . wallet . create_self_transfer (
from_node = self . nodes [ 0 ] ,
utxo_to_spend = parent_utxo ,
sequence = 0xffffffff ,
@ -631,9 +622,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert_raises_rpc_error ( - 26 , ' txn-mempool-conflict ' , self . nodes [ 0 ] . sendrawtransaction , replacement_child_tx [ " hex " ] , 0 )
def test_replacement_relay_fee ( self ) :
wallet = MiniWallet ( self . nodes [ 0 ] )
wallet . scan_blocks ( start = 77 , num = 1 )
tx = wallet . send_self_transfer ( from_node = self . nodes [ 0 ] ) [ ' tx ' ]
tx = self . wallet . send_self_transfer ( from_node = self . nodes [ 0 ] ) [ ' tx ' ]
# Higher fee, higher feerate, different txid, but the replacement does not provide a relay
# fee conforming to node's `incrementalrelayfee` policy of 1000 sat per KB.