Some checks are pending
Validate / Check (push) Waiting to run
Validate / Check-1 (push) Waiting to run
Validate / Check-2 (push) Waiting to run
Validate / Test Suite (push) Waiting to run
Validate / Test Suite-1 (push) Waiting to run
Validate / Test Suite-2 (push) Waiting to run
Validate / Lints (push) Waiting to run
146 lines
6.2 KiB
Markdown
146 lines
6.2 KiB
Markdown
# 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`](https://git.sulkta.com/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<Vec<u8>>` 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<Vec<Vec<u8>>>` 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-txbuilder` — `voting_procedures` field on `StagingTransaction`
|
|
|
|
Upstream had `voting_procedures: None, // TODO` in the conway builder.
|
|
Without this, **DRep / SPO / committee voting on Conway governance
|
|
actions can't ride a tx built with pallas-txbuilder.**
|
|
|
|
Added 2026-05-06:
|
|
- `pub voting_procedures: Option<Vec<u8>>` field (opaque CBOR for the
|
|
same `Eq`-derive reason as `auxiliary_data`).
|
|
- Builder methods `.voting_procedures(cbor_bytes)` and
|
|
`.clear_voting_procedures()`.
|
|
- `conway::build_conway_raw` decodes via `VotingProcedures::decode_fragment`
|
|
and assigns to `TransactionBody.voting_procedures`.
|
|
|
|
The `VotingProcedures` type is itself a single map
|
|
(`NonEmptyKeyValuePairs<Voter, NonEmptyKeyValuePairs<GovActionId,
|
|
VotingProcedure>>`), so callers pre-assemble the full map and encode
|
|
once. No staged accumulator needed.
|
|
|
|
Tests added:
|
|
- `voting_procedures_plumb_through_to_tx_body` — encodes a
|
|
single DRepKey-vote-Yes on a synthetic GovActionId, builds, decodes,
|
|
asserts the vote round-trips byte-for-byte.
|
|
- `no_voting_procedures_means_none` — negative path.
|
|
|
|
### 4. `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-txbuilder: thread voting_procedures 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.
|