pallas-txbuilder: voting_procedures rejects empty CBOR maps
AUDIT-2026-05-06 M-4 fix from the aldabra Phase 3-6 audit. NonEmptyKeyValuePairs::decode in pallas-codec accepts `0xa0` (empty CBOR map) because the upstream empty-map check is commented out. That decoded value re-encodes correctly and passes through pallas-txbuilder, but the resulting Conway tx fails ledger validation at submit time with a non-obvious error. Add a debug_assert_ne! on the builder method input + clear doc note warning callers to omit the field instead of passing an empty map. Release builds pass through (no overhead); dev/test builds catch accidental empty-map calls with a clear panic message. The pre-existing aldabra build_signed_drep_vote_cast always constructs a non-empty map so it doesn't trip this; the guard is for future callers.
This commit is contained in:
parent
507fd9da15
commit
8091abd1b4
1 changed files with 15 additions and 0 deletions
|
|
@ -433,7 +433,22 @@ impl StagingTransaction {
|
||||||
/// VotingProcedure>>` map and pass the encoded bytes here.
|
/// VotingProcedure>>` map and pass the encoded bytes here.
|
||||||
///
|
///
|
||||||
/// Used for DRep / SPO / committee voting on Conway governance actions.
|
/// Used for DRep / SPO / committee voting on Conway governance actions.
|
||||||
|
///
|
||||||
|
/// **Empty-map footgun**: Conway ledger expects this field to be
|
||||||
|
/// omitted (i.e. `None`) when there are no votes. Passing an empty
|
||||||
|
/// CBOR map (`0xa0`) gets through pallas-codec's
|
||||||
|
/// `NonEmptyKeyValuePairs::decode` (the upstream empty-map check is
|
||||||
|
/// commented out) but the resulting tx fails ledger validation at
|
||||||
|
/// submit time. **Don't call this builder if the map is empty —
|
||||||
|
/// just omit it.** The debug_assert below catches accidental empty-
|
||||||
|
/// map calls in dev/test builds.
|
||||||
pub fn voting_procedures(mut self, cbor_bytes: Vec<u8>) -> Self {
|
pub fn voting_procedures(mut self, cbor_bytes: Vec<u8>) -> Self {
|
||||||
|
debug_assert_ne!(
|
||||||
|
cbor_bytes.as_slice(),
|
||||||
|
&[0xa0u8],
|
||||||
|
"voting_procedures called with empty CBOR map — Conway ledger \
|
||||||
|
rejects this; omit the field instead",
|
||||||
|
);
|
||||||
self.voting_procedures = Some(cbor_bytes);
|
self.voting_procedures = Some(cbor_bytes);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue