This pull request was inspired by three things:
- Large block testing, where stress testing 100-block-long re-orgs with 100+ megabyte blocks used enormous amounts of memory.
- Planning for implementing a memory-limited memory pool.
- The general principle that using arbitrarily large amounts of memory is bad.
Block re-org code before this pull request saves all transactions in the old fork to the memory pool before adding all the blocks on the new fork to the chain. That can use arbitrary amounts of memory if the re-org is arbitrarily long; for ‘reasonable’ re-orgs almost all of the transactions will be in blocks on the new fork, so you eventually end up with a small memory pool, and allocated a lot of memory for nothing.
This pull request has almost identical behavior for short (6-or-fewer block-deep) re-orgs. But for deeper re-orgs, it does not add transactions to the memory pool– it assumes that the transactions are likely to be on the new fork, and, if they are not, that either the sender or the receiver of the transaction will re-broadcast.
I made changes to the transaction relaying code that make transaction re-broadcast more robust; if for any reason a transaction is not added to the memory pool during a re-org, it is also cleared from the networking layer’s ‘setInventoryKnown’ so a later re-broadcast will be successful.
Tested using mempool_resurrect_test.py and also manual testing to make sure the wallet’s automatic rebroadcast of unconfirmed transactions Does The Right Thing.