feat: introduce balius-proto for runtime <-> WASM schema#98
feat: introduce balius-proto for runtime <-> WASM schema#98
Conversation
Decouple the WASM ABI from the upstream utxorpc spec. The runtime previously shipped utxorpc::spec::cardano::* prost-encoded bytes across the WIT boundary as cbor; that implicitly made the upstream u5c spec the WASM ABI, so the 0.17 -> 0.18 BigInt break propagated to every existing worker. balius-proto owns a frozen schema (mirrors utxorpc-spec 0.17.0 wire format). The runtime converts upstream u5c types into this schema once at chainsync ingress and at ledger reads. BigInt -> u64/i64 is fallible and halts the worker on overflow. Workers built against the pre-BigInt SDK keep decoding cleanly because the new bytes are wire-identical to what they expect. balius-sdk drops the utxorpc-spec dep in favor of balius-proto; Utxo<D>::coin() and PParams field access become plain integers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughA new Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~55 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
balius-runtime/src/lib.rs (1)
315-319: 💤 Low valueConsider making
from_bytesfallible for robustness.The
unwrap()onBlock::decodewill panic if the stored bytes are malformed. While blocks are converted at chain-sync ingress (so stored data should be valid), returningResultwould provide graceful handling for edge cases like store corruption.♻️ Optional: Return Result instead of panicking
- pub fn from_bytes(data: &[u8]) -> Self { + pub fn from_bytes(data: &[u8]) -> Result<Self, prost::DecodeError> { use prost::Message; - Self::Cardano(balius_proto::cardano::Block::decode(data).unwrap()) + Ok(Self::Cardano(balius_proto::cardano::Block::decode(data)?)) }This would require updating call sites to handle the
Result.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@balius-runtime/src/lib.rs` around lines 315 - 319, Change from_bytes to be fallible: replace the current panic-on-error behavior in from_bytes (which constructs Self::Cardano from balius_proto::cardano::Block::decode(data).unwrap()) with a Result-returning signature (e.g., Result<Self, prost::DecodeError> or your crate error type) and propagate the decode error using ? or map_err so malformed bytes are returned as Err; update callers of from_bytes to handle the Result accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@balius-runtime/src/lib.rs`:
- Around line 315-319: Change from_bytes to be fallible: replace the current
panic-on-error behavior in from_bytes (which constructs Self::Cardano from
balius_proto::cardano::Block::decode(data).unwrap()) with a Result-returning
signature (e.g., Result<Self, prost::DecodeError> or your crate error type) and
propagate the decode error using ? or map_err so malformed bytes are returned as
Err; update callers of from_bytes to handle the Result accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 80355eac-cee7-4a23-82f6-a522fe0c6b2f
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (17)
Cargo.tomlbalius-proto/Cargo.tomlbalius-proto/src/cardano.rsbalius-proto/src/cardano.serde.rsbalius-proto/src/convert.rsbalius-proto/src/lib.rsbalius-proto/tests/wire_compat.rsbalius-runtime/Cargo.tomlbalius-runtime/src/drivers/chainsync.rsbalius-runtime/src/ledgers/u5c.rsbalius-runtime/src/lib.rsbalius-sdk/Cargo.tomlbalius-sdk/src/qol.rsbalius-sdk/src/txbuilder/dsl.rsbalius-sdk/src/txbuilder/mod.rsexamples/asteria-tracker/Cargo.tomlexamples/asteria-tracker/src/lib.rs
Drop everything from cardano.rs except the wire surface workers
actually consume:
TxOutput { address, coin, assets }
Tx { inputs, outputs, fee, hash }
TxInput { tx_hash, output_index, as_output }
Multiasset, Asset (output_coin only)
Tags absent from these structs (datum, script, certificates,
withdrawals, mint, witnesses, validity, auxiliary, proposals, ...) are
deliberately dropped — workers needing them must extend the schema and
the converter explicitly. This shrinks balius-proto from ~5400 LOC of
generated cardano + 14k LOC of pbjson serde to 181 LOC total.
Block/BlockBody/BlockHeader move out of balius-proto since they never
cross WIT. The runtime's Block enum reverts to wrapping
utxorpc::spec::cardano::Block; per-Tx conversion happens at apply_block
/ undo_block via the fallible Block::txs() accessor.
PParams gone too: the SDK txbuilder now defines a minimal
PParams { coins_per_utxo_byte: u64 } locally, and the runtime's
read-params emits a matching minimal JSON shape.
asteria-tracker example trimmed to use only multiasset fields (datum-
derived position is dropped since the datum tag is gone).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The datum payload (PlutusData) and the witness set are common worker inputs — bring them back into the trimmed schema. Both were wire-stable across utxorpc-spec 0.17 -> 0.18, so the converter just roundtrips them via prost. New types in cardano.rs: Datum, PlutusData (+ Constr, PlutusDataPair, PlutusDataMap, PlutusDataArray, BigInt), Script (+ NativeScript, NativeScriptList, ScriptNOfK), WitnessSet, VKeyWitness. Tags on PlutusData and Constr.any_constructor match upstream 0.17 verbatim (verified by failing-then-fixing wire_compat tests). asteria-tracker example restores its datum-derived position tracking. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SupernaviX
left a comment
There was a problem hiding this comment.
Hopefully tx3 integration lets you throw out all this compat stuff
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
balius-proto, a Balius-owned protobuf schema (mirrorsutxorpc-spec 0.17.0wire format) that defines the WASM ABI independently of upstream u5c.balius_proto::cardano::*at chainsync ingress and at ledger reads (u5c.rs); BigInt → u64/i64 is fallible and halts on overflow.balius-sdkdrops theutxorpc-specdep in favor ofbalius-proto;Utxo<D>::coin()andPParamsaccess become plain integer reads (no BigInt unwrap).Why
The runtime was shipping raw
utxorpc::spec::cardano::*prost bytes across the WIT boundary, which implicitly made the upstream u5c spec the WASM ABI. When u5c 0.17 → 0.18.1 flippedTxOutput.coin(and similar fields acrossAsset,Tx.fee,Collateral, certs, governance actions,PParams) fromuint64toBigInt, every existing pre-BigInt worker started decoding garbage. This PR breaks that coupling: workers built against the old SDK keep working because the new bytes are byte-identical to what they expect, and future upstream u5c churn is absorbed by a single hardcoded conversion layer inside the runtime.Notes
BigUInt/BigNIntand out-of-rangeIntproduceConvertError::Overflow. Surfaces asError::Convertin the runtime andwit::LedgerError::Upstreamfor ledger paths — workers halt rather than receive lossy values.balius-protoships pre-generatedcardano.rs+ pbjsoncardano.serde.rs(no protoc required at build).convertfeature onbalius-protois gated so the SDK doesn't pullutxorpc-spectransitively.Test plan
cargo check --workspacecleancargo test -p balius-proto --features convert— 7/7 pass (wire-compat round-trip via 0.17.0, convert path, overflow errors, load-bearing convert→0.17 decode)cargo test --workspace— all pass except the pre-existingu5c-chainsync::wallet_balance(5-vs-7 WIT variant mismatch from a stale checked-inwallet.wasm; verified failing identically onmain)utxo_handled/tx_handledmetrics advance and no decode errors appear in logs🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Refactor
Tests