Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mempool: Persist with XOR #28207

Merged
merged 1 commit into from Nov 13, 2023
Merged

Conversation

maflcko
Copy link
Member

@maflcko maflcko commented Aug 3, 2023

Currently the mempool.dat file stores data received from remote peers as-is. This may be problematic when a program other than Bitcoin Core tries to interpret them by accident. For example, an anti-virus program or other program may scan the file and move it into quarantine, or delete it, or corrupt it.

While the local wallet is expected to re-submit any pending transactions, unrelated transactions may be missing from the mempool after a restart. This may cause fee estimates to be off, or may cause block relay to be slower.

Fix this, similar to #6650, by rolling a random XOR pattern over the dat file when writing or reading it.

Obviously this can only protect against programs that accidentally and unintentionally are trying to mess with the dat file. Any program that intentionally wants to mess with the dat file can still trivially do so.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 3, 2023

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK glozow, ismaelsadeeq, achow101
Concept ACK Sjors, 0xB10C, luke-jr, RandyMcMillan
Stale ACK hernanmarino, pablomartin4btc, darosior

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #28438 (Use serialization parameters for CTransaction by ajtowns)
  • #28132 (policy: Enable full-rbf by default by petertodd)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@maflcko
Copy link
Member Author

maflcko commented Aug 3, 2023

Currently opened as draft to wait for initial feedback. There is no option to disable this feature, because I am not aware of anyone reading the mempool.dat, is there? (The getrawmempool RPC is the recommended way to get the mempool, and using the savemempool RPC instead seems like an edge-case?)

@Sjors
Copy link
Member

Sjors commented Aug 3, 2023

Concept ACK.

It may be difficult to find out if anyone relies on parsing mempool.dat. If it's not too hard, we might as well add an option (default 1) and deprecate it in a few releases. That also makes it easier to toggle between master and the last release (by setting it to 0).

You may also want to use a bit flag instead of increasing the version. The added complexity of that could be an argument to not make this optional.

@maflcko
Copy link
Member Author

maflcko commented Aug 3, 2023

I don't think bit flags make sense in this context, because the mempool.dat frequently changes and is at most expected to be read by the previous version. However, your suggestion to use a setting makes sense. The setting could have several options, like "write version 1 mempool.dat", and "use 0 for all random numbers" (if needed), and "use prng".

Edit: Hmm, I think just having a boolean option to say "write version 1 mempool.dat" is enough. If there are any users that need "use 0 for all random numbers", they can create a feature request after they read the release notes.

@0xB10C
Copy link
Contributor

0xB10C commented Aug 3, 2023

Concept ACK. I opened issue #16721 a while ago but closed it as it didn't get much attention back then.

I am not aware of anyone reading the mempool.dat, is there?

I've written a mempool.dat parser a few years ago for fun. However, as you said, the RPCs are powerful enough and if someone really really wants to read the file, they can implement XOR functionality. Similar to block0000.dat files, these files are not something considered an interface for others to rely on.

@maflcko
Copy link
Member Author

maflcko commented Aug 4, 2023

Just for context: For testing I used -datacarriersize=9999999 and then put the following nulldata raw() descriptor into the mempool.dat: raw(6a4458354f2150254041505b345c505a58353428505e2937434329377d2445494341522d5354414e444152442d414e544956495255532d544553542d46494c452124482b482a). On current master I got several hits by different virus scanners. On this pull, all virus scanners were green and didn't put the mempool.dat in the quarantine.

@maflcko maflcko force-pushed the 2308-xor-memepool- branch 2 times, most recently from a7d36ce to fa0f249 Compare August 4, 2023 07:20
@maflcko maflcko marked this pull request as ready for review August 4, 2023 07:21
@maflcko
Copy link
Member Author

maflcko commented Aug 4, 2023

Added some code to make the Windows CI pass

Copy link
Member

@darosior darosior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept and approach ACK. I don't think there is harm in making it the default behaviour immediately.

src/init.cpp Outdated Show resolved Hide resolved
src/kernel/mempool_options.h Show resolved Hide resolved
@luke-jr
Copy link
Member

luke-jr commented Aug 5, 2023

