From 52fe1f50418d3f560933b63b8bc440871d2c59bb Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Fri, 26 Jan 2024 17:02:16 +0200 Subject: [PATCH 01/15] Changed the note scanning algorithm to not require additional context. --- crates/core/src/types/storage.rs | 1 + crates/sdk/src/masp.rs | 257 ++++++++---------- ...9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin | Bin 0 -> 10105 bytes ...D4D70154B89179E7DA6F14C700AAE1EC531E80.bin | Bin 2045 -> 2045 bytes ...753FB3BE606A5729D43A6EA8F79007D34F6C60.bin | Bin 2045 -> 2045 bytes ...AA6B8D85E10E17ED9D098B9C6B8C6795B1E0F3.bin | Bin 0 -> 2045 bytes ...2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin | Bin 0 -> 12076 bytes ...0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin | Bin 2045 -> 2045 bytes ...21C4A7EB97EAC95F77B0410D41305EEF3C766F.bin | Bin 0 -> 8608 bytes ...16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin | Bin 0 -> 4895 bytes ...DF787F70D27FE1DE4CEFD4756B6753AB603FCF.bin | Bin 0 -> 2045 bytes ...80F84F6B712C682DD639AF812F29AF23E4AB7F.bin | Bin 0 -> 6393 bytes ...DBE3DA9201B7C90E74A7B6C2B9B7320F006872.bin | Bin 0 -> 6393 bytes ...346C4D5419EB8C2C4174F5DC1317D493122486.bin | Bin 0 -> 6910 bytes ...83E61BED82F25C4452CA41B769C3BABEB62D2B.bin | Bin 2045 -> 2045 bytes ...06FB77DB730FFFE562F2565B0431F7A901CC9A.bin | Bin 0 -> 2045 bytes ...48447BC02F4A27D5ECAEE75DD468D66DE97346.bin | Bin 0 -> 2045 bytes ...07ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin | Bin 0 -> 6177 bytes ...1E2DCE33145F68A217FD50B065966646F59116.bin | Bin 2045 -> 2045 bytes ...5852DCD946FCC03040DF7A58FDA0B6CC4919AA.bin | Bin 0 -> 7875 bytes ...C387A0A9919A436A15C6DEC3834051B7CC7993.bin | Bin 0 -> 7650 bytes ...926C88FA3742B7F3A45DC0E1227236BC835003.bin | Bin 0 -> 6910 bytes ...A81A7DF315190329C7C2F708876D51F60D2D60.bin | Bin 4895 -> 4895 bytes ...B78DD77AA5620AC08519F73AB740B5A44AFA65.bin | Bin 0 -> 5412 bytes ...FBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin | Bin 0 -> 2045 bytes ...5A0AD04432D0D4BB8B2488EA5E836837B00394.bin | Bin 0 -> 2045 bytes ...9BC3BBACE79DF98801EB8154EA1904597854A1.bin | Bin 4679 -> 4679 bytes ...F7858007C4DA521F8E3BF250A46E9342178EEB.bin | Bin 5660 -> 5660 bytes wasm/checksums.json | 48 ++-- 29 files changed, 131 insertions(+), 175 deletions(-) create mode 100644 test_fixtures/masp_proofs/2AB777063F53A1E6F66DB635DD9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin create mode 100644 test_fixtures/masp_proofs/5DE7FF931D7864F0C05FD54926AA6B8D85E10E17ED9D098B9C6B8C6795B1E0F3.bin create mode 100644 test_fixtures/masp_proofs/693468170864DF8C1A8C13FE2C2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin create mode 100644 test_fixtures/masp_proofs/7198F6516381EEB67048E3099D21C4A7EB97EAC95F77B0410D41305EEF3C766F.bin create mode 100644 test_fixtures/masp_proofs/7A240D86DB78C8E1478FB0857D16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin create mode 100644 test_fixtures/masp_proofs/7B6C8C638FEE08497ACAEB06BFDF787F70D27FE1DE4CEFD4756B6753AB603FCF.bin create mode 100644 test_fixtures/masp_proofs/84320514AEC06D9AADC35DEF5C80F84F6B712C682DD639AF812F29AF23E4AB7F.bin create mode 100644 test_fixtures/masp_proofs/849D9E73D858B17BBB5856FAC2DBE3DA9201B7C90E74A7B6C2B9B7320F006872.bin create mode 100644 test_fixtures/masp_proofs/891CCBE84265DFA7F35C8E5F08346C4D5419EB8C2C4174F5DC1317D493122486.bin create mode 100644 test_fixtures/masp_proofs/B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin create mode 100644 test_fixtures/masp_proofs/B7C738AE39C44060FD6EA5D7C648447BC02F4A27D5ECAEE75DD468D66DE97346.bin create mode 100644 test_fixtures/masp_proofs/B88A2DB72E3A0A624B9076C5A707ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin create mode 100644 test_fixtures/masp_proofs/C83BAD95A33CB66390611EF8155852DCD946FCC03040DF7A58FDA0B6CC4919AA.bin create mode 100644 test_fixtures/masp_proofs/C9D7CDFED7CB968E7743BE392EC387A0A9919A436A15C6DEC3834051B7CC7993.bin create mode 100644 test_fixtures/masp_proofs/CA9143A071C194759B72139C6B926C88FA3742B7F3A45DC0E1227236BC835003.bin create mode 100644 test_fixtures/masp_proofs/D38C391DF4F1F69AB04682F0C1B78DD77AA5620AC08519F73AB740B5A44AFA65.bin create mode 100644 test_fixtures/masp_proofs/D5A372904527694939249FA0AAFBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin create mode 100644 test_fixtures/masp_proofs/DBE07FDEDBF79BBC814D3EB70E5A0AD04432D0D4BB8B2488EA5E836837B00394.bin diff --git a/crates/core/src/types/storage.rs b/crates/core/src/types/storage.rs index 1ac99d11b4..da1ed2920e 100644 --- a/crates/core/src/types/storage.rs +++ b/crates/core/src/types/storage.rs @@ -1463,6 +1463,7 @@ impl GetEventNonce for InnerEthEventsQueue { PartialEq, Ord, PartialOrd, + Hash, )] pub struct IndexedTx { /// The block height of the indexed tx diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index c3cf8d1bf3..4e18ec7ecd 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -525,10 +525,11 @@ pub struct ShieldedContext { /// Location where this shielded context is saved #[borsh(skip)] pub utils: U, - /// The last indexed transaction to be processed in this context - pub last_indexed: Option, /// The commitment tree produced by scanning all transactions up to tx_pos pub tree: CommitmentTree, + /// Maps viewing keys to the block height to which they are synced. + /// In particular, the height given by the value *has been scanned*. + pub vk_heights: BTreeMap>, /// Maps viewing keys to applicable note positions pub pos_map: HashMap>, /// Maps a nullifier to the note position to which it applies @@ -550,6 +551,8 @@ pub struct ShieldedContext { pub asset_types: HashMap, /// Maps note positions to their corresponding viewing keys pub vk_map: HashMap, + /// Maps a shielded tx to the index of its first output note. + pub tx_note_map: BTreeMap, } /// Default implementation to ease construction of TxContexts. Derive cannot be @@ -558,7 +561,8 @@ impl Default for ShieldedContext { fn default() -> ShieldedContext { ShieldedContext:: { utils: U::default(), - last_indexed: None, + vk_heights: BTreeMap::new(), + tx_note_map: BTreeMap::default(), tree: CommitmentTree::empty(), pos_map: HashMap::default(), nf_map: HashMap::default(), @@ -586,33 +590,38 @@ impl ShieldedContext { self.utils.save(self).await } - /// Merge data from the given shielded context into the current shielded - /// context. It must be the case that the two shielded contexts share the - /// same last transaction ID and share identical commitment trees. - pub fn merge(&mut self, new_ctx: ShieldedContext) { - debug_assert_eq!(self.last_indexed, new_ctx.last_indexed); - // Merge by simply extending maps. Identical keys should contain - // identical values, so overwriting should not be problematic. - self.pos_map.extend(new_ctx.pos_map); - self.nf_map.extend(new_ctx.nf_map); - self.note_map.extend(new_ctx.note_map); - self.memo_map.extend(new_ctx.memo_map); - self.div_map.extend(new_ctx.div_map); - self.witness_map.extend(new_ctx.witness_map); - self.spents.extend(new_ctx.spents); - self.asset_types.extend(new_ctx.asset_types); - self.vk_map.extend(new_ctx.vk_map); - // The deltas are the exception because different keys can reveal - // different parts of the same transaction. Hence each delta needs to be - // merged separately. - for (height, (ep, ntfer_delta, ntx_delta)) in new_ctx.delta_map { - let (_ep, tfer_delta, tx_delta) = self - .delta_map - .entry(height) - .or_insert((ep, TransferDelta::new(), TransactionDelta::new())); - tfer_delta.extend(ntfer_delta); - tx_delta.extend(ntx_delta); + /// Update the merkle tree of witnesses the first time we + /// scan a new MASP transaction. + fn update_witness_map( + &mut self, + indexed_tx: IndexedTx, + shielded: &Transaction, + ) -> Result<(), Error> { + let mut note_pos = self.tree.size(); + self.tx_note_map.insert(indexed_tx, note_pos); + for so in shielded + .sapling_bundle() + .map_or(&vec![], |x| &x.shielded_outputs) + { + // Create merkle tree leaf node from note commitment + let node = Node::new(so.cmu.to_repr()); + // Update each merkle tree in the witness map with the latest + // addition + for (_, witness) in self.witness_map.iter_mut() { + witness.append(node).map_err(|()| { + Error::Other("note commitment tree is full".to_string()) + })?; + } + self.tree.append(node).map_err(|()| { + Error::Other("note commitment tree is full".to_string()) + })?; + // Finally, make it easier to construct merkle paths to this new + // note + let witness = IncrementalWitness::::from_tree(&self.tree); + self.witness_map.insert(note_pos, witness); + note_pos += 1; } + Ok(()) } /// Fetch the current state of the multi-asset shielded pool into a @@ -623,74 +632,42 @@ impl ShieldedContext { sks: &[ExtendedSpendingKey], fvks: &[ViewingKey], ) -> Result<(), Error> { - // First determine which of the keys requested to be fetched are new. - // Necessary because old transactions will need to be scanned for new - // keys. - let mut unknown_keys = Vec::new(); + // add new viewing keys for esk in sks { let vk = to_viewing_key(esk).vk; - if !self.pos_map.contains_key(&vk) { - unknown_keys.push(vk); - } + self.vk_heights.entry(vk).or_default(); } for vk in fvks { - if !self.pos_map.contains_key(vk) { - unknown_keys.push(*vk); - } + self.vk_heights.entry(*vk).or_default(); } - - // If unknown keys are being used, we need to scan older transactions - // for any unspent notes let native_token = query_native_token(client).await?; - let (txs, mut tx_iter); - if !unknown_keys.is_empty() { - // Load all transactions accepted until this point - txs = Self::fetch_shielded_transfers(client, None).await?; - tx_iter = txs.iter(); - // Do this by constructing a shielding context only for unknown keys - let mut tx_ctx = Self { - utils: self.utils.clone(), - ..Default::default() - }; - for vk in unknown_keys { - tx_ctx.pos_map.entry(vk).or_insert_with(BTreeSet::new); + // the latest block height which has been added to the witness Merkle + // tree + let Some(least_idx) = self.vk_heights.values().min().cloned() else { + return Ok(()); + }; + let last_witnessed_tx = self.tx_note_map.keys().max().cloned(); + // get the bounds on the block heights to fetch + let start_idx = std::cmp::min(last_witnessed_tx, least_idx); + // Load all transactions accepted until this point + let txs = Self::fetch_shielded_transfers(client, start_idx).await?; + + for (indexed_tx, (epoch, tx, stx)) in txs.into_iter() { + if Some(indexed_tx) > last_witnessed_tx { + self.update_witness_map(indexed_tx, &stx)?; } - // Update this unknown shielded context until it is level with self - while tx_ctx.last_indexed != self.last_indexed { - if let Some((indexed_tx, (epoch, changed_keys, stx))) = - tx_iter.next() - { - tx_ctx.scan_tx( - *indexed_tx, - *epoch, - changed_keys, - stx, - native_token.clone(), - )?; - } else { - break; - } + let mut vk_heights = BTreeMap::new(); + std::mem::swap(&mut vk_heights, &mut self.vk_heights); + for (vk, h) in vk_heights + .iter_mut() + .filter(|(_vk, h)| **h < Some(indexed_tx)) + { + self.scan_tx(indexed_tx, epoch, &tx, &stx, vk, native_token.clone())?; + *h = Some(indexed_tx); } - // Merge the context data originating from the unknown keys into the - // current context - self.merge(tx_ctx); - } else { - // Load only transactions accepted from last_txid until this point - txs = Self::fetch_shielded_transfers(client, self.last_indexed) - .await?; - tx_iter = txs.iter(); - } - // Now that we possess the unspent notes corresponding to both old and - // new keys up until tx_pos, proceed to scan the new transactions. - for (indexed_tx, (epoch, changed_keys, stx)) in &mut tx_iter { - self.scan_tx( - *indexed_tx, - *epoch, - changed_keys, - stx, - native_token.clone(), - )?; + std::mem::swap(&mut vk_heights, &mut self.vk_heights); } + Ok(()) } @@ -945,82 +922,62 @@ impl ShieldedContext { epoch: Epoch, tx_changed_keys: &BTreeSet, shielded: &Transaction, + vk: &ViewingKey, native_token: Address, ) -> Result<(), Error> { // For tracking the account changes caused by this Transaction let mut transaction_delta = TransactionDelta::new(); + let mut note_pos = self.tx_note_map[&indexed_tx]; // Listen for notes sent to our viewing keys for so in shielded .sapling_bundle() .map_or(&vec![], |x| &x.shielded_outputs) { - // Create merkle tree leaf node from note commitment - let node = Node::new(so.cmu.to_repr()); - // Update each merkle tree in the witness map with the latest - // addition - for (_, witness) in self.witness_map.iter_mut() { - witness.append(node).map_err(|()| { - Error::Other("note commitment tree is full".to_string()) - })?; - } - let note_pos = self.tree.size(); - self.tree.append(node).map_err(|()| { - Error::Other("note commitment tree is full".to_string()) - })?; - // Finally, make it easier to construct merkle paths to this new - // note - let witness = IncrementalWitness::::from_tree(&self.tree); - self.witness_map.insert(note_pos, witness); // Let's try to see if any of our viewing keys can decrypt latest // note - let mut pos_map = HashMap::new(); - std::mem::swap(&mut pos_map, &mut self.pos_map); - for (vk, notes) in pos_map.iter_mut() { - let decres = try_sapling_note_decryption::<_, OutputDescription<<::SaplingAuth as masp_primitives::transaction::components::sapling::Authorization>::Proof>>( - &NETWORK, - 1.into(), - &PreparedIncomingViewingKey::new(&vk.ivk()), - so, + let notes = self.pos_map.entry(*vk).or_default(); + let decres = try_sapling_note_decryption::<_, OutputDescription<<::SaplingAuth as masp_primitives::transaction::components::sapling::Authorization>::Proof>>( + &NETWORK, + 1.into(), + &PreparedIncomingViewingKey::new(&vk.ivk()), + so, + ); + // So this current viewing key does decrypt this current note... + if let Some((note, pa, memo)) = decres { + // Add this note to list of notes decrypted by this viewing + // key + notes.insert(note_pos); + // Compute the nullifier now to quickly recognize when spent + let nf = note.nf( + &vk.nk, + note_pos.try_into().map_err(|_| { + Error::Other("Can not get nullifier".to_string()) + })?, ); - // So this current viewing key does decrypt this current note... - if let Some((note, pa, memo)) = decres { - // Add this note to list of notes decrypted by this viewing - // key - notes.insert(note_pos); - // Compute the nullifier now to quickly recognize when spent - let nf = note.nf( - &vk.nk, - note_pos.try_into().map_err(|_| { - Error::Other("Can not get nullifier".to_string()) - })?, - ); - self.note_map.insert(note_pos, note); - self.memo_map.insert(note_pos, memo); - // The payment address' diversifier is required to spend - // note - self.div_map.insert(note_pos, *pa.diversifier()); - self.nf_map.insert(nf, note_pos); - // Note the account changes - let balance = transaction_delta - .entry(*vk) - .or_insert_with(I128Sum::zero); - *balance += I128Sum::from_nonnegative( - note.asset_type, - note.value as i128, + self.note_map.insert(note_pos, note); + self.memo_map.insert(note_pos, memo); + // The payment address' diversifier is required to spend + // note + self.div_map.insert(note_pos, *pa.diversifier()); + self.nf_map.insert(nf, note_pos); + // Note the account changes + let balance = + transaction_delta.entry(*vk).or_insert_with(I128Sum::zero); + *balance += I128Sum::from_nonnegative( + note.asset_type, + note.value as i128, + ) + .map_err(|()| { + Error::Other( + "found note with invalid value or asset type" + .to_string(), ) - .map_err(|()| { - Error::Other( - "found note with invalid value or asset type" - .to_string(), - ) - })?; - - self.vk_map.insert(note_pos, *vk); - break; - } + })?; + self.vk_map.insert(note_pos, *vk); } - std::mem::swap(&mut pos_map, &mut self.pos_map); + note_pos += 1; } + // Cancel out those of our notes that have been spent for ss in shielded .sapling_bundle() @@ -1172,8 +1129,6 @@ impl ShieldedContext { change: -amount.change(), }, ); - self.last_indexed = Some(indexed_tx); - self.delta_map .insert(indexed_tx, (epoch, transfer_delta, transaction_delta)); Ok(()) diff --git a/test_fixtures/masp_proofs/2AB777063F53A1E6F66DB635DD9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin b/test_fixtures/masp_proofs/2AB777063F53A1E6F66DB635DD9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin new file mode 100644 index 0000000000000000000000000000000000000000..5fd246bed0b1bd2888e4c42d995eec4090049572 GIT binary patch literal 10105 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 Lv0pi8e_#9u_`u6S literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin b/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin index 896302b0a08d269fd8a34f058423f58b29ea1a40..928780e08149c1c7cbbf747edb541e9311cfe51e 100644 GIT binary patch delta 601 zcmey%|Ce9q^?wLpWME*p;PWwG+j@dP&5wtQE21Y%w|Y^Nm>(WD^Y(YXuKR7%-b~cd zR3NCP)RUl^jrZ!92r8Of!>r(-FI!PEW#v4XS+hRt6g*z8Q){KH$X{1C-FV4`*jvx0 zEA#}deaG>rH}Edc?P8Z%|M{0)F;iF`)O@#Zcj2O@E3ZQ*-(faUh@GiCMa^(+5ZlHK zLz~V$PuY25T(1Q6?tQ%1?p&O&J_5JjD#q)fXA7)K%<$>yt*XoHv>Ml`T@oD87mE^0>zZL9g d2=kBH^4V;`+2%FxcTLVx*!wh&Z}LNS830E7Hwgd$ delta 601 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 P2UaA5t5zt71xf<|bCBA@ literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/693468170864DF8C1A8C13FE2C2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin b/test_fixtures/masp_proofs/693468170864DF8C1A8C13FE2C2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin new file mode 100644 index 0000000000000000000000000000000000000000..e2b6c5b4ead3c8f85f66d1fa6b329bd616288bdd GIT binary patch literal 12076 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 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/6A12E11EEAA83A0D00BF7470DD0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin b/test_fixtures/masp_proofs/6A12E11EEAA83A0D00BF7470DD0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin index 492c021d126d71f56ba59a02b19fe5e59fc312f7..0e726100161b4d3fe8b85a20f64c47d6ccc896ae 100644 GIT binary patch delta 637 zcmey%|CitJ^?wLpWME)Oy8ryw`R6U_(SKOxm)-xq^N@%11HYdapU7kCgN01Ze*5rxY`>fT=e!$*uMQ+3U<$(GwbDU z*A!Q?y4 zy6VlgjvMxzUSat9LHG?{`(Ulz5;?Elgk9n63eGp4vqpZgW6+6pFKYg6HegX;5}0`V zVzdOq);71w`Hz1;D72iMz!q3fR2V=57ep<7@HyaCjP2Vs?Xnl{gdS;~wRy!YRg;X5+neg*dO8esOvEBM3@^-stAKeA8N6O?=}ln*uFngm-jC^5u0xJZkBf0jBQt* ziB6qdw^{F*>lxQn?i*aX5p^s4KFm1zI9jrHvR-bDTu4jOwk)G}zwiEf%dh#e$#w4e z*&9v?gg#tZzJV#&+eA0%Q1}(Yt@4_;OBKs~O$s*ZK2+*h{Je%~@+zfO`dOz45v*>I~$$#mxs-H zs=#NP=-50jCMUO50s%~X7nr>#Uu1F5ouZ|+c(MK(r-JU+ZBOR86r`T~yy~mvaS+$9ochw#pQ=AcgwBapeb4SyX?U2L zboQmDWW9c9ZtUd`y$5APdM`Uxqi1WLcUp=rX=GFgeRWgJ z|Ba<%SNN=~3Ln)Y!jVfp6>$EZee>N-|06T|E_|<7*kC!$$TC~Xfot)Dn?H|6#@26P z_FXjl>R*{pPgX5BzgDbD<@{@Pm(w}>Y`(iqjgV(+5Ngkv$2j>Ry9fspFr9$_04vo) A7ytkO diff --git a/test_fixtures/masp_proofs/7198F6516381EEB67048E3099D21C4A7EB97EAC95F77B0410D41305EEF3C766F.bin b/test_fixtures/masp_proofs/7198F6516381EEB67048E3099D21C4A7EB97EAC95F77B0410D41305EEF3C766F.bin new file mode 100644 index 0000000000000000000000000000000000000000..2fa21a2cdc62d33ec4a77ec7c7bdccdad55a3728 GIT binary patch literal 8608 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 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/891CCBE84265DFA7F35C8E5F08346C4D5419EB8C2C4174F5DC1317D493122486.bin b/test_fixtures/masp_proofs/891CCBE84265DFA7F35C8E5F08346C4D5419EB8C2C4174F5DC1317D493122486.bin new file mode 100644 index 0000000000000000000000000000000000000000..be73968fd29dd1357085a023d67c528d893a25d4 GIT binary patch literal 6910 zcmeI0XE0s;x5xE%9Gz%k%R%(siFWiFg5wZGuLnW&-b)aoi{5+h(L;!Ys1bq?j$Wd7 z_sP9^W}g46%-p%}?z7%}fAgEQ_nNh5&1bK*w(tJOP<|Wg#aM2$PHE*u({bU5uE?X1 zkNwH&iDJv=%8@(}*Fdqy+kg50@G%r zEf`I5v32Qd8p$`Xl_S9KE_pzbTqMi8b+$W2pwwH@;`i9`0-zi}MFB+)Fw+PRX!`3) zpXOGtBt6T?BuvOjiEkFr|E7+v)+|XIS1%$-Zxu>Dit_1FYTW*{ZJBGw(9uj~&#^a~ zD{eEkvb4;q>#<*fdYip4e6P z)Fzysu%p`kzmhAT->~>FotaV

pF8G$Dsl5pJu+fk}lyknjwxG60-iT{zXPBhni2LmmIzKOpU^UkSk-3gu%Z zAC77Wz6rf|V+Kg$hyRY8p$-53Ya#EQbeUIYQqW*gM=lTs04zc;MqG9bQHRCusDg?| zJS-c&4-$NuI#}raxsb1YM*vijU$kKQ%kdtA?oEDlr&13Qty}my3jzcIG;;-W3oan) z#zMS%@1!w&btRiN{R; zLGo6SeqLp^65_~Ym!dY1EjAjKW9mNnQ$Q8FU1>zcO9FLi+dPrV(Bk#c=&p9tXvva` z*8_qSe?>q>@nkA_MsBlD0atv!h&pLX{YPe_;E@bSJ0;n5yDe=c_zm2k=9E~i5S%*MQ(lyg?tr%?ML)Y&#Okps1!I4}1Twa|zd?%nx- z32=JgG-gD%$oHMln};h87V3twIcZ?vRja3k>6i;M!ht9^hz&a;UhjI{@Zw#`8KK}( ziHM`FhOZvAS*c)uffbbK_IxYEnD#c^Q9LK48NPpDZ|qXz*TzgTy@ zv6}O9@^9CoeExOLRQ?%r%MsDCF+aRgW+(9(ut0zv!&61!iS??YnwRD~DLz{UIv8v@ z^pkCe&tf-B9EcKt8&;U&T+|~kUra4egl&6y(HgrG2}XZ1vs1l?#sIX5cn!BIBJ4%A zUrU7KdJk4_qn^G^rLmTtb0;hGE7J$W>;~*)lsASugQ$K~IF)#U=A3%fO{v~diQ}J!zCdWIP0@=Hfs}~*CQ@R(`oy`>* z=S^0%QV<-B_b0(*7~)f_&jF5!WdlcT8qIUJ_ssMor67-BZ6}ERnSkIZuuY0k;|C;5 zAa1ud8g_9_Q)yWI46%7B9~x4w7nW>zlljt)R&@cdI01@eE8X2GuERv&BM-|fST24SyM1{zl+Okd`=9#@a5I0%{~LWghyrF zGKWE%8DIz_(~&?cPh_(KmbqS0L9Y$bJ2IB_9Z)#Ulb!jju>r9{YMb(bre!8m2U?9Q z6_oEU3(t|pR(XnGU&Z%qWQ2g|SS)G!Xl_S62k#x-xGIuu#ChF>v>Y4Om*w6DEs_KT zFUIxRM_!VN2gJc`wgdzP%{qb^qXzD<%D-XR!`;*YK7%b~3k*_tW%Ia62_sI{7e+R3 z)4H$okJBWjIV11x1OGwTf715%8RNJ9@RFBqGAJ#op9{q9OZkU3p9Loo zQsU;j{(9nHYW+*Cf2sAqqL#s8mDmnxUXsFGKr?#(#{=Q553Na@;2UzP7shGidh&pB zjNrR{(#tV3VH_le1B+m?6vFGcgoKY9k=J`@OhXNv@C6Mhe4=H4T%`Fx?P&PnSAs#} z?{S&~vi63uZl~XwfILapEb_GYD%wK6fU2Kdg3#;v%{;z{?T^=tyFBW-P=F~;v)p*b z!Ma{~G$4^DPv`h0R z`#M-qIZL4bV4>Bf-=~nsfhgL+yB$Q-{+6UxDF`<@uyKBZL&SjfH&@X9Qq({7b+$#S z%xZIQ#kGb+g>HsCj0Q?fO6@ER@o`N7#^RIAQ?ruUeM(M_7cpo>e*&7cEa87g)`j=( z8e!DlXQBcBd+IvWO{=zY{pDN{}ktseckEr1pk%)pI_jQMg5Oqs1k8Mj@bhQH9Ye=19sVuq|DVPDchr(+|;i};6*&Wa2?By0t?GJHI;a-nk*-Z`Q^xeFT z$Y08?HXmSKL7LEd*t0rpV}m?n3Wy0-rsE=)rn9*qtR3EBlQ%N;9_|N_yJz&NUkkjM z6E)@HEu@I>Q6Dh9>SND#pVA**z<%{8hADPNp<8HcZrrh3-7V)Yi_Qua6 z>nqiitC(vaT)a;l+|0^N8xy-%8+y#+hTPQH49UF=gz43-qZb*GvaZqmtna>AKXT*# z6n*k^Bret_vp44A)A$#}%OkCJC+#b2rUG2ZUPd-f`pJU9idvd-Y440A8x)CT?9q33 zZ1rXj!z{;-E+b23n>aJ$VEG*N`U6^n7IM3+$afX{+@3P@^AnZI@On&lBj@YjHH_W@ z-!Z*9UX9Jg^L%J;v4LupQ27o2d)QDRBIRUKejq*q-4?wyO>3Q>A5qIj0IA`!a2PG3 z>6-G)sw92pW$ipHB2N_vrs#Aw*!VH%8?f)ib!AEMFg_2HZr%5}kmg>~AQ7X2w8J{A zQQo7iLgT{v(xEFtTJ3(w{E1wjcV|ouSJ0#P*n@#~D4+9hEg9e0_QTsWh~rSkp615d z?Rq!}CAT2nb3U!97OqccAiLD6OOrNJ9A1_`5Lfh}+s#ruML|^%AKRcHlO_ox8=QTZ z;vv>d-PG6!FV^p`lj03WFN72Aq>x`=W$oERs#WA-likimvg6;lD935;r4?7tLeWn! zS>Q4cT=n>0(CKXCmOsAiRB1r?naAQ%BrdEgC3>w97m5th{8)eO+v%TNSYw zGpDt;r-i=DPDde^@_`=TPnQimN)8MC2gAWhBZh2kJ$vjP$(92=jyxwVy1zjgsnY=FhUPg?!LzabNrmcqAdra1aRb?l8&)(l&Tl8?5Q z^ETu@&Y4OS*r7f3Ep~$B&+;eVB11&ijMpW+h4bni&r_8x?fprM3XWj(7F|;7-cQcT z3iaFdNIGTB@!o+bMf2ukFBMZ}8#Qyo#PYsZzY)U9M;{vOcY5HEK}oPm-Qxmv-19!s zC5sz;V}-sm_a@y#R;Td|aoVU7HA#{>*kRY#HSF6B%;Oe>&Dvg-C*av8J-hTUUSiiW zYl$s~OMXA|8ZuFNfdq_)H3x!Cv9IqaZ`i3faeI$l6?~1pQi$7^Jt~jxa^keCCsjNg zKEz3lGF z+R4&E;g}U<#eceOw37}M`Otl43LFAzkVGR{2g$gA`KZ+Eq;8L6W zc`;uDia1|}VOyiPWkwr$rfocuH>V4ZFl$J+8ss2lz4y~DfY34L#YZyc;6-N}>$PMs#ZKN6(T8S*cP=-1KWxeQubyUKA2`MPi~%blpjWelTZ2#lqpP z!HfN2QE#FRI_*{<#6#uvYqHec~f zy*7$`xTaUFpCO0xr^WZ5_T9~pFF9But=aV~?dWVHxaAHb{Ehp-c#>Ftmp(b+z3Lv- zyngv^Y78x9o{VPBR*`aU((y(ImAakNp$4U`1Q8DCj3;+95^uj+t9KRY=- zj;3j2S=|U`Di8^a3U}}=tU2}^!OO65Qu9N4khYMw7Q|Iy*rgwk=QddeT@?#TtJ50j zy?JWrpc!v(?NbwZTZGxX;=(xPZ8`f*AFiU=0okZHcziDg{)pk~z(RbW%VPx`lf_#X zvE>n)$LSTcz%>;+?f$IESPNMS)*9mP*p0l;61m03x!|mE>ITu4lAk*tq<%GA6U!B( zHL22uzbHa7@bpF~!9D=P8_uT&d#zsPh;9^G+BFL~l&i2eKr@vPz>8XzqwTdJz+{sT zZahxCvSd06xd+iNw4KQ`lJmk4$r|V-T8`qT6L4xjB+ScAQwE&$v>Bi$Hr%2qq~-aq z-)-A+i+ip}%{Z2$ghjBgZC2}{pe}wg0Jou@hYe06vDH2|gQfh5>u_zP4N6;PSm+2P zzsX2VCQ!tscP5D{|FE6uG+!g@yO+;Q>N*SrgD)kq{3M7@J^JA zZ%8usvGBJ830^i*jR%(01uc6dCOzLyV0M+bd=T3N5}xUtYP~J}`{o9BDbBCNdM#6l^#vho10t41V^bahVXL=cwBYVDF`Z)@|2}?KS;|%kw@|tgHzCUKMR)or%IG*TW-YblMp%>$$=PX5k*SOJ zB-ZDo!cyH;(%KJ2_u<#}S2tOcK+o)e_kQ-e8IvmJKewU(JpbxU|F*yH|K45x7d=7e A0{{R3 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/B0876E15DE7B2C742912E048F583E61BED82F25C4452CA41B769C3BABEB62D2B.bin b/test_fixtures/masp_proofs/B0876E15DE7B2C742912E048F583E61BED82F25C4452CA41B769C3BABEB62D2B.bin index dd3f26ba0b5e09c55eede5979d2697289b2a04d7..988eb94e354b6a2873d41af4f4225237d7911fee 100644 GIT binary patch delta 633 zcmey%|Cit3^?wLpWME)Oy8ryw`R6U_(SKOxm)-xq^N@%11HYd=<-n-HV!kn+;eLm;^4p_!;uV z?UUXey-kAay2EEqPGAeHCnf-(;R>euH5uxBzC2fSpL5sGe{GHFw|R5oCOuR+G$m!Z zm0k9BevMsWH$J2_N9!kWXFWD+YFHlJbjv4^@pfC<44y@c3Z%cSv+w#Le`(T(V`&XS z2D|FH_g$*6b>DN;(c)6_-rU2719>L+JZDU~vL@{QsZa8M0v|@I?$JD$zv$~dyFXov zg#NSL{KO=nZe_Ur-undpx3x}%T{eFm7ey|fWEs#meGC8W2}?M42c+LoO*}vCOkTGj zlON~7DJ!Pm-`<+S6>X$m6WJ;s7}Wp5?#I7&>pKk_rx+RhH&QIWwqwqtlP!B1zq$QY wINOk|EtM6K9@xWhblW3secLhv_k!I8CwP)gYsJJ5OEOG;$S%SGN@E}Z08KPJ^Z)<= delta 633 zcmey%|Cit3^?wLpWME)8;(E|za@C)QUw>%D>^Xf-_pv!^xbODFmUCUJ?Ckzmu4kBH zT0YT0RfV9soKqbWD_sez1Ddz-Q56$W3MV%(%Q*NMtX;&fF2D9jK=`A@Vot^4Yi$z} z7MLfsuJ0~XeA<7k;z{|Qy*H%xGuF-FslF%ESN`nLwJ)Au`MgCM-%mdu%`o{6v#$F5 zsF)*rPOq3=cx-0N1^1~f`_0xX{K$9E`09JZ;L<_+d;3ZsYpb#C+ibw1z$CEbT=?v+ z!mENiS#zqHFEt*UoWK@XPfP$n!xcEcOpHEbGV)XHIS~R&wK=QS0h*f6PYW4LuO?z!QG>#k%<$Pc;&t>^seR&=q zskmst{#oBNT2p`IJZ64xmYXrD+VZLCg*eBn2bRA&Dfn-@b|BxOlEOdx7eCy!&-{z1 z+m5M8_nfPrR!u&dc<~0$_lAfy``Xrv-&vZlif`wpc%yj#rq8GQvT98X>X*)UTEqT$ xsatkpWZR1?SM#qe-=&}B diff --git a/test_fixtures/masp_proofs/B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin b/test_fixtures/masp_proofs/B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin new file mode 100644 index 0000000000000000000000000000000000000000..cd3c95a2647acf30e9011caf86a628b14ce33184 GIT binary patch literal 2045 zcmaF;9|9N|7#QjulAG4vpE6mypj>itzbseNSxz0L77a9@QIlb;#iR}wgpQ?!*~C|6YJuGf6Fr#{>|D| z*t*YnS+(|LF6}`@>o1XhQZd)#vM+-DIz|yE;?7Z%Pg0F)=Q~^GpZl zvR(N0bhT_*_tbA7hmV308v;x~pL3}%S6f#4|0O68Kxvzi*wl$5KQRVesA1aU_hN%G zcZbh6)*S1S&!Q~97A^JlVfp>+#Sxw77y2G)W@YMBscsSsmE2qQ==hD^oHY#hPr3f% z{r-dfre3{{?BUcO%K70v9)@h@I!gI}CcUt5Wwbn1^yy!ckHM)K%#$pX-n+!lcDd*j zE$5@fx%c!6osty&U8VZZqs+5k@$cD_?#b`CIR0VBqM%swm0uXXMY`ur`K~qbpYi1< zhc3z2-1$C#^*N!X&$V9MkgT0ixL!z3Q?fflIO0NO7I$8Y*QqB_j4Ui6LESbtwpQ<$ z9smBT@zM?VLfRb)g^oCFmbY8X{`{y`)wLqFH3f=~Hhfz)-P0{iY3A;4OZ~%=#C)_E zS1Kni*<}9OZ0Dj3)k&o{ib5M!7ESVseG{$ba!kKdMzS!@Vzri~*o|*F-g9;b*<=_6 zD`fH3J?Qx8$J1~}_CTvFo11~j*_pdvR^4`6zP56DK5ysR=|S(8ADr9&TrPP12T_;# z|92<2+Xh{k^&~2y@ad`&a}Vv13Gc7E)W$k%G}k0CNNlKe)8jL54ihMm7s>vrQeWi9 zqM70|hs|hG;XG51WA2wGFlIhHw4-Rb+n&Ye7`CglT%9su>-^wB_usK7S`aJ8OjUcH6xh>O&OrmmB@hepvir z&hPNa0V(kT-PI{ObAI@I^)yAo#nOYyy4-;)@uy6Dnz>cdYfmq{>lrt)6$W5ZmWGiptt_WT$TfejSXw(%u`<+ z5%KY!jNvU|mX9|6Tdv;buIlZs+ro8ZXKG*kYmZ-sC$2Pe+-KeNV9Gw11_eL4)vG$9 zAM)K>zSMk8#9Qs4W&H&nyFMsfUK1+!>%_jCZe}YHm+1zTiTrmyo%ynu_uQG5cZ=V> zKj5`{Cwt<`rCCdkJZhM7RI~b{)nu{6KL4HzZM&o&Y2_Q|#eLqs_+;_x-9>MWsQx)XD{9{vr5PNa?rMxsb^)aw&%>>r$a+cdUBPk4qHt%meebcO)mz_Z?_#QL7TzehNB+?AzK#4p zXWZSw=cstzYpvz)Qyz-85ufJ@1}~7>&Gq7%J^z#q2YWAklz4X9yJ+h+4Iv5M$?tkT z`((yc^5pX!JHdLn{hiJBgMV)wwN51o$%}bO!MuH8N?5jURCc3|H@OP z=P>i@9|!5XZuiVIye6E{h~M|*%=~p9ZVRinEZ4r)G;epnn~c@7)l7Xh-g^~v_Z}Wup${;wL&>CHUJu@+SdR8 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/B7C738AE39C44060FD6EA5D7C648447BC02F4A27D5ECAEE75DD468D66DE97346.bin b/test_fixtures/masp_proofs/B7C738AE39C44060FD6EA5D7C648447BC02F4A27D5ECAEE75DD468D66DE97346.bin new file mode 100644 index 0000000000000000000000000000000000000000..30b622be46123f4fdf9af7af6099c9c2d55ff5d7 GIT binary patch literal 2045 zcmaF;9|9N|7#Jds3t86JLR1uA2R zy}DIYP2rizY?jkfZuZuj``A5vK;jIqfo2h9kUZBfsJ&nctQkarG&8(>Fi~9U|=Y6m4bLIPV9q+1&Eg#Jc$4-|~!wf3tQKwl4SD z*?&yvToi}e+9f{cKl=Rg{&3bgnvgwA_4ztyH`#0LuFh2Nn^MDgOpMF$Jk!CsY!|*g zT`gPIJ@p&N;iF*0h5!@L=UnQ`)s~h1e+dc%P_kwuHg)32PmE2R(^%WtUQC@EZ-4o@ za>z54C0_qiWG^WCZmT@_(c1aNv||@`sU@5|W_fjg`OB+^-|^k&ku_bV@c94a#Rn!^ zKlG^Akv*LHLpeXZ$HS1#Tt_MY&!iU?u8fwaiaz~I@-a9ygL#sL(tDTq*)A8IX1|)H zcVy4$72F>(m#hk?EZeQPUPRXX=(JxIw-esny8T1e?t#F@_Tmrjc~ib?P5ftk`N^S6 z@-=t9&tH8`Xz6pU7dIqpXB4g%lGBvz&Jd2cP?^P@*Wz{RNfaXsOGr?+&5f5Zb$hLuH=ykg%(tGOK0@05`&jI&s+Whr*!TaNdf-9a`PM!^bM zymb#cKKk)A+>t%dD$C|(U~+cm?w3`!-IlMdoSx6yxpsQc`{f7c_CJ>kUjISVW&Z!& z3GTK*S7tqliYR=#s>IwwJ7mK9t1h*%&Kk`%NemJjYTfks%$vgmO5{bdzpB(1`LSrG z_{?E5np8N?)Z>`@r3s9g4-f4qTJE-I@i~U=DlJ#1OxQX<_}{NQo2&OS=TH3cw&m03 zqmvV!Oq}IYcOa$Uh=&i){Nv)9TTHq#@0-ux$tODF2CO9nXSL_!tJzlV zyeDILOPJ-OjsKRbx4El&yX&@a9od=M7ysJhm*I&k%^dexH$9lL&!s`ZPj2<9j_8Mc z_m(d;UlZ|GJ7`&dfyb^73YXV}%KbXAFQ=Q?O2lQlL1iNUolj@JG=FjLEbMl8WfN|9 zH*(>noTXVyjy!6Za#XYWqt#@w#6JI?3vIikA8F+q=f!>AzW8ME>)l0fjpRH!eoLty zJeN_qlrear^IESq=4E_093H7(>5D8o_^W%-*)X{ZHF@rg_;11PyPAhuQ)h80Gq1FL{;Op5tq=FE z8eNuTwE1*&K}tcxG^uUzKRp^}=I1}tD6Z*KW$ENC6#pjpFyz`s4UzijRWhvU={)8e zc?B0O%=BF$R-In-QnhK#r1fh%tggI`e7Rt6#&_0EdyZr4tiR0c*}X}qK>XRHy!Olo z%CcYV+4}!Y`~OYp9?P=5rq>^>k1ffM+0?0Xxbow_+4lsGOo_05mp^auhc{cKq^5rL O;D8m$;HnkMfw2MPALKFs literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/B88A2DB72E3A0A624B9076C5A707ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin b/test_fixtures/masp_proofs/B88A2DB72E3A0A624B9076C5A707ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin new file mode 100644 index 0000000000000000000000000000000000000000..155287509e7d8dd4a037217e44a19304f7d446ea GIT binary patch literal 6177 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 delta 601 zcmey%|Ce9q^?wLpWME)u@m_5IvPxj{YJ;VhJim!bmQE{O6iT3oZ920dk z6$q*+^(3ff-iJ zU5E7ZzKF5+?A|ir+m8o=tjoe>1E+nJS-$fhcTx8H^jMq8cbH8SWc6*nuhLz%FIaka z+ri#A2{u_f#Xzl+%I5uN9xP5?rnlLEMS)3x&8y;*%VKlsyNm3mzS>}7I5~kWu%3`_ zp@9ddwk~_#a$>dU@^C%R;7uM!zL#?}?ds!GW$FF(BW9w!aokRiMInmfyPlqTYrSLA z+{rTCoMKPjujO~VZ2Vnlsr!NFZPmtSwg?xmUy<5){osbD^-r>eB$r%2XUZYrvBs5C zZG$9-vhNf&>lj4#8c6ySux)1rHG1_svYQHB&WJ z+1;=EcGa!Ex9ZgCbNj=u|J~>C`JV>ymqGsZe6~I{ZNdwJ>tn1!G|{&l^@C%(4J*Hg z!W|BdVtK{<0I_ii`*W@Gj3;KzYbFL=_mFY3dX18SF}7<+-SOQ$FZu1%AufDqVO!V( z*e`^wS^%!3n7^)?ii;@cl4ty5psv>m3+hR>$Az z9dJ9Vi)j0(cWw5TL*w3PR2v zc~8|hR~coSv3lt#s8Q+h5w&a@%d*fiwfsckm0bKJ#(vnN5F>X26BaRMh4xMT=d&g4 z7j886FKXc>-w1BoU$Cd_uSek$?5DWKsf;XTlCU`CYvXD{Pa<((w}t1?<#Vz>X?h|) zbs}3uH}?O|cE_W$Y38GOqpg3wR6|5B#;6toMQM)A*qO|o^y!GOHUt}j`0P3|hU(6h zRb z3W-B{N8(nU43gXOJQC41Wj%@Ea63v8jJy^Q_Tjc-0Kovjs_^ZQ-H|rr0M9eNcixcm z`>OR`l#%Jvm5#HOETv}@pcMPI4%SnI`2vJHHSB~h>&soSvM>(<*a0X*F+(E;An4JE zx9$67b-?y!8d1_59d)dDR2O3>Ik$x-bAWd(D-eDqN7n>BQ?AJ(QmI_rwJ%%MfDIeJ zVGkXPELS<>LIC875zB>4DcP{VwANC3Dr9wfI=fyMCq9afer?L_Xn+KGmG045B+)^l z#(^HLg=T!b-{S0Y8$f38P;gcWC)hfGG<>7Pkd!MQ;Fdt2Cw{0NG=V{#HvAq3__nx{l;#7=Nzwm4cEW+&5yO(t)OJh+YIJ`Z#p4Z;HS z&Ir}X!F8gYmn4P(lD#>qel*r{Fo;yicm6dh`&vGi zm8zV(8i7FpdsntGAlW&8a=zc5n+55y<5s=d!Eiu#YCwhIMWKNzUs$dN2CU{xT2qY| zJ*+(&74d8r7WGB-DC*A9Hr}#omIxk2>j5h$@F7g4I4*FJ#bwNd>zGJ1$e z8IXwbEJ~4iA!~M|k^tj4wI*hsD7RlW2cLjs)*KgMr4OVX2X5asnM|wRmbKIt%iYu% ze-!{D!1P`EV8QTCZ`%TNlN(xAN`&$^4t*3PLj@pbA0=zB#WfrIC~$~rDZ>iz=Yt)d zOy$hOYo-(7SV_Y&;|HtaA6C{(nd4Xz&$m?p*KjtRIAioXWA&G4JD?Cc#5QFwobo>M z(dnaam9AK?fKTQX+3i81ayaTb-$!5aoP4Lz_alFcm&GPf_f&7;X$i=MYmUnZh?woq z`1wBgb1wyi{$Q0CQpX^ey+N)Wu%QQJj7JM=e1uP084M;Cd7yJb??+8fNNM?;ODZ<# zv>FTmZFMXaKB%H-8e?FCArfEsK^wX$c|+p^1ifLL4T}jpz>`B@TGUgsL9YLSNbX(= zVm&nH=G$B2OmSp)@je#&(%9_F30h-2m28O4)}T!prlCY zW5cK^SW}2V(TJe{4=fged;8cv>uA7Bwl;XwA|%A%nNwXvy_V+JHAf;8zv&D0*9#Q+ z=eCwJ3|gW)L?QIBcr0JZ1-HXeHLADg-rOl)D)@0;lKfu&Pw(67lmVlA2;m2>c-_-S z@wH*^mVVbHG`K~+K~P9T3Ip%qSC#tZDr1HdkQltBcAS^?rhU&zQ(_oHCz~2#Z?EDQ zyK1IcDt~SNH?{tz*5B0nPt+1HaNi?6enN-2O$cl^qKVjogj!JH!K~ z@5QAq6DP);=wP%U)2}-V%9q+*MU_3shLh*@gKio)fM+Cq1YSb=^3YoKSx=VGJ2|5po396EJ|en_JBg{e!oZ$W5fkL~ zrYjQv+WKRyBpD`|}UmqNV0eo$_G@p^5J7#4P8I>0XeBcN=Qe;*fHLzT%|?>Q=IoHzCONp7o(f zhfyOA%3ui8TzHTPW5eIGofaOx3it&I=sywYH&K3b>rXN{BjDd8Da41K>GLj1eIZ!FWzk7e+r8W)PIlaGin+wW zmTefe=@*L&#L|!I+uAR)ezU)@>p4?5L7%Sga1*x7k7*op(V5Y~1n#Uz7Pvq+Ka`2< z8&%GiP#ObzF7s>eh@;uuecVNNk%5V`-q?cL%&=!;%&Ik`sj=l=HojD=vMANC&CY;e zEPdca_XS*tAzYF$MfwFBBkM`{iFcO|N2o7Rq8lo~8L~Nma6_L~Rth&lL#srdYY|vD zC;33Ds43d%j)C}~i9=7h@rzhLaRm9N&UM{u@)%r%`yR7VTwA9?E4y|E(SiT`8UiSO zYm=Aofs-wnG>V#m@_aB#?@tnMISczAk&Bl0j0R^?;!C~9lvyP$5k-BY9_rMOB+4BM z+&Ho6R{sBO9tt@A{O@*ue^Oh{qji*=Qf=52eGX$Q3#7DX^@YSy${M-Hi%)rlv z1CcVHBG2)8|7Qk%mQe`EKh@{ogO&d{#$xvBZt&Y7iV^(69p^T1M^v0Rqv@_Jn2v{q z3m+A7E4OQ4BP?@@rd7B~DSwDhGkz#M<~ozo33=`woqFEKoHUch0H$toLL6Awd=Qvj-0r#*Vmjir4n;yuag0Jd2vxbr%os9!es`Vh$8xI!B{-(Gbcy62pie#s*Nvo!) zhQK^B%EE}!B^!M_b_s^oeTsLyd6Gp`=<*6}i@05sr#x!SCEs*v3g)c^*Y25g(l};I zBy~iZ1HND3pvCP!vAVFw=K4;gzfbb1-i;Sqry-{va!=Y?Rf9BWqB>qn!nD#L$W0W`-g$HS@EES|+i!Ypvqg8ogTQyr;5XcVt z&AMAG7X-JrcL_lX&Nxu4in3eN_=#HLq;zZY1%tOV>l2rD2<5IA(GHU~@p@YQb$|G$ zQ+UANK}q48@x})UbCd{~pphcJ87=+#u`Y??VL@x|`Etsu$YXL1Pcjy%WD+4iy(*(} z@bi#DrJ>G_RHnMm2yNAtggb)zgBV<6Y|8a}Xsw-4=H~+0Haw!;e41Lq z*87mf*f@|o>T=^4qZ8Ei3Yc7*^B~ozaWg$q(IqZURtapV^=8K4OG8^w`0E1`7K|~= ztP0AH_U63lFvheEG4qbn*f{$cOlY-xO75EAre%*4{!p7YprEH1h`D7b@BxrgvBmh%oyyE_YCf+;ExdY{pF;zY1 z1AVRVO9PpwE?Km3)VzN7jp5BJSY<-6*2lLk=Vkjy+cW2y6jp74!Fq!oKNy2G2xH=R zLPI}%mi#o`yCgT^q(ccRYQFL3>S5000>yWPEa}T0I3Z>G(*<$|t5MB9`}S2Y=YR)x zSgvskj1vj02o<12KFVi;B`U?l6>?%ml|-f&@AaqQB!*Xg2S6MR@`r(5->YCA=E!?d zWT~j}*HC^4qc4mHdtowF*CJ-vhHJvFF*X@e_AZIe@G?i*`4dSdyo98Y#CpVSH@9!I zxRad74t&wS(UEzu!AUZ0#F4hkM=4PeRB!C1BuPac{7{{irpQb4ijI(&LZU!uCta!e z%too=^S~t~lddjLhw+QI)Gu4uRJUU(F$n^7d2*{ugqa-Lq%6rojt=IX;3ISnmMyWJ zNoD(qh!IovTm^`8Kn?-CUHsZOF8Q>u+bc(#XymY57w{VuqD`NSMr$WG*~!w< zhE4a8_j5g#~$B?jq^Q8}%A zKnAV8mC59H=nF@4R$GJX4GxO$G;)t|hLt3+R)Y)&3f`y^AvXAaJ)}fqBU8XA*6mk; zLu17&>G2c5V9KUjU~S>++h+@a9TZC{xd=sNMEe>qHxokodbgYzH;CdvxioAj@T3MY zTGg!d@`9zz_nz)k-6CpKM?U>}&=PZa)OuZP+SdCp3*<16sFz=k@4TVNAqIbIk7B<& zA&un$Tjd0(F-@qbWs_uNZ#_wYZ9Bfg4#6Wdu%=oFZ#$J^I@f!n{E&ZHdNjaa`@@So zpH{7uQB;r_?(AYCKs)gD$-mI}s>btE2{0-?);MPvNlk%z5Gb-Wo>}N3gQ@2@9^KkO zML-!3$!jnk#Xzm|y(ELoI{8N@AQLU2FR8E&8mrv8N>|x=9SjFqp^m~D6yJ@{JC{&U z#*f+;J-DBzW~>WepvzVOc1q8aH&TV5Tx0TeG{B-1lY}X=TL=tx7LK6H- z(1|v-wpZp_o4?-&3rS3KPDFk4jerfvZ=5w5loV(~a-)*qqj^_Bxw#@oB9UaeS(_YMzfU1|`dy5sv znWOyjTDDMV$C?HD?g-Y4Yx5tKN&PX9n{+fgEr}T|Y78PN$4R$~q{H_XR!?)ww?%TY z|HpOkw|4l`4bGn~VnRPbFum1N9poDc{z6zE-t=yzX3)Lva#1vzwZZ`*T&LVf4yq4niBcK?25HOwhYM~FuV$0h zGHgGBRvoj~-}G2Mzxkrg3R=Yyi9@IUTumroaFk4VtuZZghw$eN8f=6DEK3#dk%| zy=oq5 zH#Nj!Xquf(cflNc0i4D@OMyGWIO|cctIS%dac~rXnypAyWvd8ojtE4)nF^_z=j!So z)BZ3oU?$Q%yHMsb3$ec)l>~>!?tRP2x>;U2yJwnOZjEi5c0Ln6qE6O6Bvm8&$~HHI z-=II@Wl4@=P{6?e4%$^^p!xYmLg_|-9=TLRg<{{9PtC$!kNNy_>IOGtT10Q4{w;~! z?(4U9VCv7W;_lq(%gQ@~25lxciW3YdLGatJ3BS3z94eNA9|8;L?m;x0I7J_Ag|obl z=vHGSz<0;iw>OEWnIA_+g_)&BTsh_L(MneqCet;vFFt=P`KnU3L;^{t7!B{za)k&oR1x|}>8|2^Dx z?$UfoXm!?ye%a2Ajv}0xS-pW?ac>riXmWvEWd(;W0{X^WvWy|GJAto;`{SNW@yx~{ zdH2txWu61?)7-7C6@V6Cq~R|Vcm zbP5YGi++iZ`-rJN9TC}L>N$GyjwLQuPGPlW&(j=A=&P7p0x$)2YE+ii-{oazPW(-p z)kjSQYoMCva6&#E!AraGhm=)cNAkA4x61I6uYC9xK^(GY+k=s(MMPlZHQ__BQ6Fo9 m@-(Y%C&>_T{f&BL7vW#0WE!3hKjIyi*jZXq}c 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 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin b/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin index 8357cbe5ed1cb99b84554487ffc9a07d4392a450..1a4531f734866a3b3129105b299a1bc6860905d2 100644 GIT binary patch delta 1358 zcmbQQHeb!)^?wLp00KrJPP+g6*ZJoy>d}8#=9k_7zVncW^aH=2JWDp0_KNN{WPU%< zK-NRoE&K#O|IXajD?tmi6<02M? zSk)4?dM1LZfNpo#?c};yUZ&#irkl+^9|8M#5NmNmDtYo9bb)%U=atEIz zaJ2guGM&#aT4r%BGS^z;Y|x$P;&n4@TE9$Qz^SBAv)-w%-!MASO-*@r!Jgl@BlmxM zUs+#m8vgx7R#VL1E1Ms2eqnOBQ?1ptV1}-X?R|bWw%Yg8`X94u+<8#Gg)w&h^FFDG zHaA$_9TZy9_|@z;|3O8mshYOGaPCqTK z2L1fa8}U@+zFgkRg@P^ITlbr1{N9|!tH4w*?Q^@MRpg}FWI@Uk|M^io?X zz|!9D;2&+=JT z`&BQ~`HV+)*DX@M!T!O>$ymO(QsK#4M*PuK&-|X@;a65r8iD~rX=IY@BG0y6y>nNn zDt)nTQr~y;QdijY-38^s)&0!}(2Ss{3aVMW^`!XTlV+m6uV!2 zC$AoQ>;7HTF^K=ZY{CDW$JtlwUj%Kx63%?>Usq`x|I^PmmNXSyW@$7{cE2?5+Mf#^ zaZ6@%?sMhYuDPd^w|w8rrPEpR0&Ap0Yl;up&40DVpi|m>+qNB>BVJq0`bM6{2a)=B9;a_S=gocS*^})bgD)N6%Zl%Lm+g1FJAO;O z-6!53Dgiu?c%yBaDz@r83Rj!4#Li-?S&`hY6xLkF^L%GG8y5u^~qEZ0yVEbMb%V+cqbLmI)~?|2N@^ZsYW3 zm1FI#izlp(@ykoPnXz1dLtVDm{u?KzO}??t{o@LbNps9A`eXj{&zPR&wNpA*{mb$` z3C?`xeNuNO)!V<`F!@w>#pCyk%#%MbDH(C5`j*rkT=;Y8Ld)ZyeUJC3TJU==UpIY) zXXJC2f42*ES)EI}Qgzzm$rE$mkyxj`d-bn=y4DM|37P5Nn z^XJiyIWFzo-cE4VLGQ zbexR1kpFLKXy3GDOj&!c%y>L6$!>Z~mF|t^y7fowcHjF~)lnysAg;#q!M3Vz_qEHM z?^XV>v`vUSYs`F-x9?L_$bsMuz5f}^)C4s-c6n^qN9Qvw&5paegeSy%=Df5w=x delta 1358 zcmbQQHeb!)^?wLp00KrJu6IaoT6=%WWbJ}-$;th)Tuo;=b(C5(B%Lx}lsvrI=`qnj z)+6Ta!{%E~+t(jEeV64K-;%GJ173K}x$JFJYIks5>y{0&ATxX)Krrj^D99!f4L|vt4hs5Q1 z&RZ)hOd7a6r~GRvj@n*__asi>o3bo zOqVvOXFOBBrCBSldu)cL;OCi(JT6oQ?dSDoFn?J@=wuzbzzg|fi1J2oZ_>I zGgup3WF#>^*|#O2e{Q7aWw)BrL$cy4Z!zMJrut3~hKFBSL1_pE2&Iulvs2zK>*>y0 zWp;`0u<@LCTEb>A>r)Pz@)vc6Y$+4hw3D{=h_JCSj7Z3RddEdBZ*xU}r!B+5^{P6G zr6LbXrd(sP&5mEaX{E6H>puuDIuGvYqcTI~1ng zvERXaXvd>i#okXx|Hsd;d0=+^+nTzGJTE>rsQ4w=e^NZ*X4$vq-Kzjch3-9y7p!Jo z&Aw_9A$Bz4rn3K0{W;Et*YkJ}m^`X9xmF|^w}E$q{vTGA)6MPSw?1l`DtO$!yuN-7 z-&6hXx!&u4s;qiqz5dgo2}c$@j6VOK*WFiKURB%l&_N5M@T0n0%~V?Z{+aWL3(B|b zVChzEj9|O->bPD$cg;`1mT8$6btXA{KH@S(Wt*Xca;0ojz?6Ec`|b%Er_U6~pK|-( z)YHzpbA>_kK5tdy@TP_7E2c|q_;fF;x87!9eZJVF<$eb|Gq$(Nm`hA*P%y6c%(W2i z-^x3sp-wwBG`C~RiC3R1AMKl=%Jxu6$2i<|+MY?i2YT{Fd;beG9T)6dx_8F|=7p;J zgzb$umqD+jhoh!6|P9ZFKq0f4kAO*)m^YL2F}=XZ;MVIafEeJwDd3 z{zSk7#kKYOvc4>Ad^V+=DSL55#HH(di;BNTAC>4Yj8@){}#v2u1D;cicx{x83Z{gds zGR6j%?Y<}+))QYl_4mbXk2ap~ktpBB<;E$dy!X|EhSzSN&ek`5d0*wU^ZDXmsc*AS ze0z76^P2hRZ3osyWCEmTz&wu?^a*?!cz!#AvqCMW>G8u1$4zSnrhxOfD>@&6G#V(=8HoGdBHX2m8 UuzJTgWv%A~6>=ajnORr{0M2}I_y7O^ diff --git a/test_fixtures/masp_proofs/D38C391DF4F1F69AB04682F0C1B78DD77AA5620AC08519F73AB740B5A44AFA65.bin b/test_fixtures/masp_proofs/D38C391DF4F1F69AB04682F0C1B78DD77AA5620AC08519F73AB740B5A44AFA65.bin new file mode 100644 index 0000000000000000000000000000000000000000..8d9b720476074e63e2b18bb5dd3684488b8ebb83 GIT binary patch literal 5412 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 abitcT(F8(q*m(bUw*GmR{(J9l-#-924Hn-3 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/D5A372904527694939249FA0AAFBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin b/test_fixtures/masp_proofs/D5A372904527694939249FA0AAFBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin new file mode 100644 index 0000000000000000000000000000000000000000..9ba262b0f395cf26c1f7114e31617f887bdce89c GIT binary patch literal 2045 zcmaF;9|9N|7#MCZls76{9xWcpe2K?QbbsG6o#p1H|03(S{vG1Yo3!f$!^5wvKxGWE zSGS6)DLgZo&2n1G&E9%*AG?PSNSxs{&@7@1lIQvbwHHi*HG>F{W`>s!CW=eFoLxCJ z^Q6S9Y?K40hTCVQ>j)tTyjQ)(EGiE$a8XF52S?ZUUG zt7Xf&r+x!Dd=!k>5MToOoJ)PV+OpFBFF}C-O4f|TrcNCBi7`B9!R5{^h99!Y^QhD**$dU)M{m04P5G`h@t^VKCxorDQMg`6PE)cwLpb6>Wfpf{i`S_qQH(4sAwk_XH?~&qm>vKA ztMSqe_d?no3Wbh1ZI-uN%>MkSR@Jp4wlxKck2ZW;Hr>-LO=;%tZ%h5dlEi$p7*{GM zF4<)M+HB{d4An`cH;O_VRu)b2ihUEU=5kEGQ%15d&SJHerPz&cIo@-22ias81uJCn z);;L>=*QD=NA^IgESsBw$=R8^Usm0ATfVk(dOmOG+UY^>mmi$l|6DG3{RdH(`Tut( zxZ4I@ne`+pqVVae5_1pjkO}Xvy41!xYc$s+F-UBvb<^WBZw?bEkr&DSs#0I%$D*0y zGl$J+QsF#Pk7MqaCNO3`JhY=|x!az_=NPuDv|ODsVe9Kk>)gmQSCL zPEL3-ah6Zrfs}$H9zHztkBe(=G3m;@Z$5t~KRauL@^;(38|p(8@|PR^&wg0^Vb1UH z$pIceB~?a{LixPKIe;os>;~gR@?q4@67vP^m@IMQ{CHuUFSP?tL!~r zE1l)F=)B?K$JT2Mw<<)s{Cb;bw*JZsx6{&*cW$eFKcKh%$Xu2Khm8$u=gd=I91-#H zo{ZrwVU~|J{#&lz=C11PuG_+OWM^t${A-V2h9|BxbKGa$^kB+9mj(qtxz(#Wq95|z zTfWqMO~hO6pk@699=kp$TwW6@_v^&IoNi_-5tr!(m5Ka!KArip>A}hBRcZ|l&)=_d zozJf%yEJRbkw*3D+BdvVnytvQX7oRMCy}RhGk(@`zZzv%gA!BOmcKz*rFAGvrZ{Jp5c0cf1hhw*uMz>HJcRY zpPM|b^OTIo?U;zu1uxbmAIw?Lzw=9$H2dSq1$%e;n}={kt^K_In&oZo_-m`=E&wtCZ$SF`^Ip@Lu`Lov*)G`Rlf6CHUNJ`(ux28 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/DBE07FDEDBF79BBC814D3EB70E5A0AD04432D0D4BB8B2488EA5E836837B00394.bin b/test_fixtures/masp_proofs/DBE07FDEDBF79BBC814D3EB70E5A0AD04432D0D4BB8B2488EA5E836837B00394.bin new file mode 100644 index 0000000000000000000000000000000000000000..d39344547dbc331604dab3d6c2a89d96ee44b084 GIT binary patch literal 2045 zcmaF;9|9N|7#P++Jg{)Q+%Tg=Z$SSx!s2*;{Y!WB2d@i8H(gnnjdBIj1_H_JS#}W)K0=%<%HTL~*H?vn!{D zoMkZKaKH9|S19!9x4a3HpBdj*5;&1lw3T7wydS(~bIVr~>*9ld%QF`K&DvGiy4-7L z|1qI+Q5`QbethHU0KO8I{#y|8d)v^-Vx>0gqM!KoR{lPr|pyTs3Sx#%=|epJkn zJ*QXvxq6&ukx}^1I8oD-=TYxjrfhMuHmDFhp(wF7d}_S?QTMzl-?b+GGrs)f&?Whr zJKyK8J}0#Fxz>vtlC?7m*9*yMN_J-mM_j1P;?8UFI`t%qk%c8BsN3eo*6JOzm%tra z2OS^%cpC1=9%z+ib2BhGJ9GETs@rbM*H%u?=j~iOJ?Q=NgLC_z%LT9hAnG#z|Lz2L z+n_76o1VFD%cBH3S6>WlnXG*f)$ zuo+D%oM-BB%>B{?#>|I@b`&jl+q3u_!*-RHt5YUyoge(~SDww)dztem{&?H+>GRRa z2~Q@@@~JzJQgFn>hiCqAam_6zU77dI=kMfaXN^$aZo79weTYK-a-;v*4~sv{`5itv zASFJayEgS=Qa>d=XGp8GGAm+aKkfc^`~kuXl2)dmFIpe8+B;z2|GC zv%D6aH$42$g-DlQZ}ZI7UwPqnS~~L1ZME+Q^wuAl%W~kbv0?3;dFqQJB0k=e zF}x+r^3leB%hlW5RlVJHTeyzwOzn$*?eWX-#Fb`_`>dNDOxfqspx`IBdR0gCL%w^< zmzuAMc&i<>tiQlx*9V2mYeMCIo!FPt&1@y>opuk^j!8Ghd!>`IE3)-E8jRT?(_D=CyQV2E_!Pu=h5+7O7-Bm zjLM~q!3&+&dbKexPh6{kSOeaL$3+s9CSKy@)t?an80W`D@wN=zqMY_nW(W~@B0fMzj>(M{eSJg>XYr&dXG%Lb6>5D5>+X+ z%B}D6ytiVfc))|wm#T}zrX|NJovBZs;j_Hx!Vw$i(sCbe&S%qS7#upp^)~wR(l_iJ Oup${;wL&>8P#OTZ?AfLO literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin b/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin index a25fa32cf0c24c8d7437caad4c3549b2c087aa26..8cac916954e11697d45eb755016e7092e6fb521d 100644 GIT binary patch delta 1228 zcmajc{W}u~0KjouOhYm+3ERvPIaecMtt^z6Jua_}(#wU;Y%6cOHF4V-ze?t&b|=76jE2%2@ZUlwub=8LV66D?nbL!Vqe)(zgte}5i2#?sL>IBu)KssB%* zLD@jxde7vSx}+7j{;MJKrMR1+XZNnoeOildZt>)!SF5{$`g2(wHNP}Sc%VEkF zqsEzrHE9I+wpn?OhxmsD?($|NLN}>N5myGBT@gMN%npCO=Z!ilc+ekYi~N(g*i=ms ziZS5NK;KJw`K6KKMAf{TZ4I@c{B)-AUAUz%XuVN} zJZ~?1F#r5Sm{->#p9G?rL%GQ&o`|Zr1ZZa(ZcF|*`E>x`` zaKs7|1dz!`oh9gv?u`0+5v{HeJ?e)o@ptL~uZ;-dFUQ_Le&+_~-C)UzfwgpwZzMM@_F|qZEzX^0mgZSC@SWXZF;j z2A&heIQ`1OT&g8s442bG7>sr(&alp5iv5ig1}U6-PPCixwi0keh4RaIkpA`vfuH{O zOWIu@xYYJNRYv8sWY{6RrT>Ht8^b(3CX;Txa)*~0>Nh#b$YJl_`%w&n6s7-0W?Wx+ zt+TxK!tB*(y~vGueN)?du!pAGB7Uy9uWYT{Y(GEqP$c8HXXitood#+^4F=Y{U^lSf zT83jeyJFZL3Q^+c4oP}SYH4O7k@rR(mm$8-y7nM`-h9SB%eKkA{%10^f@y8(qbKdH zlwylw2dr#b1F7fDO4M5h8rKG8v0yCY%b0Rovjg{j2xyt)EYJdN*0hKmHY9UnU1^gd zFLR7>WgAF+90osQX_~me@mTP%>Mbe`2=B*U5N}8p@s+thA}#}BeT@YN(+>AWK4ZYD zZ_uG9=UCJvLQ*z-iRs*)7KLx($1Ph-GaSN-d97D&jz7$G_wr)&oO_vKj6$Yr7UBuf zHWq0`f3)oma*^=V;B234_1nM+{nlOEX~ANPcGHqKm|f%a2-T_+zD0$$1Zr1tN@KMr zM`2IeNG*szIC+96stWIEqRN%Gcjwv)uV!Q@osHZ?eaDzTHFZ>@Hht(i;$;->p&;TNA?KY>IB*hjG#MrG>CKkaI>XV(nGCk?g{Kvq zM@G1&?2LEmi$hkWB4fptk~v%z);q}>HkgtC1wYwmaI$Ed!Z?H&00Ma%`c6HX(r!>* z422#j2_jnkF0a^}rW#1wS8LK7!J966jJ8X6^m4jYnK#qn-vJp@$)?MuVrIdTmQ57X f{iL2Aes33)6hq>e5rKwsm delta 1228 zcmajc=|2+;0KoA%R>=%=q>wctS(I8l>XU_>4^Qr9q^IU+9~3hZ8e+{NW<{AOo3z|! zMa`L<+oMZpo@B+J0RKk2jE{yM;ZNtI;Rx(Ah(v9 z=urUIUph=TUJ9JyGbQvwfCo)tsz_0^W0lDU|~Z{r{BxrVM4I zp(*4x797dB@0d_~VdUb;Y3SBH^qeA?-271&$7E^X6g(}W!wZ3>vI8%Ns+OSkD%>jH zoLdQtrg+C4ytay>E^mQBoqS9pQmr-=qo362h_y!PL+MbR9a?JeUgV=q(t5p><)9{4 zMzVu4N$HH!c4xADeWT4dCPRAmK7Q$jSlCckL+y36P*&9OEcU$hq~gcn1zObbRfMBs zVnA#=)6G4F`WT+(LX86*f(9RYI!Ep_VVafZ3+7(xQ8cd~dmHwQ>?|ZeL2dH4t*jmp zRGIKnnh?O3ew?D<>ZKa7FIE1C`EO++|TdILGdhZgY)e^L;FDjra#=8B#udg2z?~#n_3HhX|`VN#J5;!xw@z zaM?4`g8xAe^m2Oy?VBj5(6?xpnf@5`Ue9ESTBB?!)v8KPHh?EEFbo`}ZJyo@s1Cau z&K;cQ8;mA;4>#O}kI-7L@)m8v*Cg^nEu&X25I`z)_Qn`RO#p00fd_gwODa-j()H7V z-7serTFp&sy&rAdwSwbk z+6Jyr+rOy-DPNAYl3OHo*hU6T+*kJ1MN=4U_$H(t<&J|s; z#s_0RS_t@%vZ@hKBzH($?OrUL!xr<~Ug)HV_^L~|S$%!P*`uq-5R0At>Jpj+vL|TI z>uk(VH@voLV!>L%u>Llqk6BYS$}1VCQ!`+Z#9qk$hMHZl#^yAgWP-Txp$yep*kVb$ fHeZ1h&>Yxkf5}n{c22{@`;Np?Z(50J3NiZ|PB~@= diff --git a/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin b/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin index e23e43bbb9a9fbbead67a8221989e232e624ca41..ab64d432336b662a53010693926fe9fa92455083 100644 GIT binary patch delta 1994 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 hF}onxMO^{OBt=>B Date: Sat, 27 Jan 2024 18:03:00 +0200 Subject: [PATCH 02/15] Added changelog entry. --- .changelog/unreleased/improvements/2458-masp-scanning.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/2458-masp-scanning.md diff --git a/.changelog/unreleased/improvements/2458-masp-scanning.md b/.changelog/unreleased/improvements/2458-masp-scanning.md new file mode 100644 index 0000000000..cafbd11a83 --- /dev/null +++ b/.changelog/unreleased/improvements/2458-masp-scanning.md @@ -0,0 +1,2 @@ +- Simplified the transaction fetching algorithm to enable it to be saved to + storage more frequently. ([\#2458](https://github.com/anoma/namada/pull/2458)) \ No newline at end of file From bbe3007181cc1abb5341ead67781f8d7c67a030b Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 30 Jan 2024 16:45:24 +0100 Subject: [PATCH 03/15] Moved fetch calls completely from other calls. Updated cli. Fixed tests --- Cargo.lock | 11 - crates/apps/src/lib/bench_utils.rs | 13 +- crates/apps/src/lib/cli.rs | 91 ++++++ crates/apps/src/lib/cli/client.rs | 35 ++ crates/apps/src/lib/client/masp.rs | 158 +++++++++ crates/apps/src/lib/client/mod.rs | 1 + crates/apps/src/lib/client/rpc.rs | 6 +- crates/core/src/types/masp.rs | 7 + crates/sdk/src/args.rs | 22 +- crates/sdk/src/masp.rs | 203 ++++++++++-- crates/tests/src/integration/masp.rs | 304 +++++++++++++++++- ...16D6748146469C7DF33C28DA6F65749E40AD45.bin | Bin 0 -> 10105 bytes wasm/checksums.json | 48 +-- 13 files changed, 808 insertions(+), 91 deletions(-) create mode 100644 crates/apps/src/lib/client/masp.rs create mode 100644 test_fixtures/masp_proofs/ACA50A646C6CEA7751373605BE16D6748146469C7DF33C28DA6F65749E40AD45.bin diff --git a/Cargo.lock b/Cargo.lock index 3ee799beeb..74382db664 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3773,7 +3773,6 @@ dependencies = [ "glob", "libc", "libz-sys", - "tikv-jemalloc-sys", "zstd-sys", ] @@ -7340,16 +7339,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tikv-jemalloc-sys" -version = "0.5.4+5.3.0-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "time" version = "0.3.30" diff --git a/crates/apps/src/lib/bench_utils.rs b/crates/apps/src/lib/bench_utils.rs index ea9e463340..9391e4aabc 100644 --- a/crates/apps/src/lib/bench_utils.rs +++ b/crates/apps/src/lib/bench_utils.rs @@ -695,12 +695,9 @@ impl ShieldedUtils for BenchShieldedUtils { // Atomicity is required to prevent other client instances from reading // corrupt data. std::fs::rename( - tmp_path.clone(), + tmp_path, self.context_dir.0.path().to_path_buf().join(FILE_NAME), )?; - // Finally, remove our temporary file to allow future saving of shielded - // contexts. - std::fs::remove_file(tmp_path)?; Ok(()) } } @@ -983,9 +980,13 @@ impl BenchShieldedCtx { .wallet .find_spending_key(ALBERT_SPENDING_KEY, None) .unwrap(); - async_runtime - .block_on(self.shielded.fetch( + self.shielded = async_runtime + .block_on(crate::client::masp::syncing( + self.shielded, &self.shell, + &StdIo, + 1, + None, &[spending_key.into()], &[], )) diff --git a/crates/apps/src/lib/cli.rs b/crates/apps/src/lib/cli.rs index 3e84538f0f..09a0485039 100644 --- a/crates/apps/src/lib/cli.rs +++ b/crates/apps/src/lib/cli.rs @@ -268,6 +268,7 @@ pub mod cmds { .subcommand(QueryMetaData::def().display_order(5)) // Actions .subcommand(SignTx::def().display_order(6)) + .subcommand(ShieldedSync::def().display_order(6)) .subcommand(GenIbcShieldedTransafer::def().display_order(6)) // Utils .subcommand(Utils::def().display_order(7)) @@ -348,6 +349,7 @@ pub mod cmds { let add_to_eth_bridge_pool = Self::parse_with_ctx(matches, AddToEthBridgePool); let sign_tx = Self::parse_with_ctx(matches, SignTx); + let shielded_sync = Self::parse_with_ctx(matches, ShieldedSync); let gen_ibc_shielded = Self::parse_with_ctx(matches, GenIbcShieldedTransafer); let utils = SubCmd::parse(matches).map(Self::WithoutContext); @@ -400,6 +402,7 @@ pub mod cmds { .or(query_metadata) .or(query_account) .or(sign_tx) + .or(shielded_sync) .or(gen_ibc_shielded) .or(utils) } @@ -487,6 +490,7 @@ pub mod cmds { QueryValidatorState(QueryValidatorState), QueryRewards(QueryRewards), SignTx(SignTx), + ShieldedSync(ShieldedSync), GenIbcShieldedTransafer(GenIbcShieldedTransafer), } @@ -1348,6 +1352,29 @@ pub mod cmds { } } + #[derive(Clone, Debug)] + pub struct ShieldedSync(pub args::ShieldedSync); + + impl SubCmd for ShieldedSync { + const CMD: &'static str = "shielded-sync"; + + fn parse(matches: &ArgMatches) -> Option { + matches + .subcommand_matches(Self::CMD) + .map(|matches| ShieldedSync(args::ShieldedSync::parse(matches))) + } + + fn def() -> App { + App::new(Self::CMD) + .about( + "Sync the local shielded context with MASP notes owned by \ + the provided viewing / spending keys up to an optional \ + specified block height.", + ) + .add_args::>() + } + } + #[derive(Clone, Debug)] pub struct Bond(pub args::Bond); @@ -2901,6 +2928,8 @@ pub mod args { Err(_) => config::get_default_namada_folder(), }), ); + pub const BATCH_SIZE_OPT: ArgDefault = + arg_default("batch-size", DefaultFn(|| 1)); pub const BLOCK_HEIGHT: Arg = arg("block-height"); pub const BLOCK_HEIGHT_OPT: ArgOpt = arg_opt("height"); pub const BRIDGE_POOL_GAS_AMOUNT: ArgDefault = @@ -3084,6 +3113,8 @@ pub mod args { pub const SIGNATURES: ArgMulti = arg_multi("signatures"); pub const SOURCE: Arg = arg("source"); pub const SOURCE_OPT: ArgOpt = SOURCE.opt(); + pub const SPENDING_KEYS: ArgMulti = + arg_multi("spending-keys"); pub const STEWARD: Arg = arg("steward"); pub const SOURCE_VALIDATOR: Arg = arg("source-validator"); pub const STORAGE_KEY: Arg = arg("storage-key"); @@ -3120,6 +3151,8 @@ pub mod args { pub const VALUE: Arg = arg("value"); pub const VOTER_OPT: ArgOpt = arg_opt("voter"); pub const VIEWING_KEY: Arg = arg("key"); + pub const VIEWING_KEYS: ArgMulti = + arg_multi("viewing-keys"); pub const VP: ArgOpt = arg_opt("vp"); pub const WALLET_ALIAS_FORCE: ArgFlag = flag("wallet-alias-force"); pub const WASM_CHECKSUMS_PATH: Arg = arg("wasm-checksums-path"); @@ -5631,6 +5664,63 @@ pub mod args { } } + impl Args for ShieldedSync { + fn parse(matches: &ArgMatches) -> Self { + let ledger_address = LEDGER_ADDRESS_DEFAULT.parse(matches); + let batch_size = BATCH_SIZE_OPT.parse(matches); + let last_query_height = BLOCK_HEIGHT_OPT.parse(matches); + let spending_keys = SPENDING_KEYS.parse(matches); + let viewing_keys = VIEWING_KEYS.parse(matches); + Self { + ledger_address, + batch_size, + last_query_height, + spending_keys, + viewing_keys, + } + } + + fn def(app: App) -> App { + app.arg(LEDGER_ADDRESS_DEFAULT.def().help(LEDGER_ADDRESS_ABOUT)) + .arg(BATCH_SIZE_OPT.def().help( + "Optional batch size which determines how many txs to \ + fetch before caching locally. Default is 1.", + )) + .arg(BLOCK_HEIGHT_OPT.def().help( + "Option block height to sync up to. Default is latest.", + )) + .arg(SPENDING_KEYS.def().help( + "List of new spending keys with which to check note \ + ownership. These will be added to the shielded context.", + )) + .arg(VIEWING_KEYS.def().help( + "List of new viewing keys with which to check note \ + ownership. These will be added to the shielded context.", + )) + } + } + + impl CliToSdk> for ShieldedSync { + fn to_sdk(self, ctx: &mut Context) -> ShieldedSync { + let chain_ctx = ctx.borrow_mut_chain_or_exit(); + ShieldedSync { + ledger_address: (), + batch_size: self.batch_size, + last_query_height: self.last_query_height, + spending_keys: self + .spending_keys + .iter() + .map(|sk| chain_ctx.get_cached(sk)) + .collect(), + viewing_keys: self + .viewing_keys + .iter() + .map(|vk| chain_ctx.get_cached(vk)) + .collect(), + } + } + } + impl CliToSdk> for GenIbcShieldedTransafer { @@ -5916,6 +6006,7 @@ pub mod args { type Keypair = WalletKeypair; type PublicKey = WalletPublicKey; type TendermintAddress = tendermint_config::net::Address; + type SpendingKey = WalletSpendingKey; type TransferSource = WalletTransferSource; type TransferTarget = WalletTransferTarget; type ViewingKey = WalletViewingKey; diff --git a/crates/apps/src/lib/cli/client.rs b/crates/apps/src/lib/cli/client.rs index a8df86db19..fca46991c3 100644 --- a/crates/apps/src/lib/cli/client.rs +++ b/crates/apps/src/lib/cli/client.rs @@ -1,4 +1,5 @@ use color_eyre::eyre::Result; +use masp_primitives::zip32::ExtendedFullViewingKey; use namada::types::io::Io; use namada_sdk::{Namada, NamadaImpl}; @@ -315,6 +316,40 @@ impl CliApi { tx::submit_validator_metadata_change(&namada, args) .await?; } + Sub::ShieldedSync(ShieldedSync(mut args)) => { + let client = client.unwrap_or_else(|| { + C::from_tendermint_address(&mut args.ledger_address) + }); + client.wait_until_node_is_synced(&io).await?; + let args = args.to_sdk(&mut ctx); + let mut chain_ctx = ctx.take_chain_or_exit(); + let vks = chain_ctx + .wallet + .get_viewing_keys() + .values() + .copied() + .map(|vk| ExtendedFullViewingKey::from(vk).fvk.vk) + .chain(args.viewing_keys.into_iter().map(|vk| { + ExtendedFullViewingKey::from(vk).fvk.vk + })) + .collect::>(); + let sks = args + .spending_keys + .into_iter() + .map(|sk| sk.into()) + .collect::>(); + let _ = chain_ctx.shielded.load().await; + crate::client::masp::syncing( + chain_ctx.shielded, + &client, + &io, + args.batch_size, + args.last_query_height, + &sks, + &vks, + ) + .await?; + } // Eth bridge Sub::AddToEthBridgePool(args) => { let args = args.0; diff --git a/crates/apps/src/lib/client/masp.rs b/crates/apps/src/lib/client/masp.rs new file mode 100644 index 0000000000..a27b39a83d --- /dev/null +++ b/crates/apps/src/lib/client/masp.rs @@ -0,0 +1,158 @@ +use std::fmt::Debug; + +use color_eyre::owo_colors::OwoColorize; +use masp_primitives::sapling::ViewingKey; +use masp_primitives::transaction::Transaction; +use masp_primitives::zip32::ExtendedSpendingKey; +use namada::proof_of_stake::Epoch; +use namada::token::Transfer; +use namada::types::storage::IndexedTx; +use namada_sdk::error::Error; +use namada_sdk::io::Io; +use namada_sdk::masp::{ + ProgressLogger, ProgressType, ShieldedContext, ShieldedUtils, +}; +use namada_sdk::queries::Client; +use namada_sdk::types::storage::BlockHeight; +use namada_sdk::{display, display_line, MaybeSend, MaybeSync}; + +pub async fn syncing< + U: ShieldedUtils + MaybeSend + MaybeSync, + C: Client + Sync, + IO: Io, +>( + mut shielded: ShieldedContext, + client: &C, + io: &IO, + batch_size: u64, + last_query_height: Option, + sks: &[ExtendedSpendingKey], + fvks: &[ViewingKey], +) -> Result, Error> { + let shutdown_signal = async { + let (tx, rx) = tokio::sync::oneshot::channel(); + namada_sdk::control_flow::shutdown_send(tx).await; + rx.await + }; + + display_line!(io, "{}", "==== Shielded sync started ====".on_white()); + display_line!(io, "\n\n"); + let logger = CliLogger::new(io); + let sync = async move { + shielded + .fetch(client, &logger, last_query_height, batch_size, sks, fvks) + .await + .map(|_| shielded) + }; + tokio::select! { + sync = sync => { + let shielded = sync?; + display!(io, "Syncing finished\n"); + Ok(shielded) + }, + sig = shutdown_signal => { + sig.map_err(|e| Error::Other(e.to_string()))?; + display!(io, "\n"); + Ok(ShieldedContext::default()) + }, + } +} + +pub struct CliLogging<'io, T, IO: Io> { + items: Vec, + index: usize, + length: usize, + io: &'io IO, + r#type: ProgressType, +} + +impl<'io, T: Debug, IO: Io> CliLogging<'io, T, IO> { + fn new(items: I, io: &'io IO, r#type: ProgressType) -> Self + where + I: IntoIterator, + { + let items: Vec<_> = items.into_iter().collect(); + Self { + length: items.len(), + items, + index: 0, + io, + r#type, + } + } +} + +impl<'io, T: Debug, IO: Io> Iterator for CliLogging<'io, T, IO> { + type Item = T; + + fn next(&mut self) -> Option { + if self.index == 0 { + self.items = { + let mut new_items = vec![]; + std::mem::swap(&mut new_items, &mut self.items); + new_items.into_iter().rev().collect() + }; + } + if self.items.is_empty() { + return None; + } + self.index += 1; + let percent = (100 * self.index) / self.length; + let completed: String = vec!['#'; percent].iter().collect(); + let incomplete: String = vec!['.'; 100 - percent].iter().collect(); + display_line!(self.io, "\x1b[2A\x1b[J"); + match self.r#type { + ProgressType::Fetch => display_line!( + self.io, + "Fetched block {:?} of {:?}", + self.items.last().unwrap(), + self.items[0] + ), + ProgressType::Scan => display_line!( + self.io, + "Scanning {} of {}", + self.index, + self.length + ), + } + display!(self.io, "[{}{}] ~~ {} %", completed, incomplete, percent); + self.io.flush(); + self.items.pop() + } +} + +/// A progress logger for the CLI +#[derive(Debug, Clone)] +pub struct CliLogger<'io, IO: Io> { + io: &'io IO, +} + +impl<'io, IO: Io> CliLogger<'io, IO> { + pub fn new(io: &'io IO) -> Self { + Self { io } + } +} + +impl<'io, IO: Io> ProgressLogger for CliLogger<'io, IO> { + type Fetch = CliLogging<'io, u64, IO>; + type Scan = + CliLogging<'io, (IndexedTx, (Epoch, Transfer, Transaction)), IO>; + + fn io(&self) -> &IO { + self.io + } + + fn fetch(&self, items: I) -> Self::Fetch + where + I: IntoIterator, + { + CliLogging::new(items, self.io, ProgressType::Fetch) + } + + fn scan(&self, items: I) -> Self::Scan + where + I: IntoIterator, + { + CliLogging::new(items, self.io, ProgressType::Scan) + } +} diff --git a/crates/apps/src/lib/client/mod.rs b/crates/apps/src/lib/client/mod.rs index 8862c5a564..7ad6d57e5f 100644 --- a/crates/apps/src/lib/client/mod.rs +++ b/crates/apps/src/lib/client/mod.rs @@ -1,3 +1,4 @@ +pub mod masp; pub mod rpc; pub mod tx; pub mod utils; diff --git a/crates/apps/src/lib/client/rpc.rs b/crates/apps/src/lib/client/rpc.rs index ec1df0f420..0bdc931ec3 100644 --- a/crates/apps/src/lib/client/rpc.rs +++ b/crates/apps/src/lib/client/rpc.rs @@ -156,6 +156,7 @@ pub async fn query_transfers( let transfers = shielded .query_tx_deltas( context.client(), + context.io(), &query_owner, &query_token, &wallet.get_viewing_keys(), @@ -897,11 +898,6 @@ pub async fn query_shielded_balance( { let mut shielded = context.shielded_mut().await; let _ = shielded.load().await; - let fvks: Vec<_> = viewing_keys - .iter() - .map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk) - .collect(); - shielded.fetch(context.client(), &[], &fvks).await.unwrap(); // Precompute asset types to increase chances of success in decoding let _ = shielded.precompute_asset_types(context).await; // Save the update state so that future fetches can be short-circuited diff --git a/crates/core/src/types/masp.rs b/crates/core/src/types/masp.rs index 61b63dab60..64b18eb6b9 100644 --- a/crates/core/src/types/masp.rs +++ b/crates/core/src/types/masp.rs @@ -202,6 +202,13 @@ impl From } } +impl From for masp_primitives::sapling::ViewingKey { + fn from(value: ExtendedViewingKey) -> Self { + let fvk = masp_primitives::zip32::ExtendedFullViewingKey::from(value); + fvk.fvk.vk + } +} + impl serde::Serialize for ExtendedViewingKey { fn serialize( &self, diff --git a/crates/sdk/src/args.rs b/crates/sdk/src/args.rs index e8d2cbcdd2..af3d0a584e 100644 --- a/crates/sdk/src/args.rs +++ b/crates/sdk/src/args.rs @@ -11,7 +11,7 @@ use namada_core::types::ethereum_events::EthAddress; use namada_core::types::keccak::KeccakHash; use namada_core::types::key::{common, SchemeType}; use namada_core::types::masp::PaymentAddress; -use namada_core::types::storage::Epoch; +use namada_core::types::storage::{BlockHeight, Epoch}; use namada_core::types::time::DateTimeUtc; use namada_core::types::{storage, token}; use namada_governance::cli::onchain::{ @@ -61,6 +61,8 @@ pub trait NamadaTypes: Clone + std::fmt::Debug { type EthereumAddress: Clone + std::fmt::Debug; /// Represents a viewing key type ViewingKey: Clone + std::fmt::Debug; + /// Represents a spending key + type SpendingKey: Clone + std::fmt::Debug; /// Represents the owner of a balance type BalanceOwner: Clone + std::fmt::Debug; /// Represents a public key @@ -101,6 +103,7 @@ impl NamadaTypes for SdkTypes { type Keypair = namada_core::types::key::common::SecretKey; type PublicKey = namada_core::types::key::common::PublicKey; type TendermintAddress = tendermint_config::net::Address; + type SpendingKey = namada_core::types::masp::ExtendedSpendingKey; type TransferSource = namada_core::types::masp::TransferSource; type TransferTarget = namada_core::types::masp::TransferTarget; type ViewingKey = namada_core::types::masp::ExtendedViewingKey; @@ -1806,6 +1809,23 @@ pub struct SignTx { pub owner: C::Address, } +#[derive(Clone, Debug)] +/// Sync notes from MASP owned by the provided spending / +/// viewing keys. Syncing can be told to stop at a given +/// block height. +pub struct ShieldedSync { + /// The ledger address + pub ledger_address: C::TendermintAddress, + /// The number of txs to fetch before caching + pub batch_size: u64, + /// Height to sync up to. Defaults to most recent + pub last_query_height: Option, + /// Spending keys used to determine note ownership + pub spending_keys: Vec, + /// Viewing keys used to determine note ownership + pub viewing_keys: Vec, +} + /// Query PoS commission rate #[derive(Clone, Debug)] pub struct QueryCommissionRate { diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index 4e18ec7ecd..ddfd733a27 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -518,6 +518,61 @@ pub type TransferDelta = HashMap; /// Represents the changes that were made to a list of shielded accounts pub type TransactionDelta = HashMap; +#[derive(Debug, Clone)] +/// A marker type indicating that the shielded context is currently +/// syncing. +pub enum Syncing {} + +#[derive(Debug, Clone)] +/// A marker type indicating that the shielded context is not currently +/// syncing. +pub enum NotSyncing {} + +pub trait SyncStatus {} + +impl SyncStatus for NotSyncing {} + +impl SyncStatus for Syncing {} + +/// A cache of fetched indexed transactions. +/// +/// The cache is designed so that it either contains +/// all transactions from a given height, or none. +#[derive(BorshSerialize, BorshDeserialize, Debug, Default, Clone)] +pub struct Unscanned { + txs: BTreeMap, +} + +impl Unscanned { + fn extend(&mut self, items: I) + where + I: IntoIterator, + { + self.txs.extend(items.into_iter()); + } + + fn contains_height(&self, height: u64) -> bool { + self.txs.keys().any(|k| k.height.0 == height) + } + + /// We remove all indices from blocks that have been entirely scanned. + /// If a block is only partially scanned, we leave all the events in the + /// cache. + fn scanned(&mut self, ix: &IndexedTx) { + self.txs.retain(|i, _| i.height >= ix.height); + } +} + +impl IntoIterator for Unscanned { + type IntoIter = + btree_map::IntoIter; + type Item = (IndexedTx, (Epoch, Transfer, Transaction)); + + fn into_iter(self) -> Self::IntoIter { + self.txs.into_iter() + } +} + /// Represents the current state of the shielded pool from the perspective of /// the chosen viewing keys. #[derive(BorshSerialize, BorshDeserialize, Debug)] @@ -553,6 +608,8 @@ pub struct ShieldedContext { pub vk_map: HashMap, /// Maps a shielded tx to the index of its first output note. pub tx_note_map: BTreeMap, + /// A cache of fetched indexed txs. + pub unscanned: Unscanned, } /// Default implementation to ease construction of TxContexts. Derive cannot be @@ -574,6 +631,7 @@ impl Default for ShieldedContext { delta_map: BTreeMap::default(), asset_types: HashMap::default(), vk_map: HashMap::default(), + unscanned: Default::default(), } } } @@ -626,9 +684,12 @@ impl ShieldedContext { /// Fetch the current state of the multi-asset shielded pool into a /// ShieldedContext - pub async fn fetch( + pub async fn fetch( &mut self, client: &C, + logger: &impl ProgressLogger, + last_query_height: Option, + _batch_size: u64, sks: &[ExtendedSpendingKey], fvks: &[ViewingKey], ) -> Result<(), Error> { @@ -640,6 +701,10 @@ impl ShieldedContext { for vk in fvks { self.vk_heights.entry(*vk).or_default(); } + self.utils + .save(self) + .await + .map_err(|e| Error::Other(e.to_string()))?; let native_token = query_native_token(client).await?; // the latest block height which has been added to the witness Merkle // tree @@ -648,11 +713,27 @@ impl ShieldedContext { }; let last_witnessed_tx = self.tx_note_map.keys().max().cloned(); // get the bounds on the block heights to fetch - let start_idx = std::cmp::min(last_witnessed_tx, least_idx); + let start_idx = + std::cmp::min(last_witnessed_tx, least_idx).map(|ix| ix.height); // Load all transactions accepted until this point - let txs = Self::fetch_shielded_transfers(client, start_idx).await?; + // N.B. the cache is a hash map + self.unscanned.extend( + self.fetch_shielded_transfers( + client, + logger, + start_idx, + last_query_height, + ) + .await?, + ); + // persist the cache in case of interruptions. + self.utils + .save(self) + .await + .map_err(|e| Error::Other(e.to_string()))?; - for (indexed_tx, (epoch, tx, stx)) in txs.into_iter() { + let txs = logger.scan(self.unscanned.clone()); + for (indexed_tx, (epoch, tx, stx)) in txs { if Some(indexed_tx) > last_witnessed_tx { self.update_witness_map(indexed_tx, &stx)?; } @@ -665,7 +746,13 @@ impl ShieldedContext { self.scan_tx(indexed_tx, epoch, &tx, &stx, vk, native_token.clone())?; *h = Some(indexed_tx); } + // possibly remove unneeded elements from the cache. + self.unscanned.scanned(&indexed_tx); std::mem::swap(&mut vk_heights, &mut self.vk_heights); + self.utils + .save(self) + .await + .map_err(|e| Error::Other(e.to_string()))?; } Ok(()) @@ -673,9 +760,12 @@ impl ShieldedContext { /// Obtain a chronologically-ordered list of all accepted shielded /// transactions from a node. - pub async fn fetch_shielded_transfers( + pub async fn fetch_shielded_transfers( + &self, client: &C, - last_indexed_tx: Option, + logger: &impl ProgressLogger, + last_indexed_tx: Option, + last_query_height: Option, ) -> Result< BTreeMap< IndexedTx, @@ -691,14 +781,17 @@ impl ShieldedContext { let last_block_height = query_block(client) .await? .map_or_else(BlockHeight::first, |block| block.height); + let last_query_height = last_query_height.unwrap_or(last_block_height); let mut shielded_txs = BTreeMap::new(); // Fetch all the transactions we do not have yet let first_height_to_query = - last_indexed_tx.map_or_else(|| 1, |last| last.height.0); - let first_idx_to_query = - last_indexed_tx.map_or_else(|| 0, |last| last.index.0 + 1); - for height in first_height_to_query..=last_block_height.0 { + last_indexed_tx.map_or_else(|| 1, |last| last.0); + let heights = logger.fetch(first_height_to_query..=last_query_height.0); + for height in heights { + if self.unscanned.contains_height(height) { + continue; + } // Get the valid masp transactions at the specified height let epoch = query_epoch_at_height(client, height.into()) .await? @@ -710,16 +803,10 @@ impl ShieldedContext { )) })?; - let first_index_to_query = if height == first_height_to_query { - Some(TxIndex(first_idx_to_query)) - } else { - None - }; - let txs_results = match get_indexed_masp_events_at_height( client, height.into(), - first_index_to_query, + None, ) .await? { @@ -1837,18 +1924,11 @@ impl ShieldedContext { } // We want to fund our transaction solely from supplied spending key let spending_key = spending_key.map(|x| x.into()); - let spending_keys: Vec<_> = spending_key.into_iter().collect(); { // Load the current shielded context given the spending key we // possess let mut shielded = context.shielded_mut().await; let _ = shielded.load().await; - shielded - .fetch(context.client(), &spending_keys, &[]) - .await?; - // Save the update state so that future fetches can be - // short-circuited - let _ = shielded.save().await; } // Determine epoch in which to submit potential shielded transaction let epoch = rpc::query_epoch(context.client()).await?; @@ -2278,9 +2358,10 @@ impl ShieldedContext { /// transactions. If an owner is specified, then restrict the set to only /// transactions crediting/debiting the given owner. If token is specified, /// then restrict set to only transactions involving the given token. - pub async fn query_tx_deltas( + pub async fn query_tx_deltas( &mut self, client: &C, + io: &IO, query_owner: &Either>, query_token: &Option
, viewing_keys: &HashMap, @@ -2295,7 +2376,8 @@ impl ShieldedContext { .values() .map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk) .collect(); - self.fetch(client, &[], &fvks).await?; + self.fetch(client, &DefaultLogger::new(io), None, 1, &[], &fvks) + .await?; // Save the update state so that future fetches can be short-circuited let _ = self.save().await; // Required for filtering out rejected transactions from Tendermint @@ -3583,14 +3665,67 @@ pub mod fs { // Atomically update the old shielded context file with new data. // Atomicity is required to prevent other client instances from // reading corrupt data. - std::fs::rename( - tmp_path.clone(), - self.context_dir.join(FILE_NAME), - )?; - // Finally, remove our temporary file to allow future saving of - // shielded contexts. - std::fs::remove_file(tmp_path)?; - Ok(()) + std::fs::rename(tmp_path, self.context_dir.join(FILE_NAME)) } } } + +/// A enum to indicate how to log sync progress depending on +/// whether sync is currently fetch or scanning blocks. +#[derive(Debug, Copy, Clone)] +pub enum ProgressType { + Fetch, + Scan, +} + +pub trait ProgressLogger { + type Fetch: Iterator; + type Scan: Iterator; + + fn io(&self) -> &IO; + + fn fetch(&self, items: I) -> Self::Fetch + where + I: IntoIterator; + + fn scan(&self, items: I) -> Self::Scan + where + I: IntoIterator; +} + +/// The default type for logging sync progress. +#[derive(Debug, Clone)] +pub struct DefaultLogger<'io, IO: Io> { + io: &'io IO, +} + +impl<'io, IO: Io> DefaultLogger<'io, IO> { + pub fn new(io: &'io IO) -> Self { + Self { io } + } +} + +impl<'io, IO: Io> ProgressLogger for DefaultLogger<'io, IO> { + type Fetch = as IntoIterator>::IntoIter; + type Scan = as IntoIterator>::IntoIter; + + fn io(&self) -> &IO { + self.io + } + + fn fetch(&self, items: I) -> Self::Fetch + where + I: IntoIterator, + { + let items: Vec<_> = items.into_iter().collect(); + items.into_iter() + } + + fn scan(&self, items: I) -> Self::Scan + where + I: IntoIterator, + { + let items: Vec<_> = items.into_iter().collect(); + items.into_iter() + } +} diff --git a/crates/tests/src/integration/masp.rs b/crates/tests/src/integration/masp.rs index deef3c1061..527dab7e08 100644 --- a/crates/tests/src/integration/masp.rs +++ b/crates/tests/src/integration/masp.rs @@ -54,6 +54,21 @@ fn masp_incentives() -> Result<()> { )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + AB_VIEWING_KEY, + "--node", + validator_one_rpc, + ], + )?; + node.assert_success(); + // Assert BTC balance at VK(A) is 1 let captured = CapturedOutput::of(|| { run( @@ -95,6 +110,14 @@ fn masp_incentives() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert BTC balance at VK(A) is still 1 let captured = CapturedOutput::of(|| { run( @@ -157,6 +180,14 @@ fn masp_incentives() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert BTC balance at VK(A) is still 1 let captured = CapturedOutput::of(|| { run( @@ -239,6 +270,14 @@ fn masp_incentives() -> Result<()> { )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert ETH balance at VK(B) is 0.001 let captured = CapturedOutput::of(|| { run( @@ -280,6 +319,14 @@ fn masp_incentives() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert ETH balance at VK(B) is still 0.001 let captured = CapturedOutput::of(|| { run( @@ -341,7 +388,6 @@ fn masp_incentives() -> Result<()> { // Wait till epoch boundary node.next_epoch(); - // Send 0.001 ETH from SK(B) to Christel run( &node, @@ -364,6 +410,14 @@ fn masp_incentives() -> Result<()> { )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert ETH balance at VK(B) is 0 let captured = CapturedOutput::of(|| { run( @@ -384,6 +438,13 @@ fn masp_incentives() -> Result<()> { assert!(captured.contains("No shielded eth balance found")); node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert VK(B) retains the NAM rewards dispensed in the correct // amount. @@ -406,6 +467,13 @@ fn masp_incentives() -> Result<()> { assert!(captured.contains("nam: 0.719514")); node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert NAM balance at MASP pool is // the accumulation of rewards from the shielded assets (BTC and ETH) @@ -452,6 +520,14 @@ fn masp_incentives() -> Result<()> { )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert BTC balance at VK(A) is 0 let captured = CapturedOutput::of(|| { run( @@ -512,6 +588,13 @@ fn masp_incentives() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert NAM balance at VK(A) is the rewards dispensed earlier // (since VK(A) has no shielded assets, no further rewards should @@ -578,7 +661,13 @@ fn masp_incentives() -> Result<()> { // Wait till epoch boundary to prevent conversion expiry during transaction // construction node.next_epoch(); - + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Send all NAM rewards from SK(B) to Christel run( &node, @@ -603,7 +692,13 @@ fn masp_incentives() -> Result<()> { // Wait till epoch boundary node.next_epoch(); - + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Send all NAM rewards from SK(A) to Bertha run( &node, @@ -626,6 +721,14 @@ fn masp_incentives() -> Result<()> { )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert NAM balance at VK(A) is 0 let captured = CapturedOutput::of(|| { run( @@ -645,6 +748,13 @@ fn masp_incentives() -> Result<()> { assert!(captured.result.is_ok()); assert!(captured.contains("No shielded nam balance found")); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert NAM balance at VK(B) is 0 let captured = CapturedOutput::of(|| { run( @@ -750,7 +860,20 @@ fn spend_unconverted_asset_type() -> Result<()> { for _ in 0..5 { node.next_epoch(); } - + // sync the shielded context + run( + &node, + Bin::Client, + vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + AB_VIEWING_KEY, + "--node", + validator_one_rpc, + ], + )?; + node.assert_success(); // 4. Check the shielded balance let captured = CapturedOutput::of(|| { run( @@ -812,6 +935,20 @@ fn masp_pinned_txs() -> Result<()> { // Wait till epoch boundary let _ep0 = node.next_epoch(); + // sync shielded context + run( + &node, + Bin::Client, + vec![ + "shielded-sync", + "--viewing-keys", + AC_VIEWING_KEY, + "--node", + validator_one_rpc, + ], + )?; + node.assert_success(); + // Assert PPA(C) cannot be recognized by incorrect viewing key let captured = CapturedOutput::with_input(AB_VIEWING_KEY.into()).run(|| { @@ -881,6 +1018,14 @@ fn masp_pinned_txs() -> Result<()> { // This makes it more consistent for some reason? let _ep2 = node.next_epoch(); + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert PPA(C) has the 20 BTC transaction pinned to it let captured = CapturedOutput::with_input(AC_VIEWING_KEY.into()).run(|| { @@ -924,6 +1069,14 @@ fn masp_pinned_txs() -> Result<()> { // Wait till epoch boundary let _ep1 = node.next_epoch(); + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // Assert PPA(C) does not NAM pinned to it on epoch boundary let captured = CapturedOutput::with_input(AC_VIEWING_KEY.into()).run(|| { @@ -978,6 +1131,22 @@ fn masp_txs_and_queries() -> Result<()> { let (mut node, _services) = setup::setup()?; _ = node.next_epoch(); + + // add necessary viewing keys to shielded context + run( + &node, + Bin::Client, + vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + AB_VIEWING_KEY, + "--node", + validator_one_rpc, + ], + )?; + node.assert_success(); + let txs_args = vec![ // 0. Attempt to spend 10 BTC at SK(A) to PA(B) ( @@ -1188,11 +1357,22 @@ fn masp_txs_and_queries() -> Result<()> { ]; for (tx_args, tx_result) in &txs_args { - // We ensure transfers don't cross epoch boundaries. - if tx_args[0] == "transfer" { + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // there is no need to dry run balance queries + let dry_run_args = if tx_args[0] == "transfer" { + // We ensure transfers don't cross epoch boundaries. node.next_epoch(); - } - for &dry_run in &[true, false] { + vec![true, false] + } else { + vec![false] + }; + for &dry_run in &dry_run_args { let tx_args = if dry_run && tx_args[0] == "transfer" { vec![tx_args.clone(), vec!["--dry-run"]].concat() } else { @@ -1304,6 +1484,21 @@ fn wrapper_fee_unshielding() -> Result<()> { node.assert_success(); _ = node.next_epoch(); + // sync shielded context + run( + &node, + Bin::Client, + vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + AB_VIEWING_KEY, + "--node", + validator_one_rpc, + ], + )?; + node.assert_success(); + // 2. Valid unshielding run( &node, @@ -1328,6 +1523,14 @@ fn wrapper_fee_unshielding() -> Result<()> { )?; node.assert_success(); + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); + // 3. Invalid unshielding let tx_args = vec![ "transfer", @@ -1393,6 +1596,20 @@ fn cross_epoch_tx() -> Result<()> { )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + "--node", + validator_one_rpc, + ], + )?; + node.assert_success(); + // 2. Generate the tx in the current epoch let tempdir = tempfile::tempdir().unwrap(); run( @@ -1471,6 +1688,19 @@ fn dynamic_assets() -> Result<()> { storage.conversion_state.tokens.retain(|k, _v| *k == nam); tokens }; + // add necessary viewing keys to shielded context + run( + &node, + Bin::Client, + vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + "--node", + validator_one_rpc, + ], + )?; + node.assert_success(); // Wait till epoch boundary node.next_epoch(); // Send 1 BTC from Albert to PA @@ -1492,6 +1722,13 @@ fn dynamic_assets() -> Result<()> { ], )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert BTC balance at VK(A) is 1 let captured = CapturedOutput::of(|| { @@ -1543,6 +1780,13 @@ fn dynamic_assets() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert BTC balance at VK(A) is still 1 let captured = CapturedOutput::of(|| { @@ -1602,6 +1846,13 @@ fn dynamic_assets() -> Result<()> { ], )?; node.assert_success(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert BTC balance at VK(A) is now 2 let captured = CapturedOutput::of(|| { @@ -1643,6 +1894,13 @@ fn dynamic_assets() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert that VK(A) has now received a NAM rewward for second deposit let captured = CapturedOutput::of(|| { @@ -1695,6 +1953,13 @@ fn dynamic_assets() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert BTC balance at VK(A) is still 2 let captured = CapturedOutput::of(|| { @@ -1742,6 +2007,13 @@ fn dynamic_assets() -> Result<()> { // Wait till epoch boundary node.next_epoch(); + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert BTC balance at VK(A) is still 2 let captured = CapturedOutput::of(|| { @@ -1783,7 +2055,13 @@ fn dynamic_assets() -> Result<()> { // Wait till epoch boundary node.next_epoch(); - + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert BTC balance at VK(A) is still 2 let captured = CapturedOutput::of(|| { run( @@ -1835,7 +2113,13 @@ fn dynamic_assets() -> Result<()> { // Wait till epoch boundary node.next_epoch(); - + // sync the shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); // Assert BTC balance at VK(A) is still 2 let captured = CapturedOutput::of(|| { run( diff --git a/test_fixtures/masp_proofs/ACA50A646C6CEA7751373605BE16D6748146469C7DF33C28DA6F65749E40AD45.bin b/test_fixtures/masp_proofs/ACA50A646C6CEA7751373605BE16D6748146469C7DF33C28DA6F65749E40AD45.bin new file mode 100644 index 0000000000000000000000000000000000000000..92b0befd053c882b89b6f6906806e95489603364 GIT binary patch literal 10105 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 Date: Tue, 30 Jan 2024 18:11:02 +0100 Subject: [PATCH 04/15] [fix] Some e2e test fixes --- crates/tests/src/e2e/ibc_tests.rs | 21 ++++++++++++++++++++- crates/tests/src/e2e/ledger_tests.rs | 13 +++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/tests/src/e2e/ibc_tests.rs b/crates/tests/src/e2e/ibc_tests.rs index 4cd825b8c8..21bac52f3d 100644 --- a/crates/tests/src/e2e/ibc_tests.rs +++ b/crates/tests/src/e2e/ibc_tests.rs @@ -1130,7 +1130,7 @@ fn transfer_on_chain( "--node", &rpc, ]; - let mut client = run!(test, Bin::Client, tx_args, Some(40))?; + let mut client = run!(test, Bin::Client, tx_args, Some(120))?; client.exp_string(TX_ACCEPTED)?; client.exp_string(TX_APPLIED_SUCCESS)?; client.assert_success(); @@ -1297,6 +1297,16 @@ fn shielded_transfer( // Send a token to the shielded address on Chain A transfer_on_chain(test_a, ALBERT, AA_PAYMENT_ADDRESS, BTC, 10, ALBERT_KEY)?; + let rpc = get_actor_rpc(test_a, Who::Validator(0)); + let tx_args = vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + "--node", + &rpc, + ]; + let mut client = run!(test_a, Bin::Client, tx_args, Some(120))?; + client.assert_success(); // Send a token from SP(A) on Chain A to PA(B) on Chain B let amount = Amount::native_whole(10).to_string_native(); @@ -1899,6 +1909,15 @@ fn check_shielded_balances( let token_addr = find_address(test_a, BTC)?.to_string(); std::env::set_var(ENV_VAR_CHAIN_ID, test_b.net.chain_id.to_string()); let rpc_b = get_actor_rpc(test_b, Who::Validator(0)); + let tx_args = vec![ + "shielded-sync", + "--viewing-keys", + AB_VIEWING_KEY, + "--node", + &rpc_b, + ]; + let mut client = run!(test_b, Bin::Client, tx_args, Some(120))?; + client.assert_success(); let ibc_denom = format!("{dest_port_id}/{dest_channel_id}/btc"); let query_args = vec![ "balance", diff --git a/crates/tests/src/e2e/ledger_tests.rs b/crates/tests/src/e2e/ledger_tests.rs index a713314c6c..004467373d 100644 --- a/crates/tests/src/e2e/ledger_tests.rs +++ b/crates/tests/src/e2e/ledger_tests.rs @@ -743,6 +743,16 @@ fn wrapper_disposable_signer() -> Result<()> { client.exp_string(TX_APPLIED_SUCCESS)?; let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; + let tx_args = vec![ + "shielded-sync", + "--viewing-keys", + AA_VIEWING_KEY, + "--node", + &validator_one_rpc, + ]; + let mut client = run!(test, Bin::Client, tx_args, Some(120))?; + client.assert_success(); + let tx_args = vec![ "transfer", "--source", @@ -764,6 +774,9 @@ fn wrapper_disposable_signer() -> Result<()> { client.exp_string(TX_ACCEPTED)?; client.exp_string(TX_APPLIED_SUCCESS)?; let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; + let tx_args = vec!["shielded-sync", "--node", &validator_one_rpc]; + let mut client = run!(test, Bin::Client, tx_args, Some(120))?; + client.assert_success(); let tx_args = vec![ "transfer", "--source", From 91b112540a3c6e7960848d0a0cc78633b699318a Mon Sep 17 00:00:00 2001 From: satan Date: Wed, 31 Jan 2024 10:55:06 +0100 Subject: [PATCH 05/15] [chore] Rebase on main --- Cargo.lock | 11 ++++++ crates/apps/src/lib/cli.rs | 8 ++--- crates/apps/src/lib/cli/client.rs | 4 +-- crates/apps/src/lib/client/masp.rs | 12 +++---- crates/sdk/src/args.rs | 2 +- crates/sdk/src/masp.rs | 58 +++++++++++++++++++----------- 6 files changed, 59 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74382db664..3ee799beeb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3773,6 +3773,7 @@ dependencies = [ "glob", "libc", "libz-sys", + "tikv-jemalloc-sys", "zstd-sys", ] @@ -7339,6 +7340,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tikv-jemalloc-sys" +version = "0.5.4+5.3.0-patched" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "time" version = "0.3.30" diff --git a/crates/apps/src/lib/cli.rs b/crates/apps/src/lib/cli.rs index 09a0485039..a65be8278b 100644 --- a/crates/apps/src/lib/cli.rs +++ b/crates/apps/src/lib/cli.rs @@ -5666,7 +5666,7 @@ pub mod args { impl Args for ShieldedSync { fn parse(matches: &ArgMatches) -> Self { - let ledger_address = LEDGER_ADDRESS_DEFAULT.parse(matches); + let ledger_address = LEDGER_ADDRESS.parse(matches); let batch_size = BATCH_SIZE_OPT.parse(matches); let last_query_height = BLOCK_HEIGHT_OPT.parse(matches); let spending_keys = SPENDING_KEYS.parse(matches); @@ -5681,7 +5681,7 @@ pub mod args { } fn def(app: App) -> App { - app.arg(LEDGER_ADDRESS_DEFAULT.def().help(LEDGER_ADDRESS_ABOUT)) + app.arg(LEDGER_ADDRESS.def().help(LEDGER_ADDRESS_ABOUT)) .arg(BATCH_SIZE_OPT.def().help( "Optional batch size which determines how many txs to \ fetch before caching locally. Default is 1.", @@ -5704,7 +5704,7 @@ pub mod args { fn to_sdk(self, ctx: &mut Context) -> ShieldedSync { let chain_ctx = ctx.borrow_mut_chain_or_exit(); ShieldedSync { - ledger_address: (), + ledger_address: self.ledger_address, batch_size: self.batch_size, last_query_height: self.last_query_height, spending_keys: self @@ -6005,8 +6005,8 @@ pub mod args { type EthereumAddress = String; type Keypair = WalletKeypair; type PublicKey = WalletPublicKey; - type TendermintAddress = tendermint_config::net::Address; type SpendingKey = WalletSpendingKey; + type TendermintAddress = tendermint_config::net::Address; type TransferSource = WalletTransferSource; type TransferTarget = WalletTransferTarget; type ViewingKey = WalletViewingKey; diff --git a/crates/apps/src/lib/cli/client.rs b/crates/apps/src/lib/cli/client.rs index fca46991c3..3285f9d8c8 100644 --- a/crates/apps/src/lib/cli/client.rs +++ b/crates/apps/src/lib/cli/client.rs @@ -316,9 +316,9 @@ impl CliApi { tx::submit_validator_metadata_change(&namada, args) .await?; } - Sub::ShieldedSync(ShieldedSync(mut args)) => { + Sub::ShieldedSync(ShieldedSync(args)) => { let client = client.unwrap_or_else(|| { - C::from_tendermint_address(&mut args.ledger_address) + C::from_tendermint_address(&args.ledger_address) }); client.wait_until_node_is_synced(&io).await?; let args = args.to_sdk(&mut ctx); diff --git a/crates/apps/src/lib/client/masp.rs b/crates/apps/src/lib/client/masp.rs index a27b39a83d..ad23a104c5 100644 --- a/crates/apps/src/lib/client/masp.rs +++ b/crates/apps/src/lib/client/masp.rs @@ -2,15 +2,12 @@ use std::fmt::Debug; use color_eyre::owo_colors::OwoColorize; use masp_primitives::sapling::ViewingKey; -use masp_primitives::transaction::Transaction; use masp_primitives::zip32::ExtendedSpendingKey; -use namada::proof_of_stake::Epoch; -use namada::token::Transfer; -use namada::types::storage::IndexedTx; use namada_sdk::error::Error; use namada_sdk::io::Io; use namada_sdk::masp::{ - ProgressLogger, ProgressType, ShieldedContext, ShieldedUtils, + IndexedNoteEntry, ProgressLogger, ProgressType, ShieldedContext, + ShieldedUtils, }; use namada_sdk::queries::Client; use namada_sdk::types::storage::BlockHeight; @@ -135,8 +132,7 @@ impl<'io, IO: Io> CliLogger<'io, IO> { impl<'io, IO: Io> ProgressLogger for CliLogger<'io, IO> { type Fetch = CliLogging<'io, u64, IO>; - type Scan = - CliLogging<'io, (IndexedTx, (Epoch, Transfer, Transaction)), IO>; + type Scan = CliLogging<'io, IndexedNoteEntry, IO>; fn io(&self) -> &IO { self.io @@ -151,7 +147,7 @@ impl<'io, IO: Io> ProgressLogger for CliLogger<'io, IO> { fn scan(&self, items: I) -> Self::Scan where - I: IntoIterator, + I: IntoIterator, { CliLogging::new(items, self.io, ProgressType::Scan) } diff --git a/crates/sdk/src/args.rs b/crates/sdk/src/args.rs index af3d0a584e..8ab98d3254 100644 --- a/crates/sdk/src/args.rs +++ b/crates/sdk/src/args.rs @@ -102,8 +102,8 @@ impl NamadaTypes for SdkTypes { type EthereumAddress = (); type Keypair = namada_core::types::key::common::SecretKey; type PublicKey = namada_core::types::key::common::PublicKey; - type TendermintAddress = tendermint_config::net::Address; type SpendingKey = namada_core::types::masp::ExtendedSpendingKey; + type TendermintAddress = tendermint_config::net::Address; type TransferSource = namada_core::types::masp::TransferSource; type TransferTarget = namada_core::types::masp::TransferTarget; type ViewingKey = namada_core::types::masp::ExtendedViewingKey; diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index ddfd733a27..6761f3de14 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -113,6 +113,26 @@ pub const OUTPUT_NAME: &str = "masp-output.params"; /// Convert circuit name pub const CONVERT_NAME: &str = "masp-convert.params"; +/// Type alias for convenience and profit +pub type IndexedNoteData = BTreeMap< + IndexedTx, + ( + Epoch, + BTreeSet, + Transaction, + ), +>; + +/// Type alias for the entries of [`IndexedNoteData`] iterators +pub type IndexedNoteEntry = ( + IndexedTx, + ( + Epoch, + BTreeSet, + Transaction, + ), +); + /// Shielded transfer #[derive(Clone, Debug, BorshSerialize, BorshDeserialize)] pub struct ShieldedTransfer { @@ -540,13 +560,13 @@ impl SyncStatus for Syncing {} /// all transactions from a given height, or none. #[derive(BorshSerialize, BorshDeserialize, Debug, Default, Clone)] pub struct Unscanned { - txs: BTreeMap, + txs: IndexedNoteData, } impl Unscanned { fn extend(&mut self, items: I) where - I: IntoIterator, + I: IntoIterator, { self.txs.extend(items.into_iter()); } @@ -564,9 +584,8 @@ impl Unscanned { } impl IntoIterator for Unscanned { - type IntoIter = - btree_map::IntoIter; - type Item = (IndexedTx, (Epoch, Transfer, Transaction)); + type IntoIter = ::IntoIter; + type Item = IndexedNoteEntry; fn into_iter(self) -> Self::IntoIter { self.txs.into_iter() @@ -743,7 +762,14 @@ impl ShieldedContext { .iter_mut() .filter(|(_vk, h)| **h < Some(indexed_tx)) { - self.scan_tx(indexed_tx, epoch, &tx, &stx, vk, native_token.clone())?; + self.scan_tx( + indexed_tx, + epoch, + &tx, + &stx, + vk, + native_token.clone(), + )?; *h = Some(indexed_tx); } // possibly remove unneeded elements from the cache. @@ -766,17 +792,7 @@ impl ShieldedContext { logger: &impl ProgressLogger, last_indexed_tx: Option, last_query_height: Option, - ) -> Result< - BTreeMap< - IndexedTx, - ( - Epoch, - BTreeSet, - Transaction, - ), - >, - Error, - > { + ) -> Result { // Query for the last produced block height let last_block_height = query_block(client) .await? @@ -3680,7 +3696,7 @@ pub enum ProgressType { pub trait ProgressLogger { type Fetch: Iterator; - type Scan: Iterator; + type Scan: Iterator; fn io(&self) -> &IO; @@ -3690,7 +3706,7 @@ pub trait ProgressLogger { fn scan(&self, items: I) -> Self::Scan where - I: IntoIterator; + I: IntoIterator; } /// The default type for logging sync progress. @@ -3707,7 +3723,7 @@ impl<'io, IO: Io> DefaultLogger<'io, IO> { impl<'io, IO: Io> ProgressLogger for DefaultLogger<'io, IO> { type Fetch = as IntoIterator>::IntoIter; - type Scan = as IntoIterator>::IntoIter; + type Scan = as IntoIterator>::IntoIter; fn io(&self) -> &IO { self.io @@ -3723,7 +3739,7 @@ impl<'io, IO: Io> ProgressLogger for DefaultLogger<'io, IO> { fn scan(&self, items: I) -> Self::Scan where - I: IntoIterator, + I: IntoIterator, { let items: Vec<_> = items.into_iter().collect(); items.into_iter() From f2ef987551bac4f30a77c36fddcc4a59114de512 Mon Sep 17 00:00:00 2001 From: satan Date: Wed, 31 Jan 2024 12:19:01 +0100 Subject: [PATCH 06/15] I don't know --- Makefile | 2 +- crates/namada/src/ledger/native_vp/masp.rs | 1 - crates/sdk/src/masp.rs | 17 -------- wasm/checksums.json | 48 +++++++++++----------- 4 files changed, 25 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index d8b389b5a8..1efe02525d 100644 --- a/Makefile +++ b/Makefile @@ -193,7 +193,7 @@ test-integration-save-proofs: # Run integration tests without specifying any pre-built MASP proofs option test-integration-slow: RUST_BACKTRACE=$(RUST_BACKTRACE) \ - $(cargo) +$(nightly) test integration::$(TEST_FILTER) --features integration \ + $(cargo) +$(nightly) test $(jobs) integration::$(TEST_FILTER) --features integration \ -Z unstable-options \ -- \ --test-threads=1 \ diff --git a/crates/namada/src/ledger/native_vp/masp.rs b/crates/namada/src/ledger/native_vp/masp.rs index b222aeaf9b..7c3f3dee5c 100644 --- a/crates/namada/src/ledger/native_vp/masp.rs +++ b/crates/namada/src/ledger/native_vp/masp.rs @@ -578,7 +578,6 @@ where return Ok(false); } } - if !(self.valid_spend_descriptions_anchor(&shielded_tx)? && self.valid_convert_descriptions_anchor(&shielded_tx)? && self.valid_nullifiers_reveal(keys_changed, &shielded_tx)?) diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index 6761f3de14..4406a514cd 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -537,23 +537,6 @@ pub type TransferDelta = HashMap; /// Represents the changes that were made to a list of shielded accounts pub type TransactionDelta = HashMap; - -#[derive(Debug, Clone)] -/// A marker type indicating that the shielded context is currently -/// syncing. -pub enum Syncing {} - -#[derive(Debug, Clone)] -/// A marker type indicating that the shielded context is not currently -/// syncing. -pub enum NotSyncing {} - -pub trait SyncStatus {} - -impl SyncStatus for NotSyncing {} - -impl SyncStatus for Syncing {} - /// A cache of fetched indexed transactions. /// /// The cache is designed so that it either contains diff --git a/wasm/checksums.json b/wasm/checksums.json index 360952d541..bcf852dfc2 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,26 +1,26 @@ { - "tx_become_validator.wasm": "tx_become_validator.326ac786f8a2d13e05c00f867112bf2eb7fd0205e41702460bdd6615e0a86501.wasm", - "tx_bond.wasm": "tx_bond.c2d8b7c0e18b6b98ab80dac0318e2505696d837a7ecfdf05c53d0f8a850a3642.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.b55678331a215efd8af07c061c970e586d5a186529b6d21ecc13d0808d433e3e.wasm", - "tx_change_consensus_key.wasm": "tx_change_consensus_key.5ffbfa39655a9307cb97e10bd3c0ba3d2f083cf191718c154df91b933e9e0e30.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.090a4c5c46cdf0bb149f82de1dd476632e6c034cdbc85484791d9a6bd4ba1579.wasm", - "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.6b9abec8900ec21ca72d8d28d49d5edc93e1d9003d4b588f721dc7ff475e4f5b.wasm", - "tx_claim_rewards.wasm": "tx_claim_rewards.540284b467fbbd41a206380d23bd4c93d6b65fa2c114b108c0e21b5596054af0.wasm", - "tx_deactivate_validator.wasm": "tx_deactivate_validator.a4b36358fbdabca1061d45ebb943eabadef496c74e9ee16943dc25e93c208cb6.wasm", - "tx_ibc.wasm": "tx_ibc.7eb2b09106b3e182819e8c9d428d64162bca7f1bf2f2ea599d639060ee962d46.wasm", - "tx_init_account.wasm": "tx_init_account.da3a893a6d2669bec7f93add473a4b37018075dd3482021f34c780a9efbcd29f.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.1c293251753a173a8ef8a0c4b2cda09873765fefc431618a98786be3a1c0d67a.wasm", - "tx_reactivate_validator.wasm": "tx_reactivate_validator.e06d10d70658c85bb1223d12d5f673eeeb10310510023a9ef8bfa78a90e24615.wasm", - "tx_redelegate.wasm": "tx_redelegate.691a4875fbf9e136dae7a3c19a5cbc893e0af86a0dedbb37030a4517cc309bbf.wasm", - "tx_resign_steward.wasm": "tx_resign_steward.a7d0b661b0c9c94a663afa2cfd83b413b59c16c5f0dad876ed9573b695201914.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.ee74b4b1a4d6e5a025fde573288f114a630839dc23a413ab3d5803cb7545bd35.wasm", - "tx_transfer.wasm": "tx_transfer.3f55838e2cbdc79ea10c3da76118f35a4457c6b386f6be26d9df1e9d00565c7e.wasm", - "tx_unbond.wasm": "tx_unbond.84cd3e6af90ace7b9911a012f9cb3191ae3bcb48d02a936bbeabd5d387aa196e.wasm", - "tx_unjail_validator.wasm": "tx_unjail_validator.6bed337952b9d752ef02a6d4eccd168c8ae60a49a2516263679065d2fff5e9c3.wasm", - "tx_update_account.wasm": "tx_update_account.aa64c34962f4ce2af6ea98e2e9260011073fa0859658f3ff8b614a16e9ff5fed.wasm", - "tx_update_steward_commission.wasm": "tx_update_steward_commission.e5728d726a07ff4d732235d08cf11ffe0154e45a8c1f5f16afae962f2770f1db.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.c46d4973fa34d260de849aea655775854ddd917ae535c3792b8c30aef8bced1e.wasm", - "tx_withdraw.wasm": "tx_withdraw.f94f13c6e21675dcee5d36e45df113a15152e65a75f0f0160a260bc810aafe23.wasm", - "vp_implicit.wasm": "vp_implicit.4e65e76c15d91af543ea1ca012eb7734dbb1fdeafc2b92d5db965b300a4605dc.wasm", - "vp_user.wasm": "vp_user.51c1f0e14d5fa6c7b4e787c732e6daf1a037cb481011840a6f8187687384fb39.wasm" + "tx_become_validator.wasm": "tx_become_validator.342d13f80c7db9462b9614b169303ea768f27f2ffa8d3f152eb9fa1e53fbfa05.wasm", + "tx_bond.wasm": "tx_bond.d231d3dd21613198245be912ccc72631730c0052eb58762b771d3014513a63a5.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.174239af9711946856652bd641c92b50d64bc3d421efa9ff55e8c2fe5cfd15eb.wasm", + "tx_change_consensus_key.wasm": "tx_change_consensus_key.d4ea4959fb2ee837e22e5e7a40233211560a9fb9514cbc1908baff90371ad873.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.47409552a74537abbe95b150213fb0bf96ff336f2a614f7098b50cdc5be1c75b.wasm", + "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.5b6d5f26a2e7e496d2400ea0b7822c160712978f2028e95f95a84a4cecb161f5.wasm", + "tx_claim_rewards.wasm": "tx_claim_rewards.4bc11106b3c1f1c5a83b6f434d5c561e441c1414cd0cb1f3456377e19b5ee41c.wasm", + "tx_deactivate_validator.wasm": "tx_deactivate_validator.551aa9604c4493af85fe4135bae091e80a111dff3cac78c134c6332fd8f99b33.wasm", + "tx_ibc.wasm": "tx_ibc.64c7f2f96d18dcd37d5e2f965a55db3150313870521e3f8153920146fe45dded.wasm", + "tx_init_account.wasm": "tx_init_account.183d63f2a1756d94d05c34c492b800cf64469f96fa89c5827ecf9ca76872e7a5.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.f593e476685555d759bf17c8a00b99eb23a395030c1d91860f8533351acac3fb.wasm", + "tx_reactivate_validator.wasm": "tx_reactivate_validator.199726342ab6115ad331fde68cce609868a7260c2e66e825d5834ad8336f93db.wasm", + "tx_redelegate.wasm": "tx_redelegate.ba0412eeecf16911d146eae01cdf3c73c496772a951d11c56f640381af15d68d.wasm", + "tx_resign_steward.wasm": "tx_resign_steward.52930818f481983c1dafff33d7d54fb262b1e817e3f53d631e57d1c148e9d9ca.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.573d68c7c0b42eba243c6902aae4002043e95bfc7d9fc2bda7334bf1b9a79ab3.wasm", + "tx_transfer.wasm": "tx_transfer.64672e859ca7a21eed446713857d439af9d3fea465075700611801a6a8d1d69d.wasm", + "tx_unbond.wasm": "tx_unbond.39ba9396dddfdbba866907b8c0c97b2fd0bd01f901dfd22426e53392bd5ee876.wasm", + "tx_unjail_validator.wasm": "tx_unjail_validator.10f93e3d9074e1d2fde280041a2e7b255cc27a974f074d958c532b57e009f1aa.wasm", + "tx_update_account.wasm": "tx_update_account.8a1f1b6a8e0d810e4a29be07331ee07cd8ade875025f0e680f2702aa23e30e9b.wasm", + "tx_update_steward_commission.wasm": "tx_update_steward_commission.dbe2f06f39f42748d45494318308abbc50b037b5d2dcd9663b14e23eb80c4c07.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.897e9cee7fd524e16be3bffc37f03cedc188f8a615ea98f6af4478ca309b3bb8.wasm", + "tx_withdraw.wasm": "tx_withdraw.0d8ca0609d9a69149a1414aa6b13d4ebc0e7f8aa1e0946c7e74089d1fc15bb95.wasm", + "vp_implicit.wasm": "vp_implicit.14c5208d7e6b17475b9535e046275b4f448f42d519340a02ff74e4c86c2995e7.wasm", + "vp_user.wasm": "vp_user.e36a0040e31cd98c920399589ea532f068fb56a6d63aa5a27395995c810edd67.wasm" } \ No newline at end of file From 5925237aa818442c82ef0e4725d4a524b5971ec1 Mon Sep 17 00:00:00 2001 From: satan Date: Wed, 31 Jan 2024 14:09:25 +0100 Subject: [PATCH 07/15] [chore]: Fix integration masp test fixtures --- ...582DAD9FBD3ACA2E0F8314642810FC958594E7.bin | Bin 10105 -> 10105 bytes ...9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin | Bin 10105 -> 0 bytes ...D4D70154B89179E7DA6F14C700AAE1EC531E80.bin | Bin 2045 -> 2045 bytes ...FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin | Bin 2045 -> 2045 bytes ...11DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin | Bin 2045 -> 2045 bytes ...DB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin | Bin 8392 -> 8392 bytes ...F2741B2A24802E41AF7F56081564BF2A160464.bin | Bin 2045 -> 2045 bytes ...753FB3BE606A5729D43A6EA8F79007D34F6C60.bin | Bin 2045 -> 2045 bytes ...AA6B8D85E10E17ED9D098B9C6B8C6795B1E0F3.bin | Bin 2045 -> 0 bytes ...2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin | Bin 12076 -> 0 bytes ...0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin | Bin 2045 -> 2045 bytes ...21C4A7EB97EAC95F77B0410D41305EEF3C766F.bin | Bin 8608 -> 0 bytes ...DF787F70D27FE1DE4CEFD4756B6753AB603FCF.bin | Bin 2045 -> 0 bytes ...16D6748146469C7DF33C28DA6F65749E40AD45.bin | Bin 10105 -> 0 bytes ...0DF6893C1C09CF3101C402BFE1465005639F14.bin | Bin 14387 -> 14387 bytes ...83E61BED82F25C4452CA41B769C3BABEB62D2B.bin | Bin 2045 -> 2045 bytes ...48447BC02F4A27D5ECAEE75DD468D66DE97346.bin | Bin 2045 -> 0 bytes ...07ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin | Bin 6177 -> 0 bytes ...DC5356710DE7B6F6FA2B23C19412005669DC2B.bin | Bin 10105 -> 10105 bytes ...9384EF0421F46F7732EE62196DEB73ECB4C225.bin | Bin 8608 -> 8608 bytes ...1E2DCE33145F68A217FD50B065966646F59116.bin | Bin 2045 -> 2045 bytes ...5852DCD946FCC03040DF7A58FDA0B6CC4919AA.bin | Bin 7875 -> 0 bytes ...C387A0A9919A436A15C6DEC3834051B7CC7993.bin | Bin 7650 -> 0 bytes ...926C88FA3742B7F3A45DC0E1227236BC835003.bin | Bin 6910 -> 0 bytes ...9AFB3B6AE2AA3ADCACF75E6520A66B2F7D184C.bin | Bin 7875 -> 7875 bytes ...A81A7DF315190329C7C2F708876D51F60D2D60.bin | Bin 4895 -> 4895 bytes ...FBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin | Bin 2045 -> 0 bytes ...5A0AD04432D0D4BB8B2488EA5E836837B00394.bin | Bin 2045 -> 0 bytes ...9BC3BBACE79DF98801EB8154EA1904597854A1.bin | Bin 4679 -> 4679 bytes ...EF52D368B771AD525817E722EA3E12B0A96971.bin | Bin 7650 -> 7650 bytes ...F7858007C4DA521F8E3BF250A46E9342178EEB.bin | Bin 5660 -> 5660 bytes ...3356453E412F862D949ABE9671C24A3903909E.bin | Bin 2045 -> 2045 bytes ...861C7F98EA4325D94989648024831E350D8F98.bin | Bin 2045 -> 2045 bytes 33 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test_fixtures/masp_proofs/2AB777063F53A1E6F66DB635DD9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin delete mode 100644 test_fixtures/masp_proofs/5DE7FF931D7864F0C05FD54926AA6B8D85E10E17ED9D098B9C6B8C6795B1E0F3.bin delete mode 100644 test_fixtures/masp_proofs/693468170864DF8C1A8C13FE2C2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin delete mode 100644 test_fixtures/masp_proofs/7198F6516381EEB67048E3099D21C4A7EB97EAC95F77B0410D41305EEF3C766F.bin delete mode 100644 test_fixtures/masp_proofs/7B6C8C638FEE08497ACAEB06BFDF787F70D27FE1DE4CEFD4756B6753AB603FCF.bin delete mode 100644 test_fixtures/masp_proofs/ACA50A646C6CEA7751373605BE16D6748146469C7DF33C28DA6F65749E40AD45.bin delete mode 100644 test_fixtures/masp_proofs/B7C738AE39C44060FD6EA5D7C648447BC02F4A27D5ECAEE75DD468D66DE97346.bin delete mode 100644 test_fixtures/masp_proofs/B88A2DB72E3A0A624B9076C5A707ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin delete mode 100644 test_fixtures/masp_proofs/C83BAD95A33CB66390611EF8155852DCD946FCC03040DF7A58FDA0B6CC4919AA.bin delete mode 100644 test_fixtures/masp_proofs/C9D7CDFED7CB968E7743BE392EC387A0A9919A436A15C6DEC3834051B7CC7993.bin delete mode 100644 test_fixtures/masp_proofs/CA9143A071C194759B72139C6B926C88FA3742B7F3A45DC0E1227236BC835003.bin delete mode 100644 test_fixtures/masp_proofs/D5A372904527694939249FA0AAFBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin delete mode 100644 test_fixtures/masp_proofs/DBE07FDEDBF79BBC814D3EB70E5A0AD04432D0D4BB8B2488EA5E836837B00394.bin diff --git a/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin b/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin index d8d0752e4d74fc2a475d90ee3fcf3eb99f40c073..809124ae22df903ecf004622ad952eae4623c7d9 100644 GIT binary patch delta 1797 zcmV+g2m1K=PWeu-78oG&?ajh~2TK6V_{fiJT4y=)GiO`xo}X3g5=iaTN&6C$HW)!+ z{$}MlSI_S2-^tgVyL_FhdfuwW81Z)vuexNO6$s6X+mQkXrEjKhC;A|6G9Y#9EqW4c z-b&*HofbwRk#7zl15JaVRZ_99yv1(D0$H#{I)kkn7xF0s;Oe+h`w!YjnzPs#qym5N z>Why&Oj3U>DNnGFCEHXfUCC?n2u&!}WtYG^L%b!Tuwq$C<3H)CdxK);*DhK~5LwnI(fpPfsmJ( zlwaF7wKw0dBcUU*x-gF*&T~X7j3Tr98A{`hH*=@??iuo%c#5xzKVu)199GCnVpU? z)u0n}^p2FAbF+Dz_Oj7F^AhdqT)fMYCy=-8>f1B=S1~$x3&mXpx&RSb>{DOije~6L z3DxIFYw?uAIzsxC6HV^64uClq>#*}AFZrVcws;*Fk_N^(L4Q{Oi}lDJ*a{O0Rg_cQ zH4(FzCtQ1Jdk)ONBJ3QX)Vd;@ee?Rn-y?M9GRfeHK)~{jnN~t1)Co~KwXk_I4`)<2 z5zwk$TW_Z%T|8VT%LAxFy8B?)1H>LnvWx>-b5AUl1-pXkM$5;hIA{F#Zc(So=>l&Z zMZ-cfG-9=+#(!8Y!k;L1rlx6vciXMY;P|qG&Vjn$0Uy)jp^CdM=1Q1uEWuU#IcjsE z9_fAkM!`Vz2;s-4ULjY?@OS*pg@3n&c;M;$DC?@jV#SgR){o}0 z%+rC$!|Kj>#`0O&O@k~!9sUl}Vo<(Uc^BG@Qe58&+aIyeu||3)wzXp~t;67D)}i3k zAcuLBxTGM|$7L7BHPDuF;~2kkF8s-i8k&cpJnCnUp%J=K%Nel#1E4m!I#E)I* zQn5`AkKoCedtgZg!-*@W#yqtHtEk4uixd{<0N^3frjWqX z!{mU!IQ-9Iyw*nuN#imiv5g>%fkyligzp5WI*+?HLHofdNn2-_%>~M4ppL=qE>0yv z$bSQbct(%)lKH|}^g8kBSg&`9Z)y-Wt`wposC2IfLR038(nK$2SPR5v0`^h_ERl7C zw3=1j3UnJ~2sW}PI}tIMv^i7wz2_}sA9yQPTzyq} zRPFxGkL0P+FB1S=Cg6Fk_Bq_ZRgev}1Hck1nktjp1f#xG9BCY4NU5aQF#k0lgnyBs zXHF^scKh6^9UDjf{IcN~1lQkzq4^VM~ delta 1797 zcmV+g2m1K=PWeu-78oF5M}2Fdge!6_?0)-LlCywTHMUSBJ~S|*%Pl}Zbc!;QHW)!+ ztE5MxPYq4l-Vb|8*^d9e!G?6fLr$_R>po#%5YM{6ocbM&&fY&0$nz@poM>%h8e^xo zN*9_YE^P>J1B){RsVJa--FHAs2wvhe!9hm z+PJvM0>kOABcUU*x-gF*&T~X7j3Tr98uAdYxSj|VICK_GNE!?Gj+Z_Aif`s5W` zgZ5;)@WhC_dr;U7=mukQ*zCrvdgGrwaxm%p46w(gT6r;s%u?X+S{I0dz;(`^4y1&$ z4$vh4?)d{_gtlgH zt&ym|?~%9C+o@~j>95n7JKQwcIdr1CZZ)4XbeReCWB`#7Ad?j$Ab*aZrrlK++E(rr zev72;tck_Mh_Ag+531_{m}UT*Q_!%6;In$7DohCrV2w9dYsup% zfwxSt$QTf}rzN#^y?-Ryct#;B-^4R#|JmR2{sa+(gkygFiQTB5`MB(wW6a7(`z}}O zdv3ZZc&@uE%D-h*n7o1}12dDP5Csd?=||VOp?^yNwE6F&8?#O;r(yR7 zjL$Ztd^FlJx9WeF&Zd@`f~|5D#L%pFaC;K{B6mJG(DD=RxmDH0bh}tH%GCR&n*{0? zS!^<5)@gh5-xg-Gla(7BUDN(u`R`0_3o<~J66LF+1xzzCX_bhe?VEvY_5XTHgU)I; z+g11AL1c&B_A?L@pf3nq@!beJ6^a%up#5Pq zOkf%-^Kf~|aMwP_KnIvL9af56R4JqMt8O$|ry=Ra74Ny|)N(?o=IP^L(5MyXd8+RPY};ny*}g=Z&7T>lLU{Ll3LQD&$yzg<2H|lHr?Q40D?x? ziX2-T?k|U~-mza|-qxVyK%0nw`$MN4^-WvQ5RU~BmofHkjjz$NQJ-27;)Y{pt&2M9 z=G(RY)4_O{S+RZVnn_=TV6k*K)gYi2$QnHmqvj)k>VOB` z-+wrdG3y&@b*{^=)t3Gp#3~?;1ahXKUhzF>YomP9fgvBS+U_%I@CAFsKmC#YG_uEq zPS6wwm;Z5*1O@Za+sJ6U$iwXoL0`RKcR#9IxvyqW39LXqq_R5Dz&(I^2cW^u*L-ij@P(M-8D*_XpWGw0 zB4ealezEgP{P)=#W&TCw$tZeWs6gh(9wR;9Hio$QcOfFI>~Wz8FR)>IEH*DD2PDlT z$B8}`g7f35qC_NeZ5|1pC-KBQ4T`$XG|UbVNe7 zDTf*);>nFgzge*@nk-sPN;y$1abXuKUt0q?agSO`=|qSiv}fCI!QkC zlTE1VETX1@h$K={1K+B&5R>dZ$p^1FGh8^|3)q~5|C8spb`S4utwjgKI%iflzdVtm nE}?*qSs*X*excJ&tX>=;n+LSq{|c624A*1SR;cy`lQkzq6C8lF diff --git a/test_fixtures/masp_proofs/2AB777063F53A1E6F66DB635DD9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin b/test_fixtures/masp_proofs/2AB777063F53A1E6F66DB635DD9C0FD9A4E019CE37AABDC5D0E4B738FE06034B.bin deleted file mode 100644 index 5fd246bed0b1bd2888e4c42d995eec4090049572..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10105 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 Lv0pi8e_#9u_`u6S diff --git a/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin b/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin index 928780e08149c1c7cbbf747edb541e9311cfe51e..d8c8886e1bb151090fca578f75ba47ed6c30de99 100644 GIT binary patch delta 601 zcmey%|Ce9q^?wLpWME)uxXN6huwG^P@$c!$EAE}QdLooM`|q!*-CrV?otrDtxp<8fFED3Rl;5j*8+Yfer&ME?!6~2jI;PvVoteZG zuTj3duCRqaDdNeT{+ZunXKb{HdU4Qqg0Hg9c_*XLE3{>rM~ShCHWubK2jzkDUJ>gGga%?*;N z8#eWZ)Uy??>0K?(yiH5IU)gUq@5Px>4<}AE+!&&DyI)bmJ;#1=y?B1+^QiU%jn9LO z#HCJ8i1e3SyzH6XuZ;4yoJ~bdG3lk76qGY_?uLk-Z5D}RhFUqt#;tLy_vCbbY?3<6V4U4D-|NL(hdOt;JBOof9Cz%MblV}_E$~t5 zm$bj~y@ii91^6ugl-AgPoXtr0MZ3J$#JK_?6IgT)t>ZFR5pTG#@W08GE%R1ePv3m( cg(2s=&Ug0bT36_C7L>f?`Ju->`60Uu0Fz%Yi~s-t delta 601 zcmey%|Ce9q^?wLpWME*p;PWwG+j@dP&5wtQE21Y%w|Y^Nm>(WD^Y(YXuKR7%-b~cd zR3NCP)RUl^jrZ!92r8Of!>r(-FI!PEW#v4XS+hRt6g*z8Q){KH$X{1C-FV4`*jvx0 zEA#}deaG>rH}Edc?P8Z%|M{0)F;iF`)O@#Zcj2O@E3ZQ*-(faUh@GiCMa^(+5ZlHK zLz~V$PuY25T(1Q6?tQ%1?p&O&J_5JjD#q)fXA7)K%<$>yt*XoHv>Ml`T@oD87mE^0>zZL9g d2=kBH^4V;`+2%FxcTLVx*!wh&Z}LNS830E7Hwgd$ diff --git a/test_fixtures/masp_proofs/3E93E8F4FC3498BA19EF4D4D70FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin b/test_fixtures/masp_proofs/3E93E8F4FC3498BA19EF4D4D70FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin index 5747b31c0179afb8170fa41f07c7b6564eea08e1..77e172baeb04122600093256d39635d6dd2f5170 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6?yFvd*G@relAdT!CT+1%qbnDe_nsEcNYIZ4a_;sG3LQ|*#{ZdrET^ly zE3|U?XW3gC-i}j)lYI|EtFe19uR6o#?v)D<84Gn2u_P`L(3u40a4JXkf&?~CpX}9W delta 308 zcmV-40n7gV5B(3YoC6?vHkO$Nu29;$R*Q!Q`fNNVB&2`!^2}Wzm}>lJcP7cRyaOcz zf4Bg-LY{FdB5nFQBjCt$QqF{rrmn;F0a*SI)bl*q^Cy;hKZkm5`%t$EC~!mSi?uKs zR>9e<4H2srYx*lwW44a${KYi7blWWR5c2=Aw!~p}6e0x60V+iF6R@20^Amd|`%XyT zHNOOHM;Sn}Ws<@UMC)Fg73VMA%er7|f34gf6J{LJjP;INB5gi?beyeV8Q~s{$sQi8 zF^GF_!>Gk2B?JCExNX+FLLTZ-f=y(-IrI6Jov>ER7}$&r^|ALpJ|z!Z(hP9VMN_NS zvR_UY!;;*#XQV}<%K=qo70u3%$wffVYGDW1I)PswYOTE2?XV+oh!Asd>l8nJI#qs%MqJjV^ zgs|54mE(f&sM;B9zh_hQs#)YiW=pYK8JCH5z0rcNSOn%H_)of9^fp@2fCNT8GvleR z4fh}c;A4z>_SeZYrdxes!a@f7ZkdsQf9i5~mD2DWN}GkY`S6SdL;;hez^*L0MtZ4G zR3rX<)?}YOW%UZ*cpjgixI_Y${WVlFAcP7GVNR3K`d>KQE%AfW)`qUuREa`OtS8

XA&dyaOcz ze}bhV1?#%dcpFV0Q3&@DH0PU47sf;j@G>>IC@K1@o7J zw+{}fzIva*-Q2Qo?YN;jG_No6Icnj~e^<2RCDW@DqLweee)!=77O|%)zr&v})$aRd z!v2$X?-vr>wHgh~heU>wumufG7fC}r@5MIx`i@-@)_eT}l~V^<_P6*tT`SrTC`sLX zv^?h_I%}vknsTV;a(7m>kT@aJP)y(Mv}nG1l+0s;h-5T_)QX0$A4)-$){q>-0!0jy G;RhVvIGgPN diff --git a/test_fixtures/masp_proofs/5355FAACD2BC8B1D4E226738EADB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin b/test_fixtures/masp_proofs/5355FAACD2BC8B1D4E226738EADB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin index c3af4cfd0cd7e2a1bae0ad839683d383c1ef9364..85b3a5b78b993b096ffe52f6b278a44dc4acd706 100644 GIT binary patch delta 1470 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 G;RhV^hLwf@ delta 308 zcmV-40n7gV5B(3YoC6?sWkfd|Uf~oFW~ZM!-qkh8`tAYIL^Xr?`I`qWTSd*YyaOcz ze~#>)k)hpX9=}uG`r?%uMC0r+GUfJescNz(L^3=W)o#E|ckn^lEN(o^DJbBH0H6U{ ztYnuc(Q)oH0f`kj)A)d}K-%-8cV|RK<1Qsu4xSu$~ z*PoR)3Krox?UndFNeTDV((0(d%?XSpe=DZK;E(f-N+zlpte{&s1h<1B-P`Ne=#d94 zO;I%Lf5}+V3H}v`=~kkddmQWr2n%82$R0Kq74i631km7d8nVbZ(i@<62{$yRdxJ*p z#GUJE{1#-w3Nf`Y4ohoAcr}vt{NK0MspwU4tovUBM0x1?HRNFd(FQ?^GLZIR0zeLv G;RhTVpp_8- diff --git a/test_fixtures/masp_proofs/59CC89A38C2D211F8765F502B6753FB3BE606A5729D43A6EA8F79007D34F6C60.bin b/test_fixtures/masp_proofs/59CC89A38C2D211F8765F502B6753FB3BE606A5729D43A6EA8F79007D34F6C60.bin index e572c3e4f0aba6969c471595665702840bf055f6..8a28e3d06019668a1123ba6ec4f279925112b8a9 100644 GIT binary patch delta 610 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 P2UaA5t5zt71xf<|bCBA@ diff --git a/test_fixtures/masp_proofs/693468170864DF8C1A8C13FE2C2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin b/test_fixtures/masp_proofs/693468170864DF8C1A8C13FE2C2A3AC62CC602036F676E17820AD9CDD04DB3F5.bin deleted file mode 100644 index e2b6c5b4ead3c8f85f66d1fa6b329bd616288bdd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12076 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 diff --git a/test_fixtures/masp_proofs/6A12E11EEAA83A0D00BF7470DD0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin b/test_fixtures/masp_proofs/6A12E11EEAA83A0D00BF7470DD0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin index 0e726100161b4d3fe8b85a20f64c47d6ccc896ae..f72e509cc8c0dc888776d63e357cb826b0253afa 100644 GIT binary patch delta 637 zcmey%|CitJ^?wLpWME)uxXN6huwG^P@$c!$EAE}QdLooM`|q!*-CrV?otrDtxtQVM zS5}6JhAOHA70Pq{`aiMCg|I@9i5nkRG7+b8awD^}gH?gW-B;~K4q_6=1!9-0&+z^f zz;^$>a;MXyC7FtgGj=iYU10W}e38XHcZ!zQ;>G%FoC>;Mw>_EXQjmJ`^Qy0wlkYI= zs=u10cVy4$6_+2f+%;#Ne|g)6>Io)q^TPEn=!!JVH#K;YTPfUe_S>e-1}q9p0^j_( zN~S;fYy0)_GVQeZP9Z~rE$}4Km{E5GwmfR@h6nplu zf{A0+W665I$>s?vId|9DMlvQoJhj*Su|VVMx!qf?9sk5GX`?>(jj27y(+RI6Lk<^r zT%64MY0Hh<$I1f!l;K=~%S%qeTvCNSl{vuBuW zqNtL@bB$%r{_lqMRdY=v&06|R_w`(4U-4-2&Sf=!)Fc}CCmQ{5*|xuWfBc#c$|k0~ zo-QSynD4Aqo?+YK|KtS=<0~79{eH^-t5;5U@z#>kQq51VvE-TjkX?j>37F16006)~ BLIeN+ delta 637 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 vfU}Xckch<(%q(+6$(@nn46eGsDXV6UC)o&aRvq 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 delta 633 zcmey%|Cit3^?wLpWME)Oy8ryw`R6U_(SKOxm)-xq^N@%11HYd=<-n-HV!kn+;eLm;^4p_!;uV z?UUXey-kAay2EEqPGAeHCnf-(;R>euH5uxBzC2fSpL5sGe{GHFw|R5oCOuR+G$m!Z zm0k9BevMsWH$J2_N9!kWXFWD+YFHlJbjv4^@pfC<44y@c3Z%cSv+w#Le`(T(V`&XS z2D|FH_g$*6b>DN;(c)6_-rU2719>L+JZDU~vL@{QsZa8M0v|@I?$JD$zv$~dyFXov zg#NSL{KO=nZe_Ur-undpx3x}%T{eFm7ey|fWEs#meGC8W2}?M42c+LoO*}vCOkTGj zlON~7DJ!Pm-`<+S6>X$m6WJ;s7}Wp5?#I7&>pKk_rx+RhH&QIWwqwqtlP!B1zq$QY wINOk|EtM6K9@xWhblW3secLhv_k!I8CwP)gYsJJ5OEOG;$S%SGN@E}Z08KPJ^Z)<= diff --git a/test_fixtures/masp_proofs/B7C738AE39C44060FD6EA5D7C648447BC02F4A27D5ECAEE75DD468D66DE97346.bin b/test_fixtures/masp_proofs/B7C738AE39C44060FD6EA5D7C648447BC02F4A27D5ECAEE75DD468D66DE97346.bin deleted file mode 100644 index 30b622be46123f4fdf9af7af6099c9c2d55ff5d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2045 zcmaF;9|9N|7#Jds3t86JLR1uA2R zy}DIYP2rizY?jkfZuZuj``A5vK;jIqfo2h9kUZBfsJ&nctQkarG&8(>Fi~9U|=Y6m4bLIPV9q+1&Eg#Jc$4-|~!wf3tQKwl4SD z*?&yvToi}e+9f{cKl=Rg{&3bgnvgwA_4ztyH`#0LuFh2Nn^MDgOpMF$Jk!CsY!|*g zT`gPIJ@p&N;iF*0h5!@L=UnQ`)s~h1e+dc%P_kwuHg)32PmE2R(^%WtUQC@EZ-4o@ za>z54C0_qiWG^WCZmT@_(c1aNv||@`sU@5|W_fjg`OB+^-|^k&ku_bV@c94a#Rn!^ zKlG^Akv*LHLpeXZ$HS1#Tt_MY&!iU?u8fwaiaz~I@-a9ygL#sL(tDTq*)A8IX1|)H zcVy4$72F>(m#hk?EZeQPUPRXX=(JxIw-esny8T1e?t#F@_Tmrjc~ib?P5ftk`N^S6 z@-=t9&tH8`Xz6pU7dIqpXB4g%lGBvz&Jd2cP?^P@*Wz{RNfaXsOGr?+&5f5Zb$hLuH=ykg%(tGOK0@05`&jI&s+Whr*!TaNdf-9a`PM!^bM zymb#cKKk)A+>t%dD$C|(U~+cm?w3`!-IlMdoSx6yxpsQc`{f7c_CJ>kUjISVW&Z!& z3GTK*S7tqliYR=#s>IwwJ7mK9t1h*%&Kk`%NemJjYTfks%$vgmO5{bdzpB(1`LSrG z_{?E5np8N?)Z>`@r3s9g4-f4qTJE-I@i~U=DlJ#1OxQX<_}{NQo2&OS=TH3cw&m03 zqmvV!Oq}IYcOa$Uh=&i){Nv)9TTHq#@0-ux$tODF2CO9nXSL_!tJzlV zyeDILOPJ-OjsKRbx4El&yX&@a9od=M7ysJhm*I&k%^dexH$9lL&!s`ZPj2<9j_8Mc z_m(d;UlZ|GJ7`&dfyb^73YXV}%KbXAFQ=Q?O2lQlL1iNUolj@JG=FjLEbMl8WfN|9 zH*(>noTXVyjy!6Za#XYWqt#@w#6JI?3vIikA8F+q=f!>AzW8ME>)l0fjpRH!eoLty zJeN_qlrear^IESq=4E_093H7(>5D8o_^W%-*)X{ZHF@rg_;11PyPAhuQ)h80Gq1FL{;Op5tq=FE z8eNuTwE1*&K}tcxG^uUzKRp^}=I1}tD6Z*KW$ENC6#pjpFyz`s4UzijRWhvU={)8e zc?B0O%=BF$R-In-QnhK#r1fh%tggI`e7Rt6#&_0EdyZr4tiR0c*}X}qK>XRHy!Olo z%CcYV+4}!Y`~OYp9?P=5rq>^>k1ffM+0?0Xxbow_+4lsGOo_05mp^auhc{cKq^5rL O;D8m$;HnkMfw2MPALKFs diff --git a/test_fixtures/masp_proofs/B88A2DB72E3A0A624B9076C5A707ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin b/test_fixtures/masp_proofs/B88A2DB72E3A0A624B9076C5A707ECEFBCDCC2ABB01BC7956857DFF45C81123C.bin deleted file mode 100644 index 155287509e7d8dd4a037217e44a19304f7d446ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6177 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 n+|Of7B2YIMfi7g5DuEZ(RZIHq&tOzNxX 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 delta 1474 zcmV;z1wHzpL!d*j=@lTcwLImA^AFQf0CB`e)Q>_}!4{lL{cud11J_AI3<4aJ2^K+N z9IUd4@1GRgd4My@T-bQ1wc>S+|FVfiyX`TQ23OuNM{fTM*U#3I`rwTPX_-1ZnnwHa zv2dyE1L_YphYnUA0=u4@j|SRU>Nt9>+p!Wc8rBAlHJ;rKBd5Bn%B$Mzy|b$pqym2s zaHIW-M+3Pr%@A}XaHf?zm%_t{(csJMr{C#iXQV0Oj15{cswaz3ppD&0e^zex9c8qt zYd0Hw#)GKq6)w!qP2i?1M=qfs3%WwfZ&-9JG;Zo3Gd|_lIW$7N%$3qP`^pMS^6_ad zrlwhqF$W+P-UU~ zPA01u{p{u61tH&#Bi-_JTA9$Q@nH+8Hsv6a>{5BN6bu3*SgT>W$;A}S8vSh;!byD( zvEB_d0g(_WlP?PhljIyge}tXjQ;*k!=xXQ69xvh^lMY%jBT`6D%7`bv7#6nX$n|bB z01x`%d9nbY<lCrmF?RE%V9uF-+yHs2%h`F{WOI4n*oXnSj~;` z-#Qx{ora-1m=d5i!Wc2cL2P(8Hef926XEp%ce=MB%5xsc0(gTie_rR`Uz4&ZAYHpx zQ%P@0;u4TF*qXxxo$i_?hI`}8Fnc;1#UJ1WF`5t`Z*7eyKt9ANYb)0$%#uJO4_!+c z@$DT5Yrm$-{85V0pz6yp?CtT|hW@T~QU|YJ2zY!Dbt4UnkX@HAnuY?2zmqVQ7-vM? z#EN)u@$Nw*u#a@pf5-}oJug%Xk5Zg_QX$~Lh5`$S0>DLx)9;VS27s|>a;9%~*T?}V zYvIYNQT~+$$!!>wWAAA(xyQywCj7_Pt<@Ihk+Ht}x9Za5say39D3lTAgiR7>8EABD z=Yhp3Zp{q}%N>-8petBtGP1z*L=8I!zXVn zuMb9~qs#h=;zf!xtww$6I>)1@ybJE`x!DDsVooq4VBvZ1z%tXgUEq^~rn#1`jzb*k z?8yxxR0tMzf3T1BY>^NI+ZHIWerNCj=|R@las?H&>`V2Rthj^JVx>X_Y6DxnsRE#| zUcM$t&6P2#!M{|5#fd+0kFRq1!iP(WEqpTg<8N{5h=`tw<7!>dq>eKBlg*D?w-b8~ zw6tZW&5M^L+{{Xg0+~n*xEpUf^sd{0jHyC#a?l%&eZaw;&PA6qz`$0>&8~kf zT6JKUr^%IBI4uq}?YuMtWT)xbyy0Q9Ge@Abi>(3Ptd2r}y4snJ3qw_nl0CO&%0YC$ zC`K=$e>+nxyb5QJC$Ug@HIRLTMQ%YN&Y}R3Sstg`yA+R6AX=dLOi+NqNM?ufLpxH0t}CV9^9iT~2LK&FCNrXen$w_a6# z_+8*PhgfPY;cfvA5mV3b@}cBF$|Yw^9VRoY1GILp_U+A0?Y=P+KNg8nSO= zNS{%NbBo2Q`X8~KiPszd9kl_yTGdTBf@kA?Ig`2h3|Gp^{V@r9R7z~N@zKEmt?U~o cCXauhytZ{p5nQbTMemfxN=LBK2a{wWJn$ymbN~PV diff --git a/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin b/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin index 51f68528d4cd92b03a2d83e5b2e058d41db47209..e93c32f27b205b6a70b6bb18e558904a5260c1ef 100644 GIT binary patch delta 601 zcmey%|Ce9q^?wLpWME)u@m_5IvPxj{YJ;VhJim!bmQE{O6iT3oZ920dk z6$q*+^(3ffNDZBOp!+1EEd z=r}0H)G4syPtl&znDs)X`&}mN`tD;fM|qp%qz?~68-Aw-a~wJ!P#<(iZSG&bjc47z zy+6>(GuK@9bG++2QL}BYw_T}z#l@vrQWo%?TZ8>$M3Rb~q=0@x{U+^QGcVl!`-$KF z;1jOpn{HU2d2?*RgA`#8qvIKW(*@j>QZoK54e(D0I_Va9n)C9VP}9Y)4S)5WZVch@ Z%@3TK>~9)>d*g9oUawkN=E)D)WdQ41D-i$y delta 601 zcmey%|Ce9q^?wLpWME(@mUFC*4!V1eXK&5c^w#7}YAt&%%`fKnU7yUf%zGi5;zS)y z1%hfyJqfDWc(0C$prXk&%nA;zbDkvUIv_#?=YJvysEmlS%NkD@Rw;x z58waO*d%)D)V%5|k9|U9oEIGq6=mOSz@oq;ASUjzHf{4+(?q{rW{W48|CyY?7FbWn zx6r_YQ)@-{zb;BV9Tt)P-h9agl}j^Ey}I)4(;U{@vRV@EiPa9r75hTHyq4dYqorW^ z_U+Nbt-?NPgf|9_a- z{IWr~EpiKIIscNzqX$LzPxGwZbLo`J-YwrpXW4WdI7!CG!9P diff --git a/test_fixtures/masp_proofs/C83BAD95A33CB66390611EF8155852DCD946FCC03040DF7A58FDA0B6CC4919AA.bin b/test_fixtures/masp_proofs/C83BAD95A33CB66390611EF8155852DCD946FCC03040DF7A58FDA0B6CC4919AA.bin deleted file mode 100644 index 31a1bd0816ae04084e9e57a728a7e29b29866c97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7875 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 m@-(Y%C&>_T{f&BL7vW#0WE!3hKjIyi*jZXq}c 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 diff --git a/test_fixtures/masp_proofs/CCDB111327E4189EC4C6FE2D429AFB3B6AE2AA3ADCACF75E6520A66B2F7D184C.bin b/test_fixtures/masp_proofs/CCDB111327E4189EC4C6FE2D429AFB3B6AE2AA3ADCACF75E6520A66B2F7D184C.bin index db2f1b978d468b75668732275e511b1170173b3e..b19f3ecf20b6c7b36fb6a8d7e717dfa48242a3d7 100644 GIT binary patch delta 1378 zcmV-o1)ciCJ;Ob)6cZpON!tPgceaYI-Mi|hyV**C6h!dsa# z?LP?t!<*Joc44|}0tt2RlfKMV3DB^cWY$?{gUmrm7F@FUDN5b~51Ub(Nwd}y^a3EO z8sqjFK3E|Q7H)Z+%Z&0bFe)_zCcV7 z1EE9>k-t>zc`n~+&ypOSD=g5x$nysq&ACFItMtUvGuk$ZwiZ3+{rdzsde4p@Tj(O( zH;MyZmK6`FwaYobAOVpOD3P5AlMfm|f1nBC&6e%EA^V8Yxv>x%Ca61a=sC{$@6qvt z@wh#3XGs92DTxkO)bxE`}}8YhPa`&;*I{4R338JskQ2d~kU%e>WMd ztwwVWWDCO(zh@Rdw8gh{knAt$DudlmrUzzCY93;{J0KD3$szh4u2-A|vNwXDEmEl(7Xya`Ul4lh{uYt&&oP zVn`8h|BXQ&Ti00+V%jnS)mm7!f2a$PT}=tkz11X>Sj%u5% zma{64zRaIRgj5wHFT4d8ARa12m4R~*3>AQpCWxOOQO!N?+myMEnGjxte}n35o1GL* zDqN41b#+@591Z1}pzd-y*k#R2?`j9qcy;;nJ&Vlmnnmx5zC)BVYexo}`Uwcp{BJo0 z=hIlD;A<*Ki6beffBRzBWNYwQNatn@K=t5{M$ed>y*1*6* zcM!#Q|MO0M+$%@ErJ*Qqhg>kL73{*JU!gZ;1<`1?3WT-0O=%sp!kDS|Wnnmg%%t0K zHzsK5g+G>fSV67oZjyi~Lg zj5lGzzoVb2D%Omx$ILvONi%GP>Uo{ZhJ60nzJ85c^f8Bhe?|+F?4Jy4SekC*?%MC1 z1zDP%d&zpg$+ohHf2+2EKCy9v5B^z3Z5(R64C97(8*Jf}EG#uz?kpcnW_(7uet@|k z6FM+Wv4SV{;^aauCWg+q433&t_vBiH0_^2j4g0FFM2(f?&9tUYN*0CPF?xY!$O%bv zTaL+(OqIry%||Jg9y(2IF#^o)%?6zD=hFbUOx9H#XOFONf1@I#Ndbp3*$_%GGbnr4 zdv?)ry�ZuDgzrKaZ{pL@G86HcN5$0ee$ZQ-O!nb+KCNbPX@*n58H;HNbhqi%)^O z{a`9#J#tz;q73l57=8Xg!@v7~l9+-fSc)1F=hqIETZ5=e5E=q1q*8B2_X0+6B5@Ud z+<-@{kXMIdND`HOh*pF^QJkhM2PfAC#%;*7*FqP^T*G#SE@^#A|> delta 1378 zcmV-o1)ciCJ;Ob)6cZqy&a{2XYFe%Jv2A<8D7PLi`RS__eYD&MuZFUx^jwUSG!sE# z)Jk@H!c=7b{dyd%Ll`1iF*|HIC46%Uc-8oy#OY^;ng1Xe7ArcU57KY5Z@IKyO#k+OyUZ^a3C} zpiu8%ar9kUu{omjBNH&BCtrH}vBHK3E|Q3=dKqK{P}U^5RRlmmrC z`RP)-IQ}Qm4Q!a9jl!$r(+1G0ftP@0WBPr&b^6?6?6(}_C{%)Ks9Y&c7V0Zuv6GLB z0tjspH4v6e6#8ze(gBeWD3P5AlMfm|f0JuC9*6#yHkDQ)iR_&zX7-6( z22&-NycoEYn)!~M8+6K=YAfEEVa;&?#B&B{U zQhhfEcWLHNrUZuf*o|vnU4_w~Sz>+Xnf;WMdahuPj%6Nr(?Sm=)OfMo-<@Ar*c%L{ ztFkMsqOsT&HzQ+6*E{wZeq3||-l-SN{xH%I*z4lpeF65LaqXqf4@?>@f5bafS@^JR7<}7g zZT3i1a`DOsaI^CeTgyHGwPqY{nKgZUj97g*e2|JwF9{l8)OHad;ghmfw;h|H|B^tk z+&86ov9BMya=m>--)--wh6$??2bWOUe^15!tScq2Bo=ws(!k6d zq&Y#W_l=m=e4*)dr>Dus;+^m}oBUw63`>LE0(kfE=i>RsuM##o5;@>n00S$b;hnrD zWo3zqE!Z+Ahxz~u_&Jc+a*d%A8K3J_w kq#`+<*kNk`5bHFP5SUT6h8#mVcn&uahf+>b2a}H;G_|g(O#lD@ diff --git a/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin b/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin index 1a4531f734866a3b3129105b299a1bc6860905d2..b15399485612fa5ac9e264f4eda3343154d362c2 100644 GIT binary patch delta 1358 zcmbQQHeb!)^?wLp00KrJu6IaoT6=%WWbJ}-$;th)Tuo;=b(C5(B%Lx}lsvrI=`qnj z)+6Ta!{%E~+t(jEeV64K-;%GJ173K}x$JFJYIks5>y{0&ATxrM)M?&^^JgaL8uzW> zw{#NRV{mFhTkqDqY2^{+=_cJin-qB~7bH(!z^SA#H)Z#&+dtn~th#E)5Rnq0 zk5hgu;!0UQO>J|+;^57XIKMDCcrNu`_kHr3Lhm0%%J2TD$*%pqH}**MtSkFHWNuvk z+?BjRJ>!}3EzMea-D5K}1wYSR8xn#xT4;5nb)XlDiw|^jGoYK20;r!X_UW$dDo?Xw(NAhA`H;#oR zDO^o6ImWtrvRCID#gb!F?nK;pTF?JC=u&jw-8V13FP-jgB|MpDo(xC+TxSV;g(8<5 zcDvlB82^+v(Os&QSFzE5Q%3bR#+>SR3$HFqUinY0_ZI(ymeqBR9<7o^H=X! zd&2G5!0Y#-g7kVm1Paf06q@zC&P5|bxV|(0YSel&zB(@R<%Pio~EA?|p8>I8U9v=cga z4>3%cqF?O(jCI|zwE54j{A|!DU-UIJ-S^j<@Xs}mb%jqAByzN@G5j6y(6@WfQitH5 z3szL63Msub=GyrDM~>Jhahpl*g`MX!cJHaqoKf#1ZnE%#)#IOuZ?>^)Ij6lxug@xz zMJVty=l9KLt^8GfcL_c`vf~wx$CJAjYqI7}Xz@A16fbl(!Nvbc!z{~}l?&9o8~i`^ zPMpXj5W}$g>dW1eVkSzP@A+u6z+rkpHLuM5gCDeCOC`ivW&Xq~*Qa^(AJyK&`TFDLmQs;f%hvn+cX>X4x|kRDJ(-jcMG}`G0;c zm?XuX`Si`(E(J5I|G!c!#Q4p4th*N5))!p%*d}8#=9k_7zVncW^aH=2JWDp0_KNN{WPU%< zK-NRoE&K#O|IXajD?tmi6<02M? zSk)4?dM1LZfNpo#?c};yUZ&#irkl+^9|8M#5NmNmDtYo9bb)%U=atEIz zaJ2guGM&#aT4r%BGS^z;Y|x$P;&n4@TE9$Qz^SBAv)-w%-!MASO-*@r!Jgl@BlmxM zUs+#m8vgx7R#VL1E1Ms2eqnOBQ?1ptV1}-X?R|bWw%Yg8`X94u+<8#Gg)w&h^FFDG zHaA$_9TZy9_|@z;|3O8mshYOGaPCqTK z2L1fa8}U@+zFgkRg@P^ITlbr1{N9|!tH4w*?Q^@MRpg}FWI@Uk|M^io?X zz|!9D;2&+=JT z`&BQ~`HV+)*DX@M!T!O>$ymO(QsK#4M*PuK&-|X@;a65r8iD~rX=IY@BG0y6y>nNn zDt)nTQr~y;QdijY-38^s)&0!}(2Ss{3aVMW^`!XTlV+m6uV!2 zC$AoQ>;7HTF^K=ZY{CDW$JtlwUj%Kx63%?>Usq`x|I^PmmNXSyW@$7{cE2?5+Mf#^ zaZ6@%?sMhYuDPd^w|w8rrPEpR0&Ap0Yl;up&40DVpi|m>+qNB>BVJq0`bM6{2a)=B9;a_S=gocS*^})bgD)N6%Zl%Lm+g1FJAO;O z-6!53Dgiu?c%yBaDz@r83Rj!4#Li-?S&`hY6xLkF^L%GG8y5u^~qEZ0yVEbMb%V+cqbLmI)~?|2N@^ZsYW3 zm1FI#izlp(@ykoPnXz1dLtVDm{u?KzO}??t{o@LbNps9A`eXj{&zPR&wNpA*{mb$` z3C?`xeNuNO)!V<`F!@w>#pCyk%#%MbDH(C5`j*rkT=;Y8Ld)ZyeUJC3TJU==UpIY) zXXJC2f42*ES)EI}Qgzzm$rE$mkyxj`d-bn=y4DM|37P5Nn z^XJiyIWFzo-cE4VLGQ zbexR1kpFLKXy3GDOj&!c%y>L6$!>Z~mF|t^y7fowcHjF~)lnysAg;#q!M3Vz_qEHM z?^XV>v`vUSYs`F-x9?L_$bsMuz5f}^)C4s-c6n^qN9Qvw&5paegeSy%=Df5w=x diff --git a/test_fixtures/masp_proofs/D5A372904527694939249FA0AAFBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin b/test_fixtures/masp_proofs/D5A372904527694939249FA0AAFBE1500FF70DC4F2365C83D9BB9015D3C28CE1.bin deleted file mode 100644 index 9ba262b0f395cf26c1f7114e31617f887bdce89c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2045 zcmaF;9|9N|7#MCZls76{9xWcpe2K?QbbsG6o#p1H|03(S{vG1Yo3!f$!^5wvKxGWE zSGS6)DLgZo&2n1G&E9%*AG?PSNSxs{&@7@1lIQvbwHHi*HG>F{W`>s!CW=eFoLxCJ z^Q6S9Y?K40hTCVQ>j)tTyjQ)(EGiE$a8XF52S?ZUUG zt7Xf&r+x!Dd=!k>5MToOoJ)PV+OpFBFF}C-O4f|TrcNCBi7`B9!R5{^h99!Y^QhD**$dU)M{m04P5G`h@t^VKCxorDQMg`6PE)cwLpb6>Wfpf{i`S_qQH(4sAwk_XH?~&qm>vKA ztMSqe_d?no3Wbh1ZI-uN%>MkSR@Jp4wlxKck2ZW;Hr>-LO=;%tZ%h5dlEi$p7*{GM zF4<)M+HB{d4An`cH;O_VRu)b2ihUEU=5kEGQ%15d&SJHerPz&cIo@-22ias81uJCn z);;L>=*QD=NA^IgESsBw$=R8^Usm0ATfVk(dOmOG+UY^>mmi$l|6DG3{RdH(`Tut( zxZ4I@ne`+pqVVae5_1pjkO}Xvy41!xYc$s+F-UBvb<^WBZw?bEkr&DSs#0I%$D*0y zGl$J+QsF#Pk7MqaCNO3`JhY=|x!az_=NPuDv|ODsVe9Kk>)gmQSCL zPEL3-ah6Zrfs}$H9zHztkBe(=G3m;@Z$5t~KRauL@^;(38|p(8@|PR^&wg0^Vb1UH z$pIceB~?a{LixPKIe;os>;~gR@?q4@67vP^m@IMQ{CHuUFSP?tL!~r zE1l)F=)B?K$JT2Mw<<)s{Cb;bw*JZsx6{&*cW$eFKcKh%$Xu2Khm8$u=gd=I91-#H zo{ZrwVU~|J{#&lz=C11PuG_+OWM^t${A-V2h9|BxbKGa$^kB+9mj(qtxz(#Wq95|z zTfWqMO~hO6pk@699=kp$TwW6@_v^&IoNi_-5tr!(m5Ka!KArip>A}hBRcZ|l&)=_d zozJf%yEJRbkw*3D+BdvVnytvQX7oRMCy}RhGk(@`zZzv%gA!BOmcKz*rFAGvrZ{Jp5c0cf1hhw*uMz>HJcRY zpPM|b^OTIo?U;zu1uxbmAIw?Lzw=9$H2dSq1$%e;n}={kt^K_In&oZo_-m`=E&wtCZ$SF`^Ip@Lu`Lov*)G`Rlf6CHUNJ`(ux28 diff --git a/test_fixtures/masp_proofs/DBE07FDEDBF79BBC814D3EB70E5A0AD04432D0D4BB8B2488EA5E836837B00394.bin b/test_fixtures/masp_proofs/DBE07FDEDBF79BBC814D3EB70E5A0AD04432D0D4BB8B2488EA5E836837B00394.bin deleted file mode 100644 index d39344547dbc331604dab3d6c2a89d96ee44b084..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2045 zcmaF;9|9N|7#P++Jg{)Q+%Tg=Z$SSx!s2*;{Y!WB2d@i8H(gnnjdBIj1_H_JS#}W)K0=%<%HTL~*H?vn!{D zoMkZKaKH9|S19!9x4a3HpBdj*5;&1lw3T7wydS(~bIVr~>*9ld%QF`K&DvGiy4-7L z|1qI+Q5`QbethHU0KO8I{#y|8d)v^-Vx>0gqM!KoR{lPr|pyTs3Sx#%=|epJkn zJ*QXvxq6&ukx}^1I8oD-=TYxjrfhMuHmDFhp(wF7d}_S?QTMzl-?b+GGrs)f&?Whr zJKyK8J}0#Fxz>vtlC?7m*9*yMN_J-mM_j1P;?8UFI`t%qk%c8BsN3eo*6JOzm%tra z2OS^%cpC1=9%z+ib2BhGJ9GETs@rbM*H%u?=j~iOJ?Q=NgLC_z%LT9hAnG#z|Lz2L z+n_76o1VFD%cBH3S6>WlnXG*f)$ zuo+D%oM-BB%>B{?#>|I@b`&jl+q3u_!*-RHt5YUyoge(~SDww)dztem{&?H+>GRRa z2~Q@@@~JzJQgFn>hiCqAam_6zU77dI=kMfaXN^$aZo79weTYK-a-;v*4~sv{`5itv zASFJayEgS=Qa>d=XGp8GGAm+aKkfc^`~kuXl2)dmFIpe8+B;z2|GC zv%D6aH$42$g-DlQZ}ZI7UwPqnS~~L1ZME+Q^wuAl%W~kbv0?3;dFqQJB0k=e zF}x+r^3leB%hlW5RlVJHTeyzwOzn$*?eWX-#Fb`_`>dNDOxfqspx`IBdR0gCL%w^< zmzuAMc&i<>tiQlx*9V2mYeMCIo!FPt&1@y>opuk^j!8Ghd!>`IE3)-E8jRT?(_D=CyQV2E_!Pu=h5+7O7-Bm zjLM~q!3&+&dbKexPh6{kSOeaL$3+s9CSKy@)t?an80W`D@wN=zqMY_nW(W~@B0fMzj>(M{eSJg>XYr&dXG%Lb6>5D5>+X+ z%B}D6ytiVfc))|wm#T}zrX|NJovBZs;j_Hx!Vw$i(sCbe&S%qS7#upp^)~wR(l_iJ Oup${;wL&>8P#OTZ?AfLO diff --git a/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin b/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin index 8cac916954e11697d45eb755016e7092e6fb521d..bd7d8bd196d23ceb71bf2bcfb665d7261be5c920 100644 GIT binary patch delta 1228 zcmX@Ea$Lpm^?wLpfC5IFCC5(+NBmwOH1*rY#pw)gzl2xHcD?;R-=a7qYih?E$%%#s z6{mFgb)xyqwa~{bA6~i(;QtP+-qRYuYV>2fD<{7vDiJbg{ zLrFnW_vg}=+ua+kd}W?wn9C=TnlE0r_9@qy*{Xk5SOo1owAqUD3zI{KW=Z|sb7vL? zD62*O>Aw79<@O2bLY#9O7s?BB_%YWie4ey#cW$QMz29HW-po!v-E3-aUlNkLccr^W z<>YNTH7=9$cuW++O?Ex&+AqISWmfOwXBR{#@^{-^iQV1h{G?uiXXlqIJ2oHUQDCaS z@U|%A_S?JnCl;@J%bS~XMmyCyby*FQ!BxvQGDXx) zxp2aBafiXVpS?Ww;`YI;3k;cBmY8jy;~Z|9#+7ciJnyBTs&7%^{cQ|)JN1~mo?QA~ z{YX81^>4F;bqO)4tA)0Eel+N7Nm25@W&hA1b1@n!z`yAE7v^KmUu3k#FY7L`jhCe=%BwTXV;khbM#+ZENr~-(lVd?CBHaW z=SSo!eA#0rCNIC*)8eqrhP=~GGC%^i+$tk2VG gZ+>1;Jx_1RmKFOi9Q*UicX7nhxidH>D+{Rr0E_xrz5oCK delta 1228 zcmajc{W}u~0KjouOhYm+3ERvPIaecMtt^z6Jua_}(#wU;Y%6cOHF4V-ze?t&b|=76jE2%2@ZUlwub=8LV66D?nbL!Vqe)(zgte}5i2#?sL>IBu)KssB%* zLD@jxde7vSx}+7j{;MJKrMR1+XZNnoeOildZt>)!SF5{$`g2(wHNP}Sc%VEkF zqsEzrHE9I+wpn?OhxmsD?($|NLN}>N5myGBT@gMN%npCO=Z!ilc+ekYi~N(g*i=ms ziZS5NK;KJw`K6KKMAf{TZ4I@c{B)-AUAUz%XuVN} zJZ~?1F#r5Sm{->#p9G?rL%GQ&o`|Zr1ZZa(ZcF|*`E>x`` zaKs7|1dz!`oh9gv?u`0+5v{HeJ?e)o@ptL~uZ;-dFUQ_Le&+_~-C)UzfwgpwZzMM@_F|qZEzX^0mgZSC@SWXZF;j z2A&heIQ`1OT&g8s442bG7>sr(&alp5iv5ig1}U6-PPCixwi0keh4RaIkpA`vfuH{O zOWIu@xYYJNRYv8sWY{6RrT>Ht8^b(3CX;Txa)*~0>Nh#b$YJl_`%w&n6s7-0W?Wx+ zt+TxK!tB*(y~vGueN)?du!pAGB7Uy9uWYT{Y(GEqP$c8HXXitood#+^4F=Y{U^lSf zT83jeyJFZL3Q^+c4oP}SYH4O7k@rR(mm$8-y7nM`-h9SB%eKkA{%10^f@y8(qbKdH zlwylw2dr#b1F7fDO4M5h8rKG8v0yCY%b0Rovjg{j2xyt)EYJdN*0hKmHY9UnU1^gd zFLR7>WgAF+90osQX_~me@mTP%>Mbe`2=B*U5N}8p@s+thA}#}BeT@YN(+>AWK4ZYD zZ_uG9=UCJvLQ*z-iRs*)7KLx($1Ph-GaSN-d97D&jz7$G_wr)&oO_vKj6$Yr7UBuf zHWq0`f3)oma*^=V;B234_1nM+{nlOEX~ANPcGHqKm|f%a2-T_+zD0$$1Zr1tN@KMr zM`2IeNG*szIC+96stWIEqRN%Gcjwv)uV!Q@osHZ?eaDzTHFZ>@Hht(i;$;->p&;TNA?KY>IB*hjG#MrG>CKkaI>XV(nGCk?g{Kvq zM@G1&?2LEmi$hkWB4fptk~v%z);q}>HkgtC1wYwmaI$Ed!Z?H&00Ma%`c6HX(r!>* z422#j2_jnkF0a^}rW#1wS8LK7!J966jJ8X6^m4jYnK#qn-vJp@$)?MuVrIdTmQ57X f{iL2Aes33)6hq>e5rKwsm diff --git a/test_fixtures/masp_proofs/EA7A88B1429EFFF0AE7167F6FBEF52D368B771AD525817E722EA3E12B0A96971.bin b/test_fixtures/masp_proofs/EA7A88B1429EFFF0AE7167F6FBEF52D368B771AD525817E722EA3E12B0A96971.bin index b1fcfa75c24ea8255db0cfe4fffc9291eeb62663..99465fb26055f553013ee2b0a13c5147fecae99b 100644 GIT binary patch delta 1355 zcmV-R1+@C&JK{UAixD6R3y5gsd}nTbZ_S430zz#Kh4=uw2q}(k;?R}_bK%94s}VpT z2r1v2Zm`hdNDiXqaXoBdGQwF);UQgZDPzN>nLQw1lM50-LFm92qfZT%_1{`wOJIVR z0n(?2i9{}=Vb4Cqz^t-tFajVecp12$A|I48g~4JB{ z81Ac~<_xgrx}hf9(|?wA;uiFO_pgt|2-O1@Coa5&Ko9fB!V8ZEVuo5>TnWa0cFk#l zs9Jmu>qN~e7`OE;RHAk#^T`Q`teWSc9Oz}Y;<)2e5|BIt`8cFb$qESK3Un9p>_GCJ z&CD01O#FS-mb>nm1BGo|k3|ba-Avt=Jy#%~tHt`kdq;NY6o0B5nbr@ZYvX1d!Wftb z*O>qzba(io3u!HRp`>~_G?`!>3o4b-MEW;a_?ufMq<;_$e~M!KG0Lw#>MHDB=iJ`D>l6l=QFpE|M`b3`{Yo?>i*e(cXVpc# z6D5-#fMeN)5W@QhX7|rs{scbVDucqF3PZ``mUwSzGUbU`L3gemlLtbe;(G+FcR?xi z#=(Hl@AgJ16$xqTI4$gbLr@|vPiZUu~4duGBgaQvKyv-Gw? z(<~kDnbr41!PMYtC1T5)c716_}Q4lHb=L zU!N8II)C%8i?bF~(5r?LAng+JoCwiXe^|w;DD3;u&3ZwXD# zB_v%-M^s)CNx@^DQT!Ra?{UGd=fGkOoEcXmTz_7QmLBv^Zt&})RqDDmEuBb(iqL3F z3yms_NYGk2 z3-Jlt_A>mfzUL5&v-5)_%dBTiSYyF_!B^4!|Nr%vw}=A1Yzpq+LD&^$P{QdCbgG!E ztbY<^`al>R7L`^RDX53O;AjZi1}^pR4DKB^3$Fp7r!>dpVgg^hQQMKm{PnUv++7aQ z>vnzdfwK~KPaMBIC(to(l|w}Cacbl*&TqJ1n9MSP_CruC{RG@8Zp^mh>d44CH5O8C zfDUR5--t{6U}Q*f57IT0o9z z+Md>g0lsHmeJFbIOCcJNJ!?F^e`Cv^8LfJm7IO!_zYH4e`R^Q{dK+qaZ#ALwTX?m) z@GdbHd5YJWI1BFK5D3~)trMIe>NcqS2qB=>C89@^OMfi)_3|-;_@x13(-=?XPY74j N!%QF3n2M9N9WBF)nDzhw delta 1355 zcmV-R1+@C&JK{UAixD7CJTWjU!`7tdj~N=3hMY*^q`W;ubeBWsg^TR#PrC+mmEdp}rJh$=c`;%6DbNBD=#lYwnp7iBPD)OUSYRXQo*Qv9O z67&KfNy6#+6YFd?*(|M;gC4yw=OzQ&mEiJrLfHTJ62kkbv!NB01Am2``<>u!#4`Vr zd3C?G<>UXsksgFNAk2`T{&9`uo~S;_1wG8NVem&wi|%@Gz6z&diEy3aXeU%`B(2<+ z@JLJ4J=IuicItNm<0Cj#dpFau;8hK`KgofAoCf;KJ9rsPeHh89YRY%oW9^|&_F}4d zbB&^%UhU40{3yF|1;Yrm74635_br7QxE0JE?qrD^e90=kMIWx!#{;3B!2yFUEMI68S(Ahtsx z)ha&T=JPwJ%75U6ArB@@EkCb0|MG6Fw=MMC!X_nR@k4#O`8HDnGhZF55MRInH3acn zKbsQxS^^1;9h~qM;qR|rTYeEI zz11lBHv8Yw`K+i^a0Tj;#!kzCpx{=+$EWRWLk1(V+S@qSxVo1G2dP6R}C2T!4-`8C#c_jVO*B&GV2pk5ml9FhIdznvxnzZH(B2*rdhr^FN=|A31+z?c$^}r z_An&A$F;F&x%1a2cS)_5%2H_B8R1<<%dsS-&z}9+$2J$Nab(hED+AEMx68@4_VC+< z<`O#+dLKD+U*JqX6FQi>EJTYQ?GNaU(SM1?qNwS!74BIv%}`J}TeIfAKT&<{MLLj! zF(dmHxXn4c7_vVu#CU$yl0td9NtV9N#vA{fvKH>9@Q}d4H>?Ldx=Er(=fp1iC6)<} z1|*f`qed}5v&Z>>3PlCXruQB&h1$ikKJ61S9WX4P62RD=YK6pFCHO?Fx#_e^rU)U) N-ZI{7dRUXS9W7kDqksSa diff --git a/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin b/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin index ab64d432336b662a53010693926fe9fa92455083..e4c74d543d00eb21d287b880c50454a6ed12b9fc 100644 GIT binary patch delta 1964 zcma)7X*3&%7LG)1K?F_I5)s;>7>d|xsY+98ZFxg1ZxltUOwgg#HsUp%p_CD#gA%n< zu_TDCtrRVygi%dveN?Mx=!hw8cT4v5X_uUK>G2bd>&$}F0ZMZ(jgjr1Xi3wIx7~H=PyL;%jt-{9#m4;H&(@xjV0v=qb4PVhC7e83 zA?(T_rMIeiX)FCO9W-C|JmX92%u+FoI8qst@{@AaL!yF-VgzNeIs2m}Ll=XaR@hzJ z_9`76JV%v~I7`~E8tC(%%KaJk6HWyBYnVUc`pCf%wN7+cz|$XQ%*&|cbU5AdR_HXq zxwZe&@KyoH{**X#QeqE?EG%mN?UVBI$=rT3g#BWLlK)tEf^AlEyMGGk$HV5?aH_)r z6iLR6mjqmf1V1*IH*^(-YcH$iuH7)+Excr+D$buY_eIi66-gP+z}6VhN6hMxck4Y} zN$RI-Ui7eRb9%6Z2PmWnI?JbdGYX?`$6kwo&$+y-o5l9dMCR+!@XF?y?Z=QBVQ*gs zRsWKT>GLJD9SEuQ(6ir(F`BQOD;u+m8eSO=L@I<8UGxhtBcye07n>~IPQiI+aK^E6e@Vupf;+wnD>kZNY%RH~-`(p0?A zZQm^F^+4}%(04N*d`~(rY9qh?3v{l_%7GO5 z{J#hOYs2=t!~L#_HEPdF*z9KUr)@3tIfW#sXq8NrZM!c+Bgjmf=cQW9 zksO)wi48B(_=iY~qs$@7LgWG@Sf+!6BE5`i0d7iC+4aXyodr}yzsEX7&2Pk#e4*^R z(446tlyz{t+>9&bLUC-x!1<7i6S@RQ)HP5fL)K8P94y$H_r)bO@{ZBIO$tPbx=PeO z;X31j@@hHTYC&hL=lb4BP#f+dPG_TA9qa_qjFOZpVX$P-Cl#}hLMO-4-guXM*ln*J z$!qTA;%&U}1>{8_3W>1GA0~mXC}(+~+Z^?wKcyf;|7|{0BH7(cEe>qwCwW`XW8iZ-RmpciJ2n~t%xRa@Edxn^uRMq z2g;7vFoEGzwKNC`)VFA%DL#k)9+UNL`&}=i+dn!` zVE&J1=9(7b`bM(>CrR?gsqj~odvawaOV?qkOZ6zT%0(tLh3x-`RoKqwNNxL;3f{Rb*J zMA;~@g|L}Yj(>4E%FS)#+?I_+PlEZ|R~sJbCzPyeHgxLT#7R#_kFyd=e!p|aTYAl7 zI_Z$yv%2~zFOLSH_p1X|fgMAeK9X5Ub``-=JfbyC^-;Yi#`j?DQt7=UZOJgZTfNll zN4+ynp2Ky}z!R5XZj;K@yfzy#I=mbQh!chk4Z-^$_a24^Jb6u9lGX~&Ek=|SxTf+b z+@HH#OzAtuN+fUmo2`~mZgYVkv!>H$wZ$`0M8Fx`KwNQ&&M-=L)aP9z#*+~tYdm6n zJG7&S?cP|TwyICB$~!!s#!saMj|qs4+T9<)BlKwQuaV9CH?NJjeh{!VU}_d-Ak*cC jAb-YPeV-5dX2NPVaO0uMVSH${c^~-etNe-_nEHPJln=9o delta 1994 zcma)7c{CIX7dOT_62{OFZ|1WOku7QLV;izB@n-C0X*dZHrh1cQtRY)Nh8HDSr_7Lb zIzl|A@C@0vH`xnWLNZ^y<&W>5=lh*=@BQbV`#Zn8oJ&?As}NS%e}UsW0N)KWXj&Lv z3Q`w^)qn-tun8Z{zYq!7^5v?=KHf? zz&GfdQJlxn@Kk!*sLVK<97igSdfsBkwHxzfk3jL)M!{S^1<_ZJXdTQU@Rtk@N?Uc&jn|YK<$x zYbzF6SoFeBe6m!GS^_ZVg1gzs4JwJUE^$_7$cLIrc;~lNj3N%4zC0h=<+^1S`hb50orOzHy+M^(T5wUnIXK}t1^u( z;M;>R-7TXiix*YrrIus8XTnttP*8Z5yq5<(kssTv60uTTl;6O6$CQ|1#Dl)p3U1i4 zU|xd^kAV*O@bR}QWaq&tccaE|vNeaDa(*NoZ9P(Lko zdlBxPq)B}pnIJ>(Zpi}V0(>O+H>Jh3%>uQJXGEH_t@$r@s5+JW3iPhC&a8SJ6aHT8aQ#OtKW%$#=l(9vv;o_WM1z@Q8@acm;VzWxP~#QIm2BVk4- z(~us{F#|qF`;9AH;Hu=GJT(-Qj3*dmBgcrm)gpWC@mvKp078%W% zG_TRgq5F0f)|ESyG&c0DW~Xq`^BIe7*-#bPV-^sDVgqEmn0)H*5R?bCP^Y*m55YGoA>iGxiQ-M^@)}BXZ&%Vo*wQO2WmY*R>N$GWGT<3 zr`4-@dJ40I-A60*PukMmgSi{kxLy+iO)=eN>_Z^bRbH1d=FlvYze?f{(lT&3Xk$ZnCj+aG1&L_%k z0$)vBK+=FqMGNPc_Z62e6#K|U^Vyxm<1J(*Oa!Ps?}S~2@h&)j%k6NV;Lnv1IeL{5 zg(-5f02SFjt~)#+N$#WB-SpsVYN1AETYx*j-OFUURR#AYkuoN!m(|uKhSM3u4w(E* z584-;KqpJ~+#OM;1$!!J5EOZr@7%j`rYy_)wdjyvK!5V3Q&OL!x_H(JS&xdD!a7xY ze;^=$yDw1rPI~ss=Q7tLFk11!qA?F!_T;o5VeU@XvcQtPjzItd)f=+vp5fB!eKbbPsO+TozXsd z>&aY-FUkFF$`0QQ29}7hIl+t@YU8}RV9&#-Lx=51l|srbMBm2{Je9jMw$s%3Ug#LyBw^nc$Fd8um|y42o_ z;I1fBHq81sp9j?^9PatrOzvN%JISR8QMI;o9?&9o32~s-8qv`3go^v5oxa>~<@!X! zl(zJj2(_bY1oQbs)IrBrC3yKwc;wBVOfV&1J-!WQ>&KDf6)-;8zNKjen-#)f@y`Xj z`fg`W6@Bw~Sw6^~b93;2{OPkkwe@$GLw2ibZAYr{AKW$s#=`YBbGM1?#Y|{kv5O>N z0qR-fzp<+tcCug4?2Bf@l;ZfzzVcFr18xPPDA5U;h}UY@BXv=ZH0Bt4-j<(WFV{?= z)I2`WIfk-`I|R$a#je1`Oja+gj9}93N1mXZLMp4>tAu^}53w2f4PS_B;?>h)JU<@k J4`ho={TG(E-pi4^0&PF-d~QEFC4eQ#?1kRlMY$H}}BTp`Bc_yaOcz ze}F&)Di0{7^NdqIB0Qa+$u5X`kOE112(&0Aiu*97prYo03RayF$3EJ$B^!d zy%1;UYpVt zuyBo)aGNdpvvO#@tz+-8xxERh!6z4Ef1KN7q?qOdafYrle-qhca;$)t-U8mfpwe5x zs|lc<>=1%UuyuMG#taRv1Y?})O0x&^3Wx8HRdtf=f#mgA6q8OY^jdh%h+&StmE}S! z1<>Xc2#|>ovQ4XWDQpzq`R6G=KlQi!WUojN>e+3ycpHdYaOIi$45eZJoQ+W(0wfEQ G;RhTv_m?98 delta 308 zcmV-40n7gV5B(3YoC6>RvVrYnztuGu#A@Zw9AV+LUMz&a>i8%5fF?U3i2$#&yaOcz ze~;6`ByB|TQsg=i=AjnFAB}vU9#5v#NDgN<%&C#qN8Vw66vm!}c6>(=tgy2Vyo3#ufSPBcvRV_xp|5rx0>}xI G;RhT#yqvNC diff --git a/test_fixtures/masp_proofs/F7D91D1E43AA598631284A69E9861C7F98EA4325D94989648024831E350D8F98.bin b/test_fixtures/masp_proofs/F7D91D1E43AA598631284A69E9861C7F98EA4325D94989648024831E350D8F98.bin index c3214e3d3438679029e06d252ff94293badd8008..38ecef6e7bb35b24fd680fa427af6c0e3c32e422 100644 GIT binary patch delta 307 zcmV-30nGmW5B(3YoC6?c(L4#`-92hOWiD7CCnbt0ktjZo5O1ILe|#i}vKr8{yaOf! zf3*l0QAJ~+gde@hG8D8`L2~4sjNZbi{a?UHlv}tC zewDF=5$o}Wo_f8FF{rf?uliV4_#e}+>WGQ~%-m7J6z|<}*S2!yM$Cgn0(wnrQw{eL z&S~U1TTZ8xSrb)K(J^AH5Ek7AGfjM6e>SL!MEvX{M7G=AJ`|!6Z zLdEX~fmuBic3bJ<#|B7y=$BTgjoZ22TXZNxkn%ADxy`BIGL^O7I|2%lIQPeEthaxu zWW(3oH--+HS5z)#0Q?vs*jl0;o}HkSCuO2g+hde+6W0lg0l+IqtVV|Ez(9*)0SlAi F2OOD;kkbGF delta 307 zcmV-30nGmW5B(3YoC6^H2`|CFMp%vhr*@WdZ-E1H&DumgQLiHVLl-_oyMrRLyaOf! zfBa8T{qj=89#yH)=|=vSw#0{H_Qn&GRL_vPXB{p$QkB+=m##hGXBp-c7jY$&plR{Z zkV2dAF&S*#&u|r5Sa&Esx-Edw{py4MJR<_uqqR>V^;XoN9jtqNNnQ_51w@3aHF&rA zKgc)$mj7XI7jFN1o5h9|Zsk$o;IEGrf6BV3^4RwBI>4>*ljCI3tA;BHUGxr{CdRfc zZG45|!ZPQ5OCcPjf_^hChixAFb87Drti$f^&z$EinlML2)8sUD)_IGPc6uD-fLmz* zPOT_kV~q>Y9yMHMbX1m+>0amX)OMo1d!#e;iQy^=Gj(&UEVm_AScikNBEgu00S1%d F2ONq)nJ54N From a2f1b7e6e0739351ba2e026cfd76eadf3a5b53c7 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Wed, 31 Jan 2024 16:55:36 +0100 Subject: [PATCH 08/15] Improves tests of fee unshielding --- crates/tests/src/e2e/ledger_tests.rs | 32 +++++++ crates/tests/src/integration/masp.rs | 129 +++++++++++++++++++++++++-- 2 files changed, 156 insertions(+), 5 deletions(-) diff --git a/crates/tests/src/e2e/ledger_tests.rs b/crates/tests/src/e2e/ledger_tests.rs index 004467373d..3cead61acf 100644 --- a/crates/tests/src/e2e/ledger_tests.rs +++ b/crates/tests/src/e2e/ledger_tests.rs @@ -698,6 +698,8 @@ fn ledger_txs_and_queries() -> Result<()> { /// operation is successful /// 2. Test that a tx requesting a disposable signer /// providing an insufficient unshielding fails +/// 3. Submit another transaction with valid fee unshielding and an inner +/// shielded transfer with the same source #[test] fn wrapper_disposable_signer() -> Result<()> { // Download the shielded pool parameters before starting node @@ -763,6 +765,8 @@ fn wrapper_disposable_signer() -> Result<()> { NAM, "--amount", "1", + "--gas-limit", + "20000", "--gas-spending-key", A_SPENDING_KEY, "--disposable-gas-payer", @@ -787,6 +791,8 @@ fn wrapper_disposable_signer() -> Result<()> { NAM, "--amount", "1", + "--gas-limit", + "20000", "--gas-price", "90000000", "--gas-spending-key", @@ -802,6 +808,32 @@ fn wrapper_disposable_signer() -> Result<()> { let mut client = run!(test, Bin::Client, tx_args, Some(720))?; client.exp_string("Error while processing transaction's fees")?; + // Try another valid fee unshielding and masp transaction in the same tx, + // with the same source. This tests that the client can properly fetch data + // and construct these kind of transactions + let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; + let tx_args = vec![ + "transfer", + "--source", + A_SPENDING_KEY, + "--target", + AB_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "1", + "--gas-limit", + "20000", + "--gas-spending-key", + A_SPENDING_KEY, + "--disposable-gas-payer", + "--ledger-address", + &validator_one_rpc, + ]; + let mut client = run!(test, Bin::Client, tx_args, Some(720))?; + + client.exp_string(TX_ACCEPTED)?; + client.exp_string(TX_APPLIED_SUCCESS)?; Ok(()) } diff --git a/crates/tests/src/integration/masp.rs b/crates/tests/src/integration/masp.rs index 527dab7e08..a07fb0f9dc 100644 --- a/crates/tests/src/integration/masp.rs +++ b/crates/tests/src/integration/masp.rs @@ -1450,6 +1450,8 @@ fn masp_txs_and_queries() -> Result<()> { /// success /// 3. Submit a new wrapper with an invalid unshielding tx and assert the /// failure +/// 4. Submit another transaction with valid fee unshielding and an inner +/// shielded transfer with the same source #[test] fn wrapper_fee_unshielding() -> Result<()> { // This address doesn't matter for tests. But an argument is required. @@ -1466,15 +1468,15 @@ fn wrapper_fee_unshielding() -> Result<()> { vec![ "transfer", "--source", - ALBERT, + ALBERT_KEY, "--target", AA_PAYMENT_ADDRESS, "--token", NAM, "--amount", - "500000", + "1979999", // Reduce the balance of the fee payer artificially "--gas-price", - "30", // Reduce the balance of the fee payer artificially + "1", "--gas-limit", "20000", "--ledger-address", @@ -1482,6 +1484,40 @@ fn wrapper_fee_unshielding() -> Result<()> { ], )?; node.assert_success(); + let captured = CapturedOutput::of(|| { + run( + &node, + Bin::Client, + vec![ + "balance", + "--owner", + ALBERT_KEY, + "--token", + NAM, + "--node", + validator_one_rpc, + ], + ) + }); + assert!(captured.result.is_ok()); + assert!(captured.contains("nam: 1")); + let captured = CapturedOutput::of(|| { + run( + &node, + Bin::Client, + vec![ + "balance", + "--owner", + AA_VIEWING_KEY, + "--token", + NAM, + "--node", + validator_one_rpc, + ], + ) + }); + assert!(captured.result.is_ok()); + assert!(captured.contains("nam: 1979999")); _ = node.next_epoch(); // sync shielded context @@ -1506,13 +1542,15 @@ fn wrapper_fee_unshielding() -> Result<()> { vec![ "transfer", "--source", - ALBERT, + ALBERT_KEY, "--target", BERTHA, "--token", NAM, "--amount", "1", + "--gas-price", + "1", "--gas-limit", "20000", "--gas-spending-key", @@ -1522,6 +1560,40 @@ fn wrapper_fee_unshielding() -> Result<()> { ], )?; node.assert_success(); + let captured = CapturedOutput::of(|| { + run( + &node, + Bin::Client, + vec![ + "balance", + "--owner", + ALBERT_KEY, + "--token", + NAM, + "--node", + validator_one_rpc, + ], + ) + }); + assert!(captured.result.is_ok()); + assert!(captured.contains("nam: 0")); + let captured = CapturedOutput::of(|| { + run( + &node, + Bin::Client, + vec![ + "balance", + "--owner", + AA_VIEWING_KEY, + "--token", + NAM, + "--node", + validator_one_rpc, + ], + ) + }); + assert!(captured.result.is_ok()); + assert!(captured.contains("nam: 1959999")); // sync shielded context run( @@ -1535,7 +1607,7 @@ fn wrapper_fee_unshielding() -> Result<()> { let tx_args = vec![ "transfer", "--source", - ALBERT, + ALBERT_KEY, "--target", BERTHA, "--token", @@ -1562,6 +1634,53 @@ fn wrapper_fee_unshielding() -> Result<()> { tx_args ); + // 4. Try another valid fee unshielding and masp transaction in the same tx, + // with the same source. This tests that the client can properly fetch data + // and construct these kind of transactions + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", + A_SPENDING_KEY, + "--target", + AB_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "1", + "--gas-price", + "1", + "--gas-limit", + "20000", + "--gas-payer", + ALBERT_KEY, + "--gas-spending-key", + A_SPENDING_KEY, + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); + let captured = CapturedOutput::of(|| { + run( + &node, + Bin::Client, + vec![ + "balance", + "--owner", + AA_VIEWING_KEY, + "--token", + NAM, + "--node", + validator_one_rpc, + ], + ) + }); + assert!(captured.result.is_ok()); + assert!(captured.contains("nam: 1939998")); + Ok(()) } From 2962a341d4097ec25bab3b255b329228c4597091 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Wed, 31 Jan 2024 16:56:19 +0100 Subject: [PATCH 09/15] Returns error if the provided gas-spending-key is not needed --- crates/sdk/src/signing.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 1519b1ae49..2324444d20 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -623,11 +623,11 @@ pub async fn wrap_tx( } _ => { if args.fee_unshield.is_some() { - display_line!( - context.io(), - "Enough transparent balance to pay fees: the fee \ - unshielding spending key will be ignored" - ); + return Err(Error::Other( + "Enough transparent balance to pay fees: please remove \ + the --gas-spending-key or select a different --gas-payer" + .to_string(), + )); } None } From a4fd6cc1a99a97d4c022dede67e2972218909f91 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Sun, 4 Feb 2024 19:25:45 +0100 Subject: [PATCH 10/15] Invalidate spent keys when generating masp transactions --- crates/apps/src/lib/bench_utils.rs | 74 +++ crates/apps/src/lib/cli/client.rs | 3 +- crates/apps/src/lib/client/tx.rs | 23 +- .../src/lib/node/ledger/shell/testing/node.rs | 23 +- crates/sdk/src/eth_bridge/bridge_pool.rs | 13 +- crates/sdk/src/masp.rs | 458 ++++++++++++++---- crates/sdk/src/signing.rs | 82 ++-- crates/sdk/src/tx.rs | 418 ++++++++++++---- crates/sdk/src/wallet/mod.rs | 2 +- crates/tests/src/integration/masp.rs | 436 ++++++++++++++--- ...582DAD9FBD3ACA2E0F8314642810FC958594E7.bin | Bin 10105 -> 10105 bytes ...D4D70154B89179E7DA6F14C700AAE1EC531E80.bin | Bin 2045 -> 2045 bytes ...FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin | Bin 2045 -> 2045 bytes ...11DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin | Bin 2045 -> 2045 bytes ...DB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin | Bin 8392 -> 8392 bytes ...F2741B2A24802E41AF7F56081564BF2A160464.bin | Bin 2045 -> 0 bytes ...753FB3BE606A5729D43A6EA8F79007D34F6C60.bin | Bin 2045 -> 2045 bytes ...0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin | Bin 2045 -> 2045 bytes ...16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin | Bin 4895 -> 4895 bytes ...80F84F6B712C682DD639AF812F29AF23E4AB7F.bin | Bin 6393 -> 0 bytes ...DBE3DA9201B7C90E74A7B6C2B9B7320F006872.bin | Bin 6393 -> 6393 bytes ...346C4D5419EB8C2C4174F5DC1317D493122486.bin | Bin 6910 -> 0 bytes ...0DF6893C1C09CF3101C402BFE1465005639F14.bin | Bin 14387 -> 14387 bytes ...83E61BED82F25C4452CA41B769C3BABEB62D2B.bin | Bin 2045 -> 2045 bytes ...06FB77DB730FFFE562F2565B0431F7A901CC9A.bin | Bin 2045 -> 2045 bytes ...DC5356710DE7B6F6FA2B23C19412005669DC2B.bin | Bin 10105 -> 10105 bytes ...9384EF0421F46F7732EE62196DEB73ECB4C225.bin | Bin 8608 -> 8608 bytes ...1E2DCE33145F68A217FD50B065966646F59116.bin | Bin 2045 -> 2045 bytes ...9AFB3B6AE2AA3ADCACF75E6520A66B2F7D184C.bin | Bin 7875 -> 7875 bytes ...A81A7DF315190329C7C2F708876D51F60D2D60.bin | Bin 4895 -> 4895 bytes ...22056C14747EAC3FB1625F0A86957E00ED109.bin} | Bin 5412 -> 5412 bytes ...9BC3BBACE79DF98801EB8154EA1904597854A1.bin | Bin 4679 -> 4679 bytes ...EF52D368B771AD525817E722EA3E12B0A96971.bin | Bin 7650 -> 7650 bytes ...F7858007C4DA521F8E3BF250A46E9342178EEB.bin | Bin 5660 -> 5660 bytes ...3356453E412F862D949ABE9671C24A3903909E.bin | Bin 2045 -> 2045 bytes ...861C7F98EA4325D94989648024831E350D8F98.bin | Bin 2045 -> 2045 bytes 36 files changed, 1226 insertions(+), 306 deletions(-) delete mode 100644 test_fixtures/masp_proofs/55CC69CC552A02161C1C9EED1AF2741B2A24802E41AF7F56081564BF2A160464.bin delete mode 100644 test_fixtures/masp_proofs/84320514AEC06D9AADC35DEF5C80F84F6B712C682DD639AF812F29AF23E4AB7F.bin delete mode 100644 test_fixtures/masp_proofs/891CCBE84265DFA7F35C8E5F08346C4D5419EB8C2C4174F5DC1317D493122486.bin rename test_fixtures/masp_proofs/{D38C391DF4F1F69AB04682F0C1B78DD77AA5620AC08519F73AB740B5A44AFA65.bin => D1F174D8596E8C1DA892DDC23D322056C14747EAC3FB1625F0A86957E00ED109.bin} (57%) diff --git a/crates/apps/src/lib/bench_utils.rs b/crates/apps/src/lib/bench_utils.rs index 9391e4aabc..bcb4aac198 100644 --- a/crates/apps/src/lib/bench_utils.rs +++ b/crates/apps/src/lib/bench_utils.rs @@ -117,6 +117,8 @@ const BERTHA_SPENDING_KEY: &str = "bertha_spending"; const FILE_NAME: &str = "shielded.dat"; const TMP_FILE_NAME: &str = "shielded.tmp"; +const SPECULATIVE_FILE_NAME: &str = "speculative_shielded.dat"; +const SPECULATIVE_TMP_FILE_NAME: &str = "speculative_shielded.tmp"; /// For `tracing_subscriber`, which fails if called more than once in the same /// process @@ -669,6 +671,31 @@ impl ShieldedUtils for BenchShieldedUtils { Ok(()) } + /// Try to load the last saved speculative shielded context from the given + /// context directory. If this fails, then leave the current context + /// unchanged. + async fn load_speculative( + &self, + ctx: &mut ShieldedContext, + ) -> std::io::Result<()> { + // Try to load shielded context from file + let mut ctx_file = File::open( + self.context_dir + .0 + .path() + .to_path_buf() + .join(SPECULATIVE_FILE_NAME), + )?; + let mut bytes = Vec::new(); + ctx_file.read_to_end(&mut bytes)?; + // Fill the supplied context with the deserialized object + *ctx = ShieldedContext { + utils: ctx.utils.clone(), + ..ShieldedContext::::deserialize(&mut &bytes[..])? + }; + Ok(()) + } + /// Save this shielded context into its associated context directory async fn save( &self, @@ -698,6 +725,53 @@ impl ShieldedUtils for BenchShieldedUtils { tmp_path, self.context_dir.0.path().to_path_buf().join(FILE_NAME), )?; + + // Remove the speculative file if present since it's state is + // overwritten by the confirmed one we just saved + let _ = std::fs::remove_file(SPECULATIVE_FILE_NAME); + Ok(()) + } + + /// Save this speculative shielded context into its associated context + /// directory + async fn save_speculative( + &self, + ctx: &ShieldedContext, + ) -> std::io::Result<()> { + // TODO: use mktemp crate? + let tmp_path = self + .context_dir + .0 + .path() + .to_path_buf() + .join(SPECULATIVE_TMP_FILE_NAME); + { + // First serialize the shielded context into a temporary file. + // Inability to create this file implies a simultaneuous write + // is in progress. In this case, immediately + // fail. This is unproblematic because the data + // intended to be stored can always be re-fetched + // from the blockchain. + let mut ctx_file = OpenOptions::new() + .write(true) + .create_new(true) + .open(tmp_path.clone())?; + let mut bytes = Vec::new(); + ctx.serialize(&mut bytes) + .expect("cannot serialize shielded context"); + ctx_file.write_all(&bytes[..])?; + } + // Atomically update the old shielded context file with new data. + // Atomicity is required to prevent other client instances from + // reading corrupt data. + std::fs::rename( + tmp_path, + self.context_dir + .0 + .path() + .to_path_buf() + .join(SPECULATIVE_FILE_NAME), + )?; Ok(()) } } diff --git a/crates/apps/src/lib/cli/client.rs b/crates/apps/src/lib/cli/client.rs index 3285f9d8c8..1bf79f503b 100644 --- a/crates/apps/src/lib/cli/client.rs +++ b/crates/apps/src/lib/cli/client.rs @@ -322,7 +322,7 @@ impl CliApi { }); client.wait_until_node_is_synced(&io).await?; let args = args.to_sdk(&mut ctx); - let mut chain_ctx = ctx.take_chain_or_exit(); + let chain_ctx = ctx.take_chain_or_exit(); let vks = chain_ctx .wallet .get_viewing_keys() @@ -338,7 +338,6 @@ impl CliApi { .into_iter() .map(|sk| sk.into()) .collect::>(); - let _ = chain_ctx.shielded.load().await; crate::client::masp::syncing( chain_ctx.shielded, &client, diff --git a/crates/apps/src/lib/client/tx.rs b/crates/apps/src/lib/client/tx.rs index eb9a01804b..625d871c84 100644 --- a/crates/apps/src/lib/client/tx.rs +++ b/crates/apps/src/lib/client/tx.rs @@ -23,6 +23,7 @@ use namada::types::dec::Dec; use namada::types::io::Io; use namada::types::key::{self, *}; use namada_sdk::rpc::{InnerTxResult, TxBroadcastData, TxResponse}; +use namada_sdk::signing::validate_fee_and_gen_unshield; use namada_sdk::wallet::alias::validator_consensus_key; use namada_sdk::wallet::{Wallet, WalletIo}; use namada_sdk::{display_line, edisplay_line, error, signing, tx, Namada}; @@ -418,13 +419,20 @@ pub async fn submit_change_consensus_key( let signing_data = init_validator_signing_data(namada, &tx_args, vec![new_key]).await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + namada, + &tx_args, + &signing_data.fee_payer, + ) + .await?; tx::prepare_tx( - namada, + namada.client(), &tx_args, &mut tx, + unshield, + fee_amount, signing_data.fee_payer.clone(), - None, ) .await?; @@ -750,13 +758,20 @@ pub async fn submit_become_validator( let signing_data = init_validator_signing_data(namada, &tx_args, all_pks).await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + namada, + &tx_args, + &signing_data.fee_payer, + ) + .await?; tx::prepare_tx( - namada, + namada.client(), &tx_args, &mut tx, + unshield, + fee_amount, signing_data.fee_payer.clone(), - None, ) .await?; diff --git a/crates/apps/src/lib/node/ledger/shell/testing/node.rs b/crates/apps/src/lib/node/ledger/shell/testing/node.rs index a3ab32dcb6..ceb4fe1637 100644 --- a/crates/apps/src/lib/node/ledger/shell/testing/node.rs +++ b/crates/apps/src/lib/node/ledger/shell/testing/node.rs @@ -438,7 +438,26 @@ impl MockNode { votes, }; - locked.finalize_block(req).expect("Test failed"); + let resp = locked.finalize_block(req).expect("Test failed"); + let mut error_codes = resp + .events + .into_iter() + .map(|e| { + let code = ResultCode::from_u32( + e.attributes + .get("code") + .map(|e| u32::from_str(e).unwrap()) + .unwrap_or_default(), + ) + .unwrap(); + if code == ResultCode::Ok { + NodeResults::Ok + } else { + NodeResults::Failed(code) + } + }) + .collect::>(); + self.results.lock().unwrap().append(&mut error_codes); locked.commit(); // Cache the block @@ -501,7 +520,7 @@ impl MockNode { /// Send a tx through Process Proposal and Finalize Block /// and register the results. - fn submit_txs(&self, txs: Vec>) { + pub fn submit_txs(&self, txs: Vec>) { // The block space allocator disallows encrypted txs in certain blocks. // Advance to block height that allows txs. self.advance_to_allowed_block(); diff --git a/crates/sdk/src/eth_bridge/bridge_pool.rs b/crates/sdk/src/eth_bridge/bridge_pool.rs index 6712e463c8..c8aeb0bb92 100644 --- a/crates/sdk/src/eth_bridge/bridge_pool.rs +++ b/crates/sdk/src/eth_bridge/bridge_pool.rs @@ -40,7 +40,7 @@ use crate::queries::{ TransferToEthereumStatus, RPC, }; use crate::rpc::{query_storage_value, query_wasm_code_hash, validate_amount}; -use crate::signing::aux_signing_data; +use crate::signing::{aux_signing_data, validate_fee_and_gen_unshield}; use crate::tx::prepare_tx; use crate::{ args, display, display_line, edisplay_line, MaybeSync, Namada, @@ -87,6 +87,12 @@ pub async fn build_bridge_pool_tx( Some(sender_), ), )?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + &tx_args, + &signing_data.fee_payer, + ) + .await?; let chain_id = tx_args .chain_id @@ -104,11 +110,12 @@ pub async fn build_bridge_pool_tx( .add_data(transfer); prepare_tx( - context, + context.client(), &tx_args, &mut tx, + unshield, + fee_amount, signing_data.fee_payer.clone(), - None, ) .await?; diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index 4406a514cd..6441126c06 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -68,7 +68,7 @@ use rand_core::{CryptoRng, OsRng, RngCore}; use ripemd::Digest as RipemdDigest; use sha2::Digest; use thiserror::Error; -use token::storage_key::is_any_shielded_action_balance_key; +use token::storage_key::{balance_key, is_any_shielded_action_balance_key}; use token::Amount; #[cfg(feature = "testing")] @@ -461,17 +461,29 @@ pub trait ShieldedUtils: /// Get a MASP transaction prover fn local_tx_prover(&self) -> LocalTxProver; - /// Load up the currently saved ShieldedContext + /// Load up the currently confirmed saved ShieldedContext async fn load( &self, ctx: &mut ShieldedContext, ) -> std::io::Result<()>; - /// Save the given ShieldedContext for future loads + /// Load up the currently saved speculative ShieldedContext + async fn load_speculative( + &self, + ctx: &mut ShieldedContext, + ) -> std::io::Result<()>; + + /// Save the given confirmed ShieldedContext for future loads async fn save( &self, ctx: &ShieldedContext, ) -> std::io::Result<()>; + + /// Save the given speculative ShieldedContext for future loads + async fn save_speculative( + &self, + ctx: &ShieldedContext, + ) -> std::io::Result<()>; } /// Make a ViewingKey that can view notes encrypted by given ExtendedSpendingKey @@ -575,6 +587,16 @@ impl IntoIterator for Unscanned { } } +#[derive(BorshSerialize, BorshDeserialize, Debug)] +/// The possible sync states of the shielded context +pub enum ContextSyncStatus { + /// The context contains only data that has been confirmed by the protocol + Confirmed, + /// The context contains that that has not yet been confirmed by the + /// protocol and could end up being invalid + Speculative, +} + /// Represents the current state of the shielded pool from the perspective of /// the chosen viewing keys. #[derive(BorshSerialize, BorshDeserialize, Debug)] @@ -612,6 +634,8 @@ pub struct ShieldedContext { pub tx_note_map: BTreeMap, /// A cache of fetched indexed txs. pub unscanned: Unscanned, + /// The sync state of the context + pub sync_status: ContextSyncStatus, } /// Default implementation to ease construction of TxContexts. Derive cannot be @@ -634,6 +658,7 @@ impl Default for ShieldedContext { asset_types: HashMap::default(), vk_map: HashMap::default(), unscanned: Default::default(), + sync_status: ContextSyncStatus::Confirmed, } } } @@ -642,12 +667,33 @@ impl ShieldedContext { /// Try to load the last saved shielded context from the given context /// directory. If this fails, then leave the current context unchanged. pub async fn load(&mut self) -> std::io::Result<()> { - self.utils.clone().load(self).await + match self.sync_status { + ContextSyncStatus::Confirmed => self.utils.clone().load(self).await, + ContextSyncStatus::Speculative => { + self.utils.clone().load_speculative(self).await + } + } + } + + /// Try to load the last saved confirmed shielded context from the given + /// context directory. If this fails, then leave the current context + /// unchanged. + pub async fn load_confirmed(&mut self) -> std::io::Result<()> { + self.utils.clone().load(self).await?; + + Ok(()) } - /// Save this shielded context into its associated context directory + /// Save this shielded context into its associated context directory. If the + /// state to be saved is confirmed than also delete the speculative one (if + /// available) pub async fn save(&self) -> std::io::Result<()> { - self.utils.save(self).await + match self.sync_status { + ContextSyncStatus::Confirmed => self.utils.save(self).await, + ContextSyncStatus::Speculative => { + self.utils.save_speculative(self).await + } + } } /// Update the merkle tree of witnesses the first time we @@ -696,6 +742,20 @@ impl ShieldedContext { fvks: &[ViewingKey], ) -> Result<(), Error> { // add new viewing keys + // Reload the state from file to get the last confirmed state and + // discard any speculative data, we cannot fetch on top of a + // speculative state + // Always reload the confirmed context or initialize a new one if not + // found + if self.load_confirmed().await.is_err() { + // Initialize a default context if we couldn't load a valid one + // from storage + *self = Self { + utils: std::mem::take(&mut self.utils), + ..Default::default() + }; + } + for esk in sks { let vk = to_viewing_key(esk).vk; self.vk_heights.entry(vk).or_default(); @@ -703,10 +763,7 @@ impl ShieldedContext { for vk in fvks { self.vk_heights.entry(*vk).or_default(); } - self.utils - .save(self) - .await - .map_err(|e| Error::Other(e.to_string()))?; + let _ = self.save().await; let native_token = query_native_token(client).await?; // the latest block height which has been added to the witness Merkle // tree @@ -729,10 +786,7 @@ impl ShieldedContext { .await?, ); // persist the cache in case of interruptions. - self.utils - .save(self) - .await - .map_err(|e| Error::Other(e.to_string()))?; + let _ = self.save().await; let txs = logger.scan(self.unscanned.clone()); for (indexed_tx, (epoch, tx, stx)) in txs { @@ -758,10 +812,7 @@ impl ShieldedContext { // possibly remove unneeded elements from the cache. self.unscanned.scanned(&indexed_tx); std::mem::swap(&mut vk_heights, &mut self.vk_heights); - self.utils - .save(self) - .await - .map_err(|e| Error::Other(e.to_string()))?; + let _ = self.save().await; } Ok(()) @@ -1013,55 +1064,59 @@ impl ShieldedContext { ) -> Result<(), Error> { // For tracking the account changes caused by this Transaction let mut transaction_delta = TransactionDelta::new(); - let mut note_pos = self.tx_note_map[&indexed_tx]; - // Listen for notes sent to our viewing keys - for so in shielded - .sapling_bundle() - .map_or(&vec![], |x| &x.shielded_outputs) - { - // Let's try to see if any of our viewing keys can decrypt latest - // note - let notes = self.pos_map.entry(*vk).or_default(); - let decres = try_sapling_note_decryption::<_, OutputDescription<<::SaplingAuth as masp_primitives::transaction::components::sapling::Authorization>::Proof>>( + if let ContextSyncStatus::Confirmed = self.sync_status { + let mut note_pos = self.tx_note_map[&indexed_tx]; + // Listen for notes sent to our viewing keys, only if we are syncing + // (i.e. in a confirmed status) + for so in shielded + .sapling_bundle() + .map_or(&vec![], |x| &x.shielded_outputs) + { + // Let's try to see if this viewing key can decrypt latest + // note + let notes = self.pos_map.entry(*vk).or_default(); + let decres = try_sapling_note_decryption::<_, OutputDescription<<::SaplingAuth as masp_primitives::transaction::components::sapling::Authorization>::Proof>>( &NETWORK, 1.into(), &PreparedIncomingViewingKey::new(&vk.ivk()), so, ); - // So this current viewing key does decrypt this current note... - if let Some((note, pa, memo)) = decres { - // Add this note to list of notes decrypted by this viewing - // key - notes.insert(note_pos); - // Compute the nullifier now to quickly recognize when spent - let nf = note.nf( - &vk.nk, - note_pos.try_into().map_err(|_| { - Error::Other("Can not get nullifier".to_string()) - })?, - ); - self.note_map.insert(note_pos, note); - self.memo_map.insert(note_pos, memo); - // The payment address' diversifier is required to spend - // note - self.div_map.insert(note_pos, *pa.diversifier()); - self.nf_map.insert(nf, note_pos); - // Note the account changes - let balance = - transaction_delta.entry(*vk).or_insert_with(I128Sum::zero); - *balance += I128Sum::from_nonnegative( - note.asset_type, - note.value as i128, - ) - .map_err(|()| { - Error::Other( - "found note with invalid value or asset type" - .to_string(), + // So this current viewing key does decrypt this current note... + if let Some((note, pa, memo)) = decres { + // Add this note to list of notes decrypted by this viewing + // key + notes.insert(note_pos); + // Compute the nullifier now to quickly recognize when spent + let nf = note.nf( + &vk.nk, + note_pos.try_into().map_err(|_| { + Error::Other("Can not get nullifier".to_string()) + })?, + ); + self.note_map.insert(note_pos, note); + self.memo_map.insert(note_pos, memo); + // The payment address' diversifier is required to spend + // note + self.div_map.insert(note_pos, *pa.diversifier()); + self.nf_map.insert(nf, note_pos); + // Note the account changes + let balance = transaction_delta + .entry(*vk) + .or_insert_with(I128Sum::zero); + *balance += I128Sum::from_nonnegative( + note.asset_type, + note.value as i128, ) - })?; - self.vk_map.insert(note_pos, *vk); + .map_err(|()| { + Error::Other( + "found note with invalid value or asset type" + .to_string(), + ) + })?; + self.vk_map.insert(note_pos, *vk); + } + note_pos += 1; } - note_pos += 1; } // Cancel out those of our notes that have been spent @@ -1078,6 +1133,7 @@ impl ShieldedContext { .entry(self.vk_map[note_pos]) .or_insert_with(I128Sum::zero); let note = self.note_map[note_pos]; + *balance -= I128Sum::from_nonnegative( note.asset_type, note.value as i128, @@ -1108,48 +1164,58 @@ impl ShieldedContext { )); } (_, 0) => { - // Shielding - let addresses = balance_keys - .iter() - .find(|addresses| { - if addresses[1] != &MASP { - let transp_addr_commit = TransparentAddress( - ripemd::Ripemd160::digest( - sha2::Sha256::digest( - &addresses[1] - .serialize_to_vec(), - ), + // Shielding, only if we are syncing. If in + // speculative context do not update + if let ContextSyncStatus::Confirmed = self.sync_status { + let addresses = balance_keys + .iter() + .find(|addresses| { + if addresses[1] != &MASP { + let transp_addr_commit = + TransparentAddress( + ripemd::Ripemd160::digest( + sha2::Sha256::digest( + &addresses[1] + .serialize_to_vec(), + ), + ) + .into(), + ); + // Vins contain the same address, so we + // can + // just examine the first one + transp_bundle.vin.first().is_some_and( + |vin| { + vin.address + == transp_addr_commit + }, ) - .into(), - ); - // Vins contain the same address, so we can - // just examine the first one - transp_bundle.vin.first().is_some_and( - |vin| vin.address == transp_addr_commit, + } else { + false + } + }) + .ok_or_else(|| { + Error::Other( + "Could not find source of MASP tx" + .to_string(), ) - } else { - false - } - }) - .ok_or_else(|| { - Error::Other( - "Could not find source of MASP tx" - .to_string(), - ) - })?; + })?; - let amount = transp_bundle - .vin - .iter() - .fold(Amount::zero(), |acc, vin| { - acc + Amount::from_u64(vin.value) - }); + let amount = transp_bundle + .vin + .iter() + .fold(Amount::zero(), |acc, vin| { + acc + Amount::from_u64(vin.value) + }); - ( - addresses[1].to_owned(), - addresses[0].to_owned(), - amount, - ) + ( + addresses[1].to_owned(), + addresses[0].to_owned(), + amount, + ) + } else { + return Ok(()); + } } (0, _) => { // Unshielding @@ -1167,7 +1233,8 @@ impl ShieldedContext { .into(), ); - // Vouts contain the same address, so we can + // Vouts contain the same address, so we + // can // just examine the first one transp_bundle.vout.first().is_some_and( |vout| { @@ -1589,6 +1656,8 @@ impl ShieldedContext { ), Error, > { + // TODO: we should try to use the smallest notes possible to fund the + // transaction to allow people to fetch less often // Establish connection with which to do exchange rate queries let mut conversions = BTreeMap::new(); let mut val_acc = I128Sum::zero(); @@ -2144,7 +2213,7 @@ impl ShieldedContext { // We want to take at most the remaining quota for the // current denomination to the receiver let contr = std::cmp::min(*rem_amount as u128, val) as u64; - // Make transaction output tied to thee currentt token, + // Make transaction output tied to the current token, // denomination, and epoch. if let Some(pa) = payment_address { // If there is a shielded output @@ -2325,6 +2394,19 @@ impl ShieldedContext { BorshDeserialize::try_from_slice(&loaded_bytes) .map_err(|_e| Error::Other(exp_str))?; + // Cache the generated transfer + let mut shielded_ctx = context.shielded_mut().await; + shielded_ctx + .pre_cache_transaction( + context, + &loaded.masp_tx, + source, + target, + token, + epoch, + ) + .await?; + Ok(Some(loaded)) } else { // Build and return the constructed transaction @@ -2339,6 +2421,20 @@ impl ShieldedContext { .await .map_err(|e| Error::Other(e.to_string()))?; } + + // Cache the generated transfer + let mut shielded_ctx = context.shielded_mut().await; + shielded_ctx + .pre_cache_transaction( + context, + &built.masp_tx, + source, + target, + token, + epoch, + ) + .await?; + Ok(Some(built)) } } @@ -2349,10 +2445,87 @@ impl ShieldedContext { let built = build_transfer( context.shielded().await.utils.local_tx_prover(), )?; + + let mut shielded_ctx = context.shielded_mut().await; + shielded_ctx + .pre_cache_transaction( + context, + &built.masp_tx, + source, + target, + token, + epoch, + ) + .await?; + Ok(Some(built)) } } + // Updates the internal state with the data of the newly generated + // transaction. More specifically invalidate the spent notes and the + // transparent balances, but do not cache the newly produced output + // descriptions and therefore the merkle tree + async fn pre_cache_transaction( + &mut self, + context: &impl Namada, + masp_tx: &Transaction, + source: &TransferSource, + target: &TransferTarget, + token: &Address, + epoch: Epoch, + ) -> Result<(), Error> { + // Need to mock the changed balance keys + let mut changed_balance_keys = BTreeSet::default(); + match (source.effective_address(), target.effective_address()) { + // Shielded transactions don't write balance keys + (MASP, MASP) => (), + (source, target) => { + changed_balance_keys.insert(balance_key(token, &source)); + changed_balance_keys.insert(balance_key(token, &target)); + } + } + + let native_token = query_native_token(context.client()).await?; + let vks: Vec<_> = context + .wallet() + .await + .get_viewing_keys() + .values() + .map(|evk| ExtendedFullViewingKey::from(*evk).fvk.vk) + .collect(); + let last_witnessed_tx = self.tx_note_map.keys().max(); + // This data will be discarded at the next fetch so we don't need to + // populate it accurately + let indexed_tx = last_witnessed_tx.map_or_else( + || IndexedTx { + height: BlockHeight::first(), + index: TxIndex(0), + }, + |indexed| IndexedTx { + height: indexed.height, + index: indexed.index + 1, + }, + ); + self.sync_status = ContextSyncStatus::Speculative; + for vk in vks { + self.vk_heights.entry(vk).or_default(); + + self.scan_tx( + indexed_tx, + epoch, + &changed_balance_keys, + masp_tx, + &vk, + native_token.clone(), + )?; + } + // Save the speculative state for future usage + self.save().await.map_err(|e| Error::Other(e.to_string()))?; + + Ok(()) + } + /// Obtain the known effects of all accepted shielded and transparent /// transactions. If an owner is specified, then restrict the set to only /// transactions crediting/debiting the given owner. If token is specified, @@ -3558,6 +3731,8 @@ pub mod fs { /// Shielded context file name const FILE_NAME: &str = "shielded.dat"; const TMP_FILE_NAME: &str = "shielded.tmp"; + const SPECULATIVE_FILE_NAME: &str = "speculative_shielded.dat"; + const SPECULATIVE_TMP_FILE_NAME: &str = "speculative_shielded.tmp"; #[derive(Debug, BorshSerialize, BorshDeserialize, Clone)] /// An implementation of ShieldedUtils for standard filesystems @@ -3588,9 +3763,21 @@ pub mod fs { ); } // Finally initialize a shielded context with the supplied directory + + let sync_status = + if std::fs::read(context_dir.join(SPECULATIVE_FILE_NAME)) + .is_ok() + { + // Load speculative state + ContextSyncStatus::Speculative + } else { + ContextSyncStatus::Confirmed + }; + let utils = Self { context_dir }; ShieldedContext { utils, + sync_status, ..Default::default() } } @@ -3606,6 +3793,8 @@ pub mod fs { #[cfg_attr(feature = "async-send", async_trait::async_trait)] #[cfg_attr(not(feature = "async-send"), async_trait::async_trait(?Send))] + // FIXME: I can probably refactor everything to have the associated + // contextsSycn state on this trait impl ShieldedUtils for FsShieldedUtils { fn local_tx_prover(&self) -> LocalTxProver { if let Ok(params_dir) = env::var(ENV_VAR_MASP_PARAMS_DIR) { @@ -3638,7 +3827,28 @@ pub mod fs { Ok(()) } - /// Save this shielded context into its associated context directory + /// Try to load the last saved speculative shielded context from the + /// given context directory. If this fails, then leave the + /// current context unchanged. + async fn load_speculative( + &self, + ctx: &mut ShieldedContext, + ) -> std::io::Result<()> { + // Try to load shielded context from file + let mut ctx_file = + File::open(self.context_dir.join(SPECULATIVE_FILE_NAME))?; + let mut bytes = Vec::new(); + ctx_file.read_to_end(&mut bytes)?; + // Fill the supplied context with the deserialized object + *ctx = ShieldedContext { + utils: ctx.utils.clone(), + ..ShieldedContext::::deserialize(&mut &bytes[..])? + }; + Ok(()) + } + + /// Save this confirmed shielded context into its associated context + /// directory. At the same time, delete the speculative file if present async fn save( &self, ctx: &ShieldedContext, @@ -3664,7 +3874,51 @@ pub mod fs { // Atomically update the old shielded context file with new data. // Atomicity is required to prevent other client instances from // reading corrupt data. - std::fs::rename(tmp_path, self.context_dir.join(FILE_NAME)) + std::fs::rename(tmp_path, self.context_dir.join(FILE_NAME))?; + + // Remove the speculative file if present since it's state is + // overruled by the confirmed one we just saved + let _ = std::fs::remove_file( + self.context_dir.join(SPECULATIVE_FILE_NAME), + ); + + Ok(()) + } + + // FIXME: refactor, the functions are exactly the same, just pass the + // enum and modify the filename based on that + /// Save this speculative shielded context into its associated context + /// directory + async fn save_speculative( + &self, + ctx: &ShieldedContext, + ) -> std::io::Result<()> { + // TODO: use mktemp crate? + let tmp_path = self.context_dir.join(SPECULATIVE_TMP_FILE_NAME); + { + // First serialize the shielded context into a temporary file. + // Inability to create this file implies a simultaneuous write + // is in progress. In this case, immediately + // fail. This is unproblematic because the data + // intended to be stored can always be re-fetched + // from the blockchain. + let mut ctx_file = OpenOptions::new() + .write(true) + .create_new(true) + .open(tmp_path.clone())?; + let mut bytes = Vec::new(); + ctx.serialize(&mut bytes) + .expect("cannot serialize shielded context"); + ctx_file.write_all(&bytes[..])?; + } + // Atomically update the old shielded context file with new data. + // Atomicity is required to prevent other client instances from + // reading corrupt data. + std::fs::rename( + tmp_path, + self.context_dir.join(SPECULATIVE_FILE_NAME), + )?; + Ok(()) } } } diff --git a/crates/sdk/src/signing.rs b/crates/sdk/src/signing.rs index 2324444d20..7bc127c68d 100644 --- a/crates/sdk/src/signing.rs +++ b/crates/sdk/src/signing.rs @@ -10,6 +10,7 @@ use masp_primitives::asset_type::AssetType; use masp_primitives::transaction::components::sapling::fees::{ InputView, OutputView, }; +use masp_primitives::transaction::Transaction; use namada_account::{AccountPublicKeysMap, InitAccount, UpdateAccount}; use namada_core::types::address::{ Address, ImplicitAddress, InternalAddress, MASP, @@ -403,8 +404,8 @@ pub async fn init_validator_signing_data( }) } -/// Information about the post-tx balance of the tx's source. Used to correctly -/// handle fee validation in the wrapper tx +/// Information about the post-fee balance of the tx's source. Used to correctly +/// handle balance validation in the inner tx pub struct TxSourcePostBalance { /// The balance of the tx source after the tx has been applied pub post_balance: Amount, @@ -414,19 +415,15 @@ pub struct TxSourcePostBalance { pub token: Address, } -/// Create a wrapper tx from a normal tx. Get the hash of the -/// wrapper and its payload which is needed for monitoring its -/// progress on chain. -#[allow(clippy::too_many_arguments)] -pub async fn wrap_tx( +/// Validate the fee of the transaction and generate the fee unshielding +/// transaction if needed +pub async fn validate_fee_and_gen_unshield( context: &N, - tx: &mut Tx, args: &args::Tx, - tx_source_balance: Option, - epoch: Epoch, - fee_payer: common::PublicKey, -) -> Result<(), Error> { - let fee_payer_address = Address::from(&fee_payer); + fee_payer: &common::PublicKey, +) -> Result<(DenominatedAmount, TxSourcePostBalance, Option), Error> +{ + let fee_payer_address = Address::from(fee_payer); // Validate fee amount and token let gas_cost_key = parameter_storage::get_gas_cost_key(); let minimum_fee = match rpc::query_storage_value::< @@ -482,27 +479,22 @@ pub async fn wrap_tx( None => validated_minimum_fee, }; - let mut updated_balance = match tx_source_balance { - Some(TxSourcePostBalance { - post_balance: balance, - source, - token, - }) if token == args.fee_token && source == fee_payer_address => balance, - _ => { - let balance_key = balance_key(&args.fee_token, &fee_payer_address); - - rpc::query_storage_value::<_, token::Amount>( - context.client(), - &balance_key, - ) - .await - .unwrap_or_default() - } - }; + let balance_key = balance_key(&args.fee_token, &fee_payer_address); + let balance = rpc::query_storage_value::<_, token::Amount>( + context.client(), + &balance_key, + ) + .await + .unwrap_or_default(); let total_fee = fee_amount.amount() * u64::from(args.gas_limit); + let mut updated_balance = TxSourcePostBalance { + post_balance: balance, + source: fee_payer_address.clone(), + token: args.fee_token.clone(), + }; - let unshield = match total_fee.checked_sub(updated_balance) { + let unshield = match total_fee.checked_sub(balance) { Some(diff) if !diff.is_zero() => { if let Some(spending_key) = args.fee_unshield.clone() { // Unshield funds for fee payment @@ -574,8 +566,7 @@ pub async fn wrap_tx( )); } - updated_balance += total_fee; - Some(transaction) + Some(transaction) } Ok(None) => { if !args.force { @@ -587,6 +578,7 @@ pub async fn wrap_tx( )); } + updated_balance.post_balance = Amount::zero(); None } Err(e) => { @@ -595,7 +587,7 @@ pub async fn wrap_tx( TxSubmitError::FeeUnshieldingError(e.to_string()), )); } - + updated_balance.post_balance = Amount::zero(); None } } @@ -605,9 +597,8 @@ pub async fn wrap_tx( let fee_amount = context.format_amount(&token_addr, total_fee).await; - let balance = context - .format_amount(&token_addr, updated_balance) - .await; + let balance = + context.format_amount(&token_addr, balance).await; return Err(Error::from( TxSubmitError::BalanceTooLowForFees( fee_payer_address, @@ -618,6 +609,7 @@ pub async fn wrap_tx( )); } + updated_balance.post_balance = Amount::zero(); None } } @@ -629,10 +621,26 @@ pub async fn wrap_tx( .to_string(), )); } + updated_balance.post_balance -= total_fee; None } }; + Ok((fee_amount, updated_balance, unshield)) +} + +/// Create a wrapper tx from a normal tx. Get the hash of the +/// wrapper and its payload which is needed for monitoring its +/// progress on chain. +#[allow(clippy::too_many_arguments)] +pub async fn wrap_tx( + tx: &mut Tx, + args: &args::Tx, + epoch: Epoch, + unshield: Option, + fee_amount: DenominatedAmount, + fee_payer: common::PublicKey, +) -> Result<(), Error> { let unshield_section_hash = unshield.map(|masp_tx| { let section = Section::MaspTx(masp_tx); let mut hasher = sha2::Sha256::new(); diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index a5ff9da0da..a95aa5cc75 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -47,6 +47,7 @@ use namada_ibc::storage::channel_key; use namada_proof_of_stake::parameters::PosParams; use namada_proof_of_stake::types::{CommissionPair, ValidatorState}; use namada_token::storage_key::balance_key; +use namada_token::DenominatedAmount; use namada_tx::data::pgf::UpdateStewardCommission; use namada_tx::data::{pos, ResultCode, TxResult}; pub use namada_tx::{Signature, *}; @@ -62,7 +63,7 @@ use crate::rpc::{ self, query_wasm_code_hash, validate_amount, InnerTxResult, TxBroadcastData, TxResponse, }; -use crate::signing::{self, SigningTxData, TxSourcePostBalance}; +use crate::signing::{self, validate_fee_and_gen_unshield, SigningTxData}; use crate::tendermint_rpc::endpoint::broadcast::tx_sync::Response; use crate::tendermint_rpc::error::Error as RpcError; use crate::wallet::WalletIo; @@ -181,18 +182,18 @@ pub fn dump_tx(io: &IO, args: &args::Tx, tx: Tx) { /// Prepare a transaction for signing and submission by adding a wrapper header /// to it. #[allow(clippy::too_many_arguments)] -pub async fn prepare_tx( - context: &impl Namada, +pub async fn prepare_tx( + client: &C, args: &args::Tx, tx: &mut Tx, + unshield: Option, + fee_amount: DenominatedAmount, fee_payer: common::PublicKey, - tx_source_balance: Option, ) -> Result<()> { if !args.dry_run { - let epoch = rpc::query_epoch(context.client()).await?; + let epoch = rpc::query_epoch(client).await?; - signing::wrap_tx(context, tx, args, tx_source_balance, epoch, fee_payer) - .await + signing::wrap_tx(tx, args, epoch, unshield, fee_amount, fee_payer).await } else { Ok(()) } @@ -286,6 +287,9 @@ pub async fn build_reveal_pk( let signing_data = signing::aux_signing_data(context, args, None, Some(public_key.into())) .await?; + let (fee_amount, _, unshield) = + validate_fee_and_gen_unshield(context, args, &signing_data.fee_payer) + .await?; build( context, @@ -293,8 +297,9 @@ pub async fn build_reveal_pk( args.tx_reveal_code_path.clone(), public_key, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -575,6 +580,12 @@ pub async fn build_validator_commission_change( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; let epoch = rpc::query_epoch(context.client()).await?; @@ -664,8 +675,9 @@ pub async fn build_validator_commission_change( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -694,6 +706,12 @@ pub async fn build_validator_metadata_change( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; let epoch = rpc::query_epoch(context.client()).await?; @@ -797,8 +815,9 @@ pub async fn build_validator_metadata_change( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -822,6 +841,12 @@ pub async fn build_update_steward_commission( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; if !rpc::is_steward(context.client(), steward).await && !tx_args.force { edisplay_line!( @@ -858,8 +883,9 @@ pub async fn build_update_steward_commission( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -882,6 +908,12 @@ pub async fn build_resign_steward( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; if !rpc::is_steward(context.client(), steward).await && !tx_args.force { edisplay_line!( @@ -900,8 +932,9 @@ pub async fn build_resign_steward( tx_code_path.clone(), steward.clone(), do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -924,6 +957,12 @@ pub async fn build_unjail_validator( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; if !rpc::is_validator(context.client(), validator).await? { edisplay_line!( @@ -1002,8 +1041,9 @@ pub async fn build_unjail_validator( tx_code_path.clone(), validator.clone(), do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -1026,6 +1066,12 @@ pub async fn build_deactivate_validator( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; // Check if the validator address is actually a validator if !rpc::is_validator(context.client(), validator).await? { @@ -1073,8 +1119,9 @@ pub async fn build_deactivate_validator( tx_code_path.clone(), validator.clone(), do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -1097,6 +1144,12 @@ pub async fn build_reactivate_validator( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; // Check if the validator address is actually a validator if !rpc::is_validator(context.client(), validator).await? { @@ -1143,8 +1196,9 @@ pub async fn build_reactivate_validator( tx_code_path.clone(), validator.clone(), do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -1313,6 +1367,12 @@ pub async fn build_redelegation( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; let data = pos::Redelegation { src_validator, @@ -1327,8 +1387,9 @@ pub async fn build_redelegation( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -1353,6 +1414,12 @@ pub async fn build_withdraw( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; let epoch = rpc::query_epoch(context.client()).await?; @@ -1410,8 +1477,9 @@ pub async fn build_withdraw( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -1436,6 +1504,12 @@ pub async fn build_claim_rewards( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; // Check that the validator address is actually a validator let validator = @@ -1458,8 +1532,9 @@ pub async fn build_claim_rewards( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -1510,6 +1585,12 @@ pub async fn build_unbond( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; // Check the source's current bond amount let bond_source = source.clone().unwrap_or_else(|| validator.clone()); @@ -1560,8 +1641,9 @@ pub async fn build_unbond( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await?; Ok((tx, signing_data, latest_withdrawal_pre)) @@ -1710,28 +1792,61 @@ pub async fn build_bond( default_signer, ) .await?; + let (fee_amount, updated_balance, unshield) = + validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; // Check bond's source (source for delegation or validator for self-bonds) // balance let bond_source = source.as_ref().unwrap_or(&validator); let native_token = context.native_token(); - let balance_key = balance_key(&native_token, bond_source); - - // TODO Should we state the same error message for the native token? - let post_balance = check_balance_too_low_err( - &native_token, - bond_source, - *amount, - balance_key, - tx_args.force, - context, - ) - .await?; - let tx_source_balance = Some(TxSourcePostBalance { - post_balance, - source: bond_source.clone(), - token: native_token, - }); + if &updated_balance.source == bond_source + && updated_balance.token == native_token + { + if *amount > updated_balance.post_balance { + if tx_args.force { + edisplay_line!( + context.io(), + "The balance of the source {} of token {} is lower than \ + the amount to be transferred. Amount to transfer is {} \ + and the balance is {}.", + bond_source, + native_token, + context.format_amount(&native_token, *amount).await, + context + .format_amount( + &native_token, + updated_balance.post_balance + ) + .await, + ); + } else { + return Err(Error::from(TxSubmitError::BalanceTooLow( + bond_source.clone(), + native_token, + amount.to_string_native(), + updated_balance.post_balance.to_string_native(), + ))); + } + } + } else { + let balance_key = balance_key(&native_token, bond_source); + + // TODO Should we state the same error message for the native token? + check_balance_too_low_err( + &native_token, + bond_source, + *amount, + balance_key, + tx_args.force, + context, + ) + .await?; + } let data = pos::Bond { validator, @@ -1745,8 +1860,9 @@ pub async fn build_bond( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - tx_source_balance, ) .await .map(|tx| (tx, signing_data)) @@ -1773,6 +1889,9 @@ pub async fn build_default_proposal( default_signer, ) .await?; + let (fee_amount, _updated_balance, unshield) = + validate_fee_and_gen_unshield(context, tx, &signing_data.fee_payer) + .await?; let init_proposal_data = InitProposalData::try_from(proposal.clone()) .map_err(|e| TxSubmitError::InvalidProposal(e.to_string()))?; @@ -1791,14 +1910,16 @@ pub async fn build_default_proposal( }; Ok(()) }; + // TODO: need to pay the fee to submit a proposal, check enough balance build( context, tx, tx_code_path.clone(), init_proposal_data, push_data, + unshield, + fee_amount, &signing_data.fee_payer, - None, // TODO: need to pay the fee to submit a proposal ) .await .map(|tx| (tx, signing_data)) @@ -1826,6 +1947,9 @@ pub async fn build_vote_proposal( default_signer.clone(), ) .await?; + let (fee_amount, _, unshield) = + validate_fee_and_gen_unshield(context, tx, &signing_data.fee_payer) + .await?; let proposal_vote = ProposalVote::try_from(vote.clone()) .map_err(|_| TxSubmitError::InvalidProposalVote)?; @@ -1884,8 +2008,9 @@ pub async fn build_vote_proposal( tx_code_path.clone(), data, do_nothing, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -1912,7 +2037,11 @@ pub async fn build_pgf_funding_proposal( default_signer, ) .await?; + let (fee_amount, _updated_balance, unshield) = + validate_fee_and_gen_unshield(context, tx, &signing_data.fee_payer) + .await?; + // TODO: need to pay the fee to submit a proposal, check enough balance let init_proposal_data = InitProposalData::try_from(proposal.clone()) .map_err(|e| TxSubmitError::InvalidProposal(e.to_string()))?; @@ -1928,8 +2057,9 @@ pub async fn build_pgf_funding_proposal( tx_code_path.clone(), init_proposal_data, add_section, + unshield, + fee_amount, &signing_data.fee_payer, - None, // TODO: need to pay the fee to submit a proposal ) .await .map(|tx| (tx, signing_data)) @@ -1956,7 +2086,11 @@ pub async fn build_pgf_stewards_proposal( default_signer, ) .await?; + let (fee_amount, _updated_balance, unshield) = + validate_fee_and_gen_unshield(context, tx, &signing_data.fee_payer) + .await?; + // TODO: need to pay the fee to submit a proposal, check enough balance let init_proposal_data = InitProposalData::try_from(proposal.clone()) .map_err(|e| TxSubmitError::InvalidProposal(e.to_string()))?; @@ -1973,8 +2107,9 @@ pub async fn build_pgf_stewards_proposal( tx_code_path.clone(), init_proposal_data, add_section, + unshield, + fee_amount, &signing_data.fee_payer, - None, // TODO: need to pay the fee to submit a proposal ) .await .map(|tx| (tx, signing_data)) @@ -1993,6 +2128,14 @@ pub async fn build_ibc_transfer( Some(source.clone()), ) .await?; + let (fee_amount, updated_balance, unshield) = + validate_fee_and_gen_unshield( + context, + &args.tx, + &signing_data.fee_payer, + ) + .await?; + // Check that the source address exists on chain let source = source_exists_or_err(source.clone(), args.tx.force, context).await?; @@ -2010,23 +2153,49 @@ pub async fn build_ibc_transfer( ))); } - // Check source balance - let balance_key = balance_key(&args.token, &source); - - let post_balance = check_balance_too_low_err( - &args.token, - &source, - validated_amount.amount(), - balance_key, - args.tx.force, - context, - ) - .await?; - let tx_source_balance = Some(TxSourcePostBalance { - post_balance, - source: source.clone(), - token: args.token.clone(), - }); + if updated_balance.source == source && updated_balance.token == args.token { + if validated_amount.amount() > updated_balance.post_balance { + if args.tx.force { + edisplay_line!( + context.io(), + "The balance of the source {} of token {} is lower than \ + the amount to be transferred. Amount to transfer is {} \ + and the balance is {}.", + source, + args.token, + context + .format_amount(&args.token, validated_amount.amount()) + .await, + context + .format_amount( + &args.token, + updated_balance.post_balance + ) + .await, + ); + } else { + return Err(Error::from(TxSubmitError::BalanceTooLow( + source.clone(), + args.token.clone(), + validated_amount.amount().to_string_native(), + updated_balance.post_balance.to_string_native(), + ))); + } + } + } else { + // Check source balance + let balance_key = balance_key(&args.token, &source); + + check_balance_too_low_err( + &args.token, + &source, + validated_amount.amount(), + balance_key, + args.tx.force, + context, + ) + .await?; + } let tx_code_hash = query_wasm_code_hash(context, args.tx_code_path.to_str().unwrap()) @@ -2149,11 +2318,12 @@ pub async fn build_ibc_transfer( .add_serialized_data(data); prepare_tx( - context, + context.client(), &args.tx, &mut tx, + unshield, + fee_amount, signing_data.fee_payer.clone(), - tx_source_balance, ) .await?; @@ -2168,21 +2338,16 @@ pub async fn build( path: PathBuf, data: D, on_tx: F, + unshield: Option, + fee_amount: DenominatedAmount, gas_payer: &common::PublicKey, - tx_source_balance: Option, ) -> Result where F: FnOnce(&mut Tx, &mut D) -> Result<()>, D: BorshSerialize, { build_pow_flag( - context, - tx_args, - path, - data, - on_tx, - gas_payer, - tx_source_balance, + context, tx_args, path, data, on_tx, unshield, fee_amount, gas_payer, ) .await } @@ -2194,8 +2359,9 @@ async fn build_pow_flag( path: PathBuf, mut data: D, on_tx: F, + unshield: Option, + fee_amount: DenominatedAmount, gas_payer: &common::PublicKey, - tx_source_balance: Option, ) -> Result where F: FnOnce(&mut Tx, &mut D) -> Result<()>, @@ -2222,11 +2388,12 @@ where .add_data(data); prepare_tx( - context, + context.client(), tx_args, &mut tx_builder, + unshield, + fee_amount, gas_payer.clone(), - tx_source_balance, ) .await?; Ok(tx_builder) @@ -2301,6 +2468,14 @@ pub async fn build_transfer( ) .await?; + let (fee_amount, updated_balance, unshield) = + validate_fee_and_gen_unshield( + context, + &args.tx, + &signing_data.fee_payer, + ) + .await?; + let source = args.source.effective_address(); let target = args.target.effective_address(); @@ -2308,8 +2483,6 @@ pub async fn build_transfer( source_exists_or_err(source.clone(), args.tx.force, context).await?; // Check that the target address exists on chain target_exists_or_err(target.clone(), args.tx.force, context).await?; - // Check source balance - let balance_key = balance_key(&args.token, &source); // validate the amount given let validated_amount = @@ -2317,20 +2490,49 @@ pub async fn build_transfer( .await?; args.amount = InputAmount::Validated(validated_amount); - let post_balance = check_balance_too_low_err( - &args.token, - &source, - validated_amount.amount(), - balance_key, - args.tx.force, - context, - ) - .await?; - let tx_source_balance = Some(TxSourcePostBalance { - post_balance, - source: source.clone(), - token: args.token.clone(), - }); + + // Check source balance + if updated_balance.source == source && updated_balance.token == args.token { + if validated_amount.amount() > updated_balance.post_balance { + if args.tx.force { + edisplay_line!( + context.io(), + "The balance of the source {} of token {} is lower than \ + the amount to be transferred. Amount to transfer is {} \ + and the balance is {}.", + source, + args.token, + context + .format_amount(&args.token, validated_amount.amount()) + .await, + context + .format_amount( + &args.token, + updated_balance.post_balance + ) + .await, + ); + } else { + return Err(Error::from(TxSubmitError::BalanceTooLow( + source.clone(), + args.token.clone(), + validated_amount.amount().to_string_native(), + updated_balance.post_balance.to_string_native(), + ))); + } + } + } else { + let balance_key = balance_key(&args.token, &source); + check_balance_too_low_err( + &args.token, + &source, + validated_amount.amount(), + balance_key, + args.tx.force, + context, + ) + .await?; + } let masp_addr = MASP; @@ -2407,8 +2609,9 @@ pub async fn build_transfer( args.tx_code_path.clone(), transfer, add_shielded, + unshield, + fee_amount, &signing_data.fee_payer, - tx_source_balance, ) .await?; Ok((tx, signing_data, shielded_tx_epoch)) @@ -2472,6 +2675,12 @@ pub async fn build_init_account( ) -> Result<(Tx, SigningTxData)> { let signing_data = signing::aux_signing_data(context, tx_args, None, None).await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; let vp_code_hash = query_wasm_code_hash_buf(context, vp_code_path).await?; @@ -2509,8 +2718,9 @@ pub async fn build_init_account( tx_code_path.clone(), data, add_code_hash, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -2536,6 +2746,12 @@ pub async fn build_update_account( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; let addr = if let Some(account) = rpc::get_account_info(context.client(), addr).await? @@ -2596,8 +2812,9 @@ pub async fn build_update_account( tx_code_path.clone(), data, add_code_hash, + unshield, + fee_amount, &signing_data.fee_payer, - None, ) .await .map(|tx| (tx, signing_data)) @@ -2622,6 +2839,12 @@ pub async fn build_custom( default_signer, ) .await?; + let (fee_amount, _, unshield) = validate_fee_and_gen_unshield( + context, + tx_args, + &signing_data.fee_payer, + ) + .await?; let mut tx = if let Some(serialized_tx) = serialized_tx { Tx::deserialize(serialized_tx.as_ref()).map_err(|_| { @@ -2646,11 +2869,12 @@ pub async fn build_custom( }; prepare_tx( - context, + context.client(), tx_args, &mut tx, + unshield, + fee_amount, signing_data.fee_payer.clone(), - None, ) .await?; @@ -2878,7 +3102,7 @@ async fn target_exists_or_err( /// Checks the balance at the given address is enough to transfer the /// given amount, along with the balance even existing. Force -/// overrides this. Returns the updated balance for fee check if necessary +/// overrides this. async fn check_balance_too_low_err( token: &Address, source: &Address, @@ -2886,7 +3110,7 @@ async fn check_balance_too_low_err( balance_key: storage::Key, force: bool, context: &N, -) -> Result { +) -> Result<()> { match rpc::query_storage_value::( context.client(), &balance_key, @@ -2894,7 +3118,7 @@ async fn check_balance_too_low_err( .await { Ok(balance) => match balance.checked_sub(amount) { - Some(diff) => Ok(diff), + Some(_) => Ok(()), None => { if force { edisplay_line!( @@ -2907,7 +3131,7 @@ async fn check_balance_too_low_err( context.format_amount(token, amount).await, context.format_amount(token, balance).await, ); - Ok(token::Amount::zero()) + Ok(()) } else { Err(Error::from(TxSubmitError::BalanceTooLow( source.clone(), @@ -2928,7 +3152,7 @@ async fn check_balance_too_low_err( source, token ); - Ok(token::Amount::zero()) + Ok(()) } else { Err(Error::from(TxSubmitError::NoBalanceForToken( source.clone(), diff --git a/crates/sdk/src/wallet/mod.rs b/crates/sdk/src/wallet/mod.rs index de8c52ff8c..c6aa765375 100644 --- a/crates/sdk/src/wallet/mod.rs +++ b/crates/sdk/src/wallet/mod.rs @@ -381,7 +381,7 @@ impl Wallet { /// Find the viewing key with the given alias in the wallet and return it pub fn find_viewing_key( - &mut self, + &self, alias: impl AsRef, ) -> Result<&ExtendedViewingKey, FindKeyError> { self.store.find_viewing_key(alias.as_ref()).ok_or_else(|| { diff --git a/crates/tests/src/integration/masp.rs b/crates/tests/src/integration/masp.rs index a07fb0f9dc..dea94da184 100644 --- a/crates/tests/src/integration/masp.rs +++ b/crates/tests/src/integration/masp.rs @@ -4,9 +4,11 @@ use std::str::FromStr; use color_eyre::eyre::Result; use color_eyre::owo_colors::OwoColorize; use namada::state::StorageWrite; -use namada::token; +use namada::token::{self, DenominatedAmount}; use namada_apps::node::ledger::shell::testing::client::run; +use namada_apps::node::ledger::shell::testing::node::NodeResults; use namada_apps::node::ledger::shell::testing::utils::{Bin, CapturedOutput}; +use namada_apps::wallet::defaults::christel_keypair; use namada_core::types::dec::Dec; use namada_sdk::masp::fs::FsShieldedUtils; use test_log::test; @@ -1357,12 +1359,6 @@ fn masp_txs_and_queries() -> Result<()> { ]; for (tx_args, tx_result) in &txs_args { - // sync shielded context - run( - &node, - Bin::Client, - vec!["shielded-sync", "--node", validator_one_rpc], - )?; node.assert_success(); // there is no need to dry run balance queries let dry_run_args = if tx_args[0] == "transfer" { @@ -1373,6 +1369,12 @@ fn masp_txs_and_queries() -> Result<()> { vec![false] }; for &dry_run in &dry_run_args { + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; let tx_args = if dry_run && tx_args[0] == "transfer" { vec![tx_args.clone(), vec!["--dry-run"]].concat() } else { @@ -1448,10 +1450,10 @@ fn masp_txs_and_queries() -> Result<()> { /// 1. Shield some tokens to reduce the unshielded balance /// 2. Submit a new wrapper with a valid unshielding tx and assert /// success -/// 3. Submit a new wrapper with an invalid unshielding tx and assert the -/// failure -/// 4. Submit another transaction with valid fee unshielding and an inner +/// 3. Submit another transaction with valid fee unshielding and an inner /// shielded transfer with the same source +/// 4. Submit a new wrapper with an invalid unshielding tx and assert the +/// failure #[test] fn wrapper_fee_unshielding() -> Result<()> { // This address doesn't matter for tests. But an argument is required. @@ -1461,6 +1463,35 @@ fn wrapper_fee_unshielding() -> Result<()> { let (mut node, _services) = setup::setup()?; _ = node.next_epoch(); + // Add the relevant viewing keys to the wallet otherwise the shielded + // context won't precache the masp data + run( + &node, + Bin::Wallet, + vec![ + "add", + "--alias", + "alias_a", + "--value", + AA_VIEWING_KEY, + "--unsafe-dont-encrypt", + ], + )?; + node.assert_success(); + run( + &node, + Bin::Wallet, + vec![ + "add", + "--alias", + "alias_b", + "--value", + AB_VIEWING_KEY, + "--unsafe-dont-encrypt", + ], + )?; + node.assert_success(); + // 1. Shield some tokens run( &node, @@ -1474,7 +1505,31 @@ fn wrapper_fee_unshielding() -> Result<()> { "--token", NAM, "--amount", - "1979999", // Reduce the balance of the fee payer artificially + "1919999", // Reduce the balance of the fee payer artificially + "--gas-price", + "1", + "--gas-limit", + "20000", + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); + + _ = node.next_epoch(); + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", + ALBERT_KEY, + "--target", + AA_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "40000", // Reduce the balance of the fee payer artificially "--gas-price", "1", "--gas-limit", @@ -1484,6 +1539,13 @@ fn wrapper_fee_unshielding() -> Result<()> { ], )?; node.assert_success(); + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); let captured = CapturedOutput::of(|| { run( &node, @@ -1517,24 +1579,9 @@ fn wrapper_fee_unshielding() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1979999")); + assert!(captured.contains("nam: 1959999")); _ = node.next_epoch(); - // sync shielded context - run( - &node, - Bin::Client, - vec![ - "shielded-sync", - "--viewing-keys", - AA_VIEWING_KEY, - AB_VIEWING_KEY, - "--node", - validator_one_rpc, - ], - )?; - node.assert_success(); - // 2. Valid unshielding run( &node, @@ -1560,6 +1607,13 @@ fn wrapper_fee_unshielding() -> Result<()> { ], )?; node.assert_success(); + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + node.assert_success(); let captured = CapturedOutput::of(|| { run( &node, @@ -1593,17 +1647,64 @@ fn wrapper_fee_unshielding() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1959999")); + assert!(captured.contains("nam: 1939999")); + _ = node.next_epoch(); + // 3. Try another valid fee unshielding and masp transaction in the same tx, + // with the same source. This tests that the client can properly construct + // two valid masp transactions at the same time + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", + A_SPENDING_KEY, + "--target", + AB_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "1", + "--gas-price", + "1", + "--gas-limit", + "20000", + "--gas-payer", + ALBERT_KEY, + "--gas-spending-key", + A_SPENDING_KEY, + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); // sync shielded context run( &node, Bin::Client, vec!["shielded-sync", "--node", validator_one_rpc], )?; - node.assert_success(); + let captured = CapturedOutput::of(|| { + run( + &node, + Bin::Client, + vec![ + "balance", + "--owner", + AA_VIEWING_KEY, + "--token", + NAM, + "--node", + validator_one_rpc, + ], + ) + }); + assert!(captured.result.is_ok()); + assert!(captured.contains("nam: 1919998")); - // 3. Invalid unshielding + _ = node.next_epoch(); + // 4. Invalid unshielding let tx_args = vec![ "transfer", "--source", @@ -1634,52 +1735,271 @@ fn wrapper_fee_unshielding() -> Result<()> { tx_args ); - // 4. Try another valid fee unshielding and masp transaction in the same tx, - // with the same source. This tests that the client can properly fetch data - // and construct these kind of transactions + Ok(()) +} + +/// Tests that multiple transactions can be constructed (without fetching) from +/// the shielded context and executed in the same block +#[test] +fn multiple_unfetched_txs_same_block() -> Result<()> { + // This address doesn't matter for tests. But an argument is required. + let validator_one_rpc = "127.0.0.1:26567"; + // Download the shielded pool parameters before starting node + let _ = FsShieldedUtils::new(PathBuf::new()); + let (mut node, _services) = setup::setup()?; + _ = node.next_epoch(); + + // Add the relevant viewing keys to the wallet otherwise the shielded + // context won't precache the masp data + run( + &node, + Bin::Wallet, + vec![ + "add", + "--alias", + "alias_a", + "--value", + AA_VIEWING_KEY, + "--unsafe-dont-encrypt", + ], + )?; + node.assert_success(); + run( + &node, + Bin::Wallet, + vec![ + "add", + "--alias", + "alias_b", + "--value", + AB_VIEWING_KEY, + "--unsafe-dont-encrypt", + ], + )?; + node.assert_success(); + + // 1. Shield tokens + _ = node.next_epoch(); run( &node, Bin::Client, vec![ "transfer", "--source", - A_SPENDING_KEY, + ALBERT_KEY, + "--target", + AA_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "100", + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); + _ = node.next_epoch(); + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", + ALBERT_KEY, + "--target", + AA_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "200", + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); + _ = node.next_epoch(); + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", + ALBERT_KEY, "--target", AB_PAYMENT_ADDRESS, "--token", NAM, "--amount", - "1", - "--gas-price", - "1", - "--gas-limit", - "20000", + "100", + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); + // sync shielded context + run( + &node, + Bin::Client, + vec!["shielded-sync", "--node", validator_one_rpc], + )?; + + // 2. Shielded operations without fetching. Dump the txs to than reload and + // submit in the same block + let tempdir = tempfile::tempdir().unwrap(); + let mut txs_bytes = vec![]; + + _ = node.next_epoch(); + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", + A_SPENDING_KEY, + "--target", + AC_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "50", "--gas-payer", ALBERT_KEY, - "--gas-spending-key", + "--output-folder-path", + tempdir.path().to_str().unwrap(), + "--dump-tx", + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); + let file_path = tempdir + .path() + .read_dir() + .unwrap() + .next() + .unwrap() + .unwrap() + .path(); + txs_bytes.push(std::fs::read(&file_path).unwrap()); + std::fs::remove_file(&file_path).unwrap(); + + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", A_SPENDING_KEY, + "--target", + AC_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "50", + "--gas-payer", + CHRISTEL_KEY, + "--output-folder-path", + tempdir.path().to_str().unwrap(), + "--dump-tx", "--ledger-address", validator_one_rpc, ], )?; node.assert_success(); - let captured = CapturedOutput::of(|| { - run( - &node, - Bin::Client, - vec![ - "balance", - "--owner", - AA_VIEWING_KEY, - "--token", - NAM, - "--node", - validator_one_rpc, - ], - ) - }); - assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1939998")); + let file_path = tempdir + .path() + .read_dir() + .unwrap() + .next() + .unwrap() + .unwrap() + .path(); + txs_bytes.push(std::fs::read(&file_path).unwrap()); + std::fs::remove_file(&file_path).unwrap(); + + run( + &node, + Bin::Client, + vec![ + "transfer", + "--source", + B_SPENDING_KEY, + "--target", + AC_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "50", + "--gas-payer", + CHRISTEL_KEY, + "--output-folder-path", + tempdir.path().to_str().unwrap(), + "--dump-tx", + "--ledger-address", + validator_one_rpc, + ], + )?; + node.assert_success(); + let file_path = tempdir + .path() + .read_dir() + .unwrap() + .next() + .unwrap() + .unwrap() + .path(); + txs_bytes.push(std::fs::read(&file_path).unwrap()); + std::fs::remove_file(&file_path).unwrap(); + + let sk = christel_keypair(); + let pk = sk.to_public(); + + let native_token = node + .shell + .lock() + .unwrap() + .wl_storage + .storage + .native_token + .clone(); + let mut txs = vec![]; + for bytes in txs_bytes { + let mut tx = namada::tx::Tx::deserialize(&bytes).unwrap(); + tx.add_wrapper( + namada::tx::data::wrapper_tx::Fee { + amount_per_gas_unit: DenominatedAmount::native(1.into()), + token: native_token.clone(), + }, + pk.clone(), + Default::default(), + 20000.into(), + None, + ); + tx.sign_wrapper(sk.clone()); + + txs.push(tx.to_bytes()); + } + + node.clear_results(); + node.submit_txs(txs); + { + let results = node.results.lock().unwrap(); + // If empty than failed in process proposal + assert!(!results.is_empty()); + + for result in results.iter() { + assert!(matches!(result, NodeResults::Ok)); + } + } + // Finalize the next block to actually execute the decrypted txs + node.clear_results(); + node.finalize_and_commit(); + { + let results = node.results.lock().unwrap(); + for result in results.iter() { + assert!(matches!(result, NodeResults::Ok)); + } + } Ok(()) } @@ -1687,7 +2007,7 @@ fn wrapper_fee_unshielding() -> Result<()> { // Test that a masp unshield transaction can be succesfully executed even across // an epoch boundary. #[test] -fn cross_epoch_tx() -> Result<()> { +fn cross_epoch_unshield() -> Result<()> { // This address doesn't matter for tests. But an argument is required. let validator_one_rpc = "127.0.0.1:26567"; // Download the shielded pool parameters before starting node diff --git a/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin b/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin index 809124ae22df903ecf004622ad952eae4623c7d9..9d6f8e4f8a770c0044b692f0baf6de89300ae37e 100644 GIT binary patch delta 1795 zcmV+e2mJW?PWeu-78oF!DvGU+i6>(gt6z+tt?+DpR#aX$;TQH=#V3OmRs#u>HW)%+ zkdE^Q)!1T$OSryx{1f$rXY5hk&nIxG(8k{M^t`YtU_zjWXo_SXt^`5SPa}~qU1UU) z8Rj=j-9l~Ee??9MM=)ztk8v0CubOan_x8K8hi{*U)=y5oad-fBW&nc`v)CA<0)IpR z%C;(wyJ;D0G5%<$u5UMG*!~si6J0N0PKvKakyng8Q>5 zTG^bD8BwJZ5A_xR%$BnN1uAkHufSd7WFAwBB}OujiR`_~h~om4yGfFac9>Gk-x9hn zHYwK)!zr&Lp(C=oFpnV4b3`kQBD4D&l>&c9O#`3xofG6X>&L@fNdL|Dh4;NLvQGR? zNkCeO9U`kXos(b1J>FubFx9I+71D{AcNhQi;BX$430Fe02PNe2(*s@z#QZJW>tOY6T}L@0;vTwZREjEp?Y8N(Cnp;@`(2uj9Q&n3+9Uv~4i< zXpYAL#5m4ZijlJFepjWh`+!>eFZWqQ*-%4wHL1L3IvWSxGZr7(mtZXrPeUJd0%Sans&og{U+gbkLXk-4 z;{@6TGM&mlrn8*T-ILoXX}P0voO1k;tU_0+7j@>N@c(Rte-i?ME=$KdbqnxLy1`Y^ zl`JQ$ho}xJVr%LAwlYG?@tR#4P(}k4Yx3)i7sukw0L{3FFmA*0!as6-$-K|tm@K?V zWlt{0dB+w}X(J}?$^Og`>NZ?2r=e|jf38n8*x;`S%%J#MtRXB&xq|~6{h^+jSD6*<#@8Izniyh>r`3qmHLOAe@7)lD5hM@DLyLVSxRyOJb zpJw;{8}7sefKY$TF|Hw#sR@g_!MhbVHDxy$_b z1169|f5ve=M(LtG(GS?SC48eFV6_`BAO?_PxXd?!RIs#$bBd5nnzj|gjwuzNi)mSn zdl9RUMO~zSY=%n`Q(3tGI&CmO# z5M?1H(-xtsTeR6{xW)X5QbIG%NbWZLHCm4Ydf0WIx@}WX9?NDsX^ZY@M4t4v_3xoX zmQ)uE$wi2Dpc6^U<17Vwwzs1~fYy5&ePW&EURoWW(B= z4!pz6Zvoq(Cc+Do?J|8x+h8f;hX2x3pv#;8_D^-OPbgKMi}vX?Cv2xJ43URA-LApa zC!Th84_}R_$xx9ul`+(y_GK-)G4g+te>0@x$@KWYxUQm1fm*}^U z3F9j)c7Io8{GTW^KK*!|*{tv|K(To?<6uc4sh9$%tl<(Ea*H|C8Xg3nt4#5K!e4L= zdGHFbI~~L_C@=?0BeDSP{lkrxGKK6hrUz^auNKk(S?(!jKUp&hDG(4Fq!1!3f0uaJ zN0;PW6f`1S7yPjl{Z)-Q*oWoX=lYN0#wFZPOQh2(xcUe_axQK~QRf9mKGOJk5uCU< z!o$^L)#ekKG$l>Hsv1wOV421?kX5mAxo9Wc+r4=bKuioemsfhbc0_$-DNa$c#=|@; lozU$K+nj%nEO+80s_|Niu2mV+2?ILK8q2{m3k{PrCq;^jcU1rY delta 1795 zcmV+e2mJW?PWeu-78oG&?ajh~2TK6V_{fiJT4y=)GiO`xo}X3g5=iaTN&6C$HW)%+ zX5~3o&+hBr$=98`e4VO#-m1nJ@plccx@4Xe2+fPzkpc&$Z>Dc2`XFvHAa(04dJ=5j zO5+5b7DgeFZw?>>O@p9SQn9bR#csv|S+GSqgRL7E@+kx0>bOz+586kXv)CA<0)O!8 zi;p}^QhzNePq2_B+f*rC$!qfnO(@l6m%uwiyd|QrVq9cjK0Z1yY_w7r=&6Li80qE; zHjgOf8rO;AKk2D^gJR~_E?P+tS=J}f{|z}_q7K+ORbq-bup{DWYuwpqIH7`pke8X1 zU)wjeH{Y)#p(C=oFpnV4b3`kQBD4D&l>&eNZu6g&$Z=*&mphRT>850{G2 z2{QY8ZkLdwODq-g*S<_+b420TzC(m;1=1s}{pl-K0FeAjUL71N%EokAGXfMwdm2BT~ZqzDrHD-XR$8 z*{r<+w#EVAkW)qevwrDac;N$4RY=8lW%ObQ^A3WjwG%K_w!1k&crnx(GHoW0WCoCB zF&Qa4=mY@aMr@Y>e`f%~xLhO3*hY>pa5W`{aZ9xCM1OwEsJsfkiiUIpao%H@osKcp zpc8cTj+C5pvw58Mve7>C67A|-yvvd&khksX+cWxCF*x z)#pfS@sz?kLi&^wP42c1fH@cIu=6A@`J)83cpVs$2F5u-e^&sD^~fIB3KI%dlvCU_ z5wn;lTzhGI4$QzJ>>Qxfx+0r>^ZLZ!BXs66$>51V!19inRzf7y2~j$=uz4~MXH+*4 z(5hZrZ>J<(JX|Ns1E@l}`(W1t#2!nsj00M8Pb`%MyMpRQ%g3fTXZ-hWQK!o30&g8f z!$LDOVzs2ke^@TUpD1>wrfGtA+pWvs__Bk}fx6!TAJgNZin}i6N|3#i1!9er~;mCAeL)%Ah-rv%?bERJwwKnP?*sfj8m|Ol{Ay>-qcl^zTf47Br;OYD*>#D z(}Bpt>dtt^@>$tUgDgQE{tnY(P`+1r7ut+cT;B=XAF!{BAsq2SaY zhk2B^q#)GCWf#UZ(3W!J7{78Z{KSvFk5xP;!8L<8Xpfekr16A||V`M_k*l z{<#iuDRJTs(zWBbdtdS~x*p!JqzpU*lw0vrbZ$S!JhcO>sK&>O6c*?J;33hbkigT! z+1eN}l> z?f%Y>{Pd+IWyc0tfkpqM>ehTJ$ lVi~}VjC(suqee>^kl^b5d1ln&3B(F698L>-fa{YqCq=$oaCZOz diff --git a/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin b/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin index d8c8886e1bb151090fca578f75ba47ed6c30de99..65e1f5ddc8e8bf282a8f715e28371a528414925e 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6>;QpsejpT*Z=<#!kP90yxd{(+A9b8}Nn&FVtR%rr~0yaOcz zf4HKowS8d0=<8w=1?{EAH`wG zVL^*l1TlHJZZdG@<*hE|MNaRcWTI9^f0E^js~Q9%^89d)XtG7K30kj!W;w#PVkkF& z!%6O!1*fg~QB~4`-~Qw13yBROuzN!{UIc}vOeCm#=Ge@bzH2X0sqK)F~CSy_wp-QctJc8aytg!0+RYsKc)2UZ@|t&i_5!wtcUHl7!{KI0wD~O G;RhUw43l>N delta 308 zcmV-40n7gV5B(3YoC6?Z!~?K&0|MlC-g@m`-0evkfr>E7Oz$i;x3lv6>KLlokuxc<8D+4tjZ}XIajcE2 z7X!8`7mp)On+?&KTH%qAF|kxC+m9hAM{GZ%7jJ3jT8F@a=Tb5k8q1JbPZ^`8=05sp zckKy+a)MlEb+RBMX>8q870rVbUI1L{e=QT}rAiOtRJa=QD*~ ztGsN9@q!w|05fZZpGxSRKz>Ia+{0TuLAbpcMz|Y`5b+xN8&4zNq2jVoOsDc@fse-q zE$D|IN|BuqRFDKM!mbK8Bo~0tq5m}0w4SRwm$Sy`F$wO8?my0js4fX`bmhcuoHS!ob|2=dbv0Z#Qst!|B^jl)GIN?gq2sCC6hFrz__^m; zz#faZ$T{_S2Sub(OVt;!;>0_}QL$Siq7ve}mc`>oe2l4&uEr_GH`^FlaqnGVz|;7PB*fw+A6sLvAz*+?NVQ-ZDgn0AF~0=f;8 G;RhU0+?UP( delta 308 zcmV-40n7gV5B(3YoC6?yFvd*G@relAdT!CT+1%qbnDe_nsEcNYIZ4a_;sG3LQ|*#{ZdrET^ly zE3|U?XW3gC-i}j)lYI|EtFe19uR6o#?v)D<84Gn2u_P`L(3u40a4JXkf&?~CpX}9W diff --git a/test_fixtures/masp_proofs/3FDD781F73CEEE5426EF9EF03811DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin b/test_fixtures/masp_proofs/3FDD781F73CEEE5426EF9EF03811DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin index e8ab8308e6785f1e2176a757d430ffa33eae0cc9..1452014ada1d9bd81330bd33b55f9682c76f18c4 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6>wPmk5Wk9Vg9XmE^(nEx@89nDWOl{L=DWOhupOatz-yaOcz ze~=!BwCMoXa)b0m?I<2mo6vWq>%SVNn7(t(LU1!9Y>;FF?-yQD5rX@z2Eel@#j?(u z7vudCf}9D!DlnO(X$k%bTlurn(++q?aL2OKTPC60!dtaPu{LS*u}xVK0v1Dk7xCXv zDQmg9^aO6DU`p<*mbfsOy-pi}@e`6nf83m3+jn~WZ@4iw81Wv7@71x{-q>}>RlTKw ziyNJCw0a}-3LJz{L1NjAA}Y+LC^nIhQ%@Zkf;AaGbn3H#Q{GL^18DI|0kFJWM-~?p zWe)1=`{X7Rs5%u`AaH#PmB-&-SDmc%2}!J G;RhTgl9P!5 delta 308 zcmV-40n7gV5B(3YoC6@*-NJ-I_?r@rsPcWYh+490whEQB8DdBAF!FVOZ)G^MyaOcz ze~hQ~)?hd9&y>swYOTE2?XV+oh!Asd>l8nJI#qs%MqJjV^ zgs|54mE(f&sM;B9zh_hQs#)YiW=pYK8JCH5z0rcNSOn%H_)of9^fp@2fCNT8GvleR z4fh}c;A4z>_SeZYrdxes!a@f7ZkdsQf9i5~mD2DWN}GkY`S6SdL;;hez^*L0MtZ4G zR3rX<)?}YOW%UZ*cpjgixI_Y${WVlFAcP7GVNR3K`d>KQE%AfW)`qUuREa`OtS8

(S0rtzi?H5_-n*yat|F)jF=Y&YcHWSGHuOv@883mX` zxdK^KUDc6cC2o=KJMDKS)vQ_}{O@elSP;WCX_Y~VD~3)u)tvNYK6DXoW$mwe6g`3- z>NWuF99qDk>V@!aOjA@CUL^6{k?*r68I=N2F2{G`yM)T!Zq*S14&L*a+_u0N(<%=U zB4zL`-~K5(i&A<1+B8v$|Ivx6Bkl5@+ESXWd4Y z-D0RLt^gi*FMwL3Tq|}4ENc{zdbkyBQJTCRfmS9u5|avOSgKKVEl+Iwdn+KTN4 z@CEemZs%A5>Qv(%`$2jMmcCmbtLQS%Da28+JVPT~226!}$q*B1Q=6UM%c%49wa93R zmoQN>@(roce@_Ir5ou~__grDmN8joZODf)Ef$WEw{exbv40ZD$gEIVE2y(7$O-rTR zumuEO59M%-zOCu?vIEh?4S#dv70lor7vW~s>RAb!* zgUCWAA(1?~nJ5El#|M4Cc>`xoW@z%~+3~egSNq)dTg7R1hal293B8j)sbc`&v?ndP zCp0tBf-AzFS^s0D>>oBZrLTdlu(1$)u!;GW)?6i$?Eq~GuBPTx`mckEk3hY$=E$Y*mkIj9Kx@8H*D5|+(kC`f}jJLrt1*CrLr z1i#5t$x!{&)A6!LQ|9aOkgfc5z#bTzKN%Jke*#pmCn=+G46L(L?J|)QWnlgGR;v~_ zH+p(FiMVG;8L_)IZI!V=(LPnComH2;vFjfvAJnwJ(DiF}?DV<4IvD^I%>I7l$)jm? znG>6#`{3ZQV&FU8Af70*-IFvE+IgtHwp17?Idzw23L@ih-)*Kb`&FIaik6E%I7_;i ze^~nqtCqmu+(pbt;n>5cNxz3+?*A9I-bqD7Q4p9yim@bFtpSe{p3cC0sh+`XuPX5< zID1|&zTFKTq%av>0Bbv~_m@_-Ju}<|KSX?*RTlH>D9m4k#k_S^qBz?d(xcc>WIENy zis_f~2-QOL)vH?uqc^a*K}=|p&kjb2e@<@%{mMBmCi5v|RXnDzfC&XtIt6?MILRPt zu5wG?^Fdlx__ss}29_y#by%+X$(97gm6w&*z>R4ii}_@uN06hb#?8)+j?@g172w36 zeYA;bX~E|;ucXIZ$r?|_yYU YdRTd99cdkp9@!N`$pqB|1e1&)Jk?^*)&Kwi delta 1470 zcmV;v1ws1ALC8U{K@}h&7yv^{v<0aFc!VU0mo$v=?5#|w8h7hVHH7P zt~&S$fuEp%7s`WcW>BdM=Hpk*H8RTi_5jIUdFdpS=H){nEnNEO zm#Cx}p4?^R7&9^j0-wCRXYi8$YjW3N#mjtB6)!EWc}~G^DXXXI{o-1v+p_}}qym4H zqf%U4=<{6u?JOn5DG*dB53ZHJ18q!7#9v57k;V@!aOjA@CUL^6{k?*r68I=N2=K@nTpM(4|`*#Yn3jFbQYDwr%Kr3F@ zw6+i$Nl4|cXA%DFEY%eLE?%S+ejQi>O~oZzXs#nk)mbqFqx4a-WH)JF1USGv~ zoz(Rg0FegeSe_GrSwBCIs;R03Nno+(q0cgOZT9FVA}bz zWiQ>Ss1hXnRBs!>Q7!WnNYgcIj0S2kD0H=|p$zfZa(G0Af2dnKx$@6Y;s&&qI$Pb+ z3bUAoOC-^kiMLgTOTRa-y$@E-%?`VniSrv~+i+Wq)xUM*9wFlfR1`ViZOxP*QA^#SiRveZdB7{xNId#a}Y z;%6WSue5ZrWsNxa8L@g@td$1N8@pe5cE1}w0C@MNbO26o7Lr`bev4H5l8nhk!&4gs&I}OOC;tYn=0bsISBo`G~|Zu;u@Ph$cA`VM{knF>8R#7fg#2Y#b7(wP`_;K z6J*fLo@UadiEs-lT4&(rIz}Fi@nkIg<}FVKe;OA3kbb1=__!`!upV&(h+3Gt?K{EE z8Aj$BJ%t2wwt;2(+@M82qJW_ht3gn2gf3nmE9J4>T~7_3dlo0`BEN!%_aV^X@gZ4@ z)F?kd0_`|zh}a6EPM}~RWUo5r-B+y6c})&*rZKe!KwV~Xwm}*?Od!j24@aQn+`zj< zf7g4&WhT9|3GS0xb#T%3BJ#I>JAaOoKqs>|%OdZc@>}+4+VrF-^D&Y3)NzAzhvoY1 zS*_WM&2N`J(}0te5fTRVTEzH+?I9(In4h z_fB*_om})`d1Zv%7_!c?JQTW+g>c?1=99u?odpE-XXA3>Ho3rb{wye9+Z-~x>;tX) zd)GLrPXUr=w+Yyimyc(IYzz{xA`)Qo3~7tztSNd1+|nEk%p33Xj~_b(NlYavNG6k5 zEc}BQitzbseNSxz0L77a>fTqVFrfRK(mN4sABEZZm7i|3alAKfHX6_d@xa5>gDXp zsUc?>OgP-HJ>V4zeflkL!sKVh_mu=r

dX*f{S8ui4!4)x^5^;NS9$g@3bl6}B$- z+Sz|h=v)+s+S(;P=Rf-V^8RqvIhv3?O!fIXXE)hv?XJ#L@0(J?cub7T@I2GOxoj7{ zJzXtZ);;wb$l;@4#D)M9(C1w0%hi^Z{(lJy1W>AGBsO*8$WM$bJ%siOz5nssUEOBc znl%ikmcKR-o9Mtgol9G8uA^bWi57idDbWAk#@QL=ALx)O?tc@n+ zwR+U+$R1App`0Jy<6+2VuA`LyXVMD`S4PWIMW6m9`52sAg$*Y?q5pvzu)l zH|#mRLZ>7}e^;sg^C2s|YHzaFk6s{MN)0FJa5RSM|nZ=#g;&tjt6e9~uNKm)Ujjh!?X2-w( zYP@vAy^wZ?LZKs0o8|2mvp+woRdub1ZB2pVqYdAdP4{$5Q<}N^+fx6qBrzW?#+Ay6 zOE#ImHru%Q=jiS(ol|_@hV&6ooxg68)l#wiqvskTVDR$#qj`y71K{gpi!3tTt zbq_i|`tdZ}kv-5V%jRZaa(3qKmsPjjmanaxp3mF4c6!kJ->*EItM@YJPyF$=<$Y$m*_qlG|Jvi1;fX8F9QRo_J(#l3r9r_@ZuP2;=!bmw zmM=A56Y*9%Xjy-O$F2_wm)C^K{W`HPr<>VI#AUicWg`EbPiMZ|Ir%u-KS-jY)_r!{jR5REnen2xls^x@FPs)00cnq*RR! zFCE)1v~bm~nKt*HckR&432%uywEDBtqTZu>CvkA}EUTINI6HZD`%v@=Gcl)0^+uI!K{+z$nAND%kcwNCxF^BfmyBqSk?F3f@ zXLP#Oa~yPCQEqVQ+s}tGuV#ER$?4B*Ey2JUNnG}kxckBic;qqcQu zcc=vO(@9^l7iC4$et%E|8;{|55e8JN0q}!jdWgEQHCJ1z~jaG4WtG+HWYM+P#Gp^v zG^ZuPIUJ?FWxCD3};6yIL$+?zvM4<>$?9F-8bdxlq!$q<*p4e4|z z+0j`wUC52dq5eSL9p->f_nc|ReweAQf4(T#nl=Mb}4 zYO;c~3DBC0gED_I-{PX-_{z>3;fe9Aia1|MI95BI5LE_$y73|+Iim&i#yljEU0i24 z1Npm{QDIcUwSQCX0zMG5OrOfz=Ts8?-DJ0Ta^+4>zYdTw8p0-*qt G;RhTPZkSsD delta 308 zcmV-40n7gV5B(3YoC6>_a5&xShcZAG7{?G@rze<8@=ylf-y?}a;-qOIqiDLbyaOcz zf1oxWU69spiy3a}$PCljZIt6#x#fn)euKqF#`6d%GE`e`?)De7#vXgfDbaR{@VTa* z#Iq(^#323ZN?N?1k^1Fy*l`IK=J9v}2%6&=PLnraBy8QTJy`)^;mW-?;}C(Xor|>A z$MOdmJSUy(H9rXDkm?y!!*htylLhj$f7si`c2N9xErqQhbN}oFhtr_x$oS3E(=v#_ z2M~9%K53M#tzZIg?mqyNG$ABn4AumkzxOeJdYv^{HiVBgzKqcasN$2krhNP+7=RCv z_(Zn9d%s_-@FO%e4M{|F@&nwdBbYsePvqzX0qQ&$zfL3nd#RU1ODY;FC2wbZ0yzwm G;RhVMQkF0P diff --git a/test_fixtures/masp_proofs/7A240D86DB78C8E1478FB0857D16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin b/test_fixtures/masp_proofs/7A240D86DB78C8E1478FB0857D16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin index eee0b431bd420ac190dc7bc444ac766a53a17340..681b074d16b20282cfd7c46cdfd4ed9d05407bbf 100644 GIT binary patch delta 926 zcmV;P17ZB1CZ8s-UPbhLForR*-e?eZ9aG%RGkzaH~P#?+~B4l`1wp z0g(_Wk(~&W8xSCWvg)P|^v#TB6$I??$;AEiavu@y)kAYhn!&6{cdN~YR!|(|)AY=7 z(2mDKeiL5_t}_}o6xFU#$g(oc18#i}2Ei8Dmvmb)Cl?Mj80QXY9Z9V!?MIMAr+6B% zn}S@86YTwjivHP)s9RCGIOSr0KEA{lL(%d#Ypoij4gh?A1N-jZTp{j)4f)Z29Mw+P z`nPql50Rm?PeR=YbLow+F*pQ6qCh+u`KCMFo~2;cvRNjs)YZ#)9P9oefv6<)^cC0T zP`cGVcDsV3{~8jM|=a(ZuGAuiryrbNV(hTD-3Jr&08x`BU#A z`c?Qzzx=v?ZU?E)+%qMJx>A0bz%3`zlDTMkQIm$qaFl8}$t40C=XZXzP)|u&^`|<( zEr-><(6N≫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 SoQw&J1_20>^di5L%or``I564( delta 1152 zcmV-`1b_SaG5ImDG7cayadydQ7i4XPQ#3<%^$c6Q`sFQz9vvhw+bJ>@R#)#I z_uwDZOV78&Yy(%^0<+W(^a3Ddi%7+pVHxVh<`IdRlcfwi~Fk z=n

QS#%9Yu+?&i9r1KmnV0%XrA&uJuh4>(crO#U)i>_vahrmC54hj5AIX-QsToxP2OaYM)D3P5AlMNL>f46APfJ`8^ zH@~&izUK^NDX-TvVNQ6BkS42SjXbAi)V&(Xs~cO~81{&=aQ5D^vy_reV>jBn=WIf)I+tt z90U-H>gr@%fca2@E^9oW7gS8p9HX}Ave5Co*RBr#gybxbgCTt_%7g$fgR+|e=Z1*|HR=7uJEab|~PePH73 zc<1mtHQX~x=@AQae{{@H07_c^%c8n&{96l=Km9iygKmvI{n?7eD1zFl*P`1m$)rga znbf*cZVf&27imN`O(--jgD)no4dPWnK5_xn&)DzM7#U9tMA41nFBl zYD!i4)v4li!b)-kA=7J}Az8=mg9*iDjsyk;vkJJ9Ds(*Tf7ZCocQUABksxVWo}NEM zxF-|+td=^gKiie|XA;eU?EQYv(-T_ory7UZgtPUKH)eFvC!0Z5vRI${Sp>+IaGzid z=wPN|V9nz3ID;Q|VurF3a*Y!`^nW&%L4sL9MZhwo@0#pn7l`#k&?(3vv_044M-pSk zUfZF4B3xD&f12DxMeB?N`r7g~N8RQa?4u(xrpP9Uf66z>#PGLx7(_e8&Z+qWvJj}B zf2H~NK(VI}p@X`vv_`XG%r zEf`I5v32Qd8p$`Xl_S9KE_pzbTqMi8b+$W2pwwH@;`i9`0-zi}MFB+)Fw+PRX!`3) zpXOGtBt6T?BuvOjiEkFr|E7+v)+|XIS1%$-Zxu>Dit_1FYTW*{ZJBGw(9uj~&#^a~ zD{eEkvb4;q>#<*fdYip4e6P z)Fzysu%p`kzmhAT->~>FotaV

pF8G$Dsl5pJu+fk}lyknjwxG60-iT{zXPBhni2LmmIzKOpU^UkSk-3gu%Z zAC77Wz6rf|V+Kg$hyRY8p$-53Ya#EQbeUIYQqW*gM=lTs04zc;MqG9bQHRCusDg?| zJS-c&4-$NuI#}raxsb1YM*vijU$kKQ%kdtA?oEDlr&13Qty}my3jzcIG;;-W3oan) z#zMS%@1!w&btRiN{R; zLGo6SeqLp^65_~Ym!dY1EjAjKW9mNnQ$Q8FU1>zcO9FLi+dPrV(Bk#c=&p9tXvva` z*8_qSe?>q>@nkA_MsBlD0atv!h&pLX{YPe_;E@bSJ0;n5yDe=c_zm2k=9E~i5S%*MQ(lyg?tr%?ML)Y&#Okps1!I4}1Twa|zd?%nx- z32=JgG-gD%$oHMln};h87V3twIcZ?vRja3k>6i;M!ht9^hz&a;UhjI{@Zw#`8KK}( ziHM`FhOZvAS*c)uffbbK_IxYEnD#c^Q9LK48NPpDZ|qXz*TzgTy@ zv6}O9@^9CoeExOLRQ?%r%MsDCF+aRgW+(9(ut0zv!&61!iS??YnwRD~DLz{UIv8v@ z^pkCe&tf-B9EcKt8&;U&T+|~kUra4egl&6y(HgrG2}XZ1vs1l?#sIX5cn!BIBJ4%A zUrU7KdJk4_qn^G^rLmTtb0;hGE7J$W>;~*)lsASugQ$K~IF)#U=A3%fO{v~diQ}J!zCdWIP0@=Hfs}~*CQ@R(`oy`>* z=S^0%QV<-B_b0(*7~)f_&jF5!WdlcT8qIUJ_ssMor67-BZ6}ERnSkIZuuY0k;|C;5 zAa1ud8g_9_Q)yWI46%7B9~x4w7nW>zlljt)R&@cdI01@eE8X2GuERv&BM-|fST24SyM1{zl+Okd`=9#@a5I0%{~LWghyrF zGKWE%8DIz_(~&?cPh_(KmbqS0L9Y$bJ2IB_9Z)#Ulb!jju>r9{YMb(bre!8m2U?9Q z6_oEU3(t|pR(XnGU&Z%qWQ2g|SS)G!Xl_S62k#x-xGIuu#ChF>v>Y4Om*w6DEs_KT zFUIxRM_!VN2gJc`wgdzP%{qb^qXzD<%D-XR!`;*YK7%b~3k*_tW%Ia62_sI{7e+R3 z)4H$okJBWjIV11x1OGwTf715%8RNJ9@RFBqGAJ#op9{q9OZkU3p9Loo zQsU;j{(9nHYW+*Cf2sAqqL#s8mDmnxUXsFGKr?#(#{=Q553Na@;2UzP7shGidh&pB zjNrR{(#tV3VH_le1B+m?6vFGcgoKY9k=J`@OhXNv@C6Mhe4=H4T%`Fx?P&PnSAs#} z?{S&~vi63uZl~XwfILapEb_GYD%wK6fU2Kdg3#;v%{;z{?T^=tyFBW-P=F~;v)p*b z!Ma{~G$4^DPv`h0R z`#M-qIZL4bV4>Bf-=~nsfhgL+yB$Q-{+6UxDF`<@uyKBZL&SjfH&@X9Qq({7b+$#S z%xZIQ#kGb+g>HsCj0Q?fO6@ER@o`N7#^RIAQ?ruUeM(M_7cpo>e*&7cEa87g)`j=( z8e!DlXQBcBd+IvWO{=zY{pDN{}ktseckEr1pk%)pI_jQMg5Oqs1k8Mj@bhQH9Ye=19sVuq|DVPDchr(+|;i};6*&Wa2?By0t?GJHI;a-nk*-Z`Q^xeFT z$Y08?HXmSKL7LEd*t0rpV}m?n3Wy0-rsE=)rn9*qtR3EBlQ%N;9_|N_yJz&NUkkjM z6E)@HEu@I>Q6Dh9>SND#pVA**z<%{8hADPNp<8HcZrrh3-7V)Yi_Qua6 z>nqiitC(vaT)a;l+|0^N8xy-%8+y#+hTPQH49UF=gz43-qZb*GvaZqmtna>AKXT*# z6n*k^Bret_vp44A)A$#}%OkCJC+#b2rUG2ZUPd-f`pJU9idvd-Y440A8x)CT?9q33 zZ1rXj!z{;-E+b23n>aJ$VEG*N`U6^n7IM3+$afX{+@3P@^AnZI@On&lBj@YjHH_W@ z-!Z*9UX9Jg^L%J;v4LupQ27o2d)QDRBIRUKejq*q-4?wyO>3Q>A5qIj0IA`!a2PG3 z>6-G)sw92pW$ipHB2N_vrs#Aw*!VH%8?f)ib!AEMFg_2HZr%5}kmg>~AQ7X2w8J{A zQQo7iLgT{v(xEFtTJ3(w{E1wjcV|ouSJ0#P*n@#~D4+9hEg9e0_QTsWh~rSkp615d z?Rq!}CAT2nb3U!97OqccAiLD6OOrNJ9A1_`5Lfh}+s#ruML|^%AKRcHlO_ox8=QTZ z;vv>d-PG6!FV^p`lj03WFN72Aq>x`=W$oERs#WA-likimvg6;lD935;r4?7tLeWn! zS>Q4cT=n>0(CKXCmOsAiRB1r?naAQ%BrdEgC3>w97m5th{8)eO+v%TNSYw zGpDt;r-i=DPDde^@_`=TPnQimN)8MC2gAWhBZh2kJ$vjP$(92=jyxwVy1zjgsnY=FhUPg?!LzabNrmcqAdra1aRb?l8&)(l&Tl8?5Q z^ETu@&Y4OS*r7f3Ep~$B&+;eVB11&ijMpW+h4bni&r_8x?fprM3XWj(7F|;7-cQcT z3iaFdNIGTB@!o+bMf2ukFBMZ}8#Qyo#PYsZzY)U9M;{vOcY5HEK}oPm-Qxmv-19!s zC5sz;V}-sm_a@y#R;Td|aoVU7HA#{>*kRY#HSF6B%;Oe>&Dvg-C*av8J-hTUUSiiW zYl$s~OMXA|8ZuFNfdq_)H3x!Cv9IqaZ`i3faeI$l6?~1pQi$7^Jt~jxa^keCCsjNg zKEz3lGF z+R4&E;g}U<#eceOw37}M`Otl43LFAzkVGR{2g$gA`KZ+Eq;8L6W zc`;uDia1|}VOyiPWkwr$rfocuH>V4ZFl$J+8ss2lz4y~DfY34L#YZyc;6-N}>$PMs#ZKN6(T8S*cP=-1KWxeQubyUKA2`MPi~%blpjWelTZ2#lqpP z!HfN2QE#FRI_*{<#6#uvYqHec~f zy*7$`xTaUFpCO0xr^WZ5_T9~pFF9But=aV~?dWVHxaAHb{Ehp-c#>Ftmp(b+z3Lv- zyngv^Y78x9o{VPBR*`aU((y(ImAakNp$4U`1Q8DCj3;+95^uj+t9KRY=- zj;3j2S=|U`Di8^a3U}}=tU2}^!OO65Qu9N4khYMw7Q|Iy*rgwk=QddeT@?#TtJ50j zy?JWrpc!v(?NbwZTZGxX;=(xPZ8`f*AFiU=0okZHcziDg{)pk~z(RbW%VPx`lf_#X zvE>n)$LSTcz%>;+?f$IESPNMS)*9mP*p0l;61m03x!|mE>ITu4lAk*tq<%GA6U!B( zHL22uzbHa7@bpF~!9D=P8_uT&d#zsPh;9^G+BFL~l&i2eKr@vPz>8XzqwTdJz+{sT zZahxCvSd06xd+iNw4KQ`lJmk4$r|V-T8`qT6L4xjB+ScAQwE&$v>Bi$Hr%2qq~-aq z-)-A+i+ip}%{Z2$ghjBgZC2}{pe}wg0Jou@hYe06vDH2|gQfh5>u_zP4N6;PSm+2P zzsX2VCQ!tscP5D{|FE6uG+!g@yO+;Q>N*SrgD)kq{3M7@J^JA zZ%8usvGBJ830^i*jR%(01uc6dCOzLyV0M+bd=T3N5}xUtYP~J}`{o9BDbBCNdM#6l^#vho10t41V^bahVXL=cwBYVDF`Z)@|2}?KS;|%kw@|tgHzCUKMR)or%IG*TW-YblMp%>$$=PX5k*SOJ zB-ZDo!cyH;(%KJ2_u<#}S2tOcK+o)e_kQ-e8IvmJKewU(JpbxU|F*yH|K45x7d=7e A0{{R3 diff --git a/test_fixtures/masp_proofs/AF6B3A470013460A05E8A522EC0DF6893C1C09CF3101C402BFE1465005639F14.bin b/test_fixtures/masp_proofs/AF6B3A470013460A05E8A522EC0DF6893C1C09CF3101C402BFE1465005639F14.bin index 12a7af575f7c235afc7cb969b944424c5847ef04..6c9a57a93a2110f597d22a7b0e8fcab9cf665ba4 100644 GIT binary patch delta 2424 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 G;RhTSL7t2N diff --git a/test_fixtures/masp_proofs/B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin b/test_fixtures/masp_proofs/B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin index cd3c95a2647acf30e9011caf86a628b14ce33184..138e8d996a07283fffed194b5b0dcb7512f8a109 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6?DR@zybJ91ObN&+V?K@R#WHO#p2ML-*Q(`r+3T1aBEyaOcz zf35yQqOCSnK3$3urnqxF7S}odIm-1Zh~=`?uNt<8KgrnckM{Z2G3Hau;oRWSqp^b@ z)UYnko~2lq;>e%;gB=!qgC0oI+JJpKJCOu?ajReCFsE#}7(iH|1XkvG_6FDIC`Nqt z(=T*z)W>rC0Q%xtB34a80*i7InGS#|eF2Y8kY%!q_m*f3|vini>mCo>XwY`j2u$`yu7(ajTI0J>` zC4Y~dy3GmdbEcCNZy23JTo&w^RRB1t>G-GJRJ$7?t5`}nWUxaVO864%bl2F%0vZ65 G;RhT>%$Csr delta 308 zcmV-40n7gV5B(3YoC6?G(0l^CPUx^B3y4hi1#CNX^A!a8qNPnt1pDUb#4P8tyaOcz zf0FVHpK}=N>el;fqqv!REKAd3^Z##sW(AbK%}w?hi6HG&ReS
e8MPogxWikR)b zP1@OEN>7KK^|?SyhY%vT=T|!99ZDO$s0hM1ak+axjmE`$weM@X0)2xMu@Sr;D3uKQjOq!gbXridXdvdM-ej z_545^-A3LvC`ypbC||zh%%86C+Y=>(rz_Tip1V-&XseqhHB7PI>QcksdIsg30#OW; G;RhVGiI{o- diff --git a/test_fixtures/masp_proofs/BE09EB8FF98C0CAF7BA8278C4ADC5356710DE7B6F6FA2B23C19412005669DC2B.bin b/test_fixtures/masp_proofs/BE09EB8FF98C0CAF7BA8278C4ADC5356710DE7B6F6FA2B23C19412005669DC2B.bin index 68f0939fe65cd9aa9a56aa9e6da30d3ea4d16b21..4e2fd1fdb85c02983101721d3478f118928730eb 100644 GIT binary patch delta 1797 zcmV+g2m1K=PWeu-78oE@VpmmD#%EE4=WtoH#!k4mX?=GDUCjY{VLrhT%gjlWHW)!+ zd3fm48|O0);{Fi7&dzB&CV*~S2tsH^=BZ5t>*<3Xufy**@=FJ6>^i`a7{fO5cd4xX zDXM6wwDq28v@s@c1FT9Uji}Hvy{36pLatlA{)$jw?oUh_#LyjR7A~scDzn%aqym3$ z_zgXAzGqu(@n1i6fMUd1#JC_ro>K7z8;muZKSN*1%(A^S~;e+#4z zOk^XpVGxKlq0(@G{SFg%Ek(x{M7)Fk69_%BTr*nnmr9N5rWp1 zvGhD+h_etJPjzZ4hivzo(nkZq6Zr*lYG4&M%JCU^d_&H@spz!{z_~(^qd|*{=6Lh7 z49W5z%m zErsJf5&w8y3)bW1HJcD-G4Q}9v>wroR7s3zb!=hHCjW{pk zbEY7%z<@*rsDJ9uc%sK;IV5VgRog0R^|{;A+qTw;?w(GSvdOI1KyMHtd=JYMKjUoQ~o)by6IR)%_ z^_E(lBI!PwkR^{tRrR%#vU3P+>+3P<>6SBHgao7uJXUbs&KzlFZzwQ$L|s@q3a2*} zphH~FTRay{hAqYt;Jk(ov@cb8Ku~(G=SZP(a!fBx?QLBRHlGs-tRz;vt2plI{3ju^ zEg8*|DSt-K?$ec+AT?V9CYAN^H3=t718r{P+uoaVR1+!i%LTtel_UE*K`YOX1 z;+`f-;B)n)ABSezWpygY_5_}z2fq;V5W0v<;p_*0ih93)JL~Q*KxsrNP}y$-bs~nJ z2&bb9@(C7&wo(wE>|GG;AKvOfP0JymzKiVoCx3P+kHn0wlfG4FNUZcI#1vHvO8!^W zhAbJ=d}7=`WNgP4l`*p&SCFQ0pUDMpX$XCv+G66^>jW76=SjmK1w6&}u>T>@hCZ6k z$t19$LKkM*|KLXgUxjOCcq8*w14~3rJ+(`x!hHJ8GJ=6q+or7YlWcr?lqf2;l~Qw9 z%zu^N`5~?2ldw7KU+i4f;>enWXKdMq+-lvtW#S8nD4~78`;YN>vIBUxBvZS&7GdX% z=fwMgpNKa9&C_3rz9SbfuqYle3VpVY7o0DkSMqi-W{b`HRF&J}YzUa4y(-Eoh{7@R zZ(nkHbuttwXKjF-sjRVI7x{fi^p%;W0DrS1Qf|tfEF_~vs#R)SkH2mF%6Ar3Fnc(e zT&}E|^3l}yaM7PT@is8%r~7-Xf$h`syql1@#;%jlW0bhKBF}1b4x^K_?zc`@6s%8~ zksW&yw_HZXTM@rgj?fb@brw}&22wur1|b$IDMhgzg=G(z(~oH5rnOWL_-cE=&wr1! zwyq2VZr-qB7rkVgd09&yUJcH|^?B2#63>htnJ|OsQ6YB2?KmfAcyJ7fS>IcOPdB!r zEdTZKnyXF{wTI22q7cMMdpn?l8iGH|BnhII{9=SdKtlC_11lI~q5U@+&(N-oKBmKf nwD9^i?lxl7zVoQxJR@eG&QG$yBMMCybC!y_ea9&VlQkzqzuIxr delta 1797 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 c^%HW&woF&t`w$U~zRC&Lu9Juoq`Bx2-2^K+N z_oI!_LXcr~ zLa+Zwm)*KeDVMGg0uadM?U5eFJvYzK1#ib4ELKAU!j4&4l8?kbuT|`vo3pDHqym3Z zbh@lfRFvF<4$_rQRnhhdxo&#L3=+9hJN!D8_XDvbLoS!Tk376 zWim?_0g(_WlP?PhljIygf0jCXAE*IH=QWpGaA&84OqrJP{J*lT{Yn+^@{lgJBfEYN zrKRBe#u7b+>NyTbbAaMEvZwD&$bTvIuhW-@l#f~||4JBymb5g7$QX^%Zif?Kj2mQj z+){P2QnmzR1_Nt{MHL}yUID4eDU#rPsFlVF3KT_?j-Z2kiu|+5e{f_+z}0jYEG4A! zpiq%|;l`=BKd&JgRV9{g%_0*^Zd*FpA5LH_(x-iD(7~ZpmyDi*at|0LsiKGlZHOfT zDuk$$y}30mdoR4T9F+MmOd*qcPu5h639~uRI;HCBrRmZ+;~DdIl=D~|e-}F@mlgC% zvRgu_ip@BeM^78CepmrMC--n2c|$nF86B;aWsr%j{I^T?2?AsE8|ObGbcdk7*Y|a0 zb7XDviU2noLrra%0y<1_Lb5s!{2J+2_72gaqiN$Q*UXIr22YqBMdvVrR;QP@D}e4jw+Jo z4%QbUe*Svje*_nbx?DO}c5A=_m?ZLw7etOQ6ER@W;sr(U*IjkiZ?MJkT@L+kJ&68I z9%FFBP6L6dX5XXW6B!uDtz6Ft=NzV(#3K*4&RBIF8>Wdy;%ravJE;cd#Q`wvFONIq z{RL7@y}f2+pLH&?hgui(FKgTt?F9a+;)_dnd zFK}Jxcw8w3L^aNmH2?Fy-~$nmv08>DI#Qv(sZ-^qt)?!qPn#9W4JV9(I3IrJeGWW|gf1vo^$tFiEY_4~)t#*O^Zq>J zi!Hz8^cWn3F%3!y{YLN+)xlh}?}a5?k(`p4f6YE;)E+x8xJG5JGfpnH0jlzGRz0z4 zG#r*mr`eP^bK~F|R^JFJ2;kP493QJ!5=a>(x;=GDrvN7sxD#Ck4eBN{2{RqpR=dCj z%hwlc^2TF1wNN!?rfUof{GFF?x;?Kth-0)bXtIlko3zYIPi_+B>6&7(0TZK~*a85 c6f+kOkcHvpn*#!*Og_9bAA$O}0+VDRJZ46}ZvX%Q diff --git a/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin b/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin index e93c32f27b205b6a70b6bb18e558904a5260c1ef..d83c46f49a3012e806cd728ab439f1e89f51fff7 100644 GIT binary patch delta 308 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�ZuDgzrKaZ{pL@G86HcN5$0ee$ZQ-O!nb+KCNbPX@*n58H;HNbhqi%)^O z{a`9#J#tz;q73l57=8Xg!@v7~l9+-fSc)1F=hqIETZ5=e5E=q1q*8B2_X0+6B5@Ud z+<-@{kXMIdND`HOh*pF^QJkhM2PfAC#%;*7*FqP^T*G#SE@^#A|> diff --git a/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin b/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin index b15399485612fa5ac9e264f4eda3343154d362c2..a791a47beefaa553566f0b6b48f721e0862166ca 100644 GIT binary patch delta 926 zcmV;P17ZB1CZ8s-U_0l0t2T{xKhyr6s-8Fc zX9END?Qqu0zp2`^t=mj~>dqLBoe!*X8d~aXcL*)+Sz@)PW2(G+{HJMb8cpb zd$U(gQA2B9GFpbiO4OYs@c&>^eeu|kmeM-mrBdip)foET znGae;WB#tM9N(_96J^oPXdY7ZSqDY61-U3yhGA4`=B#&gWW4encY5DIv`}z{>~pZ z6}9vCK#if!6JB(?mFYXokI^p^SNHkEp4k3HtWd{xC$>lz>N6R>L>+m8yD&XJQ@Q{n zh*4N$kHo_esUD|DfsP|D)-THY(!NR9@ekg_wZv9&S0F4(GYod~L9y(;0h9X@Br$Kw A<^TWy delta 926 zcmV;P17ZB1CZ8s-U`@OT!UCpOksh4ULVwswqf-jXJLodbwe_gu(SaA3d_eUS}}crLzZ%?=-Ms_j*< z0g(_Wk(~&W8xSCWf(A!gOTBF1zR*dAL`W~d-)-eJ%xAym5>+f%5Y%_gsd_9P~lCB zyrn=>`JkwJWfCIkGYYZi_-q#P7d(AR9#ksCL>@jReFmvDOx9N)q4E9)9yUN~>FyeBMe6O&M>m4&#XQZycL ziyZu4BW6gC#VfoC>+!RMbrhPWuT1|$=bx7rN(OH2=j23V}NH|8!SMdh{JAqj#W?0B4_mp@tWtia%8aoHCd~w6$*PJCW4-vY$Q`G zlR3sk1g|!-bioIujW-?A5j%z$P{3I`9bs{6u~=jgY%KYf zA-VXVdXQWNpUzr2LbWO>=(e|H<>#+EGQTB70AT~Px z`eZm34>k-tilaS$aMMh`dO|@Yuq!V$<+YPj-!BMXtrdFRIWcJLu~2(d3X}U1Bo-jI AbN~PV diff --git a/test_fixtures/masp_proofs/D38C391DF4F1F69AB04682F0C1B78DD77AA5620AC08519F73AB740B5A44AFA65.bin b/test_fixtures/masp_proofs/D1F174D8596E8C1DA892DDC23D322056C14747EAC3FB1625F0A86957E00ED109.bin similarity index 57% rename from test_fixtures/masp_proofs/D38C391DF4F1F69AB04682F0C1B78DD77AA5620AC08519F73AB740B5A44AFA65.bin rename to test_fixtures/masp_proofs/D1F174D8596E8C1DA892DDC23D322056C14747EAC3FB1625F0A86957E00ED109.bin index 8d9b720476074e63e2b18bb5dd3684488b8ebb83..f459f6dea66ef36a1bf2917fa2d836e6c349aaf5 100644 GIT binary patch delta 1276 zcmV;M1%|NsC000000000000r}6Mwp6IB`L*<<%T+i%gUrK~O_Dm{ z_(_N`BXfW{P?0g>1cmdk!?PCwLj*%L`O#P_%ZwB|e~wvb>NGVqV!MJQiN*g0s@w)^ zS#(VxGFs|MWCRmgthUi#rz8lS*CZ->VX@iUP?$bIEr|aeAOVxH1|Iq|-MGtf_=ui^DC^Eo2fXw}jpH zUzUzav8;Zn8M6-zqym55Z*RKXfFSmm*@OOODvY|fL`NpdgYZP`m|i|a6D7RRGoezZ z|I}lg?yVE0L0z~MJxbwWH|nfbR0ZKftq?oeNzEaMy{PBh9|lS2F z_*-QpbT>ym;UR(C3_-6%8|YlzT(@xJGk^mECn_ehf(9AM(XT6vG*~Tz8U~qBTICi- zC)P~8cdWU8TTi+G`Ol!XRH&@^we+ORRX9C^%)^yUk~-n|Nr*5bbAW$3P=m?RYG9nf z0Q`OA{h50RFqjpAC)ha+)^EgGfy7**NUESC#WFSzP;|=jCoSRQkE@BfU8PpY-bS=H z_H$ORO~ycK9F8hPYd9ivt(Ht~i&)G=M3})AwV9kivnnjjZW+Bu5;xhuKaJt~r1*29 zJcP8^$r$FOPHI47yUc$~f7Xo`%JkK~xv()f%oI0u29>GWz|#o1m#B_lz4!R@gl^oS zr+!R-u4#z7=G3mEkoZG3A76!M0k-1jGLsY)%!z|rCF9K>*5b-~QuVO@$3d@35b+60 zp8ONRmjxb;(rB|xM1J_}9U8J==?)p1MChE#gT-;<>0(v0Cdq#`?R*QfcJ(l~6&baM zsTT55B@yNo84P^4>45HAC%Bg$jco28^e?WDsv@nuJ3-A2w|t+MMvBzTfqZh_v#RS8pTGg#FVn(&ur5-Qv5;PiPBsDE$?$*OD+gTU8bsd>x$6b%@X_6p zhP}080a4SFF*%24e=*fW0hL0u76`{@>N09W%$4O>z*|sh25nR7A&2CUTXiwPkalGQ z2b&Jtj-F0F5?6cu^vBl6mav*02#Y`a$b$QGY4P?a9=BWqUEH(x0%?bgNtpyvC6crG;c6Oiu delta 1273 zcmV;M1%|NsC000000000000bVL+vNa`$il{AQ(bAIB4oT*4?)MB} z6u|PBh4F407m+dI1WgNB$g>v#Lj*%-a{tn?g{sEU4ZtN)+1{RTl(kfjo)f4u+Kt3_ zp#mTvsNjCfJ->t{bHiwMbA~$N%Yu9Jk#B{A1Nq{MZTW~Bi)V!GQ_^PC~HT6&p`%@;J>UE_Kz>}^wlIa`I|DCWW& zCwhXmCub>jaISK*W?=a&y=(cqVc(kTQ&}#-VI!{vg8yk8=2lJNM5l2mJN3qmrv05 zluF`K{~41*4=n`K&wC25G5}sGXREB!WYN-+(+)}IaPIdEU=+aen1%6fe;OB~d=HRH zD^c%i)gyRlrzGMEAT7GJbkYcSGu*YpTy_aWRG>LNWss&28MYNR#6{ zNqs*Or&%i%O8fGL1V7Hzf4{W249d;vW4@#Zzx{1*3C(tDk}8#0ze6#S06ZZgE+0%T z5Sk5&HkAVVXyF(!z#B$Ubzo^xf;O8ZuwG;83DXcu*Yz> zzBCGIZWZZ_OH=Gn-7&nlqPYD(HwyVO-Udt51wM)xD*!7^8+kyhb1V_?4f9r@J+aU4l zISwP$HF!3g3Eo7{5+)P}{Ge3C&~p%fCK|1O^CF1N?-*#LPsZX8A^7+bqeH7jCRR66 zwL?SUNFOjqi?@Uf(NHvz1za5E;`|{z-e|1j~O!o%wZq&kYm#3&u zja*^|tOHa?UW1fe){tQi=mAT#rBYA^a{jjn1rLl-jf&6j`SJ6}^EV`1=VgMwA-{Pq z$l#1U8Suso{$%+#5YmCz+yJYgiyyhSuxPg->U7KI5sGEB_$BrciqtD?ijicG6+uB5 zD3AT-e+Gn=NBxEaBt$2}DAD01sYaxoh7N$dhfVe#r50$XaS+`vGOU=Kpa})9h~;^& jT6T|?R+V#HO2Z%poj*CjvYS&X&0dmR+E$WYu+3K4*fGjQA1F0nd$6zv)Ntc0I~98x5FG*A@B=VH5$ye-kl&G2}i%N2yUq7*h3e>r9v>j~a{- zWvv9`Kv4-C$YvM0%=}#?G$X}27v3&?e!`q`_BP0Sa`Xqx#JYb#{ud0f>AI}EEU@QB znlPWHC4BeP+W^a~qLbXs(%mJz&H)FNk48%ZL?1TWcZyy-fe8bs+-7x^y+JyhS+zTp ze_IH&H(>EK!A|4?u4&u_Sh9Pw(nrfFpCh5jyrIms?zuE-#--)Q0qZEZ52k--U{}zB zbGY?>Q>3fi38)A|!h|pTFCxL``d}4Z+|Q}%fWNjsw33=QgW|B;Qu60Qe*r&sjKaK*m}cXYU)3e-BH?fz zhBEi)SvzU#E05Ds^edDH@`WsfXWWFCMw)(1|E@`Jhyt_k=l2`=CIpis5+vG?zZn1k delta 919 zcmV;I18DrmB*!GMxCkItk<(;^i}0EEjO@w}6_k!LuH<%QD9MYQWp5XLt>p^Ln%%M;tCRzN8 z)A*^kkY^GJoq?er69`TNeIT<=45R{4D`h)nrerYQUCus4ozCm>0$Ee8=lL=CXfkQf z-2hmxIVP;uEV=*ZGI>`!TJsT-XN#%pf{OU;%mwv0NwF}Y*$k8g^;D{_5!43_95IIa z0FebnQ%4H&(b+I7&S1 zP8Z(DwqhPCW0_$NkCH4uS)YC6be16x4;bsqW&sdx;fPo+%Fj{nPJktS^gMmo957D3 zK#=LQ@s5TbW+JzQ39_=sI6U6Gjz@^IgvBqp3}Sh^5vr%L0$6^O(8x)nh%nCijSLq* ze^UjZF#?37Hn*HZS2bn|XEvv9=@BJOa$(=L0Nsf$1B&F*_j}?eXRG@*V6I?XWvddm zN%1g_gk&O5+CSkiWXzA2c|zMj-kQVMc$UyuND2+k&=#O|`9BQKW#UZIt19jiO9jB~ zAi`5nm*W-g^SSML}0$YoC=@bpif5H?JAsNv6o(fF|I_oU-F=|4%sjT5E80Q^g z0%_)#Ipb^2q7iecZ)8O91xRQJrx_@Bh4iYbxyVA{Q`Y`Jk)4VzWWG?^8dedF>2J z!=XeNR4sBd5s(0mU)V7*KK|hd#LB%f$0UCGZ;glk6iU_5e#635C+Z?!L=D62;WN!~ z(dZw*-!YCJ{%7(Bgy0EO%c3R|Z%s`dLq t;1lRMN%Hb^X4$wwUIpi7ecAJ1qZx|{gB~UUEd*q787rjJ)v!NB01Amxo)qk1h@X^<) zEFGRqP=jkG1qllS=_{TH_(siW-P=ZdFx zp71t3XfBwX#(1(7U9j)a3_W>WBIH_OzfvVHIru$Fhf5DMyH8Wb(#lG@{1gM%pQ3az zwY;3hWZ%J8y}a)zSbvNuek4M<3ihrC>CuWm;I`t5!Qs=k;U!?PDoOcFOnYD+?eV%A z`aW`|8?pC`jM8_u^jp*ko(8NfWUjom4@l^_nMNP(t$2od4<~km?iOo~U-+X_&KDVG zh=&~xn$Jp zU9K*8P~ilPSiBV3f{kP0i$W`jN(>XNy^MN~s?{rzCOji^EG?Tf>|bAD38;r=Hlk(M zVy9s<0*CRAd4DK2S79c)=n`3lzcF!;$UK?b)YO%%Gn`2~PZDtT!z_+CLS0^uBKfjC z8HEQY=U&^VMnoqh`wx?XB=1?*A`U^occhJEy^gx#NT?L?mEA`<;s4x_|zt?FEM%E7noF4#m%abmAM5 z0BxMz=>F+UGV4(FTL`H+w1-(7a!Q-jhk$nk&py9um?DI0zh?N0`LIARr{+2krM8=u zg)F1@T!nbG?jp~&aC?fzrhx^tMxkGcf$Cx=up#5|3 zy?k);R)5IHH>Dzd6mxS%=$azk2$cUuSl3^#DGS$|-h8#S$QQA_vYkwMRlMB*k+6QO%1 z_n&~BO}!g>L{)sgrEvs%3Vo!pID-3EifWW3|0?VOaUARiEooa^h#gxF5%m-%kK;ll zRVd9+x$pfOp?E^UtFQ=@{Y9TGP_p)DxvIFNJc4f{f}e^jcW0ve)(^#fZS~*ZPKDFe z$$t=%-mU_-z>WKiv_S%zmY6duHuF6P@+DsZmgkJiEYi_nc}CwE);&2)bKdB(P^jh4 z?d&88`MDfbgl1NkgGCLjKd^By=q3G20}&aJ2Tch5?;__TSp_qo@%qAG7f_bB`<_-X znoY`LZ6VH_yY>!w-B^qU&BuS@0P>MlH|nUPs)p1^3u)n^6AA6> OWmpyg*uMdjwjC_RgPFMi delta 1356 zcmV-S1+)6%JK{UAixD6R3y5gsd}nTbZ_S430zz#Kh4=uw2q}(k;?R}_bK%94s}VpT z2r1v2Zm`hdNDiXqaXoBdGQwF);UQgZDPzN>nLQw1lM50-LFm92qfZT%_1{`wOJIVR z0n(?2i9{}=Vb4Cqz^t-tFajVecp12$A|I48g~4JB{ z81Ac~<_xgrx}hf9(|?wA;uiFO_pgt|2-O1@Coa5&Ko9fB!V8ZEVuo5>TnWa0cFk#l zs9Jmu>qN~e7`OE;RHAk#^T`Q`teWSc9Oz}Y;<)2e5|BIt`8cFb$qESK3Un9p>_GCJ z&CD01O#FS-mb>nm1BGo|k3|ba-Avt=Jy#%~tHt`kdq;NY6o0B5nbr@ZYvX1d!Wftb z*O>qzba(io3u!HRp`>~_G?`!>3o4b-MEW;a_?ufMq<;_$e~M!KG0Lw#>MHDB=iJ`D>l6l=QFpE|M`b3`{Yo?>i*e(cXVpc# z6D5-#fMeN)5W@QhX7|rs{scbVDucqF3PZ``mUwSzGUbU`L3gemlLtbe;(G+FcR?xi z#=(Hl@AgJ16$xqTI4$gbLr@|vPiZUu~4duGBgaQvKyv-Gw? z(<~kDnbr41!PMYtC1T5)c716_}Q4lHb=L zU!N8II)C%8i?bF~(5r?LAng+JoCwiXe^|w;DD3;u&3ZwXD# zB_v%-M^s)CNx@^DQT!Ra?{UGd=fGkOoEcXmTz_7QmLBv^Zt&})RqDDmEuBb(iqL3F z3yms_NYGk2 z3-Jlt_A>mfzUL5&v-5)_%dBTiSYyF_!B^4!|Nr%vw}=A1Yzpq+LD&^$P{QdCbgG!E ztbY<^`al>R7L`^RDX53O;AjZi1}^pR4DKB^3$Fp7r!>dpVgg^hQQMKm{PnUv++7aQ z>vnzdfwK~KPaMBIC(to(l|w}Cacbl*&TqJ1n9MSP_CruC{RG@8Zp^mh>d44CH5O8C zfDUR5--t{6U}Q*f57IT0o9z z+Md>g0lsHmeJFbIOCcJNJ!?F^e`Cv^8LfJm7IO!_zYH4e`R^Q{dK+qaZ#ALwTX?m) z@GdbHd5YJWI1BFK5D3~)trMIe>NcqS2qB=>C89@^OMfi)_3|-;_@x13(-=?XPYGAk O!%QF3n2HCJwjC^6F_``U diff --git a/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin b/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin index e4c74d543d00eb21d287b880c50454a6ed12b9fc..ee5646add2fef586edea8b836a6b5843838d51f1 100644 GIT binary patch delta 1061 zcmV+=1ls$YESxN`T?-)Aak08o`{Z+(e3>Sm&yv6tHhVzI0xZHU-Q>=3DoGqgs;f)Pw*h{F zkqsgVMYemZ-EL}|S+oBO^a3E%JvxDF-{QVHA#GuccWX;q5ZvkCyr35eimqvlw>O)! z6Axtrf3=)0n{QyS7k`6wW84|o04O#asyiTv zz>_3*e~s~yRpD0ZvqKy`rE+EGSkpTz5*(CLF5Q0znMJj=vW@x?sL%2qqCkA$eirFP z*$eBbHu%5?qKsL(5o*iV+hGTtcKLo;--jw>e-R*Qpv=>|dF$1s&a}8(!>gG5_>5n5 zva$d%SVwE2$c!r{7Fa58D}Y#NuSZ0D#&m%l$`Q5%0~j$Ju)^D97~ zAMc)3l5e0U?;bm{J9@)JA~K)d)H>Ezdz%#T0Ct_Bo8j)JU%fj*9ke9pgnGvrFr>fh zf3EBj}NEVB`{y@WW9&-v>oJ6i3LhwF{ zpK+7Hx7*9!I*KvXL@&^LOz;|t{fiBy2rM(u!<481)nQd=jJ0z}gNq3ZkTf z{^)CO&R*;m=QM9jBmZd+H&(al`oN#j|(@2o|W7VY3Hi1#F+!bkqVE+!0zoq71+Q8yxRz?0u80Q0qc&s!oXe|1s+rab}s{U>xw^72cu-`z}V&ullT=RNFfv7 delta 1061 zcmV+=1ls$YESxN`T?-&XA!(B>$Dl@Z{};Fx%L~z$b}L2j$J*fjfE6xX>}L^^eG5TB z-AMv&%S8Rm0gxWOsae+%3f|#I7D5i!>j9t`)8JFr!= z6Axtrf3(m)v~={nwAtM~H!8xL5&i6elMJ`43UPsy8}+Cts`8r5<+=qzmu%;Z#+4u+b})S9n|^{k)$W`&GMg zU6rcB`5RqGI^f0X29vLy9!8Khwm?4b5saUJr}bV3UHcd`VVgukp~Q1amllpu`UibY zf20Jr(PiTxZ2}@79zK`N3wjifPBynfDiNfN;Wig2d~9VoKcHC%t{j&GieS1=-f{h< zv>*nrMF==3Ezl}e$+0v5Hn{pDuX$KD4Ax;u3~Y1$e(U*njn6=~9@ZjV>Ff1Ob-j)=gEsd77Vsi1^}%hLbjm#tdE9TLLu z9?TPW>|;H%_5V}yKK-_LYiJ}Gi3S!}Zn5Dr(;bl_b3Ria4S(MQiFb zU)_sL@9_}Hh9Xj?-Mg<{2xM+fo-`q%I1bAMr^)fxm>Ajlvn2o);xgYbZcwL&e{b9Z zmxoB;vEy>Z(2xK@4lsfj+ot~wqcP@w7J}xjA~bu(9Taj$^-I!s&Zm-I%C0+0#w@jr zet>}-=4%8WRCM)G`cyN4tQTF(A&tu>5KBip_JJaaQ`9bX-r2rtobNoWt#P(iB70#J zE_bzR^nj#V*m-G8Oz~p&J2$~}e>Lda@lJ|76FI5zB&$pW$j~yhbf5Q_m{JMtPThDJ z4bH2r+)+-i^-|jfIb6ES^iv0qcs`|G2+?smmKwmVP(@S~s^+1hcq0d7K8wVYekW3l zL1I<9mJ8K&7EIR^sL{7O0iYM8RRD7JVav-G#SfytWn0JPmgWf|UX-35f1jF5g3*P{ zk-SPXp!zTqQd;NswPVb(n(vLNyHo77P?)wAl_k@O*@Bi{((iGwBfa f9)bK-eD0S6FV#8UT=Bmc2PIl#s5Qk4llT=R25JLA diff --git a/test_fixtures/masp_proofs/F4F0D829373DDA78336CF39EBA3356453E412F862D949ABE9671C24A3903909E.bin b/test_fixtures/masp_proofs/F4F0D829373DDA78336CF39EBA3356453E412F862D949ABE9671C24A3903909E.bin index 7473a8c1f03c7e9b635176336a99c09025f7d78e..77bf2689797d5f9eb972b0faae98d212fc3ae8b4 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6>Qfr!<^nw&f+n`iI~A2z9{rrrT@b0=J73Bf@=CYcGdyaOcz ze~V%fK;iuJS}3GkG5LM9l$HrrS;mM@WW?GCDz!`d5m4A7*{%#NT|nS`K| za7{2>C%9{U^>Hiwn3vd&qjOeJJxm2*<-}-yd96mnDawB7C5SFi)vW3nKn-OJ4ffY@ zh7LZDufU6q*&L<@lpZ<4+TEX&M}gu`e;84&$;hHio14BdvxNmrZY!gxudzyAP7HCe zyOHuG!m^R?Z~~k+!(>xm1TFg$cK>$dA+Fz_&GvY756!A+Q}w!n2Hm-Lvj5^miL54W z?d~7S(F@~hY;|o#(MuBdIZ@}k=5)tEsWZv|4ai$)iJ0(E-pi4^0&PF-d~QEFC4eQ#?1kRlMY$H}}BTp`Bc_yaOcz ze}F&)Di0{7^NdqIB0Qa+$u5X`kOE112(&0Aiu*97prYo03RayF$3EJ$B^!d zy%1;UYpVt zuyBo)aGNdpvvO#@tz+-8xxERh!6z4Ef1KN7q?qOdafYrle-qhca;$)t-U8mfpwe5x zs|lc<>=1%UuyuMG#taRv1Y?})O0x&^3Wx8HRdtf=f#mgA6q8OY^jdh%h+&StmE}S! z1<>Xc2#|>ovQ4XWDQpzq`R6G=KlQi!WUojN>e+3ycpHdYaOIi$45eZJoQ+W(0wfEQ G;RhTv_m?98 diff --git a/test_fixtures/masp_proofs/F7D91D1E43AA598631284A69E9861C7F98EA4325D94989648024831E350D8F98.bin b/test_fixtures/masp_proofs/F7D91D1E43AA598631284A69E9861C7F98EA4325D94989648024831E350D8F98.bin index 38ecef6e7bb35b24fd680fa427af6c0e3c32e422..1982839e223dece5cdd16786e2b77ff3befc8dc0 100644 GIT binary patch delta 307 zcmV-30nGmW5B(3YoC6@w%3jtMFDQC88hM@1wn(cRGy(958aP1Z;9;hC^T@KZyaOcz zf1#i4djSubhcR{62-%OlN13>ngBvJ+Eybn|;f$;fPZfj2x<2!eb#ZOTR&ywCZI)(~ zvJNPLDH~faSNX8Tb7U8+K9i8;%^gA|$ZDUaU!PZ(zby>f3((n#f)v?Ff0@sj zi}~T&r3c197_K%Hr4AKaBC+KBM5MDmf6Npfh;;xvnYdG(-oPq8P@R~_%h)#3u=hQzSz?jLAJl?Ez)|enb0PB1h za{yZZ3=0JNmOR+kr=|S{v0eOp^Wj$0lOR91w~s19B{@joPW3rre(~S-KR<;40i%=P F2OS-hlcE3s delta 307 zcmV-30nGmW5B(3YoC6?c(L4#`-92hOWiD7CCnbt0ktjZo5O1ILe|#i}vKr8{yaOcz zf0DI!0jFn})*yZhQ~x2~m_H|42$cfX=21msp@bj3$ubnQRY7v(os8bXsQq8SNR(T+ z4t|xfgc0lUhMs!8jWMXT60iDLR`?&&uj+`30nFS{!W8e_ao4tT!eGMx0b{O7MJ=f!#};L~hWqfh zDMH2X2Z32V6n0zb;>QL^d+3)|sEymX-dl7iLy+<@1G&wq;4+o9-a7&ck~sIrYpl0_ zsbs^~+&6{}npadVWdQsbA=p}?9iE+_lqY4PP}^gaaue4HivhqZN32GM>A*mX0b-Nj F2OY3mky!u$ From 9ada91a4370168771608bae518840f97e921b295 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 6 Feb 2024 17:17:22 +0100 Subject: [PATCH 11/15] Updates masp proofs --- ...503B92F698545B3FF57B2A849B891CD946CECC.bin | Bin 0 -> 2045 bytes ...582DAD9FBD3ACA2E0F8314642810FC958594E7.bin | Bin 10105 -> 10105 bytes ...D4D70154B89179E7DA6F14C700AAE1EC531E80.bin | Bin 2045 -> 2045 bytes ...8541CA9141D136D623086EF07F5350415C7C40.bin | Bin 0 -> 2045 bytes ...C971DEDB27EBF9B4B1E31F2C57AD7F809DDE25.bin | Bin 0 -> 6393 bytes ...FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin | Bin 2045 -> 2045 bytes ...11DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin | Bin 2045 -> 2045 bytes ...F59077CA8F2E0C07061A81B524BD6EAE7983F1.bin | Bin 0 -> 6910 bytes ...DB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin | Bin 8392 -> 8392 bytes ...753FB3BE606A5729D43A6EA8F79007D34F6C60.bin | Bin 2045 -> 2045 bytes ...0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin | Bin 2045 -> 2045 bytes ...16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin | Bin 4895 -> 0 bytes ...553D0206DBD813B523E5124BDAFC020D0CD99E.bin | Bin 0 -> 2045 bytes ...ED7D14A1C9181B0D631419A25C9CA75656C6CC.bin | Bin 0 -> 6910 bytes ...0DF6893C1C09CF3101C402BFE1465005639F14.bin | Bin 14387 -> 14387 bytes ...83E61BED82F25C4452CA41B769C3BABEB62D2B.bin | Bin 2045 -> 2045 bytes ...BCDE7BBA8F874A528B460D7DDD1733AD7DFBB0.bin | Bin 0 -> 6910 bytes ...539F2B52F796F6FF426B440F00D123BFBE8DF0.bin | Bin 0 -> 6910 bytes ...DC5356710DE7B6F6FA2B23C19412005669DC2B.bin | Bin 10105 -> 10105 bytes ...9384EF0421F46F7732EE62196DEB73ECB4C225.bin | Bin 8608 -> 8608 bytes ...2A4E4AA763188BD9D5DDAC6E217228B95AD57F.bin | Bin 0 -> 2045 bytes ...1E2DCE33145F68A217FD50B065966646F59116.bin | Bin 2045 -> 2045 bytes ...9DCB2BCD3ED17F93A016CE1CDE5ECB8486AA7.bin} | Bin 6393 -> 6393 bytes ...9AFB3B6AE2AA3ADCACF75E6520A66B2F7D184C.bin | Bin 7875 -> 7875 bytes ...A81A7DF315190329C7C2F708876D51F60D2D60.bin | Bin 4895 -> 4895 bytes ...322056C14747EAC3FB1625F0A86957E00ED109.bin | Bin 5412 -> 0 bytes ...9BC3BBACE79DF98801EB8154EA1904597854A1.bin | Bin 4679 -> 4679 bytes ...EF52D368B771AD525817E722EA3E12B0A96971.bin | Bin 7650 -> 7650 bytes ...F7858007C4DA521F8E3BF250A46E9342178EEB.bin | Bin 5660 -> 5660 bytes ...3356453E412F862D949ABE9671C24A3903909E.bin | Bin 2045 -> 2045 bytes ...861C7F98EA4325D94989648024831E350D8F98.bin | Bin 2045 -> 2045 bytes ...F77D3447A5965177C6D9C605886B0A08995DB.bin} | Bin 2045 -> 2045 bytes 32 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test_fixtures/masp_proofs/08703E9A7AE69CFFFDEAD8AE16503B92F698545B3FF57B2A849B891CD946CECC.bin create mode 100644 test_fixtures/masp_proofs/32D7D6A62781D64DCE2EF422788541CA9141D136D623086EF07F5350415C7C40.bin create mode 100644 test_fixtures/masp_proofs/3C132DF87FCD169E86C1F590E7C971DEDB27EBF9B4B1E31F2C57AD7F809DDE25.bin create mode 100644 test_fixtures/masp_proofs/493CCE9EF30CBA192D49EE26A1F59077CA8F2E0C07061A81B524BD6EAE7983F1.bin delete mode 100644 test_fixtures/masp_proofs/7A240D86DB78C8E1478FB0857D16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin create mode 100644 test_fixtures/masp_proofs/8FA9019476ABDD31BC3597C205553D0206DBD813B523E5124BDAFC020D0CD99E.bin create mode 100644 test_fixtures/masp_proofs/AC96BF36E1775448D1058D650EED7D14A1C9181B0D631419A25C9CA75656C6CC.bin create mode 100644 test_fixtures/masp_proofs/B7F07D43391B6255171E6853C3BCDE7BBA8F874A528B460D7DDD1733AD7DFBB0.bin create mode 100644 test_fixtures/masp_proofs/B8503C92DD36305EF8DD554EDE539F2B52F796F6FF426B440F00D123BFBE8DF0.bin create mode 100644 test_fixtures/masp_proofs/C5EF7E4D76C16E75B400531D982A4E4AA763188BD9D5DDAC6E217228B95AD57F.bin rename test_fixtures/masp_proofs/{849D9E73D858B17BBB5856FAC2DBE3DA9201B7C90E74A7B6C2B9B7320F006872.bin => CCACA07DFF71672EBE48AAD84DB9DCB2BCD3ED17F93A016CE1CDE5ECB8486AA7.bin} (57%) delete mode 100644 test_fixtures/masp_proofs/D1F174D8596E8C1DA892DDC23D322056C14747EAC3FB1625F0A86957E00ED109.bin rename test_fixtures/masp_proofs/{B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin => FDEF024F9FDF73B50BD5C98F056F77D3447A5965177C6D9C605886B0A08995DB.bin} (62%) diff --git a/test_fixtures/masp_proofs/08703E9A7AE69CFFFDEAD8AE16503B92F698545B3FF57B2A849B891CD946CECC.bin b/test_fixtures/masp_proofs/08703E9A7AE69CFFFDEAD8AE16503B92F698545B3FF57B2A849B891CD946CECC.bin new file mode 100644 index 0000000000000000000000000000000000000000..9b887cadb56a521848ad626863676cce09aa150e GIT binary patch literal 2045 zcmaF;9|9N|7#PevpBufNcq^yTQnKVt$eDtwhdny16-I1lxm*5AtqHo$@bD`uP#MFX z)2sd(y7tY8IUDlp;n9dIVi_zuK;jIqfo2h9kUZBfsJ&nctQkarG&5u_^;Yw_wZ}T} zgr(Wv6Xmf-m&dQjN{Qy-OjJ-=_I38Rq~$l>OX%v9b~7y{*2STb2j9lBY>-u4AGGkR zbgs(bK+pHNe{MgXUB%6kaX!9hfRjJfx!%J%;})vQrHv+L^7 zlFv&*TzY1y7EZeBQFZ>;t)|lj$N4&}_Qg0k99Jlh+N8p^OZvmYL(UuYc8dP_XI>e= zJXyU^Bsg)y|37*?6~}TCD}~q+jal6 zJgeL2&*nGjhko(CYvJ=Rs4(|OM#!v6TBV!#QFqak>%Vex=N)hp=G&D$*E9LzO_d3M z<~fHPnty-i2d4*|hC2%y1snO0|4-k4o#8I`p~$V^O~~Tv9Zb*fE?e+D);Bn4tp4`(He2pd z-PX6V8%s3uuggam=3i5FTHYkI+sXF%8+)d2Iig&P9?8Wg9^cR+(p385?~yx2CtMdC zV-x$bIw0bB`-G)>S6)s|S+VnuwwHg1pxTl0S=0BiF-7!QGkrd}PluyJh`HD(gXCK*8&&zAKzB*mG&#H{`lFY0FMsnuz z@%HuQWoIJuc;YiB&6a0oV@kexe9@%Mtoak>=Y{^+p1<~oO6}uL&7w(%F`Nny1pSLeQS^Ro;(OV-qkB;9`st3R0+A%MSkPUUW80uEI^FNIHOUrb4S*R{kiI-u+;!tC=SM z78a`r(OZ7YwRslgmP(|p$`IdDwquj()F}trK9pp}nV;^jt*cmmMDFbB*AF6BIXgbd zbBOp5DzakL)~37v)u(K~a-yM$PvVfxqZLgL;!V_cPJen_>7>ZEHFL9E-}65d>d)Q$ zCDm;!pRt8kKhNX&SC1O@CqAlLb?Q&Ur=ax=n(yc3E{|9EIOWO2iGqu}>L<$=O#2wE z;>7i|sL1%@jK9X4JSLbVvP3?fzL|Z#M(IkU{$~YMt2akG%{b#;rmC5}?#hHz2HuUy z+6pNVC%+hM5)*qJnCt8pRj{7V=J+&u`KzxP68`_+Tq5>n(gMdDxeNlOt&dFOH*&#> MWN_6A<*-0$09viwDF6Tf literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin b/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin index 9d6f8e4f8a770c0044b692f0baf6de89300ae37e..903263ae6d94de4645796ea19566221f75e7b8af 100644 GIT binary patch delta 1797 zcmV+g2m1K=PWeu-78oE4Qi)41QpumVb!q#ltHeE%{JjseHs)<3U;%^gWvtwjHW)!+ z;NyFMP-k&3*q5tLC?CC&tl7_M>QB8@5-BD{z0ArIE0U2CJR_lDb8xVLGDaW;eJ%J6 zc~?!HSa%6qviD_~1JZL7$z*NDo9SJMQ;m&43`fvpI9S-AfQ^)I40ZcU5VP1Aqym5B z_2CPN1R25k4|8`%Ax|^9PZAdahq6!?#aFN~$FGY!h|O=fTkd08bB;b?`Z{@UMK_ou z(QonXXa5v2m=u?wCI#_1J%rln&_IHovOn19=vTbFNM@&Op#9YLv4_0SQ=Nq>g)2tH ztdwCWd9hKiBcUU*x-gF*&T~X7j3Tr98{hheN#Y0KE}8T}Pp1C5 zLbnq zzK_mx#TreEx})07dTOb;uGHULlCLtv5m=L!m5Fw743wDx%u?X+S{I0dz;(`^4y1&$ z4!XOhC|r7U>vy5Il5vLdH|6TAd?j$Ab*ZBfg!DRY$A+B z76>Pz0Az<5qOW+rRzoz6EynC@9#si7Ia-V%rL*dWu**gf(~osN zWB|NJz4Y5U>ZU*^pNP-)B|By&e%9c!o?h?>_QV{JR%;A&c;xKjFlbk%M2 zz>HwEh3#Q&+c9|Ki3tswP>OZfOVGEBrjc?3e|wSt9o0~TWPe5uiI5WDf>(P&F9k8H zpSIt-V5aCZoYa!QE-So2-cfpwJ}&Rzrb*+WW%0earEry3nT`hCi8-Foj>BEGk>Ud8 zNe_9v=HD|#8Ko%Hz~{z~r?oW;vegO<0j?H|)4`Fr7ZlGb8B>MmRC&Vih#2|PTQfFlv41=`8IQ;+f9cb5!lF!4QW$hZ7NCn6XpdSm=9(eJ=&`JQ50AVZ6KTV5 zG|mTVLQ^D}6MK+OFO$0?+)Cb(2E!{wZjK;(60i5w4KbSc=8p5KnAo62X>L03Yy|c` z*XL%`R(r2B!h`4BBY-pbtc?e*3z*^=cCv79?*dL z(V7eF=c{1_>TxR12xWPdjI9?*Fm4cdgt#j@Pn!qzQO8k*xOd5XrT!lQYrToScI}F%OHS%BGf}oy z1{B!a!z;+8;1Hh1tNx`oGk(LSVDnPL1?69EOp>Tp6}?rd#R5x;m|Y08wv8d8e-oJk zt7SbH3SA3k6yWp9t!qD|xw^R< z<$t(r9*`sFiBSa!!JU@v{xA!i*phBmghHOr;xP9b04sDA=An-{pabOt2^jz@@oLt{ zHd{3-d1fW-Zq7%<3@v+JL9CMK5iiB={ z+}D{qF^3aGHVx=;Ab`dIx79vC%Du1A88Ls52k2lSvH2@%dwYN@wu7o-?XKY8-LgZ ztl+R?u01=EtzOA=$JIjB3Y$$;!NsGJhb~uk%O~F}Nhslec`7eIgTL6fs5Lx#2TpHk z9NhXCCnn^_$n@R^ko$4t#n8aOU);@orS~h|10>;2Zm`Szi?e0o2beKRfq|Q7PP9Y^ nd$w?eWG0cqpMS_A|72nj`UoQsKnmIJO~_@I1EK~AlQkzqm~499 delta 1797 zcmV+g2m1K=PWeu-78oF!DvGU+i6>(gt6z+tt?+DpR#aX$;TQH=#V3OmRs#u>HW)!+ z{*aFI2i4eOgiE--c>ELfglFtg-Ond*sL;mV^z^*2DqupOhiHmqAFc#J(oZ9iFkNIs zlNshWOWi_k)qh1!14l4xRF82N^RJq4cK7zXvWIVWN|c4h#B5wqABqym3L z0Lr#1j=O0YY%%_5r><`|W!YaCin~~&JqV6!S(`g2ONa{Uc&VWMw?~q+RX>p3gM$0B zC|cQ^kr`2?6A$$k0L+%N00k;?8n3`z<76IFiX}!ekBRKP%826vmAgrjjCPn(%-<5a zFE%OH4Z|s~BcUU*x-gF*&T~X7j3Tr98&sHtWa3TuA@T_J#MoFS1Vj zPDwyoi5()VUR8Y04WuOmo{1-nHBtjh$u*z+1sLw#bkST{Rs9*@B<|#a)Vd!ZH7Ysf zu&`a2W&VpR4uf%5Vm;%(5rjt+eshu2J0SI%gNo9{eN=fu8 z5ics81m>h*Myh-20_p9jj<@LkX9J%|J4q$VWFvL|zW|XDAd?j$Ab*mCzi~1B+f0yJ zx!?Gde!jJkH;Hz1tc{onR6yAQxl965egs6ah6tIUX%P5lv`nqMxPsm&_U(P{-JDes%?Pqo1bS1omyBT5A)65`*-BCq4UMwppBS+s31 z_GpgB0mL}YSBjCc>VGD8!c?==DtwwYb!u~}O#!Km3h{~fz01u~t=Kc=&s(A|^UDQUT*a-4Gfk*q>jsuy+UqwxQ1gnttPfi6qOJ9P{2PP)NW z(UmMGtcR!$Dq?Ht{I)Ve%ki3B8c;?96>IYAj2Fk^%>d1~h%j!$^1?rIeaXDf;Fv7D zNM%nh$9cyVQE4M4?#cel5b8EuFQ=hxc7Lu%t~6_jankKif#_9J4D3_RPZB!F-kK>|yc@UPM)xHka_l?~5ps zvs=^w>Q4C3$6(_SjLU#(3yg~F)-lNGTcrr5m4A3@=RBHQ_h$Sc>9BXRZ_t?RyUox0 zr4VHyCDRt6s#~<#XSl`uiBdu{&PeVy{54vS1A5qXp1N&QP#()>J86sVX+)m%w)O9! zM3z(+49P`^b)XYT%i}Xhnt@i*>B@BU1Wlx-Q7m`LWv#vJXA-DG1pAnFqHqd*VCZpv z(0_)k1_Kf8RDJH%R}6(hNrGCq9;LwYk>#wm8+|dY|6-a9f(A4@91;D2&fo{RSBH79JREew%|I^C|p z)hC{Ib`M{TsL4=~Hx-;7;=j_)EXWHpQ}vqf5KmI z4SDbiusa>ZGAJ+yOCz!X?ft`zmNJFxF{TG>3a=K@09o!SWA2-EPt1H z*hiP-Tog1STo?SY6#Z3=IoOBg+UNR@;>IQ1P)nrKD!BRxK5{N@MN#JkM?TW{c@dnr zIKso#W7XypnKUI$zp5Hfu3(wQHjq`Za=BiNK z%&B;pqRr-k9}Fw}q-y1+64>09-ZChIe@aLb)nsm{0)<}H+BZ#dTH2GWR(@fLH64cY zIg8k-;k9bMA}EDQ5S%K&v9Eboj&`5Espg4Lq@DSA{Ilyc2E_k1aeV(LgJl4N3U^*% z$QWYp;QpsejpT*Z=<#!kP90yxd{(+A9b8}Nn&FVtR%rr~0yaOcz zf4HKowS8d0=<8w=1?{EAH`wG zVL^*l1TlHJZZdG@<*hE|MNaRcWTI9^f0E^js~Q9%^89d)XtG7K30kj!W;w#PVkkF& z!%6O!1*fg~QB~4`-~Qw13yBROuzN!{UIc}vOeCm#=Ge@bzH2X0sqK)F~CSy_wp-QctJc8aytg!0+RYsKc)2UZ@|t&i_5!wtcUHl7!{KI0wD~O G;RhUw43l>N diff --git a/test_fixtures/masp_proofs/32D7D6A62781D64DCE2EF422788541CA9141D136D623086EF07F5350415C7C40.bin b/test_fixtures/masp_proofs/32D7D6A62781D64DCE2EF422788541CA9141D136D623086EF07F5350415C7C40.bin new file mode 100644 index 0000000000000000000000000000000000000000..37ce06c3a990a19ad65b59101420baf140100a7a GIT binary patch literal 2045 zcmaF;9|9N|7#QZ)ugiRSV_w1MTRCg4PJO;NB<+mY#upyChOZ(Ol+XHiFdTZ#4OGUk z=k%(-hOT`xV$O#AdU!PAidY8A4v;v*YoJ*~8DuB&1!^yt0&4~lAk7RfA50XNdO5pt zYRFjz6At%l4|s(_pMJ}mF!`DBeIY9*-iFZyQ?$R`=-<|9uwm-JkNA+F587~ zPgl#9bx-{Ua`-41u_3?&^f{OMaL($No`Yz8UswEtHjdMb4-4ETgNuGHJr}w$d+rU;3J89>#rs@Y09Lzhq{XR2Y zW~$ebJ)HVOIX}F|!;sBfM=Af$q!$*hjFzX0KK)DbF*r4Yd6I?FdzbjxE*G6mUP!w`q0kYh&GL4O*`FWPs=8Lhwx&Sw(S~o!rhB@jDb3vdZK;1)l9-Pc<4Wbk zC7aA&o9$ebp*pGbMp0)$9vB1Ae#)MV1+E+ zx(6K}{dgMg$R22wWpgtyIXiRr%c|RM%hy&;&*$x2J3Z+A@`H2xpUVZW{~+oz|Nrg; zciW&Vvz|mn6h2*5V(y_GGU5GIm)clojpmvp28j)|ZhCy?&0zv1@*>$^RqBiUSTs|7 z=CBz}Dx7EPam@YF1jfvVhjtV#ciXf09K&{%ma9`HY@Hwc?^mA9)q9!qC;oWb^6B%@ z$q7#;&hn`{kWz5O!-r@7adFKpCS95L&FAmrXJ?I2-fp{hLw$%s{&J)L*$<09%=sNY zIUprIpu0L{XU-3wuY6^l|5?`E=X?=RRT+ERYTF;>op~ROUaxm@s(Tx->wL#`d*8f9>(h@Whp7j{B^e9!%Ni(xBicw|Z4a^h3UT z%a@w3iFm6Ww5-3tW7h|T%WFdAex2Bt)6Hxp;xgT!GLiqzr!!x~%6|U)%a{6BYL$KO ztECkjOS6_7dDJlFsAly?tI1-Cef~Wc+IC4l(#ki^i~GEN@yX)XyNli$$$51AmQp=< zE~9cOWAH-fwO(z^%lK|MJW{{X7g=`jSNEc`VR992Dn-%(gfkUd-O}b&|NY7ANe3&$ z{HtH6>|D5U>4m<6m^WOLmaX87Sh`Prxl&|!*^@~(f^)92zV7(lyK(Z|Ktn!}*8IPd z#2=Wykc@Ud`uvx{J;^OS%ZnTR3}TkeaCchwZH`5H-TFgYLd&;^J^!8*y#jt9-(4B|eu-^-)S5+$+ZD_Gs}m*lcCGrb;#cS4DcQ;^kh;x@{Int&7K_T!^=VF)F&3T(%-I&;T zDSG#w9c*Qy1xs$OQ}~zH`a!<3o1O94y<4-^uHS3T*B>%%i{%#k{TElteW*H-xcLh! OtVjk|txyg#lm-B6FzTQH literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/3C132DF87FCD169E86C1F590E7C971DEDB27EBF9B4B1E31F2C57AD7F809DDE25.bin b/test_fixtures/masp_proofs/3C132DF87FCD169E86C1F590E7C971DEDB27EBF9B4B1E31F2C57AD7F809DDE25.bin new file mode 100644 index 0000000000000000000000000000000000000000..6261d28c0b27d323c2e8bc467e3d9d77e13a19f9 GIT binary patch literal 6393 zcmeI1Wl$Vzm&b7k1I*xhp@HB8GQom`32uX1umlUi-8Hy7GeAfnSa1zakO6|b1a}Ee zf?LAg?B4r+*xIVRyI=SItGdq9Rb9{N=c(@B|Mcm-yZ;i}pF;oh5LEd3XfJWjHc*(_ zbzf`H(R($98{6{{&JZZ%j;2&&8m*VI5bMwDJ`EKAfXc+B84hV(uYP_uNnwfAfbP5L zR56ZDt^D4}F)pGrq!O<-eI$hS=uW^Gy6T0rVc+{R*Z(HTubcWM^l&(Q=G}VIZJ_Po zYTv~9dneh}JCAkdseQO8L1BTa#ji>KrBYuQK2hvQ0W*WprXqydm|8yO2kynTSyCnY z61Csku@+r&5>UJ{h)$%20F^tO;%w#IQ9F>MZzWAc&{n`ig2B63L@V>iyL0 zuK=pCb2L!IXI5IF&#L~~PtV_%uca7gWq=d2knwf=&lZ$1;dSD4an+B-87xA`htYvLTC+zDCNR-ydfV;9_EiL zoRd=tXv*8w#-@3Cw#RO8rPku1CGe`<`*UHaA0C$3KdhUaLJJfdEC^57%i z;nzyvhNKM8`0?bvtPqlDZ=TyHByaI8GeLT7oomsmGA{`Q-+7c^1UPUHRl_)&eXQ8x zQhd?7De$2q7^rtRqvx9?f4D~@2wpIF*SrC#to!dv8(8ukB@24*r%NPUz@&nN?Rh|0 z0I(!=HQ>B&fZiu^M;-WKz~kk|m2RS;$#09O?~6GacSJxL`Bgo(zclm|L^(0&POTg) zT(vkm0|Ep93^Q3Xa~>e_hq-9m;aN@C##$y_`ZPC3id^LQ!Kv> zhsk@bfCN5)<7*IOjKltZ*@K>{E}(4FM(GCiwwHFERAx zJ+mZg1M}pQ;RB7@;eusnFD4?SzZ@VTcQ%RmBE8cgdrx#epC)Bec|D^>;6wtXfkZeq zwb}u-OshPr*~QWsYp%r2r55dDcL$xvaIQgfZh`^_&HfVTn#|I04+_tNQjDw5pe`J**4^g&>b0 z4F_hM3x0uNV2{)e&IgDWFuVS=RI!e$olL{wV~ov4_J2g)E-qU_5s%VNHnah+IDQI* z1@X0oEItUg~Oz+cBVptZ$pLW!(xv4R3&vuXuez$*7Z3)0N@tGMYTavN3A@j zV{;;yc`-M`mPd?SVjiVctK9mHrhtJinU)wvaT2Emu*#D_Ep=;v+5BepnJwA_Glb)# zSGa&k9*t%3=h{^k6I(i!8%4C0n7qra=N8#=guZe;oMd1?cqEoIefWKIH8=E*eoSeL zbHMTI3({g--HvzejZ*pIz$@pw@v6|`?lHo47WLVsOvjX3t+-6mLcY1!E{|*s0I1A% z$Jv-9Uov`0iSmIjOe{3NtD#c%niRKAYouQvvIW-NWvMvASc0|kLmy1hapc3_3HOZ(dYeKL&H?loR1rxhY6`*VJ7}r{7)czw^t=&7XjZqw zYR;>^Q|iD=(>?0Ws_=WI`QN73ND&zp!`oI(bujhqo%#3+nJ`|!ZRwMN_Zy-So3M^5 zA2#W4rPO;Zs8*?O9dgiJV*D;B;6gXzc?RrT8!pMo8}OmO0Dz3#qzg=?X=5IOhK@A6=j1`uYJ=S{Y0 zJ#GkJS0=dh4@jH!D3DM(gaEz$ z=_rp3lhOSz0~95r6_Eqj+bV66QcT=E(a*a^Qd2rHE=ebN6cN)vXe2MIZ2Fz}&&m~z zM0*fVs7LI%)3`=dgTV=@!?p^}AXoJ#S%xE$yu%yxNG-dqBYad;^a?IXwYjRT>k}!H7?-Vc@P9YOk3Q|e{X6=EMQcYVnt*EDWAbi-Ax)332Go- z|MAB>y9q3_EY0d;(lx`o#MbX6raIVtmOZ?hB&8n3agom!=L<8)V)etl#!#fT5=BNz36@H}f-vGg9WJZ%sZVFUozIorw&rv7FO^sZ33jf(DT z0cRa;>rM1r3IgN{UT7NOb;r0^WM(lC+I?%@w3d~i?ukGsYcQMXKbAn|h1Zka^D1NRhHRkXPnV&OKSQ%0gOI4`c@yPbcY@qd?g-&19riDG!96t# zdCYyAk1i++Ez)T0Y1J^KeN?lV<*Q}o)bf&tHKZr!ZcHX|zhtese(xY=Kko}-+ zw{~f>xmFmYbpYB3Wb0~r6{Jw?dG5RDi7RO_b3co2h(y~_wt)_IJv{T%G!n1%2dt-5b4Z?!`_!M`wN~Za>`EcF%ngEmJS@#Z( z-=O7n2ZfvqgWb4LyIiVYyDrB0>g46P19xx9IW8o2>^J%sj=H=QY(s` zh7E}>YC4+8!(n(>`ku+*&2a|+Pm(uLP+I|wRIi_BX>C4|8G)(xbF_Y7ioE%dpPa@L>mMTg`-ZIO?7lno< z74n!P@fa9$Yb1-Cft~V9BD{=O=8aE6KU5U| z+dlVqZScGP0McANs3nLXn@U(NWA=hB^Ke%y}KP*w|oBQTeXKc z*VE@w^o6^#36Ljin7Oa$smSIqq!ir`%X0O_*{0aYqo89*8AMYI)%ug~ehdT4J+PGc z6SwhIa%v)kEnG<4z=H2Z>PsB5M7hQwdrr@0qyA=9-FaDP)j<;c(cczien>1iK004KKn3(P`*-B~O14 zkwatp*Mz?~6IJvwbcUbPRv8V1z@G54v+NA6;Q6oXN4c6h4fNfu1VTiDpo*&$CzX z-@VaCbG}f5y0;}jYK6dznM@OYCfqTi!fnEB;Twj{B;=<~EoJAg&asU?xENJfr|Ftn z#3W2L^I$J%ldrR9Y*q4by-94JjZVo~e}GR9EXzQoe!$*_pR9Z#g=D1iYS^q-MQ?J6 zyi29?B5p$_l9qG;MvC6~6p}Eo?IjEFW8xj(Gn?%U1xGGoz-K-}g!_?j+Db_8K;m>! z=R16`%`rQkI`c4p?s0L&b=q~uWtzcp*up=a@S6WI#~mt@SXI7paFxm1E@%G00=xy2 G;RhUhcuoHS!ob|2=dbv0Z#Qst!|B^jl)GIN?gq2sCC6hFrz__^m; zz#faZ$T{_S2Sub(OVt;!;>0_}QL$Siq7ve}mc`>oe2l4&uEr_GH`^FlaqnGVz|;7PB*fw+A6sLvAz*+?NVQ-ZDgn0AF~0=f;8 G;RhU0+?UP( diff --git a/test_fixtures/masp_proofs/3FDD781F73CEEE5426EF9EF03811DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin b/test_fixtures/masp_proofs/3FDD781F73CEEE5426EF9EF03811DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin index 1452014ada1d9bd81330bd33b55f9682c76f18c4..e3c754f494219bb7ba36a85bfe433d1afd74329b 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6>hejA6e2oGO&s*D>%ft{Q>c4S?=bnJhCWT_(MEsN5#yaOcz zf2$Z<3mofSgobtoZ9ii_t67_Vb)%zd8^k{ZVY|PLsI81;h6w|0fK*Wn;I@vz?4v9! z!j6Z&!XV|2Y76T{8La=X;)oA>0Vas#P?lVijgt;!pp@9vD?hkXD3iE@)dw6r5f7Y64Q22nbQ7wdSJ=JBCc!Yv%th-$ULguct zP@A(k4WL~8&L3Ucke6UwPmk5Wk9Vg9XmE^(nEx@89nDWOl{L=DWOhupOatz-yaOcz ze~=!BwCMoXa)b0m?I<2mo6vWq>%SVNn7(t(LU1!9Y>;FF?-yQD5rX@z2Eel@#j?(u z7vudCf}9D!DlnO(X$k%bTlurn(++q?aL2OKTPC60!dtaPu{LS*u}xVK0v1Dk7xCXv zDQmg9^aO6DU`p<*mbfsOy-pi}@e`6nf83m3+jn~WZ@4iw81Wv7@71x{-q>}>RlTKw ziyNJCw0a}-3LJz{L1NjAA}Y+LC^nIhQ%@Zkf;AaGbn3H#Q{GL^18DI|0kFJWM-~?p zWe)1=`{X7Rs5%u`AaH#PmB-&-SDmc%2}!J G;RhTgl9P!5 diff --git a/test_fixtures/masp_proofs/493CCE9EF30CBA192D49EE26A1F59077CA8F2E0C07061A81B524BD6EAE7983F1.bin b/test_fixtures/masp_proofs/493CCE9EF30CBA192D49EE26A1F59077CA8F2E0C07061A81B524BD6EAE7983F1.bin new file mode 100644 index 0000000000000000000000000000000000000000..dc2432b7edc91dba0caac708e0e7eb929f363ed8 GIT binary patch literal 6910 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 I`|A_yKmRfG;{X5v literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/5355FAACD2BC8B1D4E226738EADB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin b/test_fixtures/masp_proofs/5355FAACD2BC8B1D4E226738EADB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin index ef1caa155360534f60706e063e0c8b7e64b0aadc..a99382fefc7ae75c8f9ad68a6c38eeccd7808f43 100644 GIT binary patch delta 1470 zcmV;v1ws1ALC8U{K@}i!js7uWglp#&4qI6UdRZjisIEEg5!pmMzcr+8$@}kDID4KtSeIb=VI^}oqCD4^T; znY@SsdGqym5L zHeYUSpQy@y?N>_mJ(!`7oGzbT8STTv<7)ENbNNO|w^NRit~obhiEmCv*BDtJo)w=D zNqg}xGDHp72zXt&S^us5Rdo?A_OZ7OLY}Qmnf)~l*FNFw5w}Q0eV@!aOjA@CUL^6{k?*r68I=N2iD?fa(a0LwlwObC#AYW^m_k`YV{Rcu z7(p{^xp0Ftt*gy)^1;`s-bH(J^hlUNsQzQG=p1J#gz;K-v57|iAai(&3mmr>*AR zEq+l_-CgMN4Wt3mg0P7OA2L@p(+Cstti5Tgi8Z>@iiHDo6lNd2Z15?tQ9)01X}o|4 z59-Wy5E;ud!z0cii7RUC7@UfOhm&*W&~LeO*~RKo{<35d5DUWw%G}mU+w24$yUBMZ-%%W?5SP!bHv!Ll&%1 zjC03uQs(QstR!X}fJ-&(!uS}%`s{=t9~o13-$w%Nf)gl*Mc}~K#Lp4-jeq9UZ57TR z*q6QCKOmQ~e+~+XsM4A)3`{-L5^H!Wat66=V9RpHn0hP+2_76JEB?{7(rVK0E>YrF zOht(vW37Fl%aaPaa35Cf;+x0E%V3xjN6CF_m42Z;TG{VaepE=xuH%o`^kl~5_KV(F zPNzZwsW_pmHAJwkP&y$lg$HipKI1G=)gq`0Ol^N{f6}!B4B#%&=XQG6N;Y`ZZYJfF zu?ymqyS?z=d>dw0e{uGGh*?Rv|Nwmuvm?(Y6kkSd6i?kxBh>X;X z-M1ffM|LQ<1YEchrD}(!-|h88qf?d^%FS}7Jr5&B#wb0kt*86V;<*|Rw6l_Gv1-5$ zM^06-e~h7VLlx>>_h}-u%6ki^J5@Fu@BvxT6r-m`P^nVpjhDqv>Jnz4w)HW-9Yb_Y zE&Re#-jseU$w+eCSz2;S+ig=OE2b~ZNJN$Hlk${+4i7T<45W8vE-~eT_}8mF!&l+NRu(_SR zHD=fC>wa85-71-+ME*>&hruJ{4d&5WCH^j#pg*uc`bMN8&ljIo|A0_kvMV1WxEy-+ z8Vx;*MM^=*B#c>hzNnd-rP?g>U%rtilG+bP;mNp{DB;%k zcm~L321~rN{d%6NlFfmlZ}MeKdP@#Zf8C9ae7OM)@!_V6J=gByanjKf$REhs`?%p5 zZ_*&q7;Z`3dFz@t5UPv~rE-tvak`kCDD^TG&3R_@w0Ehk8hSw(Jy1U)7?(B(@W4ve z>F~&gp;QYUm;hR!Vxq6!U;5GreRz$=56k3x&8uV>Vi}bINBe=tL_ghN9V!YwNP@Xp z8ZEZi2jPFxu1wvQl=F|Da|La5eDJENuq9uG!vzcW17mce@se6 YJp9Xp2PLa`OC*y`bj)r~43mr?JY`MSK>z>% delta 1470 zcmV;v1ws1ALC8U{K@}jI-5%xqj(nZZI%8v(ZmJLw36v50mX<6f!pO#a5eVp$VHH7P zvUn$wp;(S0rtzi?H5_-n*yat|F)jF=Y&YcHWSGHuOv@883mX` zxdK^KUDc6cC2o=KJMDKS)vQ_}{O@elSP;WCX_Y~VD~3)u)tvNYK6DXoW$mwe6g`3- z>NWuF99qDk>V@!aOjA@CUL^6{k?*r68I=N2F2{G`yM)T!Zq*S14&L*a+_u0N(<%=U zB4zL`-~K5(i&A<1+B8v$|Ivx6Bkl5@+ESXWd4Y z-D0RLt^gi*FMwL3Tq|}4ENc{zdbkyBQJTCRfmS9u5|avOSgKKVEl+Iwdn+KTN4 z@CEemZs%A5>Qv(%`$2jMmcCmbtLQS%Da28+JVPT~226!}$q*B1Q=6UM%c%49wa93R zmoQN>@(roce@_Ir5ou~__grDmN8joZODf)Ef$WEw{exbv40ZD$gEIVE2y(7$O-rTR zumuEO59M%-zOCu?vIEh?4S#dv70lor7vW~s>RAb!* zgUCWAA(1?~nJ5El#|M4Cc>`xoW@z%~+3~egSNq)dTg7R1hal293B8j)sbc`&v?ndP zCp0tBf-AzFS^s0D>>oBZrLTdlu(1$)u!;GW)?6i$?Eq~GuBPTx`mckEk3hY$=E$Y*mkIj9Kx@8H*D5|+(kC`f}jJLrt1*CrLr z1i#5t$x!{&)A6!LQ|9aOkgfc5z#bTzKN%Jke*#pmCn=+G46L(L?J|)QWnlgGR;v~_ zH+p(FiMVG;8L_)IZI!V=(LPnComH2;vFjfvAJnwJ(DiF}?DV<4IvD^I%>I7l$)jm? znG>6#`{3ZQV&FU8Af70*-IFvE+IgtHwp17?Idzw23L@ih-)*Kb`&FIaik6E%I7_;i ze^~nqtCqmu+(pbt;n>5cNxz3+?*A9I-bqD7Q4p9yim@bFtpSe{p3cC0sh+`XuPX5< zID1|&zTFKTq%av>0Bbv~_m@_-Ju}<|KSX?*RTlH>D9m4k#k_S^qBz?d(xcc>WIENy zis_f~2-QOL)vH?uqc^a*K}=|p&kjb2e@<@%{mMBmCi5v|RXnDzfC&XtIt6?MILRPt zu5wG?^Fdlx__ss}29_y#by%+X$(97gm6w&*z>R4ii}_@uN06hb#?8)+j?@g172w36 zeYA;bX~E|;ucXIZ$r?|_yYU YdRTd99cdkp9@!N`$pqB|1e1&)Jk?^*)&Kwi diff --git a/test_fixtures/masp_proofs/59CC89A38C2D211F8765F502B6753FB3BE606A5729D43A6EA8F79007D34F6C60.bin b/test_fixtures/masp_proofs/59CC89A38C2D211F8765F502B6753FB3BE606A5729D43A6EA8F79007D34F6C60.bin index 18d1c0c99e4a01dbb08eb8a098bbce380b1f9448..369f3df25fe224ea322260acf97e31f4b16e6afd 100644 GIT binary patch delta 307 zcmV-30nGmW5B(3YoC6>);R9gwv?_i%R!3KP(fcZ`ymKuY5BC0XUQ3 F2OX*;lvw}( delta 307 zcmV-30nGmW5B(3YoC6?F%}%7F^u^t{!2m&ZPgw3R$?4B*Ey2JUNnG}kxckBic;qqcQu zcc=vO(@9^l7iC4$et%E|8;{|55e8JN0q}!jdWgEQHCJ1z~jaG4WtGbcb6k9)lISb?rqi@6t&1!(1)c5@&jU3j&WI%l4;` z&BJ2e>bDReAyQc&bOuQ?tl-_EL3;?-e!G8IprOX=40RfZX F2OT+#lqmoJ delta 307 zcmV-30nGmW5B(3YoC6@hF};6yIL$+?zvM4<>$?9F-8bdxlq!$q<*p4e4|z z+0j`wUC52dq5eSL9p->f_nc|ReweAQf4(T#nl=Mb}4 zYO;c~3DBC0gED_I-{PX-_{z>3;fe9Aia1|MI95BI5LE_$y73|+Iim&i#yljEU0i24 z1Npm{QDIcUwSQCX0zMG5OrOfz=Ts8?-DJ0Ta^+4>zYdTw8p0il!N F2OWKrm|6e; diff --git a/test_fixtures/masp_proofs/7A240D86DB78C8E1478FB0857D16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin b/test_fixtures/masp_proofs/7A240D86DB78C8E1478FB0857D16BE737B7C747CD18D3B832DEC3C9DDCF3DBF8.bin deleted file mode 100644 index 681b074d16b20282cfd7c46cdfd4ed9d05407bbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4895 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 R!v-so!Bs1i11haR005c%-njq( literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/AC96BF36E1775448D1058D650EED7D14A1C9181B0D631419A25C9CA75656C6CC.bin b/test_fixtures/masp_proofs/AC96BF36E1775448D1058D650EED7D14A1C9181B0D631419A25C9CA75656C6CC.bin new file mode 100644 index 0000000000000000000000000000000000000000..600bdbc6c988759dd29ca7f5e4c4b1d55bc9d496 GIT binary patch literal 6910 zcmeI1^;gv0*1(AYBt;qo`2rFm4TB7z)DRM*#1MigA>AM;De%w@k}8d)0}P!*NDkdO zQqm<|@Acm2S?k`r-nIM#?z4Y6XP>iAuDw2IuYERe{v}v{3O4>@{P)#m*z=C#tmNe{ zG&^;&CSkmj2>LrNV<5s)bH2@g*#EM{-Y0yJO)e#$8cIu1O(l_;I+Ls$`#sg+qKQEV z@8`s$``CX?`Kx>^d#D?Qv+dHO-h5{-;dsl_?6E0R8;1mCDF2CQcJr}9$fr_ik^RD; z_B+gJ5S9lF>LTe`iUfe1RupzqGzs@6Jp0u!PwfUZ-2%LoEJ}GjPop{w6_pq+XBjm$A zP&L$VO+3^?8gK8NQH^D;3Ww@+gM@k)MD*#J&}QtkjX#9mWlO8i!4ng~gXb=U-%lKP z!%(a-frUB3`*kF^UhDQt&{rmwGL6imySDe+)SvF!Ud}9~c@l#x23`e?8tvr zU}dULLTCis&pS#xHqM{irQ_v!8;+BU<7>~;UoOR6?`6pumGBO`lZHre0H-wrfADyv zh{-iPk>nM#XJsleY{_Q}s&65@8!zg)l_C>!A|)39vEw5K0l>W6S+CQUK6bbG4ZVL} zuiKl7#ZI#R(Y?9W{kbfS8#17T`m7qy2P*iJn0BPkm0s;V1Ti-?NeqAi91{f-Q$8T{ z%2c9x=cqDx`TIx4lnI^(35v08{3v#awVq(Gf0Zy0bqwRF#~mxv6M~j&7PYObRn$`B zC1IR#6G&m@W9|$GM1b<>TgYQj~lpkN#Sp+gghaNN8N#5qf%u zSl%qe+vAI+q{M2XQ*JG>B>@h;-G^Oj13-nKPN`SfLlS#o($reDeV)!tbh0wI`E_dpG zo;IElh51`MLJvY?&jnneT6clT@P-kngTgM2>XK+qiYFM>A>WJAS_-SVjJdoQS1|lj|OAgX9d30Y72z6nzcxW4~eYvK8)}DWI8@!M& zW(SA8(`GO(0JmkE0Z&nryNBy7xmnoWE1s3#TlqG4_KdkGd^vP)Kl@Uq%?8*_m^Y=H zO?%t>)Tz@sPE8xhzvieuB*z#E>lMpv#k~gR$Oys(N@(2iV~R=z?=Di3aHryulD_HM z=iU-B-42ofLPhlSi;Qlam9L(^9mNa>ZF+bx8oH8$!}^V_RA_NnfLbw+?ixi~Ylud? z=#{^)M>r(Y_v&vz%Dwr^E4qHm|kWVqYf zQbh_V#rhPcsS>JLZfSi0y&YLluu6ulmrf9TAhB#njJ7iZK5mCBpVga>!p}+@tBPQ! zNVBg}Y_~w)jsmDa5~ItG0M9Vyg`LLTXQwXTIGB42h}{A-?AfeOM8IfZlhRgI7A^JLhIP_sCa>!+D6BHGOHy zzOkc6w^qwNsO|%PR*3ADPK4p7`z#w^1OwAzhY;RP}X@wT~?Ti_#lZm4aHX zj|INJ41&xAM;r)0lhvVM7(XSg>UQ7-RL#&|kO6YLO?<{f)8e=}5f^BSU6zNEZp8=; z&x=}PKwpPSOA@Crj@t~t@Ws%}UFzf3r($$%uy{=p9fZsY0P!3Ki^2{hhTX`95q6=B zwHT3ex@u^asYv=x@f$bQZ2&S5NtuHFTwl&3cyn(^WtF?vVeJ)VA%PAm!?ji}_X%L` zbTfayL-c8>+ON}J> z9Q?2C{!OjFsr5It{y%EHP0}}FF%JDuDz#!?Q=G}bd^s4aiOhl=`f{A5(BD%4zTY0A zCJ>LKQY|}}*AR~#V=&{+#TdqJYjY01-yX%~23qpuqd8i5`wVnHwOGoPmvkjldq#Zm z9p8zlS9Rt`Jp$lG7hu2Z+dnA|X3S%Dx)0iHNSKscBtZY@QJ{-C5Wdq{zOTXkG))S+&L^;7g?DIDXRAuKUgL z9%a3Vu~#lh*0_XS;J~@f-%kBM=EeVY++XM<;>_pBdwa9~tLs-(_z!+N8nR{?!ws+5 zUlGE4i}_^q=b7>J(<5*qkM2hI3;Ty`R2bbjuU(qwc-?a@oV#{>AQ>PEk=+>>soKFV zLc}3H)aLp1CzRg8w%OEv=hICz9 zOp0sm)mR@FM$OSosCFkBXJf9FIXzhi$X8Ke5T;Q%4PQ5P=Qs0fJO9Qk{#cUeA*;5; z!c3nb*+#h;125#|`g!3?F=$T)#N70d@xF=UON{o1TQ)ojA-yr0PkLJA;|M2S4Ae4% zi^6+?7nRsKm8DnFcUIsfJGcy~YhORnhDyz&lz2f9$M8%^9&(D7#p@^2G%&>OySlb#n43C4a2Fw?l?V}BnW$@W4@95q8Gv|h%vK6iZ@*UWy1_-=HhT>d<#tb{No zoU~O4PbvxV0nweidHe_Uvg-Ij%_nVCZ?f7BC%S1zNR!?<$m8kD#kx$;a`}#LRg)6F zqM6OLl7W=e(l=-ZQB31LX?yOe5_OAL_@>&oxk!;`sMKmMzA=;U_2{g&>mo_r=rdOI zS`}8_+WQi%F2WW(L5>VD#*p!7X}=sXStZdl^^W)1*|V*@JE0b!dz57zH|ri_T>(S( zDXI4+HSdWrQ9c@~hN|p=(;9hZjvKT8kl8S9&+vp&s6FlbmnI5l$5`wP^WhnKyQztsuY9(V=1G$I; zxqTNqNGP}bNri8l>kZjCyLIiY!lWt=aRo};bKV%fq?hWBeD*+=sOsY(UP~tHq;ziN zBB9~8w8dZ+L77R)nnL~qXY7)oEje`lGc?zbkfrB018<#-k~S+^&_MiFRmhDk3Bn3( zjBPrtX-ieO1I9Jtk*UtYg;7lmq+GadT*>AROh-*+2dC zfDW&CrpaJ#j8f58z?S;k~7tnQQAcU@E>H{L{=UD)&fNKdq$SU>1C$}IgK;rU^$X93AS}bXJSAG-u z=$)Bxg@{XuGnafRea0f3ne%v|UT`77#nwD#k%_#1yc^@LxDl0(3rn_F3F6sHac*+< zmhVKUsw`x(7&032T=qVOy|2zoB`5V3Sw9=w<+WJl>@7~=VcqZX)t!E~T&TELXeTfh zCF(DZZyPK?mh^QAOR0ik@9jxGV~ra@;*KOF`bGuz;xAPViV-J4qX>G7$yP3 zTgc(|Vl{G)gRpA0^-%2lBZJZ|8G2RQaeej0NA#2_nu9L5Un8!#(_CINA2Z;BY&4X& zD4LgsCq2yC>Yv$YJYW%Lxxo;n3v-b^ukvSaN7+&lsE1xnSlXhXW2t9K%ZW9Saa~R5r$Zfet?WMDJeSSF_%kPMa zqK>i2lJCE(F>rbhqc3gqrp!;IN3H%sb1<}PAE{U=jdkI%JAtvb#9!hF_sR)gT)&cK z9f=#;_1(w$x|tseY2Yk^4Kd%?)Zsfm*z9k@lpZjbt~{|%g;IG&M6F(N{n0#7)9NT=rtDq=0M z3j3&sQ7-N6fQX{3HhdRx`+2Q~*3#-wU{32;-3+Vy0vxQGy{1+Pkx_*t&DV=C>t`wI ztOWa5*$GYP5U!vY&dQTg&|6dL%rCD{2i)R2(qA!sTB}&UOML$>-(8KC*Qkpt&ahm6 zQ#nn*CY}o^f4oZrZ^r}<#5P^o7|Y{2bajCj$q}?e^%1(Py#-^ZZdWeQFVQFQ<}9=` zlba@oH_^0SadQrNLJ~eT{H(XmDm&^Xr?1Z>!rU7|yXo!=7*Qu{PZUn$R_19RR~jW# zoHYJ0R~Q;7Z&3A0qy%2y*#>_~sltkH&a7$$a?T>QtMQ)~M99m2yD#o%Ec*DNfHoaOCK^L(#i$4NYiny{*(0pFaQuk;Y7 z;b4PqjiD4u@(je!^sS0OjyK6at~B`ted-U6B3-E>_mXXVQ*G~Hlpq8hhPEN5<4g&h zO$kE^80_8i4AKu6@FG^66n@626VvfWhls-WS$GMju&=1+Zs{nZJIe@SLJQ zUBeX?gdY#+vyQm&*p~0?H znQLV~?Vy+`yY0&TBEzpm?G?|f2Evcncg1o>eO=i+4MyyR{Vyrz|InKznz=a*R_p7a literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/AF6B3A470013460A05E8A522EC0DF6893C1C09CF3101C402BFE1465005639F14.bin b/test_fixtures/masp_proofs/AF6B3A470013460A05E8A522EC0DF6893C1C09CF3101C402BFE1465005639F14.bin index 6c9a57a93a2110f597d22a7b0e8fcab9cf665ba4..c2b83d239bc4fce065d199abf773dd20aa49cc6b 100644 GIT binary patch delta 2424 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 G;RhUpO`UrH delta 308 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 literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/B8503C92DD36305EF8DD554EDE539F2B52F796F6FF426B440F00D123BFBE8DF0.bin b/test_fixtures/masp_proofs/B8503C92DD36305EF8DD554EDE539F2B52F796F6FF426B440F00D123BFBE8DF0.bin new file mode 100644 index 0000000000000000000000000000000000000000..0fe60623858919643d7bb846b3aa2570802e4c60 GIT binary patch literal 6910 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 bW1d+J+gqG}{x|(|{HrqkTmH6V{Wkmuy)6?n literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/BE09EB8FF98C0CAF7BA8278C4ADC5356710DE7B6F6FA2B23C19412005669DC2B.bin b/test_fixtures/masp_proofs/BE09EB8FF98C0CAF7BA8278C4ADC5356710DE7B6F6FA2B23C19412005669DC2B.bin index 4e2fd1fdb85c02983101721d3478f118928730eb..d06d04d7a991a661fa6953dd7de060e75722fc21 100644 GIT binary patch delta 1797 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 diff --git a/test_fixtures/masp_proofs/BEDD60F57C8F73C0266B1DFF869384EF0421F46F7732EE62196DEB73ECB4C225.bin b/test_fixtures/masp_proofs/BEDD60F57C8F73C0266B1DFF869384EF0421F46F7732EE62196DEB73ECB4C225.bin index 86758ab1c20419fb819a55e0c73d8c09ce78e16f..ffb7f36e77649bdf940c5f2c532c608908b7b632 100644 GIT binary patch delta 1474 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 PRwRR~RwxHlT7dun4<+F> literal 0 HcmV?d00001 diff --git a/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin b/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin index d83c46f49a3012e806cd728ab439f1e89f51fff7..e63ff5ba2c34df5fb85f8a7fea33daae3b4a3b69 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6@QWHyacZU0mngkL>=BV3Er-ehO5aPR7>b07@n-Axj+yaOcz zf2|Ojv$AX0E5##*N&>i_?qP8T8a1fY1}SBYA$=D*UwY7jUzpjH9~U0_qBr G;RhU30F$`@ delta 308 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 delta 1994 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 delta 925 zcmV;O17iH2CZ8s-U_0l0t2T{xKhyr6s-8Fc zX9END?Qqu0zp2`^t=mj~>dqLBoe!*X8d~aXcL*)+Sz@)PW2(G+{HJMb8cpb zd$U(gQA2B9GFpbiO4OYs@c&>^eeu|kmeM-mrBdip)foET znGae;WB#tM9N(_96J^oPXdY7ZSqDY61-U3yhGA4`=B#&gWW4encY5DIv`}z{>~pZ z6}9vCK#if!6JB(?mFYXokI^p^SNHkEp4k3GtWd{xC$>lz>N6R>L>+m8yD&XJQ@Q{n zh*4N$kHo_esUD|DfsP|D)-THY(!NR9@ekg_wZv9&S0F4(GYod~L9y(;lll@RXYb17 diff --git a/test_fixtures/masp_proofs/D1F174D8596E8C1DA892DDC23D322056C14747EAC3FB1625F0A86957E00ED109.bin b/test_fixtures/masp_proofs/D1F174D8596E8C1DA892DDC23D322056C14747EAC3FB1625F0A86957E00ED109.bin deleted file mode 100644 index f459f6dea66ef36a1bf2917fa2d836e6c349aaf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5412 zcmeHLS5(tm_NIddA`n1|!VhT@1JbKB6RHrUmw@zM1*A#uh!m+2u+V$xARtIUx*%PO zfT0ACsz?b^=H8jPYu)+3`0{_7`CiUm`|Pv!+Gl<1+xwi&i+_RW-ykM@def*^QbB0= zSum(CB^U9rD_tu^26wC;E5zj$D)V6TkNAJa690AN&$S{@;W9YkQ!y8Z z+Y?|lY+Rv{eVdYk4164=Ves$L$#g)yi+YC%*XH0}5oFkw<3xr$_-a?=pM0Zmq0=8Z# zB_Aok!=>E>L1X~104EH3ZlQ?#WiD94iUxgc>%R7YhbH#svES$ObS}U^B_pAUJQyMT z6LfX_qYsN#gmlgP%rpoP2S}_{tZf8=xHB8s_d5sm(JM=@uD$pS<4;q4-gUc^N7~s~ zI6ACR6i7To!dgiutBgeuwYue98(MYEjN})8DL5`Fp6mFTjjHbXn z$`-Xj4gWjDi<{OdEGV1Q{o!q$hT-BxPyZX>j9^tjN%deNeG0MBsd7nnu8=itLTfp@ zUVL8(q?3{E(bDb;G~B=m;&RIn*-PGZtv`?32$!FRIX^=Dh7E8J5BLfXstxCkZ^6dci>F#jgG=R;-J-l z`X#L3H`t!lP5KaCqbv7Is|>gRx6k(NId-!_?!hhE%#UVfEtM^JoAzmO4@HeDl(teV zfO#-wyig^RA4PIGMwsm@gc_PfN<(AY_Z_+=VzV733&e>TqslF*2(|c=#}l}*s7-(W zYY%;B#h(sYIo-QT!U;4>`S-t7b#<23Nxc*CCZGqiNqqP&lg(an)`y`WsMH9Maq4zb zQeW?H3u9R>cQ5t>&AMZ?ELlD<<+8G2I~r*KwdcWQ*_xNM9Jll`$sUg{syLyM8<@|O znbeN&(v#dQfmhqHD}+}234H>lt+5<=++bI&z(qyYdl1e*COfh62!M^@Ox$$X?jL*i z@^TE8fPBMs+_{{O#KebzO^B+XbygXJtqWp8Xnj*yX%+$G4&e2Qz850#JqwdUr_5QlNGKPB57Teu^S(&B7VE z5D8ePdx+Rm0x|`x4rSd9I37!vYsg<3L|>m39OEC_<*L#Is`f$|t^m@X5+E;z-?Y}k zgfG}f@8O|?9&6^1GD^eFmp;w#LU}-(Fluyb@EL<_NTRXBH!*Q>tJZMtxb6#zvM&_Q z#@F*nuA&)m=e%bJ=zrIUNW=E~irt-kAeI=7r103vhvWFGmuJik@R!@m{zKl8uu27XKG zzqR(?wdCKCIuyS0|I_+gnG|EboO`HFdq9$#$y>Hl*E|3kk$Ct_m^n1HKC23X|vC&TG0=v!BZC1^Y;&JJSs zELu$iH_l`77GGhkyLp%J=GT0k`CT?CL4NW1bl|1Q#Ms5jSAtyptpPIQXG*ocK6_jj z795!~`2oBs_Yp}p3bfQjB(jIc1>=&Siqc54_%4A_0UP?8O_B45<{60^H5I|7EL_v} z#oA@;10_N%f=U_R?{aPnC9#8PZAD*`nL#_%ZmL)ER^K4>ru1yQe1rZZbG171r;s;( z1Gy3L<|Ne6pk|G<&=4@Id=9XENFZm= zj8Ad3#>eMXe6vfMX!R28lspuU$8&cW`MA9exD`cSM*XyuAssq)WCgo95|=taQm2jI zEG-ONp*(hGjvUd|sEDp5_c8N04PPb0<_CTjs!F zTF2_xMsRG2VRVim{>fV3fwYo1kAu4w2|PvC*)_B;NMBL`&k>UqI>U1~(iaN}iB7_A zy`0#;t=)tqLS4gc&G8E};5yr(kZIQRXC6Xj6fuZK7j-{Kzy!9CG5 zX@e+ebH~mt-*nqQK*Szm3;j?Y0pWQ!BATmHbTMI_vr`EvR5E+ZAg6(|l>Am< zphu2_SJKMPs1I?*ww0`XVXt$^seL_$=syn}BF1;Uk|@zu8l0;%3C=xMKV{A?;>wlQ zGY1tu7{*9FZBoNuVkCfTZ0x3NoC8VS!zUHu(=nQK_p=S^bLh~+YOM5WS~M=(fnHHx z&J2CeL6rP0mAPVm&5F~Dd`WkJh=F#rZG8%OcZ_0}OU1HIMP<@>}Lj3bsb& zVW!(UBYF=xw)m>Hc#NquB58UJok^-#Nafe~KGVcQ%(ycH^d@yu^zd3`23iX~MQ@)T z#niI1KYB^gSEv>#k@8e7R;FA~bM`x7t_l=$j5DOPC-TmIYUYPtms7T8509~`dtuiD zgYaMd?i6yx?e*i247}kBw8t<>vs-U9dWg5tCn&?#Bkg2i*Va9RB37lS9cjkCF487XOtw~W5;q|X;`mrfPU{@cY#;dPvl-blbTNxyECZEw{I%svM3p>Q)-y39fe2QL7uqJPOe%a+nr*%n%^|4!EkwWj28!q(bF#?65}gLEoV|EL zC4^=SY|Zt+GR5ePJvso_PAVjUDV+3;OAs}bG5M4M+V8q6zQe29phBZnI(x9ZAZuZk#1jdi-R>oFpjaU z_z6sY@-bY3!#v8KxN&JsB$a{jV_XD^XL*QYYH1)q=b-w$SE)*a_WLD`SEmqcCOLb; zm_wZ=BKUagI%}=P2ACxav7R#!(fw$7!%Dx7w_jpA5LD-LAk@Uj(hyV1^h1Y-4$sI! z9oV!Hx`X0-o5`NwvcvK7HYTa;MrE6<(hyBk;Ok74rxPDn=udjCdph4|@X8(L-+L`( z{?hO9nyv~IQ@-QCwO}yk7Pio>e@WL_)MyftwU=p655+mJ5G(s6D{f!A+Z4`st_UFw z&;6j5dYb#$73nskBh=7*wZ$VuE^`gzbHuYs#P>_l*-~5IYwX6{g3mP50NiYU(M8T8 zZ3k7EP}DQO~%yCwc{!Cs5$(rEE+MDfbaC>0lT(RgOTg{AKx#h zia0r{>$W?bZ)L$c@@;F9AI2jki0AwF=5JA&uCO8&X_`05H}^*8Q=;1%tckV9Q-!5t z>_dbn5ya_t>zSx}?Z1gQ!9S+28g-x^I8wOke&dW;Nk%;u#wPpNl2T@a=MrBb<>?Kd zoc-*b>dmOmVyB8%_|+Hw%ggcmAs>5_DT&#ahW@h5`rCsWFm|DQ!fXm3%_QW6V&3K5 z*y;E8+meTt23jUE9WP7~>d#~FYq%&TU5j@mq^R9)<~B`zODb9$o|4#dw==<0R%`Q@c;k- diff --git a/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin b/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin index b6ab8d50e05688560075dda36c690264ab9d94c9..dfb37d4178fd1d5cf8512fb04c74aea04ab3214a 100644 GIT binary patch delta 919 zcmV;I18DrmB*!GMxCkJldl}%g8)!kG4lY@RE#>otwM(!oKtn5Fn+=8$RdY|1*a$)( z=ySL7Saa>hV2tv)Cx`g<@KEde_}?6Y$I)KvAJMHJvpNa%0wB;0kUq+$LJ`dCa_tOE zJ6Dt)9~@Xn@H`)N#UQU+9vevN78)xAwBe|;-cxrpK_N0*DTW)bW(4yulTO+4ah zoFT_s+sihO3Zgx|5ce~~Ep>X#-a+XU1&tGoYnM-hNB(20j4&K5B|g1v~>&)JAv zM7h2o@T;pB?sl~K?E3$L9gEb3r{f$?yrV?t2P^AT0-Iuji4|pplq739voHhR!}}c4VJm9N0`x5XSi=0_J)_O{W{_rtR-HU&vLcs| z^p9|R|1c&ZNc)_jAlXVf5q=3 zl^8mD>K;y{um``VyfS0<_gIkIz75DFBlr5+uE8#asXY delta 919 zcmV;I18DrmB*!GMxCkK1_ZBJ|Dula7G3X|#>&0dmR+E$WYu+3K4*fGjQA1F0nd$6zv)Ntc0I~98x5FG*A@B=VH5$ye-kl&G2}i%N2yUq7*h3e>r9v>j~a{- zWvv9`Kv4-C$YvM0%=}#?G$X}27v3&?e!`q`_BP0Sa`Xqx#JYb#{ud0f>AI}EEU@QB znlPWHC4BeP+W^a~qLbXs(%mJz&H)FNk48%ZL?1TWcZyy-fe8bs+-7x^y+JyhS+zTp ze_IH&H(>EK!A|4?u4&u_Sh9Pw(nrfFpCh5jyrIms?zuE-#--)Q0qZEZ52k--U{}zB zbGY?>Q>3fi38)A|!h|pTFCxL``d}4Z+|Q}%fWNjsw33=QgW|B;Qu60Qe*r&sjKaK*m}cXYU)3e-BH?fz zhBEi)SvzU#E05Ds^edDH@`WsfXWWFCMw)(1|E@`Jhyt_k=l2`=CIpis5+vG?zZn1k diff --git a/test_fixtures/masp_proofs/EA7A88B1429EFFF0AE7167F6FBEF52D368B771AD525817E722EA3E12B0A96971.bin b/test_fixtures/masp_proofs/EA7A88B1429EFFF0AE7167F6FBEF52D368B771AD525817E722EA3E12B0A96971.bin index 7695d29496711e756e0726dc9bb3e6812d5b9955..81801c7ea71aae9d14599222393c3eb8e8bc4aaf 100644 GIT binary patch delta 1356 zcmV-S1+)6%JK{UAixD99IR}kOSF+FXY1V{Uu{vQ?tLmaXQj$NdU!g2fnh|f4s}VpT z@f8PLJOqG2`2I^C1IAqW?BcFr0A4%=q{%(3=~)RmlM50-K@buY*vc|R(zyLjShD0J zblO5EaaPq;To3jBERgjx-U3a5&0`BlvmL)WuWJlTr4m`Rd-C*(KIrJp<|tR2amPAEZ)nWPv!NB01Al|%uQglWu!=_k zNe`&-vvRFI^?Fk{P4vAZKHsPnVT||5*qgDTtuwxRFCL4g^Z#vx{xKnksylB%2Sjy zJqZLCbq-3%=f#%OUV*%242(`(`9$(kuqLf@0~*`fDUV%i4EFHd-9Mfs zAvd|FAm~Fw311}8H67XG=Br@QEAvdL_}ZmHDTu+{ntvILFA1?b69?jHOIBh|XW3~K zDKY8xp_F=ly|8s@&&{RuZ#o|4nYZRJEH$2uDOb!)x55z{!GKWD@(J{$4Id*}bw+t^fVcE1<<8B8_q6{1$4ecVOEN+U zbLR7<_rLw^{!wlGVNT>lDW*}P+2105NhuUNRDZ&Uz}BWFP!7t|d};C8Q@@6%lMe5sOI+FR) zKpB&`hWuzQA*f|hf*1|QO2AKjrX{6la(`1qZx|{gB~UUEd*q787rjJ)v!NB01Amxo)qk1h@X^<) zEFGRqP=jkG1qllS=_{TH_(siW-P=ZdFx zp71t3XfBwX#(1(7U9j)a3_W>WBIH_OzfvVHIru$Fhf5DMyH8Wb(#lG@{1gM%pQ3az zwY;3hWZ%J8y}a)zSbvNuek4M<3ihrC>CuWm;I`t5!Qs=k;U!?PDoOcFOnYD+?eV%A z`aW`|8?pC`jM8_u^jp*ko(8NfWUjom4@l^_nMNP(t$2od4<~km?iOo~U-+X_&KDVG zh=&~xn$Jp zU9K*8P~ilPSiBV3f{kP0i$W`jN(>XNy^MN~s?{rzCOji^EG?Tf>|bAD38;r=Hlk(M zVy9s<0*CRAd4DK2S79c)=n`3lzcF!;$UK?b)YO%%Gn`2~PZDtT!z_+CLS0^uBKfjC z8HEQY=U&^VMnoqh`wx?XB=1?*A`U^occhJEy^gx#NT?L?mEA`<;s4x_|zt?FEM%E7noF4#m%abmAM5 z0BxMz=>F+UGV4(FTL`H+w1-(7a!Q-jhk$nk&py9um?DI0zh?N0`LIARr{+2krM8=u zg)F1@T!nbG?jp~&aC?fzrhx^tMxkGcf$Cx=up#5|3 zy?k);R)5IHH>Dzd6mxS%=$azk2$cUuSl3^#DGS$|-h8#S$QQA_vYkwMRlMB*k+6QO%1 z_n&~BO}!g>L{)sgrEvs%3Vo!pID-3EifWW3|0?VOaUARiEooa^h#gxF5%m-%kK;ll zRVd9+x$pfOp?E^UtFQ=@{Y9TGP_p)DxvIFNJc4f{f}e^jcW0ve)(^#fZS~*ZPKDFe z$$t=%-mU_-z>WKiv_S%zmY6duHuF6P@+DsZmgkJiEYi_nc}CwE);&2)bKdB(P^jh4 z?d&88`MDfbgl1NkgGCLjKd^By=q3G20}&aJ2Tch5?;__TSp_qo@%qAG7f_bB`<_-X znoY`LZ6VH_yY>!w-B^qU&BuS@0P>MlH|nUPs)p1^3u)n^6AA6> OWmpyg*uMdjwjC_RgPFMi diff --git a/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin b/test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin index ee5646add2fef586edea8b836a6b5843838d51f1..aeb018888414d86545e5c16c4dc8c8c7521e4c37 100644 GIT binary patch delta 1061 zcmV+=1ls$YESxN`T?-&+&mBi8T9ocJ0!2ws)41?S65R_;jMABN;Jk|Q&51~peG5TB zz`#AZln^c!*0>*8@*SN@uTz|lJN$ z3UO~`YQcGUowECKFcf3Be9A!9-?w%Q=22YCA?x$PkD=PV;lYmzau z6Axtre}|kD-eWQ`_bzi0;zj+MS}dvBT8*RW3deEy5SeBOHx}qDDR4@ZCG@(MKbsQ* z^SA=>Fn?=YjRDG(2wg2_F}U?CExoi&759ksu_^1x$nrJVDcmd4gxeif{Z`!1JQy=~ z3n*&49T{vk*2Kx*1iAn3BUa|Chtm#ZH1wsP{M)mi)eK-E2V9x57vs^<4xpHNjH&3{H@A!))yEHu)>_2VC zf9wdSib-$bGvICcYgoJXJlH`2#>0CXN5}D;aSj=^+e;N$cY%W|H=T{hf_fxN*{HCE z;Y?-N{y~}%qbDdk?q>RSn2>Pxj;9rFi6L}Ew}O+~)GoIL-uG4sWFRZ@i*YmzKAO+= za2xt3FJYc~PuJ6`EWsO30qAnGfk}rCf86cVWN19X%NfnHWn@u#7r&{#ib>2Z1N#qa zt@%U47+4U~mGS(d&=NlXp)PJ7g#pz^5a&<5-&I7@!coy8-B*eBkwrZU-tkS6{A(vs zYo3wY%^ z-9K>UoUJ`z@`~|LfiF%tq)3_hf6Lw23|5E5BKel-Ss;<1$OWlnFY5EQ=otYm1IO(l zYXH&*#W2svV*B3#KPmbkOwEP_vvR2U+FbD)hbju&BLKQ+3^Kob*N?6d!e|<#;6cDw z!_`?9LGA+Q?n^)E>kf+*!K?|2t|nRRa-a6A17bp)VThb%lN@0<|EVwbe|u@Yu}06V zgMmG_LY&xG)1RMb`+z941$vfxN48)~D5EaD7ETx&dXauet5H2-m2l_H6&dqF^0xm+ zLsnu%#&>4qqj6PZ{6@9i*sTBn1mLG2!&H5hKjR94bkv<;+mgqhz{^z5xg?s{3(g>& fYjHxCQAPydU36U9(VUx|2Xi*iOZ_$jllT=R@Bk4E delta 1061 zcmV+=1ls$YESxN`T?-)Aak08o`{Z+(e3>Sm&yv6tHhVzI0xZHU-Q>=3DoGqgs;f)Pw*h{F zkqsgVMYemZ-EL}|S+oBO^a3E%JvxDF-{QVHA#GuccWX;q5ZvkCyr35eimqvlw>O)! z6Axtrf3=)0n{QyS7k`6wW84|o04O#asyiTv zz>_3*e~s~yRpD0ZvqKy`rE+EGSkpTz5*(CLF5Q0znMJj=vW@x?sL%2qqCkA$eirFP z*$eBbHu%5?qKsL(5o*iV+hGTtcKLo;--jw>e-R*Qpv=>|dF$1s&a}8(!>gG5_>5n5 zva$d%SVwE2$c!r{7Fa58D}Y#NuSZ0D#&m%l$`Q5%0~j$Ju)^D97~ zAMc)3l5e0U?;bm{J9@)JA~K)d)H>Ezdz%#T0Ct_Bo8j)JU%fj*9ke9pgnGvrFr>fh zf3EBj}NEVB`{y@WW9&-v>oJ6i3LhwF{ zpK+7Hx7*9!I*KvXL@&^LOz;|t{fiBy2rM(u!<481)nQd=jJ0z}gNq3ZkTf z{^)CO&R*;m=QM9jBmZd+H&(al`oN#j|(@2o|W7VY3Hi1#F+!bkqVE+!0zoq71+Q8yxRz?0u80Q0qc&s!oXe|1s+rab}s{U>xw^72cu-`z}V&ullT=RNFfv7 diff --git a/test_fixtures/masp_proofs/F4F0D829373DDA78336CF39EBA3356453E412F862D949ABE9671C24A3903909E.bin b/test_fixtures/masp_proofs/F4F0D829373DDA78336CF39EBA3356453E412F862D949ABE9671C24A3903909E.bin index 77bf2689797d5f9eb972b0faae98d212fc3ae8b4..b693d517819227ad57345225b59f247498b75cff 100644 GIT binary patch delta 308 zcmV-40n7gV5B(3YoC6?RxfVQXNJXmK3wVF?$jp7uS0&9Kzubipp`P9=t-evSyaOcz zf3~Zjc-MT!pf;tGSp3QDT1Bq4X1COY_8O%^A(&N2JL}GG z?Y9KpX{kbQTn@VMDH>swX;+D6_;Bay*@+v-EepLniXRayzBoj>ZKJ(NY4@B^Y`~1P zcE-jJMM3v-1-zY-N}8P(8zMSsSl<)MIK@)Mb+Jd29=mCW6~BOg;n!8|wZfc#0zC?o G;RhV$hMWKZ delta 308 zcmV-40n7gV5B(3YoC6>Qfr!<^nw&f+n`iI~A2z9{rrrT@b0=J73Bf@=CYcGdyaOcz ze~V%fK;iuJS}3GkG5LM9l$HrrS;mM@WW?GCDz!`d5m4A7*{%#NT|nS`K| za7{2>C%9{U^>Hiwn3vd&qjOeJJxm2*<-}-yd96mnDawB7C5SFi)vW3nKn-OJ4ffY@ zh7LZDufU6q*&L<@lpZ<4+TEX&M}gu`e;84&$;hHio14BdvxNmrZY!gxudzyAP7HCe zyOHuG!m^R?Z~~k+!(>xm1TFg$cK>$dA+Fz_&GvY756!A+Q}w!n2Hm-Lvj5^miL54W z?d~7S(F@~hY;|o#(MuBdIZ@}k=5)tEsWZv|4ai$)iJ0+9+$<{K_*uzg+DCVMUOX1Z|+_;j)`-|v4 zAaI|zN?wtX<0dngBvJ+Eybn|;f$;fPZfj2x<2!eb#ZOTR&ywCZI)(~ zvJNPLDH~faSNX8Tb7U8+K9i8;%^gA|$ZDUaU!PZ(zby>f3((n#f)v?Ff0@sj zi}~T&r3c197_K%Hr4AKaBC+KBM5MDmf6Npfh;;xvnYdG(-oPq8P@R~_%h)#3u=hQzSz?jLAJl?Ez)|enb0PB1h za{yZZ3=0JNmOR+kr=|S{v0eOp^Wj$0lOR91w~s19B{@joPW3rre(~S-KR<;40;3C) G;RhVA-;=HY diff --git a/test_fixtures/masp_proofs/B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin b/test_fixtures/masp_proofs/FDEF024F9FDF73B50BD5C98F056F77D3447A5965177C6D9C605886B0A08995DB.bin similarity index 62% rename from test_fixtures/masp_proofs/B13164F18807523FAB9840F34106FB77DB730FFFE562F2565B0431F7A901CC9A.bin rename to test_fixtures/masp_proofs/FDEF024F9FDF73B50BD5C98F056F77D3447A5965177C6D9C605886B0A08995DB.bin index 138e8d996a07283fffed194b5b0dcb7512f8a109..fdb004369583b2b86a9277819abf18d976b7ee9a 100644 GIT binary patch delta 418 zcmV;T0bTz65B(32Ed;&W2)~grMFc`5_dt<)Wdyz32*0u8ngRs9+X%mtfdd;rdv%Dy z8G9BP(QciBT(F7vFvxGJ1h%vzd$SD$Ljn*LQm8BWO>n=2ItjQt56uyiUVpcR*XDDG(OHdi=0jG=q-%pW>xa*#Vu^-^>QZkAG5sl0`?51njsCLOXpj?`oA4KCWT^>2D67+G<(w)J0cSm|tj# zqly2TICwIh{L6HJ%6DQchy&T!_hb&Q$M${+m#`}V7oD&xf1u*bjswSr@@NAP$!+tx z0xB4&ao-)US M)A+a`2b19k9A7=oK>z>% delta 418 zcmV;T0bTz65B(32Ed&)K0nL#yMFi^H{xXqzWds!?0nM@FngRqBBLU5mfdd;rO;*}j znmck+&PoC&Eclx@kKxzdDCiBaau@X(2n9MYH2KbC9)A!8NGJm$JmW*tN`E2 zMg9%<_y^f8liUL>1RhK(39}6ZLjn+^4bIGj?xXJSz)HKh2Vtp`UfHV^{{R2~ z|NsC0|NsB3{zIazHdQ`diV~){b37K;IsZAz^(lzuvemB|wue8-*zS+^`PMP!Q_SJq z;L)S8gCEqeF3+B&SeN3+pZtRz7JY*rNYdJXeLFjm1bcC-U*s^SY`GXfSfK<~=6Uu8 z*XJlkeD>2Xba2$ia{K^)`r=t4R!u?zi*gc~4uC2qr>|hAdgKEv#)Srj<)cGQuoyo@ ze&lGEr^62(8xs~Wk*S`*{*4|ftXD3=Mxksmp%9nj{e!amQT3J1@OHJmj90Lor|cL% zfABa1h2$lFkDa>B3F>pElN4_lokLs}?3q;nIH~FQr`=S$8zHL^SV}l#utOY5_!8@M M*Vx7y0F&Vd9A=cw#Q*>R From d21925c095180810b20ec1e08fd8b6eee7d64896 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 6 Feb 2024 18:10:46 +0100 Subject: [PATCH 12/15] Fixes e2e test --- crates/tests/src/e2e/ledger_tests.rs | 59 ++++++++++++++++------------ 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/crates/tests/src/e2e/ledger_tests.rs b/crates/tests/src/e2e/ledger_tests.rs index 3cead61acf..cda133ebef 100644 --- a/crates/tests/src/e2e/ledger_tests.rs +++ b/crates/tests/src/e2e/ledger_tests.rs @@ -724,34 +724,43 @@ fn wrapper_disposable_signer() -> Result<()> { let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); - let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; - + // Add the relevant viewing keys to the wallet otherwise the shielded + // context won't precache the masp data let tx_args = vec![ - "transfer", - "--source", - ALBERT, - "--target", - AA_PAYMENT_ADDRESS, - "--token", - NAM, - "--amount", - "50", - "--ledger-address", - &validator_one_rpc, + "add", + "--alias", + "alias_a", + "--value", + AA_VIEWING_KEY, + "--unsafe-dont-encrypt", ]; - let mut client = run!(test, Bin::Client, tx_args, Some(720))?; + let mut client = run!(test, Bin::Wallet, tx_args, Some(120))?; + client.assert_success(); - client.exp_string(TX_ACCEPTED)?; - client.exp_string(TX_APPLIED_SUCCESS)?; + let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; + + // Produce three different output descriptions to spend + for _ in 0..3 { + let tx_args = vec![ + "transfer", + "--source", + ALBERT, + "--target", + AA_PAYMENT_ADDRESS, + "--token", + NAM, + "--amount", + "50", + "--ledger-address", + &validator_one_rpc, + ]; + let mut client = run!(test, Bin::Client, tx_args, Some(720))?; + client.exp_string(TX_ACCEPTED)?; + client.exp_string(TX_APPLIED_SUCCESS)?; + } let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; - let tx_args = vec![ - "shielded-sync", - "--viewing-keys", - AA_VIEWING_KEY, - "--node", - &validator_one_rpc, - ]; + let tx_args = vec!["shielded-sync", "--node", &validator_one_rpc]; let mut client = run!(test, Bin::Client, tx_args, Some(120))?; client.assert_success(); @@ -809,8 +818,8 @@ fn wrapper_disposable_signer() -> Result<()> { client.exp_string("Error while processing transaction's fees")?; // Try another valid fee unshielding and masp transaction in the same tx, - // with the same source. This tests that the client can properly fetch data - // and construct these kind of transactions + // with the same source. This tests that the client can properly + // construct multiple transactions together let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; let tx_args = vec![ "transfer", From c7070fd3b0b931ca2d3d8bc7b300f1020f6208c5 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 6 Feb 2024 19:08:06 +0100 Subject: [PATCH 13/15] Refactors the `ShieldedUtils` trait --- crates/apps/src/lib/bench_utils.rs | 99 +++++++----------------- crates/sdk/src/masp.rs | 118 +++++++---------------------- 2 files changed, 55 insertions(+), 162 deletions(-) diff --git a/crates/apps/src/lib/bench_utils.rs b/crates/apps/src/lib/bench_utils.rs index bcb4aac198..9cff3d0368 100644 --- a/crates/apps/src/lib/bench_utils.rs +++ b/crates/apps/src/lib/bench_utils.rs @@ -76,7 +76,7 @@ use namada::types::token::{Amount, DenominatedAmount, Transfer}; use namada::vm::wasm::run; use namada::{proof_of_stake, tendermint}; use namada_sdk::masp::{ - self, ShieldedContext, ShieldedTransfer, ShieldedUtils, + self, ContextSyncStatus, ShieldedContext, ShieldedTransfer, ShieldedUtils, }; pub use namada_sdk::tx::{ TX_BECOME_VALIDATOR_WASM, TX_BOND_WASM, TX_BRIDGE_POOL_WASM, @@ -656,42 +656,26 @@ impl ShieldedUtils for BenchShieldedUtils { async fn load( &self, ctx: &mut ShieldedContext, + force_confirmed: bool, ) -> std::io::Result<()> { // Try to load shielded context from file - let mut ctx_file = File::open( - self.context_dir.0.path().to_path_buf().join(FILE_NAME), - )?; - let mut bytes = Vec::new(); - ctx_file.read_to_end(&mut bytes)?; - // Fill the supplied context with the deserialized object - *ctx = ShieldedContext { - utils: ctx.utils.clone(), - ..ShieldedContext::deserialize(&mut &bytes[..])? + let file_name = if force_confirmed { + FILE_NAME + } else { + match ctx.sync_status { + ContextSyncStatus::Confirmed => FILE_NAME, + ContextSyncStatus::Speculative => SPECULATIVE_FILE_NAME, + } }; - Ok(()) - } - - /// Try to load the last saved speculative shielded context from the given - /// context directory. If this fails, then leave the current context - /// unchanged. - async fn load_speculative( - &self, - ctx: &mut ShieldedContext, - ) -> std::io::Result<()> { - // Try to load shielded context from file let mut ctx_file = File::open( - self.context_dir - .0 - .path() - .to_path_buf() - .join(SPECULATIVE_FILE_NAME), + self.context_dir.0.path().to_path_buf().join(file_name), )?; let mut bytes = Vec::new(); ctx_file.read_to_end(&mut bytes)?; // Fill the supplied context with the deserialized object *ctx = ShieldedContext { utils: ctx.utils.clone(), - ..ShieldedContext::::deserialize(&mut &bytes[..])? + ..ShieldedContext::deserialize(&mut &bytes[..])? }; Ok(()) } @@ -701,8 +685,14 @@ impl ShieldedUtils for BenchShieldedUtils { &self, ctx: &ShieldedContext, ) -> std::io::Result<()> { + let (tmp_file_name, file_name) = match ctx.sync_status { + ContextSyncStatus::Confirmed => (TMP_FILE_NAME, FILE_NAME), + ContextSyncStatus::Speculative => { + (SPECULATIVE_TMP_FILE_NAME, SPECULATIVE_FILE_NAME) + } + }; let tmp_path = - self.context_dir.0.path().to_path_buf().join(TMP_FILE_NAME); + self.context_dir.0.path().to_path_buf().join(tmp_file_name); { // First serialize the shielded context into a temporary file. // Inability to create this file implies a simultaneuous write is in @@ -723,55 +713,20 @@ impl ShieldedUtils for BenchShieldedUtils { // corrupt data. std::fs::rename( tmp_path, - self.context_dir.0.path().to_path_buf().join(FILE_NAME), + self.context_dir.0.path().to_path_buf().join(file_name), )?; // Remove the speculative file if present since it's state is // overwritten by the confirmed one we just saved - let _ = std::fs::remove_file(SPECULATIVE_FILE_NAME); - Ok(()) - } - - /// Save this speculative shielded context into its associated context - /// directory - async fn save_speculative( - &self, - ctx: &ShieldedContext, - ) -> std::io::Result<()> { - // TODO: use mktemp crate? - let tmp_path = self - .context_dir - .0 - .path() - .to_path_buf() - .join(SPECULATIVE_TMP_FILE_NAME); - { - // First serialize the shielded context into a temporary file. - // Inability to create this file implies a simultaneuous write - // is in progress. In this case, immediately - // fail. This is unproblematic because the data - // intended to be stored can always be re-fetched - // from the blockchain. - let mut ctx_file = OpenOptions::new() - .write(true) - .create_new(true) - .open(tmp_path.clone())?; - let mut bytes = Vec::new(); - ctx.serialize(&mut bytes) - .expect("cannot serialize shielded context"); - ctx_file.write_all(&bytes[..])?; + if let ContextSyncStatus::Confirmed = ctx.sync_status { + let _ = std::fs::remove_file( + self.context_dir + .0 + .path() + .to_path_buf() + .join(SPECULATIVE_FILE_NAME), + ); } - // Atomically update the old shielded context file with new data. - // Atomicity is required to prevent other client instances from - // reading corrupt data. - std::fs::rename( - tmp_path, - self.context_dir - .0 - .path() - .to_path_buf() - .join(SPECULATIVE_FILE_NAME), - )?; Ok(()) } } diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index 6441126c06..8aaf61015f 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -461,29 +461,18 @@ pub trait ShieldedUtils: /// Get a MASP transaction prover fn local_tx_prover(&self) -> LocalTxProver; - /// Load up the currently confirmed saved ShieldedContext + /// Load up the currently saved ShieldedContext async fn load( &self, ctx: &mut ShieldedContext, + force_confirmed: bool, ) -> std::io::Result<()>; - /// Load up the currently saved speculative ShieldedContext - async fn load_speculative( - &self, - ctx: &mut ShieldedContext, - ) -> std::io::Result<()>; - - /// Save the given confirmed ShieldedContext for future loads + /// Save the given ShieldedContext for future loads async fn save( &self, ctx: &ShieldedContext, ) -> std::io::Result<()>; - - /// Save the given speculative ShieldedContext for future loads - async fn save_speculative( - &self, - ctx: &ShieldedContext, - ) -> std::io::Result<()>; } /// Make a ViewingKey that can view notes encrypted by given ExtendedSpendingKey @@ -667,19 +656,14 @@ impl ShieldedContext { /// Try to load the last saved shielded context from the given context /// directory. If this fails, then leave the current context unchanged. pub async fn load(&mut self) -> std::io::Result<()> { - match self.sync_status { - ContextSyncStatus::Confirmed => self.utils.clone().load(self).await, - ContextSyncStatus::Speculative => { - self.utils.clone().load_speculative(self).await - } - } + self.utils.clone().load(self, false).await } /// Try to load the last saved confirmed shielded context from the given /// context directory. If this fails, then leave the current context /// unchanged. pub async fn load_confirmed(&mut self) -> std::io::Result<()> { - self.utils.clone().load(self).await?; + self.utils.clone().load(self, true).await?; Ok(()) } @@ -688,12 +672,7 @@ impl ShieldedContext { /// state to be saved is confirmed than also delete the speculative one (if /// available) pub async fn save(&self) -> std::io::Result<()> { - match self.sync_status { - ContextSyncStatus::Confirmed => self.utils.save(self).await, - ContextSyncStatus::Speculative => { - self.utils.save_speculative(self).await - } - } + self.utils.save(self).await } /// Update the merkle tree of witnesses the first time we @@ -3793,8 +3772,6 @@ pub mod fs { #[cfg_attr(feature = "async-send", async_trait::async_trait)] #[cfg_attr(not(feature = "async-send"), async_trait::async_trait(?Send))] - // FIXME: I can probably refactor everything to have the associated - // contextsSycn state on this trait impl ShieldedUtils for FsShieldedUtils { fn local_tx_prover(&self) -> LocalTxProver { if let Ok(params_dir) = env::var(ENV_VAR_MASP_PARAMS_DIR) { @@ -3814,29 +3791,18 @@ pub mod fs { async fn load( &self, ctx: &mut ShieldedContext, + force_confirmed: bool, ) -> std::io::Result<()> { // Try to load shielded context from file - let mut ctx_file = File::open(self.context_dir.join(FILE_NAME))?; - let mut bytes = Vec::new(); - ctx_file.read_to_end(&mut bytes)?; - // Fill the supplied context with the deserialized object - *ctx = ShieldedContext { - utils: ctx.utils.clone(), - ..ShieldedContext::::deserialize(&mut &bytes[..])? + let file_name = if force_confirmed { + FILE_NAME + } else { + match ctx.sync_status { + ContextSyncStatus::Confirmed => FILE_NAME, + ContextSyncStatus::Speculative => SPECULATIVE_FILE_NAME, + } }; - Ok(()) - } - - /// Try to load the last saved speculative shielded context from the - /// given context directory. If this fails, then leave the - /// current context unchanged. - async fn load_speculative( - &self, - ctx: &mut ShieldedContext, - ) -> std::io::Result<()> { - // Try to load shielded context from file - let mut ctx_file = - File::open(self.context_dir.join(SPECULATIVE_FILE_NAME))?; + let mut ctx_file = File::open(self.context_dir.join(file_name))?; let mut bytes = Vec::new(); ctx_file.read_to_end(&mut bytes)?; // Fill the supplied context with the deserialized object @@ -3854,7 +3820,13 @@ pub mod fs { ctx: &ShieldedContext, ) -> std::io::Result<()> { // TODO: use mktemp crate? - let tmp_path = self.context_dir.join(TMP_FILE_NAME); + let (tmp_file_name, file_name) = match ctx.sync_status { + ContextSyncStatus::Confirmed => (TMP_FILE_NAME, FILE_NAME), + ContextSyncStatus::Speculative => { + (SPECULATIVE_TMP_FILE_NAME, SPECULATIVE_FILE_NAME) + } + }; + let tmp_path = self.context_dir.join(tmp_file_name); { // First serialize the shielded context into a temporary file. // Inability to create this file implies a simultaneuous write @@ -3874,50 +3846,16 @@ pub mod fs { // Atomically update the old shielded context file with new data. // Atomicity is required to prevent other client instances from // reading corrupt data. - std::fs::rename(tmp_path, self.context_dir.join(FILE_NAME))?; + std::fs::rename(tmp_path, self.context_dir.join(file_name))?; // Remove the speculative file if present since it's state is // overruled by the confirmed one we just saved - let _ = std::fs::remove_file( - self.context_dir.join(SPECULATIVE_FILE_NAME), - ); - - Ok(()) - } - - // FIXME: refactor, the functions are exactly the same, just pass the - // enum and modify the filename based on that - /// Save this speculative shielded context into its associated context - /// directory - async fn save_speculative( - &self, - ctx: &ShieldedContext, - ) -> std::io::Result<()> { - // TODO: use mktemp crate? - let tmp_path = self.context_dir.join(SPECULATIVE_TMP_FILE_NAME); - { - // First serialize the shielded context into a temporary file. - // Inability to create this file implies a simultaneuous write - // is in progress. In this case, immediately - // fail. This is unproblematic because the data - // intended to be stored can always be re-fetched - // from the blockchain. - let mut ctx_file = OpenOptions::new() - .write(true) - .create_new(true) - .open(tmp_path.clone())?; - let mut bytes = Vec::new(); - ctx.serialize(&mut bytes) - .expect("cannot serialize shielded context"); - ctx_file.write_all(&bytes[..])?; + if let ContextSyncStatus::Confirmed = ctx.sync_status { + let _ = std::fs::remove_file( + self.context_dir.join(SPECULATIVE_FILE_NAME), + ); } - // Atomically update the old shielded context file with new data. - // Atomicity is required to prevent other client instances from - // reading corrupt data. - std::fs::rename( - tmp_path, - self.context_dir.join(SPECULATIVE_FILE_NAME), - )?; + Ok(()) } } From 88e401b1fc4481ddfa8c74f9b2318273fa4c6e87 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 6 Feb 2024 19:49:11 +0100 Subject: [PATCH 14/15] Changelog #2534 --- .../unreleased/SDK/2534-invalidate-masp-notes-in-client.md | 6 ++++++ .../improvements/2534-invalidate-masp-notes-in-client.md | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 .changelog/unreleased/SDK/2534-invalidate-masp-notes-in-client.md create mode 100644 .changelog/unreleased/improvements/2534-invalidate-masp-notes-in-client.md diff --git a/.changelog/unreleased/SDK/2534-invalidate-masp-notes-in-client.md b/.changelog/unreleased/SDK/2534-invalidate-masp-notes-in-client.md new file mode 100644 index 0000000000..d4e0ef86bf --- /dev/null +++ b/.changelog/unreleased/SDK/2534-invalidate-masp-notes-in-client.md @@ -0,0 +1,6 @@ +- Reworked the sdk to support the new speculative state of the + `ShieldedContext`:\n-`ShieldedContext` now has an extra field to determin its + state\n-When calling `gen_shielded_transfer` the context now invalidates the + spent notes (if any)\n-The fee unshielding `Transaction` is now built before + the actual transaction\n-`find_viewing_key` only requires a shared reference + now ([\#2534](https://github.com/anoma/namada/pull/2534)) \ No newline at end of file diff --git a/.changelog/unreleased/improvements/2534-invalidate-masp-notes-in-client.md b/.changelog/unreleased/improvements/2534-invalidate-masp-notes-in-client.md new file mode 100644 index 0000000000..d1c9cd659f --- /dev/null +++ b/.changelog/unreleased/improvements/2534-invalidate-masp-notes-in-client.md @@ -0,0 +1,3 @@ +- The client, when generating a shielded transfer, invalidates the + masp notes that have been spent without the need to sync with a node. + ([\#2534](https://github.com/anoma/namada/pull/2534)) \ No newline at end of file From 8f5e41b56ed3f35cb0a14f2ddd757958c4423ea0 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 13 Feb 2024 14:33:00 +0100 Subject: [PATCH 15/15] Refactors `check_balance_too_low_err` to accept either a balance key or a balance --- crates/sdk/src/tx.rs | 260 ++++++++++++++++--------------------------- 1 file changed, 98 insertions(+), 162 deletions(-) diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index a95aa5cc75..158b069e1f 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -1804,49 +1804,22 @@ pub async fn build_bond( // balance let bond_source = source.as_ref().unwrap_or(&validator); let native_token = context.native_token(); - if &updated_balance.source == bond_source + let check_balance = if &updated_balance.source == bond_source && updated_balance.token == native_token { - if *amount > updated_balance.post_balance { - if tx_args.force { - edisplay_line!( - context.io(), - "The balance of the source {} of token {} is lower than \ - the amount to be transferred. Amount to transfer is {} \ - and the balance is {}.", - bond_source, - native_token, - context.format_amount(&native_token, *amount).await, - context - .format_amount( - &native_token, - updated_balance.post_balance - ) - .await, - ); - } else { - return Err(Error::from(TxSubmitError::BalanceTooLow( - bond_source.clone(), - native_token, - amount.to_string_native(), - updated_balance.post_balance.to_string_native(), - ))); - } - } + CheckBalance::Balance(updated_balance.post_balance) } else { - let balance_key = balance_key(&native_token, bond_source); - - // TODO Should we state the same error message for the native token? - check_balance_too_low_err( - &native_token, - bond_source, - *amount, - balance_key, - tx_args.force, - context, - ) - .await?; - } + CheckBalance::Query(balance_key(&native_token, bond_source)) + }; + check_balance_too_low_err( + &native_token, + bond_source, + *amount, + check_balance, + tx_args.force, + context, + ) + .await?; let data = pos::Bond { validator, @@ -2153,49 +2126,23 @@ pub async fn build_ibc_transfer( ))); } - if updated_balance.source == source && updated_balance.token == args.token { - if validated_amount.amount() > updated_balance.post_balance { - if args.tx.force { - edisplay_line!( - context.io(), - "The balance of the source {} of token {} is lower than \ - the amount to be transferred. Amount to transfer is {} \ - and the balance is {}.", - source, - args.token, - context - .format_amount(&args.token, validated_amount.amount()) - .await, - context - .format_amount( - &args.token, - updated_balance.post_balance - ) - .await, - ); - } else { - return Err(Error::from(TxSubmitError::BalanceTooLow( - source.clone(), - args.token.clone(), - validated_amount.amount().to_string_native(), - updated_balance.post_balance.to_string_native(), - ))); - } - } + let check_balance = if updated_balance.source == source + && updated_balance.token == args.token + { + CheckBalance::Balance(updated_balance.post_balance) } else { - // Check source balance - let balance_key = balance_key(&args.token, &source); - - check_balance_too_low_err( - &args.token, - &source, - validated_amount.amount(), - balance_key, - args.tx.force, - context, - ) - .await?; - } + CheckBalance::Query(balance_key(&args.token, &source)) + }; + + check_balance_too_low_err( + &args.token, + &source, + validated_amount.amount(), + check_balance, + args.tx.force, + context, + ) + .await?; let tx_code_hash = query_wasm_code_hash(context, args.tx_code_path.to_str().unwrap()) @@ -2491,48 +2438,23 @@ pub async fn build_transfer( args.amount = InputAmount::Validated(validated_amount); - // Check source balance - if updated_balance.source == source && updated_balance.token == args.token { - if validated_amount.amount() > updated_balance.post_balance { - if args.tx.force { - edisplay_line!( - context.io(), - "The balance of the source {} of token {} is lower than \ - the amount to be transferred. Amount to transfer is {} \ - and the balance is {}.", - source, - args.token, - context - .format_amount(&args.token, validated_amount.amount()) - .await, - context - .format_amount( - &args.token, - updated_balance.post_balance - ) - .await, - ); - } else { - return Err(Error::from(TxSubmitError::BalanceTooLow( - source.clone(), - args.token.clone(), - validated_amount.amount().to_string_native(), - updated_balance.post_balance.to_string_native(), - ))); - } - } + let check_balance = if updated_balance.source == source + && updated_balance.token == args.token + { + CheckBalance::Balance(updated_balance.post_balance) } else { - let balance_key = balance_key(&args.token, &source); - check_balance_too_low_err( - &args.token, - &source, - validated_amount.amount(), - balance_key, - args.tx.force, - context, - ) - .await?; - } + CheckBalance::Query(balance_key(&args.token, &source)) + }; + + check_balance_too_low_err( + &args.token, + &source, + validated_amount.amount(), + check_balance, + args.tx.force, + context, + ) + .await?; let masp_addr = MASP; @@ -3100,6 +3022,11 @@ async fn target_exists_or_err( .await } +enum CheckBalance { + Balance(token::Amount), + Query(storage::Key), +} + /// Checks the balance at the given address is enough to transfer the /// given amount, along with the balance even existing. Force /// overrides this. @@ -3107,62 +3034,71 @@ async fn check_balance_too_low_err( token: &Address, source: &Address, amount: token::Amount, - balance_key: storage::Key, + balance: CheckBalance, force: bool, context: &N, ) -> Result<()> { - match rpc::query_storage_value::( - context.client(), - &balance_key, - ) - .await - { - Ok(balance) => match balance.checked_sub(amount) { - Some(_) => Ok(()), - None => { - if force { - edisplay_line!( - context.io(), - "The balance of the source {} of token {} is lower \ - than the amount to be transferred. Amount to \ - transfer is {} and the balance is {}.", - source, - token, - context.format_amount(token, amount).await, - context.format_amount(token, balance).await, - ); - Ok(()) - } else { - Err(Error::from(TxSubmitError::BalanceTooLow( - source.clone(), - token.clone(), - amount.to_string_native(), - balance.to_string_native(), - ))) + let balance = match balance { + CheckBalance::Balance(amt) => amt, + CheckBalance::Query(ref balance_key) => { + match rpc::query_storage_value::( + context.client(), + balance_key, + ) + .await + { + Ok(amt) => amt, + Err(Error::Query( + QueryError::General(_) | QueryError::NoSuchKey(_), + )) => { + if force { + edisplay_line!( + context.io(), + "No balance found for the source {} of token {}", + source, + token + ); + return Ok(()); + } else { + return Err(Error::from( + TxSubmitError::NoBalanceForToken( + source.clone(), + token.clone(), + ), + )); + } } + // We're either facing a no response or a conversion error + // either way propagate it up + Err(err) => return Err(err), } - }, - Err(Error::Query( - QueryError::General(_) | QueryError::NoSuchKey(_), - )) => { + } + }; + + match balance.checked_sub(amount) { + Some(_) => Ok(()), + None => { if force { edisplay_line!( context.io(), - "No balance found for the source {} of token {}", + "The balance of the source {} of token {} is lower than \ + the amount to be transferred. Amount to transfer is {} \ + and the balance is {}.", source, - token + token, + context.format_amount(token, amount).await, + context.format_amount(token, balance).await, ); Ok(()) } else { - Err(Error::from(TxSubmitError::NoBalanceForToken( + Err(Error::from(TxSubmitError::BalanceTooLow( source.clone(), token.clone(), + amount.to_string_native(), + balance.to_string_native(), ))) } } - // We're either facing a no response or a conversion error - // either way propagate it up - Err(err) => Err(err), } }