Skip to content

Conversation

glozow
Copy link
Member

@glozow glozow commented Jun 20, 2020

Picked up from #15810. Add separate fee-checking logic for clients that need to enforce max fee rates, then remove the absurdFee logic from ATMP.

ATMP's nAbsurdFee argument is used to enforce user-specific behavior (it is not policy since it isn't applied consistently: it is only ever used in RPC and wallet, and set to 0 everywhere else internally). It should be removed from AcceptToMemoryPool because (1) validation results/mempool behavior should not be user-specific and (2) enforcing a max fee rate should be the responsibility of the client instead of the mempool.

Note: this PR does not intend to remove protection from high fees, just re-delegate the responsibility to clients.

@luke-jr
Copy link
Member

luke-jr commented Jun 20, 2020

Absurd fees aren't even close to the only policy being enforced in ATMP... It doesn't make sense to split just this one out.

@glozow
Copy link
Member Author

glozow commented Jun 20, 2020

Absurd fees aren't even close to the only policy being enforced in ATMP... It doesn't make sense to split just this one out.

@luke-jr Sorry 😅 I'm a beginner so I don't know very much. Do you mean that there are other things that should be taken out too, or that it's not worth doing so at all?

@luke-jr
Copy link
Member

luke-jr commented Jun 20, 2020

It might be worth doing, but I'm not sure if the costs outweigh the benefits, and if/when done, it should be splitting all policy from all consensus checks, not just one policy from the rest.

@luke-jr
Copy link
Member

luke-jr commented Jun 20, 2020

Check out 0.20...luke-jr:sendraw_force-0.20+knots#diff-24efdb00bfbe56b140fb006b562cc70bR578

This changes all the policy checks to conditionals, while leaving the non-policy checks as strictly enforced. So a split would be on the same criteria. Note that reordering stuff may not always be a good idea, however...

@DrahtBot
Copy link
Contributor

DrahtBot commented Jun 20, 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.

@glozow
Copy link
Member Author

glozow commented Jun 20, 2020

@luke-jr okay, I see what you're saying. Agree that refactoring consensus/policy should be as a whole + may or may not be worth it. I could be completely mistaken, but I thought that this was more... a user's preference rather than node's fee policy, since it's pretty much only used in RPC and wallet. It seems to be set to 0 in other places?

@JeremyRubin
Copy link
Contributor

I think you're correct in the abstract on this one @gzhao408, but concretely this behavior is probably desirable as it's a belt-and-suspenders check of preventing things getting into the mempool that are almost certainly a mistake.

Even though mining/accepting these things should be done, and our node shouldn't really do 'deep transaction inspection', the case of absurd fees is pretty clearly accidental, so we add this redundant check (which can be disabled afaict via allowhighfees) even though clients should ultimately be responsible for this and not rely on absurd fees being rejected.

I think if you wanted to move the logic somewhere else (e.g., to just RPC layer) you could do that too, but the most convenient place for that logic is in ATMP as we load the required context to check fees there already.

Client side absurd fee problems should generally improve post-taproot & with the segwit fixes as signers should be more aware of how much fees their txn is spending as they can be made aware of all the inputs values they are signing for.

@luke-jr
Copy link
Member

luke-jr commented Jun 20, 2020

@gzhao408 You may be right - it's a good point that we don't enforce it on other stuff. Maybe we should really be checking it before even calling ATMP.

@JeremyRubin This is needed for GUI transactions too, at least.

@JeremyRubin
Copy link
Contributor

One approach might be to introduce a redundant layer of logic to all the places we actually want to perform the absurdfee check, and then in a follow up PR (or commit if you want to do it in one), remove the now redundant ATMP check. I agree that ATMP is later than ideal for checking this property.

@achow101
Copy link
Member

I agree with removing the absurd fee check from ATMP, but we should still have it somewhere instead of removing it completely. Since it only is used for transactions sent by the node, the ideal place to move this to would be BroadcastTransaction in src/node/transaction.cpp. The RPC and wallet (GUI goes through the wallet) both use BroadcastTransaction.

