diff --git a/BRANCH-NOTES.md b/BRANCH-NOTES.md new file mode 100644 index 0000000..7458e8b --- /dev/null +++ b/BRANCH-NOTES.md @@ -0,0 +1,120 @@ +# Sulkta-Coop/pallas — `feat-aux-data` branch notes + +This is a vendored fork of [txpipe/pallas](https://github.com/txpipe/pallas) +based on the `v0.32.1` tag. It exists to fill in three upstream `// TODO` +markers that block real-world Conway-era transaction building. + +The fork is consumed via `[patch.crates-io]` in +[`Sulkta-Coop/aldabra`](http://192.168.0.5:3001/Sulkta-Coop/aldabra)'s +workspace `Cargo.toml`. Once these changes are accepted upstream, the +patch entry gets dropped and aldabra goes back to vanilla crates.io. + +## What's added beyond `v0.32.1` + +### 1. `pallas-txbuilder` — `auxiliary_data` field on `StagingTransaction` + +Upstream had `// pub auxiliary_data: TODO` on the struct and +`auxiliary_data: None.into(), // TODO` in the conway builder. Without +this, **CIP-20 / CIP-25 / CIP-68 metadata can't ride a tx built with +pallas-txbuilder.** + +Added: +- `pub auxiliary_data: Option>` field (opaque CBOR bytes — + `pallas_primitives::AuxiliaryData` doesn't impl `Eq`, which the + rest of `StagingTransaction` requires). +- Builder methods `.auxiliary_data(cbor_bytes)` and + `.clear_auxiliary_data()`. +- `conway::build_conway_raw` now decodes the bytes via + `AuxiliaryData::decode_fragment` and plumbs them in. The existing + `auxiliary_data_hash` computation block (already in upstream) runs + after assignment and populates the body's hash automatically. + +Tests added: +- `auxiliary_data_round_trips_through_build` — encodes a CIP-25 + shape, attaches, builds, decodes, asserts byte-equivalent + re-encode + matching `auxiliary_data_hash`. +- `no_auxiliary_data_means_no_hash` — negative path. + +### 2. `pallas-txbuilder` — `certificates` field on `StagingTransaction` + +Upstream had `// pub certificates: TODO` and +`certificates: None, // TODO` in the conway builder. Without this, +**stake registration / delegation, pool registration, DRep ops, and +Voltaire-era cert types can't be built.** + +Added: +- `pub certificates: Option>>` field (opaque CBOR per + cert, same reason as `auxiliary_data`). +- Builder methods `.add_certificate(cbor_bytes)` and + `.clear_certificates()`. +- `conway::build_conway_raw` decodes each entry via + `Certificate::decode_fragment` and plumbs them into + `TransactionBody.certificates` via `NonEmptySet::from_vec`. + +Tests added: +- `certificates_plumb_through_to_tx_body` — encodes a + `StakeRegistration(AddrKeyhash([7;28]))`, builds, decodes, + asserts the cert round-trips byte-for-byte. +- `no_certificates_means_none` — negative path. + +### 3. `pallas-addresses` — `pub fn new` on `StakeAddress` + +Upstream defined `pub struct StakeAddress(Network, StakePayload)` with +**unexported tuple fields** and no `new()` constructor — so external +callers can't construct one directly. `ShelleyAddress::new` exists +already; this just matches the pattern. + +Without this, computing a wallet's reward (stake) address +required round-tripping through a `ShelleyAddress` and `TryFrom` — +clunky and indirect. + +## How aldabra consumes this + +`Sulkta-Coop/aldabra/Cargo.toml` has: + +```toml +[patch.crates-io] +pallas-codec = { git = "...Sulkta-Coop/pallas.git", branch = "feat-aux-data" } +pallas-crypto = { git = "...Sulkta-Coop/pallas.git", branch = "feat-aux-data" } +pallas-primitives = { git = "...Sulkta-Coop/pallas.git", branch = "feat-aux-data" } +pallas-traverse = { git = "...Sulkta-Coop/pallas.git", branch = "feat-aux-data" } +pallas-addresses = { git = "...Sulkta-Coop/pallas.git", branch = "feat-aux-data" } +pallas-wallet = { git = "...Sulkta-Coop/pallas.git", branch = "feat-aux-data" } +pallas-txbuilder = { git = "...Sulkta-Coop/pallas.git", branch = "feat-aux-data" } +``` + +All seven pallas crates we depend on are patched against the same +commit so cargo's version graph resolves consistently. + +## Upstream PR status + +**Not yet submitted.** Plan: + +1. ✅ Land the changes locally on the fork. +2. ✅ Verify no upstream tests broken (`cargo test --workspace` + passes — confirmed 2026-05-04). +3. ✅ Verify aldabra builds + tests against the fork (88 unit tests + green). +4. ☐ Open PR against `txpipe/pallas` on github.com. +5. ☐ Once upstream merges, drop our `[patch.crates-io]`. + +The PR will probably need to be split into three separate PRs (one +per change) for upstream review ergonomics: + +- `pallas-txbuilder: thread auxiliary_data through StagingTransaction → Conway build` +- `pallas-txbuilder: thread certificates through StagingTransaction → Conway build` +- `pallas-addresses: pub fn new on StakeAddress` + +## Change discipline going forward + +If we add more fork-only patches (e.g. for upcoming withdrawals / +voting_procedures / proposal_procedures TODOs), each goes in a +separate commit on this branch so the eventual upstream PRs are +clean to extract. + +All commits on this branch must: +- Have a self-contained subject explaining what TODO it fills in. +- Pass the full pallas-txbuilder test suite (`cargo test -p pallas-txbuilder`). +- Add at least one positive + one negative test for the new code path. +- Not depend on Sulkta-specific naming or assumptions — these + patches need to be upstream-mergeable as-is.