Skip to content

consensus_encoding: add u64 support to compact size#5784

Merged
apoelstra merged 6 commits into
rust-bitcoin:masterfrom
nyonson:compact-size-u64
Mar 21, 2026
Merged

consensus_encoding: add u64 support to compact size#5784
apoelstra merged 6 commits into
rust-bitcoin:masterfrom
nyonson:compact-size-u64

Conversation

@nyonson

@nyonson nyonson commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add u64 support to the Compact Size codec since there are non prefix length use cases (#5762). Kind of related to #5752.

I believe this is the simplest way to add support, but the asymmetry kind of annoys me. On the encoding side, only a new constructor is necessary. But on the decoding side a new type is required since there is a 1:1 with the associated output. I don't think symmetry is a strong enough reason to put a type on the encoding side though.

I didn't put much though into the names, focusing on minimal change. But maybe it would be worth it to name each encoder/decoder after its use case instead of impl? So the existing one would be called something like LengthPrefixDecoder and so on.

The first commit moves the existing compact size stuff into its own ::compact_size module, to kind of corner this weirdness. This creates kind of a funky dependency graph with ::decode and ::decode::decoders (and the equivalent encoders side), but none of that is exposed from the crate since it is a private module.

@github-actions github-actions Bot added C-consensus_encoding PRs modifying the consensus-encoding crate test labels Mar 5, 2026
@nyonson nyonson force-pushed the compact-size-u64 branch 2 times, most recently from 82364b5 to ccbfdaf Compare March 5, 2026 21:50
@tcharding

Copy link
Copy Markdown
Member

Are we writing the 'decoding a compact size should fail if value over 32MB' bug back in by providing the CompactSizeU64Decoder or does the p2p usecase not have this check in Core? If we are not, and there is legit use case for this type, I rekon we need some good docs on the type explaining how we got here and when to use the type. Otherwise users are just going to go 'yeah I want a u64 - YOLO'. Remember our mandate is 'write API's that are easy to use and hard to misuse'. Even when Core bites us in the arse ...

@tcharding

Copy link
Copy Markdown
Member

Part of me wants to move all the compact size stuff into its own ::compact_size module

I rekon we should do this. The module layout in this crate is simply a code organisation thing so we are free to do it how we like. Top level private file compact_size.rs would serve use well I rekon. Do remember that private modules don't get their rustdocs included so if we add module level docs explaining all this decoding limit kerfuffle they won't be user facing.

@nyonson

nyonson commented Mar 6, 2026

Copy link
Copy Markdown
Contributor Author

Part of me wants to move all the compact size stuff into its own ::compact_size module

I rekon we should do this. The module layout in this crate is simply a code organisation thing so we are free to do it how we like. Top level private file compact_size.rs would serve use well I rekon. Do remember that private modules don't get their rustdocs included so if we add module level docs explaining all this decoding limit kerfuffle they won't be user facing.

Cool, think I can tack on the move to ::compact_size here with another commit? Or will that be a pain to review?

@tcharding

tcharding commented Mar 6, 2026

Copy link
Copy Markdown
Member

Do it, its easy to review if its a separate patch because of git zebra config. At the front of the PR or the back, its the same for me to review.

@apoelstra

Copy link
Copy Markdown
Member

Needs rebase.

@rustaceanrob

rustaceanrob commented Mar 9, 2026

Copy link
Copy Markdown
Member

Per ServiceFlag, check out my comment pls

@Bortlesboat Bortlesboat left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK ccbfdaf. Encoding/decoding is symmetric across all prefix boundaries, non-minimal rejection is correct at each tier, and the round-trip tests are thorough.

@nyonson nyonson force-pushed the compact-size-u64 branch 3 times, most recently from 66d4143 to 7c28f91 Compare March 10, 2026 03:38
Comment thread api/primitives/all-features.txt Outdated
pub type bitcoin_primitives::Wtxid::Err = hex_conservative::error::DecodeFixedLengthBytesError
pub type bitcoin_primitives::block::Block::Decoder = bitcoin_primitives::block::BlockDecoder
pub type bitcoin_primitives::block::Block::Encoder<'e> where Self: 'e = bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_primitives::block::HeaderEncoder<'e>, bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_consensus_encoding::encode::encoders::CompactSizeEncoder, bitcoin_consensus_encoding::encode::encoders::SliceEncoder<'e, bitcoin_primitives::transaction::Transaction>>>
pub type bitcoin_primitives::block::Block::Encoder<'e> where Self: 'e = bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_primitives::block::HeaderEncoder<'e>, bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_consensus_encoding::compact_size::CompactSizeEncoder, bitcoin_consensus_encoding::encode::encoders::SliceEncoder<'e, bitcoin_primitives::transaction::Transaction>>>

@nyonson nyonson Mar 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hm, need to dig in to why these APIs changed.

EDIT: maybe just a limitation of the docs-as-type-checker system?

@nyonson nyonson force-pushed the compact-size-u64 branch 3 times, most recently from e1322cf to cc51369 Compare March 10, 2026 04:25
@nyonson

nyonson commented Mar 10, 2026

Copy link
Copy Markdown
Contributor Author

cc51369: moved compact size stuff into its own module and beef'd up the docs.

For some reason this move triggered a mutant, not sure how yet, but tossed in a test to cover it. There is also a confusing diff in the primitives API files due to the move, but I think it is ok?

@nyonson

nyonson commented Mar 10, 2026

Copy link
Copy Markdown
Contributor Author

Ah, the mutant timeouts are on master already, going to deal with those separately in #5806 and then rebase.

@apoelstra

Copy link
Copy Markdown
Member

Needs rebase.

@nyonson

nyonson commented Mar 12, 2026

Copy link
Copy Markdown
Contributor Author

fe83d4f: rebased and toned down some of the yelling in the docs

@apoelstra apoelstra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK fe83d4f; successfully ran local tests

@apoelstra

Copy link
Copy Markdown
Member

@tcharding this is a nontrivial API change to consensus-encoding so we need your ACK


/// The maximum length of a compact size encoding.
const SIZE: usize = 9;
pub use crate::compact_size::CompactSizeEncoder;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think we should do this. And if we do want to do it we should mirror it for decoders.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Was the concern here about the encoder constructors? Or did I just make the commits confusing?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh it was adding 'pub use' in encoders but the decoder is not re-exported in decoders. But I don't think we should do either, just the crate root is enough IMO.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ooo, and I missed this while reviewing this morning. Thanks for flagging it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah I see now, yea, I did this really round-about. Will fix.

@tcharding

Copy link
Copy Markdown
Member

Didn't finish review sorry mate, will come back tomorrow.

@tcharding tcharding left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK fe83d4f

@tcharding

Copy link
Copy Markdown
Member

Sorry for taking so long.

@nyonson

nyonson commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

2c9b904: simplified the compact_size re-export from the root.

Comment thread api/hashes/all-features.txt Outdated
pub const bitcoin_hashes::HashEngine::LEN: usize
pub const bitcoin_hashes::IsByteArray::LEN: usize
pub const bitcoin_hashes::hash160::Hash::DISPLAY_BACKWARD: bool
pub const bitcoin_hashes::hash160::Hash::LEN: usize

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Huh, dunno why all these hashes changes showed up now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, the version of cargo-public-api is only set int he CI rust.yml workflow, it isn't shared for local dev. Need to run on cargo +nightly install --locked cargo-public-api --version 0.50.1 for now. The new cargo-rbmt tools command will handle this in the future.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yep that bit me before, sorry I didn't notice during review.

@nyonson

nyonson commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

85a6da3: regenerated api files with v0.50.1

@tcharding tcharding left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK 85a6da3

@apoelstra apoelstra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK 85a6da3; successfully ran local tests

@apoelstra apoelstra merged commit d283a89 into rust-bitcoin:master Mar 21, 2026
28 checks passed
tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request May 14, 2026
    
Manually revert 91a6e64
    
(`git revert` didn't work.)
    
This was a backport of rust-bitcoin#5697 which added range checking to the
`VarInt` type. On master we did this then realized there are
legitimate use cases for the full range of a `u64`. We then added
`u64` support to compact size (rust-bitcoin#5784).

Note that we cannot break the API so the new stuff introduced in
`0.32.9` has to stay in there. Comment the code as such.

NB: 'compact size' is the new name for varint.
    
This backport then broke downstream users.
tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request May 14, 2026
    
Manually revert 91a6e64

Note that we cannot break the API so the new stuff introduced in
`0.32.9` has to stay in there. Comment the code as such.
    
This was a backport of rust-bitcoin#5697 which added range checking to the
`VarInt` type. On master we did this then realized there are
legitimate use cases for the full range of a `u64`. We then added
`u64` support to compact size (rust-bitcoin#5784).

NB: 'compact size' is the new name for varint.
    
This backport then broke downstream users.
tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request May 14, 2026
    
Manually revert 91a6e64

Note that we cannot break the API so the new stuff introduced in
`0.32.9` has to stay in there. Comment the code as such.
    
This was a backport of rust-bitcoin#5697 which added range checking to the
`VarInt` type. On master we did this then realized there are
legitimate use cases for the full range of a `u64`. We then added
`u64` support to compact size (rust-bitcoin#5784).

NB: 'compact size' is the new name for varint.
    
This backport then broke downstream users.
tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request May 17, 2026
    
Manually revert 91a6e64

Note that we cannot break the API so the new stuff introduced in
`0.32.9` has to stay in there. Comment the code as such.
    
This was a backport of rust-bitcoin#5697 which added range checking to the
`VarInt` type. On master we did this then realized there are
legitimate use cases for the full range of a `u64`. We then added
`u64` support to compact size (rust-bitcoin#5784).

NB: 'compact size' is the new name for varint.
    
This backport then broke downstream users.
apoelstra pushed a commit that referenced this pull request May 24, 2026
    
Manually revert 91a6e64

Note that we cannot break the API so the new stuff introduced in
`0.32.9` has to stay in there. Comment the code as such.
    
This was a backport of #5697 which added range checking to the
`VarInt` type. On master we did this then realized there are
legitimate use cases for the full range of a `u64`. We then added
`u64` support to compact size (#5784).

NB: 'compact size' is the new name for varint.
    
This backport then broke downstream users.
apoelstra added a commit that referenced this pull request May 24, 2026
3bcd7c9 Manually revert VarInt range check (Tobin C. Harding)

Pull request description:

  Manually revert 91a6e64
  
  Note that we cannot break the API so the new stuff introduced in `0.32.9` has to stay in there. Comment the code as such.
  
  This was a backport of #5697 which added range checking to the `VarInt` type. On master we did this then realized there are legitimate use cases for the full range of a `u64`. We then added `u64` support to compact size (#5784).
  
  NB: 'compact size' is the new name for varint.
  
  This backport then broke downstream users.
  
  Close: #6138


ACKs for top commit:
  apoelstra:
    ACK 3bcd7c9; successfully ran local tests


Tree-SHA512: d01078f4f8fae59c439fd404a643abfb353bcec1757ebfbcabde487ff8620d927387f91d0e749a7bbd36163f2386290d301f17c0cff9e628e37585329daf116b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-consensus_encoding PRs modifying the consensus-encoding crate test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants