From fa1e168fb553b2317266017c4924cf35371ee6ba Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Fri, 20 Dec 2019 15:33:45 -0800 Subject: [PATCH] Ensure that invalid JoinSplitDatas are unrepresentable. All JoinSplitDatas must contain at least one JoinSplit. --- zebra-chain/src/transaction/joinsplit.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/zebra-chain/src/transaction/joinsplit.rs b/zebra-chain/src/transaction/joinsplit.rs index 93fc0929..bd808bab 100644 --- a/zebra-chain/src/transaction/joinsplit.rs +++ b/zebra-chain/src/transaction/joinsplit.rs @@ -52,8 +52,13 @@ pub struct JoinSplit { /// A bundle of JoinSplit descriptions and signature data. #[derive(Clone, Debug, PartialEq, Eq)] pub struct JoinSplitData { - /// A sequence of JoinSplit descriptions using proofs of type `P`. - pub joinsplits: Vec>, + /// The first JoinSplit description, using proofs of type `P`. + /// + /// Storing this separately from `rest` ensures that it is impossible + /// to construct an invalid `JoinSplitData` with no `JoinSplit`s. + pub first: JoinSplit

, + /// The rest of the JoinSplit descriptions, using proofs of type `P`. + pub rest: Vec>, /// The public key for the JoinSplit signature. // XXX refine to a Zcash-flavored Ed25519 pubkey. pub pub_key: [u8; 32], @@ -62,3 +67,10 @@ pub struct JoinSplitData { // for now it's [u64; 8] rather than [u8; 64] to get trait impls pub sig: [u64; 8], } + +impl JoinSplitData

{ + /// Iterate over the [`JoinSplit`]s in `self`. + pub fn joinsplits(&self) -> impl Iterator> { + std::iter::once(&self.first).chain(self.rest.iter()) + } +}