@jnewbery
Copy link
Contributor

Concept ACK! This isn't policy, it's wallet/RPC behaviour (and as such, belongs in the wallet/RPC).

@NicolasDorier
Copy link
Contributor

Concept ACK

@glozow glozow changed the title [WIP] mempool: Remove absurd fee logic from ATMP [WIP] mempool: re-delegate absurd fee checking from mempool to clients Jul 1, 2020
@ariard
Copy link

ariard commented Jul 24, 2020

Concept ACK,

This check should be part of a consistent wallet tx-sanitization policy, i.e a set of checks protecting users funds against harmful actions before authorizing spend. Some signers already do this like Coincard. We could envision Core implementing the same kind of logic behind ScriptPubKeyMan::SignTransaction, with user settings. Now do this policy should apply to transaction flowing through our node but not originating from our wallet (sendrawtransaction) ? That's harder to decide on because in some cases an absurd fee may have a game-theory rational (a LN justice transaction burning everything in fees before CSV delay expiration).

Overall, absurd fee protection is already enforced on its own in CreateTransaction (grep m_default_max_tx_fee) but blindly removing from mempool checks would be a behavior change as it won't be applied anymore to sendrawtransaction/GUI transactions. So going forward with this PR check should be moved inside BroadcastTransaction to conserve behavior IMO.

With regards to untangling policy/consensus checks I think that should be a distinct conversation, order of them matter for anti-DoS reasons.

@glozow glozow force-pushed the mempool-remove-absurdfee branch from 717faed to 5fe1b1e Compare July 25, 2020 20:46
@glozow
Copy link
Member Author

glozow commented Jul 25, 2020

This builds on #19093. If that one is merged first then I’ll rebase this; if this one gets more review attention, @rajarshimaitra is listed as the author of the base commit here so hopefully that’s ok.

Per y’all’s wonderful advice, I moved the absurd fee checking into BroadcastTransaction and as an extra step in testmempoolaccept. Calling this a TransactionError::MAX_FEE_EXCEEDED seemed more appropriate, since that’s what the wallet uses. I still don’t think it’s policy since it’s empty for transactions not originating from the node’s own wallet. Whether it should be policy would a separate and interesting discussion 👀 .

There’s a couple intermediate stages to (1) test_accept and check fee before submitting (7dc55a5) and (2) keep absurd fee but ignore it in validation (40703b1) to show that the behavior is the same.

@glozow glozow force-pushed the mempool-remove-absurdfee branch from 5fe1b1e to 47980f4 Compare July 25, 2020 20:53
@glozow glozow marked this pull request as ready for review July 26, 2020 13:35
@glozow glozow changed the title [WIP] mempool: re-delegate absurd fee checking from mempool to clients validation: re-delegate absurd fee checking from mempool to clients Jul 26, 2020
@jnewbery
Copy link
Contributor

Approach ACK. This looks great. Thanks Gloria!

Copy link
Member

@maflcko maflcko 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 8784930, left some questions 😈

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Concept ACK 8784930dfaf4b981be6a3670c4298de2226a3989, left some questions 😈
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUjoWAwAwUFIuJljEL0JfJpPE2ETBPrIL0soXgmLHNBRHXgwPZ10WH2y6TrXAR7t
Xo9NESbW4Qp17O/PJWn9GZ/Oxl6UjbE9KF6XMqptXaUC0Jt2eGbNdvoHkVyj2Mqc
+pp76rgrKd+AU0G6YObPkDy0e8RCG66PX8u2JfLmCYoQA+cRcblg4GEFqWlBTZGw
43jQ9uGLCC3ShF2tbFfFJVeTRF4ywnyUGnmWno/vtqlWxGRtYSBdf8WSseUMHJz7
OzsWnvPyOajSCIFEHI2rJ7rutEXJQ4RXQMwCwC4RMkLTL5rsm+E3QHXmHUXOoT3r
chFpzmP7XqiEaPDEJE4zhmM8+aL3JUzGa6bBoc4EZyWLIf1imwHVREhVW9BZYV4d
AydaxhQ96c0uK5sIcfUWGZb4h8cv6tgSl/glM9gmUDewAg3JczHmwDCZv22cvcy6
ONYwgiB/0S8BpWx4OsIGVQvAjfBXtfpmkjD+ya5VoPTSCqIW+mYPpVWkGyRDjInm
EVIDY2IH
=1moD
-----END PGP SIGNATURE-----

Timestamp of file with hash 41bb2c8bffc4df4e4705ffe7775dabf9aa5e03d062a86e3f08624699d44592ad -

@@ -456,9 +456,9 @@ def run_test(self):
# Thus, testmempoolaccept should reject
testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']], 0.00001000)[0]
assert_equal(testres['allowed'], False)
assert_equal(testres['reject-reason'], 'absurdly-high-fee')
assert_equal(testres['reject-reason'], 'max-fee-exceeded')
Copy link
Member

Choose a reason for hiding this comment

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

question in commit f907f4b:

Any reason to change the reject-reason?

Copy link
Member Author

Choose a reason for hiding this comment

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

I wanted to use the same reject reason that wallet gives when a fee is too high, which is TransactionError::MAX_FEE_EXCEEDED. Also a little sanity check for all the absurdly-high-fee tests.

Copy link
Member

@maflcko maflcko Oct 5, 2020

Choose a reason for hiding this comment

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

Not sure if I understand this. MAX_FEE_EXCEEDED returns the string "Fee exceeds maximum configured by user", not "max-fee-exceeded".

As there is no reject code, RPC users might match on the reject reason, which seems brittle, but if there is no convincing argument to change, I'd prefer to leave it as is.

edit: probably not too much of a deal

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right, yeah. I guess this is an arbitrary change to make the error messages more similar 😅

glozow and others added 3 commits October 5, 2020 04:54
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.
@glozow glozow force-pushed the mempool-remove-absurdfee branch from 8784930 to b048b27 Compare October 5, 2020 11:58
@jnewbery
Copy link
Contributor

jnewbery commented Oct 5, 2020

utACK b048b27

@maflcko
Copy link
Member

maflcko commented Oct 5, 2020

re-ACK b048b27 , only change is squashing one commit 🏦

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

re-ACK b048b275d9 , only change is squashing one commit 🏦
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgq2gv8DSuQInycB5w6VMTMI7aBtPBoUDAX9yY9Z4Ruix1Im9Bf2fcJts6d9TxY
Abgr2NlSDVGkF4wNvOi3SnXkcYSto+Yt7vNat1HCORsRSzKiyshjKbXjJg/Rvi7K
S11vfpiA5YI87HoYgP/+QGUM912cLBt7DH78lnuskTVeN7B94PiyycU+WHgZw9Qm
8WvFmyft5Tn5iEhOJufn7kB1B4Zdc4CbwTRsT1FpDyxoS+JQ2rvcpJgsXRf4l4Yn
9wmZt637cYe4r5Nh4qyi56CgClbQvyyW1jgXZr3InFozkzPfXt9flbQJSKGGBDKy
c8sVErF1g2QYC5jjkvhJ6c5fpkCt9lvrudf5ol8Ouv/KVhGE9HBqtK/05GVjUefw
FfJaatnobEBXGE8JXVGvHWIazgjEd70MF1GSkZjxIyGHvvWU6IELJ2um0WP/1t4B
SDSUbDFECh4hhZQupjXmTKF5dxl2h3RgkAot+tQc4EgIt9mAg10+vL/jTWTaE1B6
l9ujyThH
=rq5V
-----END PGP SIGNATURE-----

Timestamp of file with hash ef381a3560ba63d06ec8d836ebc9b3379cdaab5ad0d2d7c5ddbfb38d235c2c69 -

@LarryRuane
Copy link
Contributor

re-ACK b048b27

@instagibbs
Copy link
Member

concept ack, this will require release notes since people tend to use sending failure codes/text in fine-grained ways and it may break downstream things

Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

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

utACK b048b27

please don't address my nit unless you have to rebase or something.

} else {
return TransactionError::MEMPOOL_ERROR;
CAmount fee{0};
if (max_tx_fee) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (max_tx_fee) {
if (max_tx_fee > 0) {

@fanquake fanquake merged commit db88db4 into bitcoin:master Oct 7, 2020
@fanquake
Copy link
Member

fanquake commented Oct 7, 2020

please don't address my nit unless you have to rebase or something.

@glozow can follow up with some release notes and address any remaining nits. Either in a new PR, or possibly as part of #20025.

@maflcko
Copy link
Member

maflcko commented Oct 7, 2020

Instead of mentioning that absurdly-high-fee changed into max-fee-exceeded, I'd rather just change it back and prevent the release notes from bloating.

Though, the reason (my reason) testmempoolaccept doesn't return an error code because we can't really guarantee stability of failure reasons across versions of Bitcoin Core. Similarly the string can't be expected to be stable. So either we assume that and don't mention the string change in the release notes, or we mention in the RPC help doc that the strings shouldn't be assumed to be stable. In both cases, the release notes don't mention the change.

@instagibbs
Copy link
Member

instagibbs commented Oct 7, 2020 via email

@maflcko
Copy link
Member

maflcko commented Oct 7, 2020

Mind sharing a link on further information how LND was broken by this?

@instagibbs
Copy link
Member

instagibbs commented Oct 7, 2020 via email

@glozow
Copy link
Member Author

glozow commented Oct 8, 2020

fwiw I think max-fee-exceeded is a more accurate error message - we're checking the maxfeerate passed in by the user, absurd or not. I'm not sure how to determine whether something should be in release notes or not :/ I'll just open a PR and we can talk there

fanquake added a commit that referenced this pull request Oct 14, 2020
88197b0 [doc] release notes for max fee checking (gzhao408)
c201d73 style and nits for fee-checking in BroadcastTransaction (gzhao408)

Pull request description:

  Pretty trivial... addresses some tiny comments from #19339. Also fixes a docs typo from #19940 and adds a release note about the error message change for testmempoolaccept.

ACKs for top commit:
  achow101:
    ACK 88197b0
  MarcoFalke:
    cr re-ACK 88197b0

Tree-SHA512: fff16d731426b9b4db5222df02633983402f4c7241551eec98bb1554145dbdc132f40ed8ca4abd5edcebe1f4d1e879fb6d11bd91730604f6552c10cdf65706a1
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 15, 2020
88197b0 [doc] release notes for max fee checking (gzhao408)
c201d73 style and nits for fee-checking in BroadcastTransaction (gzhao408)

Pull request description:

  Pretty trivial... addresses some tiny comments from bitcoin#19339. Also fixes a docs typo from bitcoin#19940 and adds a release note about the error message change for testmempoolaccept.

ACKs for top commit:
  achow101:
    ACK 88197b0
  MarcoFalke:
    cr re-ACK 88197b0

Tree-SHA512: fff16d731426b9b4db5222df02633983402f4c7241551eec98bb1554145dbdc132f40ed8ca4abd5edcebe1f4d1e879fb6d11bd91730604f6552c10cdf65706a1
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Nov 16, 2021
Summary:
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.

This is a backport of [[bitcoin/bitcoin#19339 | core#19339]] [1/3] and [[bitcoin/bitcoin#20109 | core#20109]]
bitcoin/bitcoin@8f1290c

Depends on D10463 and D10474

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10464
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Nov 16, 2021
Summary:
This is a backport of [[bitcoin/bitcoin#19339 | core#19339]] [2/3]
bitcoin/bitcoin@932564b

Depends on D10464

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10465
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Nov 16, 2021
Summary:
Mempool behavior should not be user-specific.
Checking that txfee is acceptable should be
the responsibility of the wallet or client, not
the mempool.

This is a backport of [[bitcoin/bitcoin#19339 | core#19339]] [3/3]
bitcoin/bitcoin@b048b27

Depends on D10465

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10466
@bitcoin bitcoin locked and limited conversation to collaborators Aug 14, 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.