40
40
import time
41
41
42
42
from test_framework .test_framework import BitcoinTestFramework
43
+ from test_framework .mininode import P2PTxInvStore
43
44
from test_framework .util import (
44
45
assert_equal ,
45
46
assert_greater_than_or_equal ,
46
47
assert_raises_rpc_error ,
48
+ connect_nodes ,
49
+ disconnect_nodes ,
47
50
wait_until ,
48
51
)
49
52
@@ -80,6 +83,11 @@ def run_test(self):
80
83
assert_greater_than_or_equal (tx_creation_time , tx_creation_time_lower )
81
84
assert_greater_than_or_equal (tx_creation_time_higher , tx_creation_time )
82
85
86
+ # disconnect nodes & make a txn that remains in the unbroadcast set.
87
+ disconnect_nodes (self .nodes [0 ], 2 )
88
+ self .nodes [0 ].sendtoaddress (self .nodes [2 ].getnewaddress (), Decimal ("12" ))
89
+ connect_nodes (self .nodes [0 ], 2 )
90
+
83
91
self .log .debug ("Stop-start the nodes. Verify that node0 has the transactions in its mempool and node1 does not. Verify that node2 calculates its balance correctly after loading wallet transactions." )
84
92
self .stop_nodes ()
85
93
# Give this node a head-start, so we can be "extra-sure" that it didn't load anything later
@@ -89,7 +97,7 @@ def run_test(self):
89
97
self .start_node (2 )
90
98
wait_until (lambda : self .nodes [0 ].getmempoolinfo ()["loaded" ], timeout = 1 )
91
99
wait_until (lambda : self .nodes [2 ].getmempoolinfo ()["loaded" ], timeout = 1 )
92
- assert_equal (len (self .nodes [0 ].getrawmempool ()), 5 )
100
+ assert_equal (len (self .nodes [0 ].getrawmempool ()), 6 )
93
101
assert_equal (len (self .nodes [2 ].getrawmempool ()), 5 )
94
102
# The others have loaded their mempool. If node_1 loaded anything, we'd probably notice by now:
95
103
assert_equal (len (self .nodes [1 ].getrawmempool ()), 0 )
@@ -105,17 +113,18 @@ def run_test(self):
105
113
self .nodes [2 ].syncwithvalidationinterfacequeue () # Flush mempool to wallet
106
114
assert_equal (node2_balance , self .nodes [2 ].getbalance ())
107
115
116
+ # start node0 with wallet disabled so wallet transactions don't get resubmitted
108
117
self .log .debug ("Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file." )
109
118
self .stop_nodes ()
110
- self .start_node (0 , extra_args = ["-persistmempool=0" ])
119
+ self .start_node (0 , extra_args = ["-persistmempool=0" , "-disablewallet" ])
111
120
wait_until (lambda : self .nodes [0 ].getmempoolinfo ()["loaded" ])
112
121
assert_equal (len (self .nodes [0 ].getrawmempool ()), 0 )
113
122
114
123
self .log .debug ("Stop-start node0. Verify that it has the transactions in its mempool." )
115
124
self .stop_nodes ()
116
125
self .start_node (0 )
117
126
wait_until (lambda : self .nodes [0 ].getmempoolinfo ()["loaded" ])
118
- assert_equal (len (self .nodes [0 ].getrawmempool ()), 5 )
127
+ assert_equal (len (self .nodes [0 ].getrawmempool ()), 6 )
119
128
120
129
mempooldat0 = os .path .join (self .nodes [0 ].datadir , self .chain , 'mempool.dat' )
121
130
mempooldat1 = os .path .join (self .nodes [1 ].datadir , self .chain , 'mempool.dat' )
@@ -124,12 +133,12 @@ def run_test(self):
124
133
self .nodes [0 ].savemempool ()
125
134
assert os .path .isfile (mempooldat0 )
126
135
127
- self .log .debug ("Stop nodes, make node1 use mempool.dat from node0. Verify it has 5 transactions" )
136
+ self .log .debug ("Stop nodes, make node1 use mempool.dat from node0. Verify it has 6 transactions" )
128
137
os .rename (mempooldat0 , mempooldat1 )
129
138
self .stop_nodes ()
130
139
self .start_node (1 , extra_args = [])
131
140
wait_until (lambda : self .nodes [1 ].getmempoolinfo ()["loaded" ])
132
- assert_equal (len (self .nodes [1 ].getrawmempool ()), 5 )
141
+ assert_equal (len (self .nodes [1 ].getrawmempool ()), 6 )
133
142
134
143
self .log .debug ("Prevent bitcoind from writing mempool.dat to disk. Verify that `savemempool` fails" )
135
144
# to test the exception we are creating a tmp folder called mempool.dat.new
@@ -139,6 +148,27 @@ def run_test(self):
139
148
assert_raises_rpc_error (- 1 , "Unable to dump mempool to disk" , self .nodes [1 ].savemempool )
140
149
os .rmdir (mempooldotnew1 )
141
150
151
+ self .test_persist_unbroadcast ()
152
+
153
+ def test_persist_unbroadcast (self ):
154
+ node0 = self .nodes [0 ]
155
+ self .start_node (0 )
156
+
157
+ # clear out mempool
158
+ node0 .generate (1 )
159
+
160
+ # disconnect nodes to make a txn that remains in the unbroadcast set.
161
+ disconnect_nodes (node0 , 1 )
162
+ node0 .sendtoaddress (self .nodes [1 ].getnewaddress (), Decimal ("12" ))
163
+
164
+ # shutdown, then startup with wallet disabled
165
+ self .stop_nodes ()
166
+ self .start_node (0 , extra_args = ["-disablewallet" ])
167
+
168
+ # check that txn gets broadcast due to unbroadcast logic
169
+ conn = node0 .add_p2p_connection (P2PTxInvStore ())
170
+ node0 .mockscheduler (16 * 60 ) # 15 min + 1 for buffer
171
+ wait_until (lambda : len (conn .get_invs ()) == 1 )
142
172
143
173
if __name__ == '__main__' :
144
174
MempoolPersistTest ().main ()
0 commit comments