pallas/BRANCH-NOTES.md
Cobb Hayes 36adf8fe8c
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
Public-flip audit: scrub residual LAN URL from fork notes
2026-05-27 11:31:18 -07:00

6.2 KiB

Sulkta-Coop/pallas — feat-aux-data branch notes

This is a vendored fork of 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'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-txbuilderauxiliary_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-txbuildercertificates 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-txbuildervoting_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-addressespub 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:

[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.