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

assumeutxo: fail early if snapshot block hash doesn't match AssumeUTXO parameters #28652

Conversation

theStack
Copy link
Contributor

Right now the loadtxoutset RPC call treats literally all files with a minimum size of 40 bytes (=size of metadata) as potential valid snapshot candidates and the waiting loop for seeing the metadata block hash in the headers chain is always entered, e.g.:

$ ./src/bitcoin-cli loadtxoutset ~/.vimrc
<wait>

bitcoind log:
...
2023-10-15T14:55:45Z [snapshot] waiting to see blockheader 626174207465730a7265626d756e207465730a656c62616e65207861746e7973 in headers chain before snapshot activation
...

There is no point in doing any further action though if we already know from the start that the UTXO snapshot loading won't be successful. This PR adds an assumeutxo parameter check immediately after the metadata is read in, so we can fail immediately on a mismatch:

$ ./src/bitcoin-cli loadtxoutset ~/.vimrc                                                                                      
error code: -32603                                                  
error message:                                                      
Unable to load UTXO snapshot, assumeutxo block hash in snapshot metadata not recognized (626174207465730a7265626d756e207465730a656c62616e
65207861746e7973)

This way, users who mistakenly try to load files that are not snapshots don't have to wait 10 minutes (=the block header waiting timeout) anymore to get a negative response. If a file is loaded which is a valid snapshot (referencing to an existing block hash), but one which doesn't match the parameters, the feedback is also faster, as we don't have to wait anymore to see the hash in the headers chain before getting an error.

This is also partially fixes #28621.

@DrahtBot
Copy link
Contributor

DrahtBot commented Oct 15, 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 ryanofsky, maflcko, pablomartin4btc

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:

  • #28659 (assumeutxo, rpc: Add 'start' parameter to loadtxoutset by hernanmarino)
  • #28647 (test: Add assumeutxo test for wrong hash by maflcko)

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

maflcko commented Oct 16, 2023

Wasn't the goal to make the RPC async, in which case the wait loop can be replaced with an immediate error? This would also avoid having to duplicate error checks in the RPC, as well as the Activate function?

@theStack
Copy link
Contributor Author

theStack commented Oct 16, 2023

Wasn't the goal to make the RPC async, in which case the wait loop can be replaced with an immediate error? This would also avoid having to duplicate error checks in the RPC, as well as the Activate function?

Yes, I think that's one of the long-term plans: #28620. It seems that currently no-one is working on that though and even if, it's likely too late to include it into the upcoming release v26 anyway. This PR is based on the assumption that the loadtxoutset RPC is released in its current form (if that's the case, we should add an "EXPERIMENTAL" warning) and given that, we shouldn't waste users time and leave them up to 10 minutes in the dark (creating the illusion that something useful happens in the background) until they get an error for an RPC that currently can only fail on mainnet. Or is the plan to deactivate loadtxoutset until #28620 is implemented?

Copy link
Member

@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

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

Concept ACK.

It happened to me during assumeutxo testing so returning errors earlier if possible makes sense to me, even if loadtxoutset is made async at some point.

@@ -2751,6 +2751,10 @@ static RPCHelpMan loadtxoutset()
afile >> metadata;

uint256 base_blockhash = metadata.m_base_blockhash;
if (!Params().AssumeutxoForBlockhash(base_blockhash).has_value()) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: Use chainman to get the params, instead of using the global?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, done. Intentionally moved the chainman definition up more than needed (right after node) to fail early in the (hypothetical?) case that there's no chainman.

@theStack theStack force-pushed the 202310-assumeutxo-fail_early_if_blockhash_not_in_params branch from 164273c to 9620cb4 Compare October 16, 2023 15:21
Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

Code review ACK 9620cb4. This should fix an annoyance and bad UX.

It would be possible to deduplicate the checks in the loadtxoutset function and ActivateSnapshot without making the RPC async by splitting ActivateSnapshot up and returning util::Result as suggested #27596 (comment). But the current PR seems like a simple improvement for now.

@maflcko
Copy link
Member

maflcko commented Oct 16, 2023

lgtm ACK 9620cb4

@DrahtBot DrahtBot requested review from pablomartin4btc and removed request for pablomartin4btc October 16, 2023 15:53
@fanquake fanquake added this to the 26.0 milestone Oct 16, 2023
Copy link
Member

@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

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

tACK 9620cb4

error ouput with a file which size >= 40 bytes (size of SnapshotMetadata)
./src/bitcoin-cli -datadir=${AU_DATADIR} loadtxoutset ${AU_DATADIR}/utxo-111.dat
error code: -32603
error message:
Unable to load UTXO snapshot, assumeutxo block hash in snapshot metadata not recognized (3634353634363536363435363436353636343536343635363634353634363536)
error ouput with a file which size < 40 bytes (not enough to fit SnapshotMetadata structure)
./src/bitcoin-cli -datadir=${AU_DATADIR} loadtxoutset ${AU_DATADIR}/utxo-111.dat
error code: -1
error message:
AutoFile::read: end of file: iostream error

I left a suggestion to handle iostream error when utxo file size is less than 40 bytes.

@@ -2751,14 +2752,16 @@ static RPCHelpMan loadtxoutset()
afile >> metadata;
Copy link
Member

Choose a reason for hiding this comment

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

Since we are touching this file I think we could improved the iostream error that's thrown when the file size is less than 40 bytes.

Suggested change
afile >> metadata;
// Check if the file size is at least as large as the expected size of SnapshotMetadata
if (afile.size() < sizeof(SnapshotMetadata)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Unable to load UTXO snapshot, "
"file size is invalid");
}
afile >> metadata;

