Skip to content

Commit

Permalink
Add regtest tests for RBF
Browse files Browse the repository at this point in the history
  • Loading branch information
Ouziel committed Jan 15, 2025
1 parent d64757c commit 0bed836
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
3 changes: 2 additions & 1 deletion counterparty-core/counterpartycore/lib/follow.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def receive_sequence(self, body):
try:
raw_tx = backend.bitcoind.getrawtransaction(item_hash, no_retry=True)
except exceptions.BitcoindRPCError:
logger.trace("Transaction not found in bitcoind: %s", item_hash)
logger.warning("Transaction not found in bitcoind: %s", item_hash)
return
# add transaction to mempool block
# logger.trace("Adding transaction to mempool block: %s", item_hash)
Expand All @@ -205,6 +205,7 @@ def receive_sequence(self, body):
logger.trace("Waiting for new transactions in the mempool or a new block...")
# transaction removed from mempool for non-block inclusion reasons
elif label == "R":
logger.debug("Removing transaction from mempool: %s", item_hash)
mempool.clean_transaction_events(self.db, item_hash)

def receive_message(self, topic, body, seq):
Expand Down
65 changes: 65 additions & 0 deletions counterparty-core/counterpartycore/test/regtest/regtestnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ def start_bitcoin_node(self):
"-acceptnonstdtxn",
"-minrelaytxfee=0",
"-blockmintxfee=0",
"-mempoolfullrbf",
f"-datadir={self.datadir}",
_bg=True,
_out=sys.stdout,
Expand All @@ -384,6 +385,7 @@ def start_bitcoin_node_2(self):
"-minrelaytxfee=0",
"-blockmintxfee=0",
"-bind=127.0.0.1:2223=onion",
"-mempoolfullrbf",
_bg=True,
_out=sys.stdout,
)
Expand Down Expand Up @@ -1134,6 +1136,69 @@ def test_fee_calculation(self):
)
assert size * 3 - 3 <= unsigned_tx["btc_fee"] <= size * 3 + 3

def test_rbf(self):
self.start_and_wait_second_node()

unsigned_tx = self.compose(
self.addresses[0],
"send",
{
"destination": self.addresses[1],
"quantity": 1,
"asset": "XCP",
"exact_fee": 1,
"verbose": True,
"validate": False,
},
)["result"]
transaction = Transaction.from_raw(unsigned_tx["rawtransaction"])
raw_hexs = []
# create 10 transactions with increasing fees
for _i in range(10):
transaction.outputs[1].amount -= 170
new_raw_transaction = transaction.to_hex()
signed_tx = json.loads(
self.bitcoin_wallet("signrawtransactionwithwallet", new_raw_transaction).strip()
)["hex"]
raw_hexs.append(signed_tx)

# check that no transaction is in the mempool
mempool_event_count_before = self.api_call("mempool/events?event_name=TRANSACTION_PARSED")[
"result_count"
]
assert mempool_event_count_before == 0

# broadcast the transactions to the two nodes
tx_hahses = []
for i, raw_hex in enumerate(raw_hexs):
tx_hash = self.bitcoin_wallet("sendrawtransaction", raw_hex, 0).strip()
tx_hahses.append(tx_hash)
print(f"Transaction {i} sent: {tx_hash}")

# check that all transactions are in the mempool
mempool_event_count_after = self.api_call("mempool/events?event_name=TRANSACTION_PARSED")[
"result_count"
]
while mempool_event_count_after == 0:
time.sleep(1)
mempool_event_count_after = self.api_call(
"mempool/events?event_name=TRANSACTION_PARSED"
)["result_count"]
time.sleep(10)

print("Mempool event count: ", mempool_event_count_after)

# only one event should be in the mempool
assert mempool_event_count_after == 1
# check that RBFed transactions are removed from the mempool
for tx_hash in tx_hahses[:-1]:
assert f"Removing transaction from mempool: {tx_hash}" in self.server_out.getvalue()
event = self.api_call("mempool/events?event_name=TRANSACTION_PARSED")["result"][0]
# check that the last transaction is the one in the mempool
assert event["tx_hash"] == tx_hahses[-1]

print("RBF test successful")


class RegtestNodeThread(threading.Thread):
def __init__(self, wsgi_server="waitress", burn_in_one_block=True):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ def run_scenarios(serve=False, wsgi_server="gunicorn"):
regtest_node_thread.node.test_electrs()
print("Testing fee calculation...")
regtest_node_thread.node.test_fee_calculation()
print("Testing RBF...")
regtest_node_thread.node.test_rbf()
except KeyboardInterrupt:
print(regtest_node_thread.node.server_out.getvalue())
pass
Expand Down

0 comments on commit 0bed836

Please sign in to comment.