Skip to content

Commit 3702e1c

Browse files
author
MarcoFalke
committed
Merge #15646: [tests] Add test for wallet rebroadcasts
529c1ae [tests] Add test for wallet rebroadcasts (John Newbery) Pull request description: The existing wallet_resendwallettransactions.py test only tests the resendwallettransactions RPC. It does not test whether transactions are actually rebroadcast, or whether the rebroadcast logic is called on a timer. Update the test to not use the resendwallettransactions RPC and test that transactions are resent on a timer. ACKs for commit 529c1a: MarcoFalke: re-utACK 529c1ae Tree-SHA512: 7341e7dd07cdc8ecbc08b1949121824148d2b58133a8e298ecdc5b7555713df3cecffb49854443cef9f033ef847cbf329e879a3bf57ab4e1fc733be432e9f718
2 parents 656a15e + 529c1ae commit 3702e1c

File tree

1 file changed

+51
-12
lines changed

1 file changed

+51
-12
lines changed

test/functional/wallet_resendwallettransactions.py

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,70 @@
22
# Copyright (c) 2017-2018 The Bitcoin Core developers
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5-
"""Test resendwallettransactions RPC."""
5+
"""Test that the wallet resends transactions periodically."""
6+
from collections import defaultdict
7+
import time
68

9+
from test_framework.blocktools import create_block, create_coinbase
10+
from test_framework.messages import ToHex
11+
from test_framework.mininode import P2PInterface, mininode_lock
712
from test_framework.test_framework import BitcoinTestFramework
8-
from test_framework.util import assert_equal, assert_raises_rpc_error
13+
from test_framework.util import assert_equal, wait_until
14+
15+
class P2PStoreTxInvs(P2PInterface):
16+
def __init__(self):
17+
super().__init__()
18+
self.tx_invs_received = defaultdict(int)
19+
20+
def on_inv(self, message):
21+
# Store how many times invs have been received for each tx.
22+
for i in message.inv:
23+
if i.type == 1:
24+
# save txid
25+
self.tx_invs_received[i.hash] += 1
926

1027
class ResendWalletTransactionsTest(BitcoinTestFramework):
1128
def set_test_params(self):
1229
self.num_nodes = 1
13-
self.extra_args = [['--walletbroadcast=false']]
1430

1531
def skip_test_if_missing_module(self):
1632
self.skip_if_no_wallet()
1733

1834
def run_test(self):
19-
# Should raise RPC_WALLET_ERROR (-4) if walletbroadcast is disabled.
20-
assert_raises_rpc_error(-4, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast", self.nodes[0].resendwallettransactions)
35+
node = self.nodes[0] # alias
36+
37+
node.add_p2p_connection(P2PStoreTxInvs())
38+
39+
self.log.info("Create a new transaction and wait until it's broadcast")
40+
txid = int(node.sendtoaddress(node.getnewaddress(), 1), 16)
41+
42+
# Can take a few seconds due to transaction trickling
43+
wait_until(lambda: node.p2p.tx_invs_received[txid] >= 1, lock=mininode_lock)
44+
45+
# Add a second peer since txs aren't rebroadcast to the same peer (see filterInventoryKnown)
46+
node.add_p2p_connection(P2PStoreTxInvs())
47+
48+
self.log.info("Create a block")
49+
# Create and submit a block without the transaction.
50+
# Transactions are only rebroadcast if there has been a block at least five minutes
51+
# after the last time we tried to broadcast. Use mocktime and give an extra minute to be sure.
52+
block_time = int(time.time()) + 6 * 60
53+
node.setmocktime(block_time)
54+
block = create_block(int(node.getbestblockhash(), 16), create_coinbase(node.getblockchaininfo()['blocks']), block_time)
55+
block.nVersion = 3
56+
block.rehash()
57+
block.solve()
58+
node.submitblock(ToHex(block))
2159

22-
# Should return an empty array if there aren't unconfirmed wallet transactions.
23-
self.stop_node(0)
24-
self.start_node(0, extra_args=[])
25-
assert_equal(self.nodes[0].resendwallettransactions(), [])
60+
# Transaction should not be rebroadcast
61+
node.p2ps[1].sync_with_ping()
62+
assert_equal(node.p2ps[1].tx_invs_received[txid], 0)
2663

27-
# Should return an array with the unconfirmed wallet transaction.
28-
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
29-
assert_equal(self.nodes[0].resendwallettransactions(), [txid])
64+
self.log.info("Transaction should be rebroadcast after 30 minutes")
65+
# Use mocktime and give an extra 5 minutes to be sure.
66+
rebroadcast_time = int(time.time()) + 41 * 60
67+
node.setmocktime(rebroadcast_time)
68+
wait_until(lambda: node.p2ps[1].tx_invs_received[txid] >= 1, lock=mininode_lock)
3069

3170
if __name__ == '__main__':
3271
ResendWalletTransactionsTest().main()

0 commit comments

Comments
 (0)