Concept ACK, I don't think we need to concern with external programs reading this. If they do exist, they can adapt easily.

@luke-jr
Copy link
Member

luke-jr commented Aug 5, 2023

(Although downgrading might be something we want to support?)

@maflcko
Copy link
Member Author

maflcko commented Aug 6, 2023

(Although downgrading might be something we want to support?)

It is. You can simply set -persistmempoolv1=1.

@glozow
Copy link
Member

glozow commented Aug 7, 2023

concept ACK

@RandyMcMillan
Copy link
Contributor

Concept ACK

Copy link
Member

@ismaelsadeeq ismaelsadeeq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

light code-review ACK fac48d2

Idk why but I try testing the behavior on master 5aa67eb with the steps you provided here but no anti virus quarantined the mempool.dat file, I used Intego, bitfinder.

When we want to drop support for writing in the legacy format (v1), mempool_compatibilty.py functional test should be deleted along the CL I think.

Do we also want fee_estimates.dat to be persisted with XOR?

src/kernel/mempool_persist.cpp Show resolved Hide resolved
src/kernel/mempool_persist.cpp Outdated Show resolved Hide resolved
src/kernel/mempool_persist.cpp Outdated Show resolved Hide resolved
src/kernel/mempool_persist.cpp Outdated Show resolved Hide resolved
src/kernel/mempool_persist.cpp Outdated Show resolved Hide resolved
src/kernel/mempool_persist.cpp Outdated Show resolved Hide resolved
@maflcko
Copy link
Member Author

maflcko commented Aug 23, 2023

but no anti virus quarantined the mempool.dat file, I used Intego, bitfinder.

The majority won't detect the eicar test virus I used. I used an online service to scan the mempool.dat and IIRC 4/50 were red (or so), but I don't recall which.

Do we also want fee_estimates.dat to be persisted with XOR?

Why? IIUC correctly, it only stores integers and floating point number calculated locally, or am I missing something? peers.dat may be a better choice for XOR?

Copy link
Member

@glozow glozow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK fa52084
Code LGTM, tried a few roundtrips of stop/start/savemempool/importmempool with combinations of the options. I originally thought -persistmempool=0 should imply something for -persistmempoolv1 but makes sense that it applies to savemempool when we're not persisting.

test/functional/mempool_compatibility.py Show resolved Hide resolved
src/kernel/mempool_persist.cpp Show resolved Hide resolved
@DrahtBot DrahtBot requested review from hernanmarino and removed request for hernanmarino November 9, 2023 13:59
Copy link
Member

@glozow glozow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reACK fa6b053

@DrahtBot DrahtBot requested review from darosior, hernanmarino and achow101 and removed request for hernanmarino November 10, 2023 17:41
Copy link
Member

@ismaelsadeeq ismaelsadeeq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK fa6b053

Used this PR to successfully read a mempool.dat saved in the legacy format.
Additionally, the persistmempoolv1 option downgraded and allowed dumping using the legacy format.

Code looks good to me.

@@ -458,6 +458,11 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-par=<n>", strprintf("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)",
-GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-persistmempool", strprintf("Whether to save the mempool on shutdown and load on restart (default: %u)", DEFAULT_PERSIST_MEMPOOL), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-persistmempoolv1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is an improvement, this patch allows you to read mempool.dat dumped using the legacy format.
Whats the a rationale to temporary retention of persistmempoolv1, and when can we expect to remove this option?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fine to remove in the second next release after this is merged. I presume the read code (// Leave XOR-key empty ) can stay forever/longer, because it is just one line of code, so no strong opinion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIU we are persisting with XOR to "protect against programs that accidentally and unintentionally are trying to mess with the dat file" so I think it will be better if we completely prevent dumping without XOR.

@DrahtBot DrahtBot requested review from hernanmarino and removed request for hernanmarino November 13, 2023 13:56
@achow101
Copy link
Member

re-ACK fa6b053

@DrahtBot DrahtBot requested review from hernanmarino and removed request for achow101 and hernanmarino November 13, 2023 16:17
@achow101 achow101 merged commit d232e36 into bitcoin:master Nov 13, 2023
16 checks passed
@maflcko maflcko deleted the 2308-xor-memepool- branch November 13, 2023 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet