Skip to content

Support serde_2026 generators in trusted RPC helpers - #1500

Draft
richardkiss wants to merge 1 commit into
mainfrom
rpc-helpers-serde-2026
Draft

Support serde_2026 generators in trusted RPC helpers#1500
richardkiss wants to merge 1 commit into
mainfrom
rpc-helpers-serde-2026

Conversation

@richardkiss

Copy link
Copy Markdown
Contributor

Why

#1438 made the INTERNED_GENERATOR consensus path emit and require serde_2026-encoded generators. Bugbot flagged on that PR (r3662079661) that trusted helper functions still parse generators with node_from_bytes_backrefs() only, and arvidn confirmed as a non-blocking follow-up: the helper functions the full node uses to respond to RPCs (like get_puzzle_and_solution_for_coin and additions_and_removals) need to support the new generator format as well.

Layering: consensus stays strict, trusted read helpers sniff

  • The consensus path (run_block_generator2) is unchanged: with INTERNED_GENERATOR active, serde_2026 is the only legal encoding, and pre-HF2 the classic/backrefs encodings are the only legal ones. No sniffing there.
  • Trusted (non-consensus) helpers run on already-validated blocks, so format detection is appropriate. They now dispatch on the serde_2026 magic prefix via the existing chia_consensus::serde_2026::node_from_bytes_auto() (introduced for exactly this purpose). Detection is unambiguous: the 6-byte magic starts with 0xfd, which cannot begin a valid classic CLVM serialization (0xfd declares an atom length >= 2^40, above the 2^34 cap).

Audited surface

Changed (parsed generator blobs with node_from_bytes_backrefs() only):

  • additions_and_removals() (chia-consensus) — also fixes the python binding, which wraps it
  • get_puzzle_and_solution_for_coin() and get_puzzle_and_solution_for_coin2() (python bindings; the generator-bytes parsing for these lives in the wheel)
  • generator_interned_vbytes() (python binding)

Audited and deliberately unchanged:

  • run_block_generator() / run_block_generator2() — consensus path, stays strict
  • get_coinspends_for_trusted_block() / get_coinspends_with_conditions_for_trusted_block() — already handle serde_2026 (via INTERNED_GENERATOR flag dispatch, from [CHIA-3823] Add INTERNED_GENERATOR consensus path + serde_2026 prefix guard #1438)
  • solution_generator*(), InternedBlockBuilder, run_spendbundle(), fast-forward — parse puzzle/solution blobs from spend bundles, not block generators
  • wheel run_chia_program() — general-purpose CLVM runner, not a generator-specific helper
  • chia-tools (visit_spends::run_generator, test-block-generators --test-serializer) — offline analysis tools; can be updated when post-HF2 blocks exist on chain

Notes

  • Program (Streamable) cannot hold a serde_2026 blob yet (serialized_length_from_bytes* rejects 0xfd), so get_puzzle_and_solution_for_coin2() and the get_coinspends_* wrappers — which take the generator as Program — can't receive serde_2026 blobs from python until that lands. The buffer-taking helpers are covered end-to-end from python now.
  • Python-visible behavior is otherwise unchanged: same signatures, same results for classic generators.

Tests

Each changed helper has a test exercising it with both a classic and a serde_2026 encoding of the same spends (built with solution_generator() / solution_generator_2026(), the latter producing the same wire format as InternedBlockBuilder::finalize()), asserting identical results:

  • Rust: test_serde_2026_generator_equivalence in additions_and_removals.rs (with pre- and post-HF2 flag sets)
  • Python: test_additions_and_removals_serde_2026, test_get_puzzle_and_solution_for_coin_serde_2026, test_generator_interned_vbytes_serde_2026

Made with Cursor

Post-HF2 blocks (INTERNED_GENERATOR) encode their transactions generator
with serde_2026, but several trusted (non-consensus) helpers the full
node uses to respond to RPCs still parsed generators with
node_from_bytes_backrefs() only, and would fail on such blocks:

- additions_and_removals()
- get_puzzle_and_solution_for_coin() / ..._for_coin2() (python bindings)
- generator_interned_vbytes() (python binding)

These helpers run on already-validated blocks, so unlike the consensus
path (which stays strict about the one legal encoding per era) they now
detect the encoding by sniffing the serde_2026 magic prefix, via the
existing node_from_bytes_auto() from chia_consensus::serde_2026. The
sniffing is unambiguous: the magic prefix starts with 0xfd, which cannot
begin a valid classic CLVM serialization.

Each changed helper gets a test exercising it with both a classic and a
serde_2026 encoding of the same spends, asserting identical results.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coveralls-official

Copy link
Copy Markdown

Coverage Report for CI Build 30841843169

Coverage increased (+0.1%) to 82.041%

Details

  • Coverage increased (+0.1%) from the base build.
  • Patch coverage: 13 of 13 lines across 3 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 20035
Covered Lines: 16437
Line Coverage: 82.04%
Coverage Strength: 11581254.31 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant