-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
rpc: distinguish between vsize and sigop-adjusted mempool vsize #27591
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, 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. |
Concept ACK |
Concept ACK on clarifying and returning both variants. It would useful to peruse a few other projects to see how they use |
Concept ACK, but should be split into two commits. |
…p size CTxMemPoolEntry::GetTxSize() returns the maximum between vsize and "sigop size" which is used internally. Users of the RPC interface are probably not expecting this result from "vsize" (as it is not documented). Fix this, and add a separate result for "mempool_vsize". Github-Pull: bitcoin#27591 Rebased-From: 60bde2d
On further thought, it might make more sense to correct the description and maybe add a |
Add a result for users who are expecting BIP141 vsize without sigop adjustment.
60bde2d
to
9cf46b6
Compare
Makes sense to me, changed. Also means no changes to the existing field apart from documentation.
Did this, one editing the doc and another to add the new field Also rebased since it's been a few months. |
@@ -130,7 +130,9 @@ static RPCHelpMan testmempoolaccept() | |||
{RPCResult::Type::STR, "package-error", /*optional=*/true, "Package validation error, if any (only possible if rawtxs had more than 1 transaction)."}, | |||
{RPCResult::Type::BOOL, "allowed", /*optional=*/true, "Whether this tx would be accepted to the mempool and pass client-specified maxfeerate. " | |||
"If not present, the tx was not fully validated due to a failure in another tx in the list."}, | |||
{RPCResult::Type::NUM, "vsize", /*optional=*/true, "Virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted (only present when 'allowed' is true)"}, | |||
{RPCResult::Type::NUM, "vsize", /*optional=*/true, "Maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just define "virtual size" to consider bytespersigop policy in general. (But the difficulty calculating it may be an issue)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting we add a doc/policy/virtual_size.md?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps doc/policy/feerates-and-vsize.md (or perhaps policy/mining-score.md) with the idea being to document how we prioritise txs for mining (namely via fee vs vsize), how vsize is calculated (weight scaled down by a factor of 4, then rounded up, and only sigop-adjusted when that is possible), and that for normal transactions sigop-adjustment doesn't actually change anything. Could also add that -bytespersigop
allows tweaking how the sigop-adjustment works, and why that's important to do and can be a bad thing to change (bad fee estimation, suboptimal block templates).
Concept ack. Kinda unfortunate that the "vsize" field is still kinda broken IMO, only it's backwards compatible. In fact, arguably since you changed the documentation, it is now also a breaking change in the API spec. And arguably the field not being implemented as it's documented could be seen as a bug and fixing the field to actually be what it says to be is a bugfix. Personally I'd change the semantics of the vsize field to keep it "as per 141" and add something else like "vsize_sigops" for the alternative weird mempool-specific value. |
I disagree that the sigop-adjusted value is a "weird mempool-specific value"; in fact I'd contend it's the only value anyone should ever use (which is why it got dropped in in the first place). It is our best estimate for how much effective block space a transaction uses, rescaled to 1000000, for purposes of block building, fee estimation, feerate-based policies one would want to enforce, ... Now, it's also not perfect. Sadly it can only be computed in contexts where the input is known, and it is subject to a fudge factor (20 vbytes / sigop) that'll likely be off in case a very large number of transactions would be high sigop. So I see why it's annoying to define precisely and work with, but that doesn't change the fact that uninformed users should use the adjusted value if it is available. |
I suppose this is only relevant for pre-taproot (pre-segwit?) sigops, right? Because tapscript introduces this "validation weight/budget" concept? So I guess eventually the confusion will mostly disappear :) |
@@ -840,7 +845,8 @@ static RPCHelpMan submitpackage() | |||
{RPCResult::Type::OBJ, "wtxid", "transaction wtxid", { | |||
{RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"}, | |||
{RPCResult::Type::STR_HEX, "other-wtxid", /*optional=*/true, "The wtxid of a different transaction with the same txid but different witness found in the mempool. This means the submitted transaction was ignored."}, | |||
{RPCResult::Type::NUM, "vsize", "Virtual transaction size as defined in BIP 141."}, | |||
{RPCResult::Type::NUM, "vsize", "Maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."}, | |||
{RPCResult::Type::NUM, "vsize_bip141", "Virtual transaction size as defined in BIP 141."}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR description needs updating from "mempool_vsize"
@@ -130,7 +130,9 @@ static RPCHelpMan testmempoolaccept() | |||
{RPCResult::Type::STR, "package-error", /*optional=*/true, "Package validation error, if any (only possible if rawtxs had more than 1 transaction)."}, | |||
{RPCResult::Type::BOOL, "allowed", /*optional=*/true, "Whether this tx would be accepted to the mempool and pass client-specified maxfeerate. " | |||
"If not present, the tx was not fully validated due to a failure in another tx in the list."}, | |||
{RPCResult::Type::NUM, "vsize", /*optional=*/true, "Virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted (only present when 'allowed' is true)"}, | |||
{RPCResult::Type::NUM, "vsize", /*optional=*/true, "Maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps doc/policy/feerates-and-vsize.md (or perhaps policy/mining-score.md) with the idea being to document how we prioritise txs for mining (namely via fee vs vsize), how vsize is calculated (weight scaled down by a factor of 4, then rounded up, and only sigop-adjusted when that is possible), and that for normal transactions sigop-adjustment doesn't actually change anything. Could also add that -bytespersigop
allows tweaking how the sigop-adjustment works, and why that's important to do and can be a bad thing to change (bad fee estimation, suboptimal block templates).
@@ -252,7 +255,8 @@ static RPCHelpMan testmempoolaccept() | |||
static std::vector<RPCResult> MempoolEntryDescription() | |||
{ | |||
return { | |||
RPCResult{RPCResult::Type::NUM, "vsize", "virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."}, | |||
RPCResult{RPCResult::Type::NUM, "vsize", "maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."}, | |||
RPCResult{RPCResult::Type::NUM, "vsize_bip141", "virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think rather than adding vsize_bip141
to mempool RPCs, it would be better to (a) document mempool vsize as being sigop-adjusted, and (b) document rawtransaction vsize as not being sigop-adjusted? (Or, even better, do the sigop adjustment in cases where we can -- getrawtransaction of txs in blocks could pull up the utxo being spent via rev*.dat and calculate the sigop adjustment?)
Could be sensible to add "sigopsize" for the cases where we have a sigop count -- in that case vsize is simply max(floor((weight+3)/4), sigopsize), and the presence of a sigopsize with the exact same value as the weird vsize might be mostly self-explanatory as to what's going on. (And for the normal case where the weight dominates, it actually shows why the sigop adjustment isn't relevant)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC the suggestion is:
- Add docs for where vsize is sigop-adjusted and where it isn't.
- Add some doc/policy/?.md describing feerate, vsize, mining score
- Add an optional "sigopsize" result for
getrawtransaction
and the mempool RPCs when we're able to provide it
Will work on this
🐙 This pull request conflicts with the target branch and needs rebase. |
Concept ACK |
⌛ There hasn't been much activity lately and the patch still needs rebase. What is the status here?
|
Concept ACK. |
⌛ There hasn't been much activity lately and the patch still needs rebase. What is the status here?
|
Sorry, I kept thinking I would get back to this but haven't. Closing + marking up for grabs. |
CTxMemPoolEntry::GetTxSize()
returns the maximum between vsize and "sigop-adjusted size" which is used by mempool validation and mining code as a heuristic to avoid 2DKnapsacking the block weight and sigop limits.Sigop-adjusted vsize is returned as the "vsize" value of a transaction for RPCs retrieving mempool entry information (e.g.
getmempoolentry
andgetrawmempool
) and mempool acceptance (testmempoolaccept
andsubmitpackage
). The documentation for these RPCs usually says "virtual transaction size as defined in BIP 141" without mentioning the sigop adjustment. At least 1 user has expressed confusion in a tweet.I think we should at least mention something in the docs about the sigop-adjusted size. But imo it would be better to provide 2 vsize results: one that is sigop-adjusted and one that isn't.
Seeking feedback on what might be most clear/helpful for users.
This PR's approach is to change the result for "vsize" to not include sigop limits. The sigop-adjusted vsize is returned as a new result, "mempool_vsize".