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

validation/util: add GetTransactionFee #20025

Closed
wants to merge 5 commits into from

Conversation

glozow
Copy link
Member

@glozow glozow commented Sep 26, 2020

This is a followup to #19339, refining upon the 2xATMP approach. It adds a GetTransactionFee utility function which uses CheckTxInputs to get a transaction fee.

It also updates the Absurd Fee checking (see BroadcastTransaction in src/node/transaction.cpp):

  • Use GetTransactionFee to get the fee.
    • If it fails, dry-run ATMP to return a proper validation result. (GetTransactionFee does not take responsibility for filling in TxValidationState although it may be modified).
    • If it succeeds, check against max_tx_fee. If fee is too high, just return MAX_FEE_EXCEEDED.
  • If fee is ok, call ATMP to submit to mempool. Broadcast.

ATMP is called at most 1 time. I think it's best to dry-run ATMP in the failure case because ATMP should be the authority on validation, i.e. be responsible for filling in TxValidationResult here. If the results don't match; i.e. GetTransactionFee fails but ATMP somehow succeeds (which should never happen), we don't risk accidentally allowing an absurd fee through.

glozow and others added 5 commits September 24, 2020 15:19
Check absurd fee in BroadcastTransaction and RPC,
return TransactionError::MAX_FEE_EXCEEDED instead
of TxValidationResult::TX_NOT_STANDARD because this
is client preference, not a node-wide policy.
-BEGIN VERIFY SCRIPT-
sed -i 's/Fee exceeds maximum configured by \-\maxtxfee/Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)/g' src/util/error.cpp test/functional/rpc_fundrawtransaction.py test/functional/rpc_psbt.py test/functional/rpc_rawtransaction.py test/functional/wallet_bumpfee.py test/functional/wallet_create_tx.py
-END VERIFY SCRIPT-
Mempool behavior should not be user-specific.
Checking that txfee is acceptable should be
the responsibility of the wallet or client, not
the mempool.
Co-authored-by: Suhas Daftuar <sdaftuar@gmail.com>
@glozow
Copy link
Member Author

glozow commented Sep 26, 2020

@sdaftuar @jnewbery following up on our discussion about GetTransactionFee here!

@DrahtBot
Copy link
Contributor

DrahtBot commented Sep 26, 2020

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

Conflicts

Reviewers, this pull request conflicts with the following ones:

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.

@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft".

Copy link
Contributor

@LarryRuane LarryRuane left a comment

Choose a reason for hiding this comment

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

Could this PR also remove the fee return value from ATMP? I think all you'd need to do is call GetTransactionFee() from the testmempoolaccept rpc handler (before the existing call to ATMP(test_accept=true)). That would increase the lines-of-code count slightly, but is cleaner and creates even more separation between the fee stuff and ATMP.

// Failed GetTransactionFee indicates a validation failure.
// Use ATMP with test_accept to return the validation error.
AcceptToMemoryPool(*node.mempool, state, tx,
nullptr /* plTxnReplaced */, false /* bypass_limits */, true /* test_accept */);
Copy link
Contributor

Choose a reason for hiding this comment

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

I may be missing something, but I think this can be simplified further by dropping the call to ATMP here. Suppose the transaction has two problems, one that GetTransaction() catches and another that's outside its scope. GetTransactionFee() will return a failure and presumably set state appropriately (I didn't verify this, but if it doesn't, that's a bug that should be fixed). I don't see what's wrong with just returning that error.

It's true that by calling ATMP here, state may get set to a different error, but it's not clear to me why that's a better error to return.

Copy link
Member Author

Choose a reason for hiding this comment

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

ATMP should be the authority on validation; I don't want to trust anything else with filling in TxValidationResult. I think I could make it a little cleaner and have GetTransactionFee just not touch state, but CheckTxInputs needs it 🤔

@glozow
Copy link
Member Author

glozow commented Oct 1, 2020

Could this PR also remove the fee return value from ATMP? I think all you'd need to do is call GetTransactionFee() from the testmempoolaccept rpc handler (before the existing call to ATMP(test_accept=true)). That would increase the lines-of-code count slightly, but is cleaner and creates even more separation between the fee stuff and ATMP.

We just introduced the fee return value in #19940 and the hope is that, for testmempoolaccept, we can return more fee information gathered from ATMP like modified fees as well. We get this information for free, so I think it's cleaner to just use ATMP. I don't think it's possible to separate fees since it's a big part of policy.

@LarryRuane
Copy link
Contributor

LarryRuane commented Oct 4, 2020

ACK 6831972 (last commit only), provisional since this PR needs rebasing onto latest #19339.

@laanwj laanwj added this to the 22.0 milestone Oct 28, 2020
@glozow glozow closed this Nov 19, 2020
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants