diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4579,6 +4579,11 @@ bool CWalletTx::AcceptToMemoryPool(const Amount nAbsurdFee, CValidationState &state) { + // Quick check to avoid re-setting fInMempool to false + if (g_mempool.exists(tx->GetId())) { + return false; + } + // We must set fInMempool here - while it will be re-set to true by the // entered-mempool callback, if we did not there would be a race where a // user could call sendmoney in a loop and hit spurious out of funds errors diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py --- a/test/functional/mempool_persist.py +++ b/test/functional/mempool_persist.py @@ -64,6 +64,7 @@ for i in range(5): self.nodes[2].sendtoaddress( self.nodes[2].getnewaddress(), Decimal("10")) + node2_balance = self.nodes[2].getbalance() self.sync_all() self.log.debug( @@ -71,16 +72,23 @@ assert_equal(len(self.nodes[0].getrawmempool()), 5) assert_equal(len(self.nodes[1].getrawmempool()), 5) - self.log.debug( - "Stop-start node0 and node1. Verify that node0 has the transactions in its mempool and node1 does not.") + 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.") self.stop_nodes() self.start_node(0) self.start_node(1) + self.start_node(2) # Give bitcoind a second to reload the mempool time.sleep(1) wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5) + wait_until(lambda: len(self.nodes[2].getrawmempool()) == 5) assert_equal(len(self.nodes[1].getrawmempool()), 0) + # Verify accounting of mempool transactions after restart is correct + assert_equal(node2_balance, self.nodes[2].getbalance()) + self.log.debug( "Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file.") self.stop_nodes()