@fjahr
Copy link
Contributor

fjahr commented Oct 17, 2023

Since this adds the test for a bad hash, that Todo should be removed from the list at the top of feature_assumeutxo.py

@theStack
Copy link
Contributor Author

Since this adds the test for a bad hash, that Todo should be removed from the list at the top of feature_assumeutxo.py

This PR doesn't add a new test; the "bad hash" TODO (which refers to the UTXO set hash, not the block hash in the metadata, as far as I understand) is tackled in #28647.

@maflcko
Copy link
Member

maflcko commented Oct 17, 2023

Since this adds the test for a bad hash, that Todo should be removed from the list at the top of feature_assumeutxo.py

This PR doesn't add a new test; the "bad hash" TODO (which refers to the UTXO set hash, not the block hash in the metadata, as far as I understand) is tackled in #28647.

No, I'd say it is still up for grabs: #28647 (comment)

@fanquake fanquake merged commit 738ef44 into bitcoin:master Oct 17, 2023
16 checks passed
@theStack theStack deleted the 202310-assumeutxo-fail_early_if_blockhash_not_in_params branch October 17, 2023 09:23
@fjahr
Copy link
Contributor

fjahr commented Oct 17, 2023

Since this adds the test for a bad hash, that Todo should be removed from the list at the top of feature_assumeutxo.py

This PR doesn't add a new test; the "bad hash" TODO (which refers to the UTXO set hash, not the block hash in the metadata, as far as I understand) is tackled in #28647.

Sorry, I actually meant the block hash one, just misspelled/confused: TODO: Valid snapshot file, but referencing an unknown block. But I guess the "unknown" part is not covered yet, so I addressed it here: #28666

@hernanmarino
Copy link
Contributor

Wasn't the goal to make the RPC async, in which case the wait loop can be replaced with an immediate error? This would also avoid having to duplicate error checks in the RPC, as well as the Activate function?

Yes, I think that's one of the long-term plans: #28620. It seems that currently no-one is working on that though and even if, it's likely too late to include it into the upcoming release v26 anyway. This PR is based on the assumption that the loadtxoutset RPC is released in its current form (if that's the case, we should add an "EXPERIMENTAL" warning) and given that, we shouldn't waste users time and leave them up to 10 minutes in the dark (creating the illusion that something useful happens in the background) until they get an error for an RPC that currently can only fail on mainnet. Or is the plan to deactivate loadtxoutset until #28620 is implemented?

I implemented a (partial) fix for #28620 , you might want to take a look.

Frank-GER pushed a commit to syscoin/syscoin that referenced this pull request Oct 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

rpc: loadtxoutset should return errors that currently go to logs
8 participants