Give Tx and Header native field newtypes - #597
Conversation
Replace raw integer and byte-vector protocol fields with bitcoin-rs newtypes: Amount, Sequence, Script, Witness, LockTime, and CompactTarget. JSON, RPC, and packed UTXO layouts stay in satoshis and consensus u32 at those boundaries via to_sat and to_consensus. This is the typed-field half of keeping crates/primitives native (#172). Co-authored-by: metaphorics <metaphorics@users.noreply.github.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_f213d1c5-111e-4c00-a895-d76e7ecfc197) |
PR Summary by QodoAdopt native newtypes for transaction and header fields
AI Description
Diagram
High-Level Assessment
Files changed (120)
|
Code Review by Qodo
1. Non-coinbase inputs lose fields
|
| /// One bitcoin in satoshis. | ||
| pub const COIN: Self = Self(100_000_000); | ||
| /// Consensus maximum money (21 million bitcoin). | ||
| pub const MAX_MONEY: Self = Self(21_000_000 * 100_000_000); |
There was a problem hiding this comment.
1. max_money has duplicate owners 📘 Rule violation ⚙ Maintainability
Amount::MAX_MONEY independently redefines the existing consensus maximum-money rule instead of reusing its canonical owner. The duplicate constants can diverge and cause inconsistent amount validation.
Agent Prompt
## Issue description
`Amount::MAX_MONEY` duplicates the existing consensus `MAX_MONEY` constant and its 21-million-BTC literal, creating multiple owners for the same protocol rule.
## Issue Context
Choose one canonical owner for the maximum-money limit. Either remove the unused associated constant or migrate consensus validation to the primitives-owned typed constant and eliminate the old independent definition.
## Fix Focus Areas
- crates/primitives/src/units.rs[14-21]
- crates/consensus/src/lib.rs[201-202]
- crates/consensus/src/verify_tx.rs[789-798]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| "txid": prev_txid.to_string(), | ||
| "vout": prev_vout, | ||
| "scriptSig": { | ||
| "asm": script_asm(&input.script_sig), |
There was a problem hiding this comment.
2. Non-coinbase inputs lose fields 🐞 Bug ≡ Correctness
input_json now emits only sequence for non-coinbase inputs, dropping txid, vout, and scriptSig from verbose transaction responses. Clients can no longer identify the spent outpoint or inspect the unlocking script.
Agent Prompt
## Issue description
Restore `txid`, `vout`, and the `scriptSig` object in the non-coinbase branch of `input_json`, while retaining the new `Sequence::to_consensus()` conversion.
## Issue Context
The typed-field migration accidentally removed public transaction JSON fields rather than only adapting the sequence value. The compatibility projection demonstrates the intended non-coinbase shape.
## Fix Focus Areas
- crates/rpc/src/tx_render.rs[180-202]
- crates/rpc/src/compat/convert.rs[323-334]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| use bitcoin_rs_primitives::{ | ||
| Amount, Hash256, LockTime, Script, Sequence, Sighash, SighashCache, SighashError, Tx, TxOut, | ||
| Witness, | ||
| }; |
There was a problem hiding this comment.
3. Clippy fails on imports 🐞 Bug ⚙ Maintainability
checker.rs imports LockTime, Script, Sequence, and Witness in the production module but only uses them in its separately-importing test submodule; this produces unused_imports. The CI clippy command passes -D warnings, so the PR cannot pass the required lint gate.
Agent Prompt
## Issue description
Remove primitive types imported into production scopes but used only by nested test modules. These trigger `unused_imports`, which CI promotes to an error.
## Issue Context
`checker.rs` already imports the test-only types inside its `#[cfg(test)]` module. Apply the same cleanup to analogous migration imports in other production modules where applicable.
## Fix Focus Areas
- crates/script/src/checker.rs[12-15]
- .github/workflows/ci.yml[59-80]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Qodo Fixer🍒 Ready to be cherry-picked — ✅ Merged (0) · ☑ Fixed (3) 🔗 Fix PR: #601 This fix PR was closed automatically. Its branch is preserved so you can cherry pick the changes into the original PR. Prompt for coding agent Process — 3 fixed
|
Amount::MAX_MONEY owns the 21-million-BTC rule (derived from COIN). Consensus MAX_MONEY is now a satoshi view of that constant, and transaction output checks compare against the typed limit. Keep production primitive imports to types named on the production path and restore test-only names under cfg(test) so clippy -D warnings stays clean. Restore verbose non-coinbase vin txid, vout, and scriptSig that wrapping sequence dropped. Co-authored-by: metaphorics <metaphorics@users.noreply.github.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_6f2ab73a-461c-49fe-9f19-fc7251197e6e) |
Stacked on #522 (and #483). Breaking field types for native primitives.
Tx,TxIn,TxOut, andHeadernow use bitcoin-rs newtypes instead of raw integers and byte vectors:TxOut.value:AmountTxIn.sequence/Tx.lock_time:Sequence/LockTimeTxIn.script_sig/TxOut.script_pubkey:ScriptTxIn.witness:WitnessHeader.bits:CompactTargetThese types live in
crates/primitives(units.rs,script.rs). They are notrust-bitcoinaliases or conversion shims. Wire conversion isfrom_sat/to_satandfrom_consensus/to_consensus. JSON, RPC, and packed UTXO layouts still speak satoshis and consensusu32at those boundaries.Integer comparisons (
Amount == 50_000,Sequence < 0xfffffffe,CompactTarget == 0x1d00ffff) andFrom<u32>/From<u64>keep call sites tight without Deref to the inner integer.Workspace consumers (chain, consensus, script, mempool, mining, utxo, node, rpc, p2p, index) are updated. rust-bitcoin remains only at RPC/wallet-facing and differential-oracle seams.
Toward #172:
crates/primitivesowns the protocol vocabulary end to end.Review follow-up (
fda86b80):Amount::MAX_MONEYis the sole 21-million-BTC owner; consensusMAX_MONEYisAmount::MAX_MONEY.to_sat(), and output-value checks compare against the typed limit.txid,vout, andscriptSigfor non-coinbase inputs.cfg(test).