Skip to content

Conversation

jnewbery
Copy link
Contributor

nAbsurdFee is indeed absurd. It's a parameter that the client passes in when calling AcceptToMemoryPool() which asks "If the transaction that I'm passing you has a fee greater than this, don't accept it". The client already has the transaction in hand, and is able to look up the inputs, so it can just as easily do the check itself before submitting the transaction to the mempool.

Furthermore, nAbsurdFee is only used by the RPC and wallet clients. For transactions received from the network or the mempool.dat file (which are the majority of calls to AcceptToMemoryPool()), it is not used.

Removing this cleans up the AcceptToMemoryPool() interface and clarifies responsibilities (don't submit a transaction to the mempool if its fee is higher than you want to pay!)

This builds on #15778 and #15784.

@maflcko
Copy link
Member

maflcko commented Apr 12, 2019

Seems a lot of new code added for a simplification. Also, releasing the locks in between makes this non-atomic: Missing coins are counted as -1 satoshis (instead of their true amount), this can easily lead to not firing an error at all and accepting the tx later on, because the coins became available again.

@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 18, 2019

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

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #16129 (refactor: Remove unused includes by practicalswift)
  • #15921 (Tidy up ValidationState interface by jnewbery)
  • #15713 (refactor: Replace chain relayTransactions/submitMemoryPool by higher method by ariard)
  • #15169 (Parallelize CheckInputs() in AcceptToMemoryPool() by sdaftuar)
  • #15112 (build: Optionally enable -Wzero-as-null-pointer-constant by Empact)
  • #14920 (Build: enable -Wdocumentation via isystem by Empact)

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.

@jnewbery
Copy link
Contributor Author

Thanks for looking at this @MarcoFalke . This is still in RFC mode and I'm looking for concept feedback.

Seems a lot of new code added for a simplification.

Yes, it's additional LOC. It removes code from validation and simplifies the interface to the mempool, in exchange for adding checking to client code (RPC, wallet). I think that counts as an improvement because all other things being equal, we'd prefer less and simpler code in validation. It also makes sense for me that the client should be responsible for this checking.

Also, releasing the locks in between makes this non-atomic: Missing coins are counted as -1 satoshis (instead of their true amount), this can easily lead to not firing an error at all and accepting the tx later on, because the coins became available again.

Yikes! Good catch.

@maflcko
Copy link
Member

maflcko commented Apr 18, 2019

It removes code from validation and simplifies the interface to the mempool

The fee is already calculated in the mempool, so using it for other things is "free". I agree that the current interface to pass in the absurd fee is a bit odd, but what about returning the fee from testmempoolaccept? that way you wouldn't need to duplicate any utxo validation logic, but still could avoid passing in the absurd fee into the mempool and the client can use the result of TMPA to check if the fee was too high.

@gmaxwell
Copy link
Contributor

It would be nice to get this "local user specific behaviour" out of ATMP, I agree!

And even beyond that... fine with simplifying this, but having a lot of duplicated code isn't great. It's also important that it's reasonably precise. I think it would be okay to reject a txn with inputs not found, but we shouldn't bypass the check in that case. I think if the original behaviour had looked like this, the change would have been rejected as not worth it.

We have seen this functionality protect users from loss (including people coming into irc furious that it wouldn't send because it was protecting them... :) ) and it seems likely that there is a lot more that we don't hear about. So I wouldn't suggest removing the functionality.

It's not entirely trivial because we do have to resolve inputs against the mempool not just the chain or wallet... which ATMP inherently does for us.

+0.5 to Marco's suggestion, if something like that works, it sounds like it might be good.

@jnewbery jnewbery force-pushed the 2019-04-remove-absurd-fee branch from 88dd4b2 to 4c39963 Compare May 16, 2019 16:11
@jnewbery
Copy link
Contributor Author

Rebased. I still haven't addressed the feedback from Marco here: #15810 (comment)

@sipa
Copy link
Member

sipa commented May 20, 2019

I agree it's weird to have special logic for the absurd fee check in the mempool code, so concept ACK getting rid of that, but @MarcoFalke's suggestion seems simpler.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jun 6, 2019

Needs rebase

@jnewbery jnewbery changed the title [WIP] Remove nAbsurdFee fee from AcceptToMemoryPool [WIP] mempool: Remove nAbsurdFee fee from AcceptToMemoryPool Aug 25, 2019
@jnewbery jnewbery force-pushed the 2019-04-remove-absurd-fee branch from 4c39963 to 2373200 Compare October 11, 2019 15:17
@jnewbery
Copy link
Contributor Author

I'm not actively working on this, so I'm going to close the PR for now. In case anyone else wants to pick it up, I've rebased it on master.

A couple of things need addressing:

@glozow
Copy link
Member

glozow commented Jun 19, 2020

I’ve started working on this, rationale still = (1) mempool behavior should not be user-specific and (2) enforcing a user’s maxfeerate should be the responsibility of the client/wallet. I’d like to ask for a little bit of approach advice.

but what about returning the fee from testmempoolaccept?

I’m guessing this motivates #19093; it’ll be really simple to have a check in testmempoolaccept without passing nAbsurdFee to ATMP this way. But just to clarify, @MarcoFalke do you mean that sendrawtransaction wouldn’t need to enforce maxfeerate anymore?

For sendrawtransaction and the wallet, my current thinking is we want something like John’s GetTransactionFee here to calculate fee as cheaply as possible (maybe implemented with less duplicate code)... does this approach make sense?

@jnewbery
Copy link
Contributor Author

@gzhao408 - I think the idea is that you call AcceptToMemoryPool() with test_accept set to true to determine the feerate, and then if it's below the acceptable level, call AcceptToMemoryPool() again with test_accept set to false to actually submit the transaction to the mempool.

@glozow
Copy link
Member

glozow commented Jun 20, 2020

Ohhh okay 👍 thanks @jnewbery! Is that what "using the fee for other things is 'free'" means? It should be easy to do this on top of #19093 then.

@jnewbery
Copy link
Contributor Author

Yes, I think Marco means that no additional logic is required to be written in AcceptToMemoryPool. We already work out the feerate, so it's no additional work to just return it to the caller.

fanquake added a commit that referenced this pull request Oct 7, 2020
…l to clients

b048b27 [validation] Remove absurdfee from accepttomempool (John Newbery)
932564b scripted-diff: update max-fee-exceeded error message to include RPC (gzhao408)
8f1290c [rpc/node] check for high fee before ATMP in clients (gzhao408)

Pull request description:

  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.

ACKs for top commit:
  jnewbery:
    utACK b048b27
  LarryRuane:
    re-ACK b048b27
  MarcoFalke:
    re-ACK b048b27 , only change is squashing one commit 🏦
  instagibbs:
    utACK b048b27

Tree-SHA512: 57c17ba16d230a4cae2896dd6a64c924f307757824e35784bf96da7b10aff2d8ea910710edf35e981035623a155f8766209a92a0fdb856549fde78bc3eaae4d2
@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.

9 participants