From 1dfd4bf979dd7479773b157ef64efdefa910fed4 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Sun, 11 Feb 2024 22:55:21 -0800 Subject: [PATCH 1/4] Remove unused index from the UpdateKeyValue finalize operation --- ledger/block/src/transactions/confirmed/mod.rs | 14 ++------------ ledger/store/src/program/finalize.rs | 2 +- .../program/src/logic/finalize_operation/bits.rs | 16 ++++------------ .../src/logic/finalize_operation/bytes.rs | 8 ++------ .../program/src/logic/finalize_operation/mod.rs | 8 ++++---- .../src/logic/finalize_operation/serialize.rs | 9 +++------ 6 files changed, 16 insertions(+), 41 deletions(-) diff --git a/ledger/block/src/transactions/confirmed/mod.rs b/ledger/block/src/transactions/confirmed/mod.rs index b1d4164d9a..f859ad8947 100644 --- a/ledger/block/src/transactions/confirmed/mod.rs +++ b/ledger/block/src/transactions/confirmed/mod.rs @@ -356,12 +356,7 @@ pub mod test_helpers { true => vec![FinalizeOperation::InitializeMapping(Uniform::rand(rng))], false => vec![ FinalizeOperation::InitializeMapping(Uniform::rand(rng)), - FinalizeOperation::UpdateKeyValue( - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - ), + FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)), ], }; @@ -461,12 +456,7 @@ mod test { // Create an `AcceptedExecution` with valid `FinalizeOperation`s. let finalize_operations = vec![ FinalizeOperation::InsertKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)), - FinalizeOperation::UpdateKeyValue( - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - ), + FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)), FinalizeOperation::RemoveKeyValue(Uniform::rand(rng), Uniform::rand(rng)), ]; let confirmed = ConfirmedTransaction::accepted_execute(index, tx.clone(), finalize_operations.clone()).unwrap(); diff --git a/ledger/store/src/program/finalize.rs b/ledger/store/src/program/finalize.rs index a9608ea420..a3d4f6d7d1 100644 --- a/ledger/store/src/program/finalize.rs +++ b/ledger/store/src/program/finalize.rs @@ -244,7 +244,7 @@ pub trait FinalizeStorage: 'static + Clone + Send + Sync { })?; // Return the finalize operation. - Ok(FinalizeOperation::UpdateKeyValue(to_mapping_id(&program_id, &mapping_name)?, 0u64, key_id, value_id)) + Ok(FinalizeOperation::UpdateKeyValue(to_mapping_id(&program_id, &mapping_name)?, key_id, value_id)) } /// Removes the key-value pair for the given `program ID`, `mapping name`, and `key` from storage. diff --git a/synthesizer/program/src/logic/finalize_operation/bits.rs b/synthesizer/program/src/logic/finalize_operation/bits.rs index 504bbd9d15..c912fbf223 100644 --- a/synthesizer/program/src/logic/finalize_operation/bits.rs +++ b/synthesizer/program/src/logic/finalize_operation/bits.rs @@ -52,14 +52,12 @@ impl FromBits for FinalizeOperation { 2 => { // Read the mapping ID. let mapping_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_le(&next_bits(64)?)?; // Read the key ID. let key_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; // Read the value ID. let value_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::UpdateKeyValue(mapping_id, index, key_id, value_id)) + Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id)) } 3 => { // Read the mapping ID. @@ -122,14 +120,12 @@ impl FromBits for FinalizeOperation { 2 => { // Read the mapping ID. let mapping_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_be(&next_bits(64)?)?; // Read the key ID. let key_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; // Read the value ID. let value_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::UpdateKeyValue(mapping_id, index, key_id, value_id)) + Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id)) } 3 => { // Read the mapping ID. @@ -176,13 +172,11 @@ impl ToBits for FinalizeOperation { // Write the value ID. value_id.write_bits_le(vec); } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { // Write the variant. 2u8.write_bits_le(vec); // Write the mapping ID. mapping_id.write_bits_le(vec); - // Write the index. - index.write_bits_le(vec); // Write the key ID. key_id.write_bits_le(vec); // Write the value ID. @@ -230,13 +224,11 @@ impl ToBits for FinalizeOperation { // Write the value ID. value_id.write_bits_be(vec); } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { // Write the variant. 2u8.write_bits_be(vec); // Write the mapping ID. mapping_id.write_bits_be(vec); - // Write the index. - index.write_bits_be(vec); // Write the key ID. key_id.write_bits_be(vec); // Write the value ID. diff --git a/synthesizer/program/src/logic/finalize_operation/bytes.rs b/synthesizer/program/src/logic/finalize_operation/bytes.rs index a88e65a10c..88ba12f30f 100644 --- a/synthesizer/program/src/logic/finalize_operation/bytes.rs +++ b/synthesizer/program/src/logic/finalize_operation/bytes.rs @@ -40,14 +40,12 @@ impl FromBytes for FinalizeOperation { 2 => { // Read the mapping ID. let mapping_id = Field::read_le(&mut reader)?; - // Read the index. - let index = u64::read_le(&mut reader)?; // Read the key ID. let key_id = Field::read_le(&mut reader)?; // Read the value ID. let value_id = Field::read_le(&mut reader)?; // Return the finalize operation. - Ok(Self::UpdateKeyValue(mapping_id, index, key_id, value_id)) + Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id)) } 3 => { // Read the mapping ID. @@ -94,13 +92,11 @@ impl ToBytes for FinalizeOperation { // Write the value ID. value_id.write_le(&mut writer)?; } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { // Write the variant. 2u8.write_le(&mut writer)?; // Write the mapping ID. mapping_id.write_le(&mut writer)?; - // Write the index. - index.write_le(&mut writer)?; // Write the key ID. key_id.write_le(&mut writer)?; // Write the value ID. diff --git a/synthesizer/program/src/logic/finalize_operation/mod.rs b/synthesizer/program/src/logic/finalize_operation/mod.rs index 03f25cb2e5..2baed2917f 100644 --- a/synthesizer/program/src/logic/finalize_operation/mod.rs +++ b/synthesizer/program/src/logic/finalize_operation/mod.rs @@ -27,9 +27,9 @@ pub enum FinalizeOperation { /// Inserts a key-value leaf into the mapping tree, /// as (`mapping ID`, `key ID`, `value ID`). InsertKeyValue(Field, Field, Field), - /// Updates the key-value leaf at the given index in the mapping tree, - /// as (`mapping ID`, `index`, `key ID`, `value ID`). - UpdateKeyValue(Field, u64, Field, Field), + /// Updates the key-value leaf in the mapping tree, + /// as (`mapping ID`, `key ID`, `value ID`). + UpdateKeyValue(Field, Field, Field), /// Removes the key-value leaf at the given index in the mapping tree, /// as (`mapping ID`, `index`). RemoveKeyValue(Field, u64), @@ -58,7 +58,7 @@ pub(crate) mod test_helpers { /// Samples a random `UpdateKeyValue`. pub(crate) fn sample_update_key_value(rng: &mut TestRng) -> FinalizeOperation { - FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), rng.gen(), Uniform::rand(rng), Uniform::rand(rng)) + FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)) } /// Samples a random `RemoveKeyValue`. diff --git a/synthesizer/program/src/logic/finalize_operation/serialize.rs b/synthesizer/program/src/logic/finalize_operation/serialize.rs index 1a128d3e94..253fec5709 100644 --- a/synthesizer/program/src/logic/finalize_operation/serialize.rs +++ b/synthesizer/program/src/logic/finalize_operation/serialize.rs @@ -35,11 +35,10 @@ impl Serialize for FinalizeOperation { operation.serialize_field("value_id", value_id)?; operation.end() } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { - let mut operation = serializer.serialize_struct("FinalizeOperation", 5)?; + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { + let mut operation = serializer.serialize_struct("FinalizeOperation", 4)?; operation.serialize_field("type", "update_key_value")?; operation.serialize_field("mapping_id", mapping_id)?; - operation.serialize_field("index", index)?; operation.serialize_field("key_id", key_id)?; operation.serialize_field("value_id", value_id)?; operation.end() @@ -97,14 +96,12 @@ impl<'de, N: Network> Deserialize<'de> for FinalizeOperation { Some("update_key_value") => { // Deserialize the mapping ID. let mapping_id = DeserializeExt::take_from_value::(&mut operation, "mapping_id")?; - // Deserialize the index. - let index = DeserializeExt::take_from_value::(&mut operation, "index")?; // Deserialize the key ID. let key_id = DeserializeExt::take_from_value::(&mut operation, "key_id")?; // Deserialize the value ID. let value_id = DeserializeExt::take_from_value::(&mut operation, "value_id")?; // Return the operation. - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) + Self::UpdateKeyValue(mapping_id, key_id, value_id) } Some("remove_key_value") => { // Deserialize the mapping ID. From 8732f5fd72cec741eee0cc97172aed98eea19dca Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Sun, 11 Feb 2024 23:00:11 -0800 Subject: [PATCH 2/4] Regenerate genesis block --- parameters/src/mainnet/genesis.rs | 2 +- .../src/mainnet/resources/block.genesis | Bin 13989 -> 13925 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/parameters/src/mainnet/genesis.rs b/parameters/src/mainnet/genesis.rs index 45196d18d3..bd0dc48cdd 100644 --- a/parameters/src/mainnet/genesis.rs +++ b/parameters/src/mainnet/genesis.rs @@ -27,6 +27,6 @@ mod tests { #[test] fn test_genesis_block() { let bytes = GenesisBytes::load_bytes(); - assert_eq!(13989, bytes.len() as u64, "Update me if serialization has changed"); + assert_eq!(13925, bytes.len() as u64, "Update me if serialization has changed"); } } diff --git a/parameters/src/mainnet/resources/block.genesis b/parameters/src/mainnet/resources/block.genesis index a18eb8c0527cd572d0b6a6eaec2b75c78f6095b0..77027a8803f406c83c9e20665051f18f48bb0ca9 100644 GIT binary patch delta 11347 zcmZwNRaBIX{`T>ifuV*NkWjjj?gmLo3F&T-lF(|ZU$@VC z_ImeP|2dhHIl1THyFT}|et8a?_LM-D++0E=oY{iQB@CktA4-N1aia8w$;U=@JOTL} z+Q?W+NwG9mxu+fhXX#uWB;LaAPhrA1O5r5A-nb)MB;uF(e&~Aq!7U0@naKgp$3Ybo zE++fMd^6+5Rl&=T=AGCk-(qv>#hZH8-ic}ff}#MY!aIeJ^yybTZWJ!r2ZunlJQJBm z03Q=hoe`_cT^*ll26pk#uY^;kcZDuVD=SBclw-Ie=tnBB5-257l&!qTjve3>e22ob zm;5`0hUsxMGt!V%TbYoXUF}48}xCmKT@w_S6QzE-X$LOL%%oiWp5Ye(64* zAjd}|F~MrOes9M_5D1g6r-L)2c6NV!@YhR_@?h}E@f&4Jx&;A2fEmsG2)drCyv#tl z5uU>zDCuP(dm=(hSY}zJg$*16AQ2m;<)0QPW%`oFabtcO#T}u>+@m^t){P>V$c2zL zT%b)2EvJC@@7;#LkWi{(v`fL$VS9>QNEO!UGz@QDd=Ci-zytuGd6PQ;004x9?3(;K zqPR*X8P$|2V&HKaW8qr6jDtP^(;o-bo(Ka4?rzeNij|w=tbjCzPoS6oY~FC_Fqk@h zk7+gb%={Pl&!YpLC$-P!Ig;Rc$h=KaH0Ccd;2Y9#SaTN9GqtOZq`yZ2VmjEEyEvNL zyI5M-xVh2*KtKRVO&*>*-#Rr4F|*QeCaykC^>Y#n<;F)6-}FfYyaf8Nv01R*Q~C}F z-ntl6{o-ET%a<0?c9qS-f1#DWLWT|2+O1MG60NFxJBW)-kBc+7qIH9@adU+E-qYEF z$e{-mKSpk3f)HwWDG>b1;0Vj_!x z_*F0$OxA5GrM2OxGi~y%+PAkQ0k;=JeD0AY1vrS~wZl*7-xLG=p7s}Bg!P0Efo1N} zfWWkZdY!}D?kSW>S>ySUZ(;x`O#04q5&kAW4UDTO$jk)!xuTc0-lNy#ZIg*oFT72F z`ay7tYozK2yu-wNTd69Ry9Y82e$ z^bne79-w#H+EgA(79`bw7`LBJW}kPSQzlGh`8`!7*Ol%1JM{~H`zc&|m4W(qoGbN_ z+E^4EbJ43T7pSz2(#CeO8_RxF<)6F)K`!(>VP@Mi%zYKReX?x$OGtqTdSZi+7fTHGA8OR^iARK{9gTBo zIMj2HR%61iE8xh9sUEv!s02Ptd-YE+T_i!^+Q9&RP6_8s;ptNOWP($zWKWlE8E&Gg z!gO|&QozY#XK#6RA013SW3=Cc&kqM7a!{@3#A4{tDyvJ}C5PAuWxu~9NcFYI92EO` zd5ZzO4MtH29wL%eoB8aoEKnPHoC{n4Ncf|TX?cv1#!RA#q44scvVtOfR^nk%cDyxJ z%%~ZTC_dgt>ZBll!xulX+9dnyvIFr|o~AEM{8lFW;FM@}06&(B0%vB!IhHOgaOnX< zrs^K*L_rc=%n-suT9Hf!h+)+Eq36)yrYDW99{aK3C7*>bFk9>wQVv z$L$;1X*fctQXP{b)wr8(Au%wK_D@hp2jp&FWwG8iBR*mdJOP&+VA-B?0+Ir=yxK7X zki0grsSe`zJeJ#a>d4^AZDC;mO0HnDX|cHAD8~8pRyYCKZRnE6FJJbf%yIkSzZl-78ahW=O8E@H7)#VP~ zVWbtkH0i58Jma@*IenPSefM_be7M>!s5KZb?6oVtx5alj0DaD5#%__)%YfL`6Wa3` z*W++6fQw7|yzopWp3(?+3BM28eI51Unb?3?We#p099TgVLf->!J!vGCf&iGJ77qma zy{6*7lW5vAv9Y0P`C`T0Zn2d(o;M%~-OYr*O1&t=KAe$WP@6GiiiTbA7H%(5e~tf^ zL>V%HRX^tpxq$=zRLe6rtndSg_WIRTlIq8m$XCy^h%8=$4JcXU z3O<~W4ncqb5P(BsWJXDV&JbCvIHF_(9Ov{?QDGa~N?alJ0JU9mAAtn~^GzxD^|)mo z`ceDyCt!a@sJ&Wru(m686>VZ$^z0bwsJJ4pqF^ms;Ix_1uo7cw1YL(UJ2SxvFp zl1Xvc!bKdSGHwdHs<(zRGAu;sqW!HPS~*udWiDUhXa(%(%7&C+WnD?$JW#Jc5oKN3 z+mB@%zW%ANhQ=-_+=D#Vo6H#j9DpQ&5dv*du{a|o;7>fAKIU*rne8oNcTk+0zAYx&dXVExPHvc2j zP%c|!_ju(pfMHB*i)S*V#n6U#SK*eOT7xO#Uf`nSD>`*J{ZQZ6M=kR&Lm&g1PlZ@* zS>mIM05+x3IPqvJ>C}|vuMx0dD~zeA*A-dzSmTB@`hxc{1+^pm@)^r`x(Vj)(hbAW zQiv!p_uMmS`_O~*!~LHW-$fP5d7m#u)h0v)&ULmjA_XxVy~lLiEf?e;1IsHA#sbA~ z1CC09y2((vKleLU+p??Mf?&Ruad5?cJ?rdX!QHxNBI5vGDpPlX54f;LLhccUu@kG?BZ$9UbQ1DHl9tJT zt%a}WGyh_>sj@x>lcEF+$#OQ%BJ;qFSkQ=iNi(RQ@XI_1JqppTliP(TOGsvU2^2b`+j76hKScrby+z{*_tMwAxbj`1O~jt;PXx&w-uTRV{U1K@ z|F?o;utG-U(@kN9kGX})lV~%63YxoM%L%%sdcMkm^2pQPEGzn}yVPEdJN=`_@MT3f z!0yw7aGz;(rI~XN50a-}#&|8t=&ZQK(5tHx)i_mN{DV-(fh6bB$&4UD^gH-D90(bz zSNkRtb6Rp_T8l8|DWuU2;sDMZp;Fbv^F{`6#Q}0qk$~m6QVl^@`O=1?QP12e#D%9K zB=GEMWgD<#iaT83)v#*f1rKOH6^UW45g?wNls2A|`w__VD*F52H0Y^TGW#Rd}(DLGAGO!BJ`%>SisP&M1FG~2-*n$7FM z!#EMbf{U6ptUk|TMFVVQ4c9j0&(6Z0&G9Ua99MD}Qff{_B>^!a{Ot*?Pc#Gvrk%f_ z|DkT?c*Q#-sfOr*U@iL{OR{~rwiHqWgR1Cshpn?BwFHd+i@N&jD$IwErnfJCO*4ly zg<}62eZ*8Q`s6fIHftp?k^}J~%&V;6=#;hlimvotL!^I5%_3RqyG;EVGeY^<6&xKL zinYK5d>PaP@Fqg87>Gb3FI%?hs6l?@(mHK+uVEc_Z?9Gu448TQ6Y65(`t-2800{MkbUHWOF z$pI%BIf(7$W|26E^OLov2A^9I=je?;;Qoz#NrFqS!n=JRy_=bxX2(HYM*<}V%Ed15 zJZmta%SV;AsFBP>>raH4>|IWA(=0S_;P&u5-tc^S&~3N-*}G|w;u6{5Q%mrWV0weDH&QYA7>dt24PXgkOa zS8H$nbOpq2hi4#d2-N3BzE5uJ@_qvY?K+gui0UNluPKH^ydfjJm_!&*_ge{Y9k5Mjpx87>Wd|CK-T} zElcfB2<%g7pEmX%jTu8@0{6}3s=%Hc!tWlp5lb&b@X_{kUFaHdO*a@+^*zfY^I zGoO5C^(czl`bzUK#tV$vL`)ujf9S|+`=Jc#fjv|IuqNNf=kwJIIOFm{+w$4x35Bz8 zHj1_Mom|~{sPKX$*-!|I%(0nIRm%%f2JBAl@^}p2p zo+MTwRj%tg4*52;A6xjiM2j2*8dvg*a4yAjUAD#hAL{m8RDW)aKytlG0K~NVq|Cs4 z$dp)75^ZXn2zYw-ME_J31Zb1kXqrc^Y7`G`zW$1AQkoT6{8WmzucZ;v%KzHDq7w}W zPSpOcRU+XS`aZej_Pjm30>b>zwI72Ih{DF4<5{7c>Jwz#mZMe^6mi%?~OW?pgy zIzwwZXu^Z~s4kQenvTpGcauiBSF*5otL-J>WFU^wONY&n{u(EQVLsC+HL_qi!WlvKCl^NJ9#z%x zrU9#Sm(07mwv;$i%{Ex_CjQ#o^-Qp0M1upX9f;q373mdZQ179%&cK%|C)3U=`$5*~ znh>txex@CY9L47)c-fp|Kawf~X*!0-Y+e~my>=70?A4#65mB!GG6swIcouC8c~EF; zb@753Y7{~@u}NMCv!TVm5?Qi@3qL{o6tCzEIO}FgHr7wd?e0Q!$k*VdCrBC@zjK7- z?*pEl&0Ry)${Skd{MS7J)H<|I#;b8uS&-0e>Tk@KAs4O2Y}2x4XA>`>(Z$w6&;3{) zv9FP>#-@B~216_m)UwI7%%P|I^J%E>cPn8fX>=s#3_b1>eX_z^T*Zn$tVt%XS(UibInm~(ZM<~gwLjytnNBQ2)V`-OIW zwYua=cxpeX>U&q4mclOPiq(AT`zP~RNhnO{tvF>Uf9087(CHPi_NPd6#r)da@p2fR z4`N5`^>|}8SzPG%L3yjy)s#w&_fm&vc)r!Va+;5iYI-s1Z5FrDMCmt@e&ctMmvE|1 zi*D;Udh+^L#{~guw8+cqL>Kr6HiyMZPK{(Ky0~*;SGxm(Ym^1XXB8lq%T(v{!XPXe zr?_4^CufTndpL?t6&BuD&p{^S`hKuzv7+t;Nnmc|;UQkyfS-9||0hgl=PpNa%Lkde zHVcNC=2Y2bCdGl3b3?c;b0HPd=^KpS-wwxGm0BL?){b?UtOgHEt7cF#{5>UwXXJlQ zo|a*d^!4=0IM~8Sofv)vW)&p)6*yQ9R*_bZiVRiY5!<3+v2`S4 z(-~s<8=13BRb}09mc=RFL;iBmdczvhJvfMb-7>=zk#oMiR($3T>aV%ZY1$J3dC8X) zzD5H8$K~G<$Fz;Jo=o4sajcaP)*S5b;BLAh;$JCLj1+u0z`ny3-QNb_{+oASy5*Tl zWER8-CA@{6UeO9#4&8fsNIOQ2TB~snfS7O5&e5KR;>k$q{sPyQ^dIO>kTOX9w4)5B zyfY}O+3bi#&HJ2q(o%}MG0>IVToS3{Vrm z<_^5Zr&?_o1o;cy_^bZ8zF77=!qzk&(8P982}4O812(gS`nhPsQkBeqpj&qdNVbj9 z?a!MtY>?~)&CTsKvC-Iwf!BcX^Z=Ahly6+e$z=8~+D?7y%CI`7th>}c3ckT`x7l(8 zk}vul0D%d}9_G{6VdgcxhfPywE+vi`+K60^6q1#Z36XWH3K`&_g8pC74S#mXrcoN(WlERwnMg^xJHOL+<{X@?hmU6|7eRZdf1#_(b2!96m598kuh6Py+T?A0*f!Ou z;%Q%BR3O)@zKMy*D{C=DYZ+RpNUNNz6-EGe+oL|pfA=9gnPcP3sT{~1)-b*6W34Vi zJrtP5qxiJm$oPg(LGg10>}FxH@Xi5&d|?TF#)5w5;Kdsp8{kciu!}Mcd#|+bF}eMm z{5cH2z0{I{b^qCpjvJ_Ia^6i0U=*Fw3D|r|(5L4uUirI)i{zu7<;BfLReaix=m9Ts=#wjgdn_x^-a+8F z-0pgecjz{8b1K9nc2U44YyPU_FHw5wp})waa`~VG3M0S3E58!zPIJ^~X>4>>!0_1u zVkBiu#VhPk_9k#3#j94{YZcQ4$O~A67BxbSF-Uv|S%ky(_dOmbxn&j9#Jdh`(mtZq z$M8u>BP$(dqNhI0-(N8xEzpuNi!%>y`!HA(w_p?_M?vLBWgTQ?er>%uA*N&_)EfEp zevKO^GeC2aXh2f!79ryo+M4zIq=C&^@J2L9au@ca-6eMg zt1p_}>LIbmtgZz{5|U zR^ACLA8MVhj9DpHG_-U>G`plfyBXPP4{`Wm0L<$w6ECV*Gk*rhKab+=pyqNQ&k#oH z9i1@x7V_fK_`hpL1*}#b;MOG>H0NB+r&=^NT9pTT6?v-U4MKJgc}`vse2+pWHybS- zq}u!)8|i!u4lv8#EmwKEgT0lZq@(q;M8jF0dJYC~gOXGU+Zhct@`j2~c%NY%36dkF zuZrbg!+~_3_Tx~`+h0XK_g?QZI`NH;C?MD)s`I>z+PPwsnol^&mRvQabky@VOU8Gi zOM`q~)em-$uVzg0B|=!=PPt>wD62j0@8hyhVwbC4p-=vWE-B-^|HvmbBDKCtWmPVT zSc?1iy$-{84Vk(0(jUMQe}wn~h6Lon3qo?!JqlK~Jj3UE<)x!=7U^6Xr`yU~=ny86 z_4vo5|KF%PrTD?naA1UUP4NT1VUmWxfx<4Ea&85_V6tTAC3e zMZA{PoLe%|8P^`-BC5A9Df^w!M~eJMx>A7mwLPdtG+MVkG{we0%jIXCRC3q$gRa8Z z%`eb?_3|JC!OK&hfnlQfL4?Yjq1f_6RHPpM=fX;BpMBS%v*hRHSbwEE>#vX~P{sR+ z@@ORhGdLPox0q#`$i2veTMw>Ur)~wYFw93nm+VQFXV$_oX!G8Pz~9FN3)R=M8kG=X zvw&ChY}RO*xY9ys%cF0EfL< zqdr+F4D>61IBePox4vaW74+y69rmNodZHRYMd!{Sk-tkQM}Z(EE&R&9BHxc|a1sUq z(#7l2`bf*{NsLLIWPEQCZNt}G42(oXs>x84T<7bk>d-+(FjRevtoJr`8lOz(d4?$L z_W5XZIFzwI4fGCHz%rN%BS!#^xV4fZexwJD-|A8_VSHv#En)`;!dAyt^1h8G{_W62 z5!u(9`)E90e`G6aL!37OW{a+gN~MtBH8)lcQaT~b>rQsIs>pMDI}Wd$T&x1*wZICw z)$Ve%W1`;J%Em^BaN3@w2K^LuoS1qZVrCWao1mbwxrCGY;~5Ssz&hb|1rcGVw))}z z0dPMbwo9r7xM0^N(9FFJ>-c;d9W;GO@J4?poV`Qbc(7@v1?Y?=jV@tmf5R-`pd{hO z)gWaDM2s%`n^Mg)p30H*+!v|Y z2{K^p_2{{#Sg1gcpx1g<{mosNSI?4tZUdTtt|# zTg!RHP??lnD<6z<%rz`Cb>5-~SyV40-_9>X5RUak#IB}gW!{DnhjQ+M+jT)G}eOG(vy3ucbjsjJW?&w+<$}MUbTCJVui7T!QBQm|yoD@ICU=!=UJK3@3qFO=fy@ z5>oMgTJR5iLan-AjsU=usM6IeK^&hN%TiplCgb|<+o}*u>2YVymJxT~SOchg?c3Y7 zs<sJG)EkWj_zc}siqmC_BCVv^KT}*vuwpu(KOH>=MH}Pe4}vQ7rf5LKi_y;BQ=QB zZXI~Gy%Xx~qE&l~{m-DQBEv9_C9?wGVjvXCi={`@9QXpr*1z1v2-7lFb=YG6ajr*% z%k1xjdAiNF&l>L;S5fs?u42A;P<}S&;6s*mV7p~ zFF2iD3uX;ZA;sV~7vD>MijaIR)RVc6Ia31`Mq_?A7rff#dS_+}Kv!g}%_c}hbDdbG zfwe}KzsSb>&!EdBGWnKgPq=(e#=DyN-PX~0S-%-l0{rZmPXB$rrs4nTT%%_VKIEFn z&1VzBakPYF_%WGQejE-dq2)rYdSv1tw6D^n0R;IGQE=zk9-iqhCKmK_4F$z3J$00vDN%?z#AT4%#i_1F32&n2H#P)isru_J^$v~d4ASAM2$o+Q+woeDDz zdibOg0l7u{?VkJV#yG8eZ^&K*=i145j>qqF8Ef3ag$9UOEfVSYMR_YP%Fny}E_Z+k z)~!p+=j_cuB5t+YB7DJ)%VQG@?0AvsEb)gQimnp#|2Q|g&a7Xa-+gnuNNGokh_&Eu z&m!@Tt0Q)rhAU6EY?|yqCb}`C>2c|N3sZhC2Neipjgqq}XxHIC0L5ByZE@3Jj0t8; z%cFV*XGlL-JL#_dEHs9ds^4{wcgmX6jfVl42%WS#BYeNBFTC@y8GqYs77~Q#;P|Ez z&+-2I3nJJ~LC__j2Ld;49Q{pjRtx?B1kc3*7OAv3FWdLIyhmPd-)ZiX(p-u=hQ2#0 zN&i&r@@IGco-adx)s;T2;*@U(kB<$n*^uiMa=UBuFF<_%inJZA*m1=0rMCWKbvD6F z5-U2i1KO=-qLb}MbI(r%{7FV_39@P7xxMp6Hi8w-``OLb)!Y3XsLrLAyZ;!%%JieT z0*Z?@1PrhG#-j}N1@Od%Ah|VzKM=>QVR#%7i;JzqkQu+=iFpqf8tJ} z`~Y)lmP1^AIv54Gh{7dr2gIcHQ_dNYi*?tX)Sp9w@<&j>yUiW8^C@RzB0g9bhktx_;->kvZ*+Iydt0!2J5~#p6(va3 zTy^MW9x>&moG@RThLJpzFC!k?)!Kt-ymb+1ml>y?lpC5Cw+tL&D!tfdCd}`8V}|&# zGf(bpcU>d&cfMV&{GriBvkmNC zIo;Qba>=M^_Lz-e>F7pQ;&|u~M~<(Jamk{#h0*h1+Xwdp4M)mBM5Fh9 zCVGFstb>|zHx@Afa1N^)Aw|yR!#9O&@uw^b=YOk?ZUE=Sr~1cPp*uM5FqLr6v=F$; z{Ji?Ik&GsT05+pjihWXN853Vv<3<)Eo?Ng?>>4Wo(^gZbkVi{tHR7NINKOa+T;IJKG{2g?2|C|c2SL@WTfb}z~kc-il=IWj|ypojaxEZ>2 zJXQX?8T|Kl!IbarmC+{Gs}GwfOJPWwGFvLl=2W|ghf8_e-XzbtHg7g4!w!0)d4wO%jfPd)S~@rZ(`7u1B}JXBy+_RR34eJZ`=XBODj-wK*?Oru^msh6AD;s#O5D0pv8LRHwM+MOk*@3XHk1_i zj$^Bf{HuI!>k0~g)!w{h?Z_^z~-^y;xMk!2|_M|v~s1$6dkwRcGM0xZk^U@hH9)t zfyUy^fY10B3mN`o%zZjmc!gti8BF=I+I#RpFJeE8$6+s{(_O)n7-R942 zYyO6LbJj~+B$%+HFrc&X^>BOEOap=I*7JqRUQs_0zg0;){<_Y~Loc3{)5aH(+$6|i zmto(YiEh%O1_Lj=ef3B^wS{9PYMD&9vOM4p0_UZqM8xu#741Kci*fGC=*nJ2x!+vc z_83*9l&{-KykAoA5GIAg(K*_j9H2R`OZ}|tkveDlq+w3#ro$eT%uM$Up$7G?8~Rkj zZF*qygWX(5^GOu+G*&~phhD*A`xjd&h#Rc$rBF3VyFqmGuCq>(fF*bI34P25C$H+| zkHTD_cSnU7EG0`$3epfPFGU_qwkTZ-f;y$lUJkhlu%@&}`}A|E@4^N2)EH>vj1PqO z{F5T~Td+wB*zs9j4DNUANNE)n53)N?Z!=B+fc<57{N&8bbJnajvuej0>t0Ln}96h@@SLV1Bj!moRJ)9yhJ)Shro)YT3 zi4Wd;FmJc^{}{l*`Zm@oJccQX^KS)(U;)=$BL~LNqbK$1oar;PyU)>xoP+5 z9$B-!=#BLHY0G5xKI<7|XnCpJ=ve>NjfH_a&$i&;38s#EjHloJk- z)?a%l2$2jl@7tk*lLc*u=sw@_U!8#pRBGcsI}1YJ?l_s8-w@>g+TpZJttzl7wUWQtz1b zBoh=_K3uzh6U{gP;>lBO!IpldHdvLOtI2_G$N<&@C2us$C$NO=YeC0j#==oN)ph8G zGuS+&WAbJb7m{O{&_Ezim7Z<>#^?9Yz5res*Y_lmzOVzg0CACKVkO9u&=4tNQam&x zI1_1Jsgw?91jRalq*)6#z_La2b#}K^i!o!-beA^=2?zz4CZRC=W@H5P^*KOaCMlCp zl_D~4FXyS2>QrIYCzwajiA8p(=OJfng0{N%{o^#`@+mBHpd4?@^ll&l++;nS4+{jK008L43x@yz01DdUL)=)1`r)xK zejjF?&NNx~7LZH_#hnHl6?QkZM1yV;|#_BF+BOm}#9PKRJoGl#OtSs$3 z+^GOiK!71u_@Vj|-$ZK;mpW*LK7zo53gb7G;-M51DrzZP9n>g`!Xq)gd08>0BI+=X zJVQq{6eC-&wO>Yi*&&3579N&FoZZV<;6={h;irABG8P-Xt@)RBVD`8LhCvZmtRGTR z9jUSDbtmP#a%gqb%Es^Vh0Tsjh1iF&j-VWy#fOuk#SS36k`7Aqq(z-$an`+H{0_`8 z%q>2#G5!$kxilf#evSzA12WuBBJc8+O^csFH-kXZ#Ni36Vt zEEtBS=)C+WQj6UbirSzgDVSRqrHCKmJy~HDp30nho<2F_$d1s7cY06%e47aY$_bMV z-zmoLAwPZD4lwv;gpJ}k^iBq z`=SL~Ue*y~yotb^Z^b)rft%cRy@F2&d0%ogHgij!4v`Rp1!!}1>mnVG!uKFnO~2rd z)7R9dc;UrwkLr~${UJlT%#^%?qbWN_DJQ)7N$;hY9;j{!7YwHuZqD`CKJWSkocT4& zK2lz*QYoVGFxHD=%cy?Au#MGI+WvCRF5P4-=-v#?)>IWPh%jk`KK&CoFd}kc>cfmWbLY7L-eepe)=4@) z3$|9OMMzC(-1vZt;QE2YxzZ9gB~6^a2NlA6Bc~G|_(1V)hyL)DlP#MI;~g5|>YVjA zVfYWTd8QVFT}J|)pWE|qb6$Sij2&rqE**wK#I{ox14 zsPs2Op}Jk$Ay${~TD8~;z)PnTZA|U@G1|0?<)D3>icd{nO{IJtNAE-eb_)!#|s zE|tc9wkc#w?>qX7-1B%xf5g1Fj3OR3u+qM_#6rRBD}egZ@J(P|3Y`~>f)CNPxC9_} z$zfrd-7?XH$fZq+L=jrZR{EOrPCfs;nk4vIv5yG-ryl=YdB@NdJ+dx=X7(T6M6vXOfBo|Ic4gvKn8wizu0E$Q zRKW6RdJL}wVzO6ZMk?qgMf}DmOpxf8d#Wb9`PUZ#WZa6jBGBk?Hvp+m!hYr` z3=LYNeU@axscEh#I#w)4|J&Vv-3tJcym4$tKeX0Qbivi5>m$vEUKIodWIZ=9Oz034 zv0Nbm0Z;%GasMb;h6jF!x~FCB!M!1=_hW&lCBNuhL)mzuD=IkQfUvn%1l%VHUt0zE zduw+&>kgY{gC**(y1y5IZX)cf(4mqrI8;o9M6$mZyS=?c(Cpu%%EL`;@gOt5(~`Ps zQDqLUMO=d#3m=D^(LNc}4lu{Bm3#U&YrhBFCK^XU;yxH1f69Wp+-8WlFZb;|o{oEt zZ()cu8aFjh6mlYGXlyO%8m|N;ZNYMaTk;@W{>hughutg_=z#?xE3B~@gy7z8)o^Bt zSebd^)vX)48$NofwS9UDwsboP@Ti99x2iy|B8W9kbI(jW9O|c3aX`;{b%drYHMoJg z%qTY6F;14`a2`JZWS->#c#5x%Qh)yp6LyIkM1tZ*4&zrdBfD|;Yo}UVNn8s&Lc*_j z1LqQ`ySW!(MD-K~09v?2XxZ6}e=sW5kexgYkrx(J*U!4CtzDeO^I5UFEzC?S8hiU3 z^SXJS)un9A1$k$*jqv5iy(Gsk#E`gCRX(Uwn2Z*U!1J(@37NMAIE0i`@7l!YU_iL}hoQ1}pXyo8 z#_@n4CsPv*2jAnuKzIb>uAAlptUyim!mgJu&IS3V*YYq$$?!sGcXsSBg-6uib}k_| zl{URM->ge|jq_N!^WbiNLs>y3m?t2UYkVR&zZw=Rubo0~LSdEqfVI~PjxX5+%###E z(JAx3`~I583O?O@hJtSnl`wWJO}G+{9>%~u2s<`t=fDY# zjj@oa_ScV(R-abcLjaOtoA9DgSP1@putD1R%!u8PCAkXz9v$cQV^Y5p7c8c2H@DgQ zat9t>^o)&?j#LBPmc$b`@V>`-rmY@gNGLb`C0EE?=8ta`bNymg?#kjSy&{!%*S zpcD$P%<9rfh`gMx{Nujw0J@Pe1B>*zXfY#ZxI$FrB#e4dW8h%7Jdq?5l5w%8Cu&ho zYQ2d4e8^&YWj-Ft4~inWJqYN=t*D}JioYfW*rHwtqG%ZsIKs(j4{TNqcl}yLCKBK#ZhFWDV=U`t zb+|niLFP%-q&bB;_O7RsI?Yg{tm}wSUGj@neU{^uCs!!6&14}Zrs0N3N*_(6W>;Q257MhqB4r$A#Q9`jss@gG#8VI+DLarvC3aWi*i*C?|7)=m!Pw0q=UAd=t=Rzt z$j|tld#rJzORi`a0Y5xmtS{#^$3te!AqVLjVAt|ADp1k zNjR2iebDY*nq|`R#4dO~Z}E8Dwlxs5aDohD-dwOUV*Y9A6e_QyRJ)^FR7RgjVxaR%{Jx^Gl;aU+t)YgaUe6?y@+jEKZcrR%ied6%>ld$+J6uq4tC5<*I8<<5T5%!o(1nv|-B02^(j|BJqF zgUQ_M>quB)hYMYFL;c2F!WRN*+SmKEk(@h2u6wY8?7Hi4k@oOQ0UCt;AFtx{_-&6? zy`hWarA&L0-A#~S+x8xb=@&+lgY~|I$}iQ!pPN z75;WUbU*GOd*01vy(7jjVn7x77@3^Cdkm=%v!t8$pc7kYZ40(s8Ktb`wBN8g%COGQ z-!~Y4!3?^!$Cnh%@kB-BgtwYEi__&j8h%w)I_uX(6(6YTEiZ(>)#ng@2W+I-Be%3C zsrT!4huR^7CYbf-9khHsWJddqHD~K*qAhWkp+U^BUEX;T1ppGwM)gpXZJ(4>&JWb( z8qh96?miVFp|nq4($Z=(fQ^!OA+EWyUBf01ws|3Q5rF1OZCM6H8}EHHS}!Rz8tVxu zEU}DfW|K6VLfOJ?Fum`#+qY|C!@x0%0hDvgUUs0>8MQ||i$ZCd3zXgAMOdD^t{f;e z24xldV`BWMfS-HDyJjI*hrU1&_0jpt9V>v=n)}4zhA~|6Z&7`kgy7m0te(q7**uA_ zYLX88@(E&MJo=j=5~B?21nFL)y>bu*g1Z zH@s-RoSK7+E%G?DXamCqUoc8{D}*FP-1Bz7RM+;~gpi!pQ9mO-5fx683ku+%x#^1= z0%Yyy1(*}2kJXpWIh5pD4A@ZFR&BnpzjuaFk6CG54Nw}15y?<66&GMmIEgAvC46fl z9r=YK3Xgy^JqNxE=(}{tKU#;xKn_v|y9|i!Y@t`MS@yp^4pTv+)7y%LRFzO1a36Wq zj#s@K^v=FqJ&a|@!0cm?gdBnXU429Fwe2u24P{A%Ou)d4NYLEfbZP%nuxwjp!Fyf4 z%0$0QLDb>g4yEm*Ph1gF^+*r^h4l;!n`FV4>@pGUwRgA5{S97x`3d<;^~UIVx@UP1 zRPy^mf$^LL%lht}tR>4JV6hGU?0%jN*Qy%l*V$DwEmhoh&Vck@*IRz+eYIxoXy~hu z?20e6l{YG$n4aq-m~P{Hez@daZ*2tqUmbKwrvoBSgJC;d#H*P5Sat5K7$N`Icb}16 zEp3T7qTGD@mmr-ZDk)v)Xe)REO(bJ@fVdGK`LBJkDD0u%;xT(8KR2W|Vq%fBq(D$? zJ%pq8D24VM)OZm8!@d?|mIPHocV!<1YT#-kJjw@XVTsG$dSdi9$_`mXyDD3ABR|wQNut@Ws>bn6rjZ_3hj~LjPl5ck!pgxDrj$uQzqY+a4!O^gn+} z8|STDE}L{`Y?+GG0D-Vn`6}GP8Sm2*(|wWzTicc~@BKcwR_q_9hw6%-dP4*M+PC3y zzY(KiIir8Dm^l8yN3}MZN86wX#bvOUen5t03r?E6*<VDN19?5(KTyIL zm3k=M;(GjBRi@##%G!y^!Prf^t0K5{eGX|DFb8hsMBHl3)`qvjB+q2w32mR3pN0K(kbC!~|2kv!u5yr^~?&!W+XbiNV% z+z`bI8f!Cq{o+qnRmr0j`(4z)rGipL*!TU6T@$1~GN>RD0-O*bxbOGxBs=xbgj2{7FKGML^c$zph!eV-I zY?N-w*$qyo+f(0r;{fus*tsHNG+>kw7yzMA+Xn=K2mN2ZwI6AK=Nl|-0IUPZ?AP?L z`4LT|?5PfjgyNK|WJ%)R;&=;X7d(R2Op@p;o8LZde_6B%W0VR=fwy)`A|e>z(dOgT zk4U9vSH0j9O4%~ewP{9@i$sCM0Psn7G;d;E%U13-9DFy|Zs#?`%tdFo(*hj0!k}^- z9el5BdE$Oe(AleiNvnN;4q0MB{(fjb3s1`mkGt2e?99?_5!8KhN;LAg67(76^@@Fu zv&9Q)kbhzYcs_Xn7-o2A@EsejIKJ2mlNS1sLbK_{Ohn-K_wXi8MtAj_LX>xjmaT`mKFgvI*Eu~2S_bW!FwoSIXsOf?Q(B%i@ z!S{Sb`igy3vttD=EPVj&JZoWu02)Cw< zV1AP#<}=6yX1Dl6j4(=99*m-=<7P_mn_ZFnJv3BKb|N9uUTjo;jUeq8PgnwdBb<`^ zU731ii)r+&?+R!X*cj+&l}}2fUhYn8H~3_D8|!*$zFa(V*i&*rHwGY~>a*9x)9`m6 zL59C)4h??W7+=B6_eNj(-AE72GZLWxyMk$8N0V;@bP{QBmcEFx4qB1O&1r9`Z(}u; z&_n1l)IaF=smxF@~)M@n|macPD~cBzZW~RVynp3^RAfB&d;t`GNEpxSC67wVicn}>_Qf~sC*I8%`n?ZEML#d^6giLMiiA1LKLEsQT(h4= zhYC{H`_#R+9ns&v3CUEgNpEmc9b z(11I9Lr7HG8UBxb9T74n*i$6>9uLT&Rr7fj!mhOm=WCe_&@nEfpXFf+Z?t1gmUD-cHy1mCO&If^uR(5+oNBc zU@0zmg8wo5B3;P&nWViWz#d^h$_S;eAtl`0VcRMxGn~rIGRc_;XwvF4A&!>ZB$7?# z{rcF(H!?!@K$GWJO?Pg#S?M33f9#8hNyRIe3rmb?fi6;Wn0r60$nk3*`ob(Y2i?62 z+YkQ#vaj44Q#!VF#;}ZO_-cV#7Bbfxm!G!fvG12o{TF_&1whkQ94UWJoEA?{t?nX{<0t3}?(DX0+ zl2b;%b#zBE*6R91vSKtjy42wEY7#no1$@5IJQkXSRp@L_nFAMRskKNNhX)A%f;lZx zfx>Nrr;&6o`iia!e6$~&z>wPZR4x)gT&oDJHS#PsBD2PEjeZcGZ5Iwj|66@6+P!(X zKD_%0*N6|*4HZL_TnT$HlSvP!ioRS#PHg*nQq_z6@R(n>A0}yEO7sChW>1t=AIk8v z)u-_6V$Am{xwjc!QdXR0x)0Z#n-yi+Xn`$#jU6z)XJOQF#VF(e-e0cpnk;En6jK)M zyA8`ubO?4`FKw(Sx{Fa5;Yi?}!M z{+{N_wyzcP9s(uh5#i+rh%%jYvw1&~E6x=Hzpkx)gV3+F1sAsHw^z=dzVnWtIPkp- z;MGhqx5S8E)amL^W!+yH7F2D6k-k^VgX8XJ0R%PqZ?Is_4fnmr4LSrzsWGcs(abM` z>Ti;Mbk~ zpKcrdXU5eg^kx?q=f_&cgt4)lYHb5U{lbv(#F&i16c#_A#lvAAaNns~Y_NFCr6BD=%o>+p5iJlHTkjEyE-7g4pW=BvlG!H3iVrx#Rn?F-o3exHH=kqQ- z6zAw-PD_gqm`Xgj{OoF-6mM{($4A0Jc|eji!($oXC0Zfa8)q z=P*E-Nv>X@-S=MRN{kLaxv?t38zqTi&Y+{Jm2CBO7P47g9XOWr>#UEH_%MlQNQ4#l z&l9*>tT`x2YM+j;$sa0cZV=1xU~F>$!hnBQUmyG>nNZ~JyN;c=_>4jo0Vd1(IgWl- zsoKYn4*?JSipw$6YBg8&nt|sU32%_qGV5%+l(D6#@WixF4C+32E2=PF3iOYYCvg4a5Fr|kXk zI;}m6czH)I=OR^m{XbKJHnATvl^USrzwsTA{#Zn5$Z81nhyrH_o-i z@0oqF?MJpp8+=pew}D8XfY&WY{&3jP-r&wz4`*hzH0?17%D11v1}~n#)6ctXI1fo~ zPV<0-a{h@+lCZq-qLOAWBZ-X+#4$NZm@y^HD1<0FvWHFht|eq(G-g-P<3)TMJ!ecZ zHCF{po{|GQL~JslJ)4Qq@P1m8rVX#sLEdk*oUUswaREO_2}$84@Btamz*tJD06c;; z7mx@_mIM&s5z)kIQ4CN{!J~YSY#PHoEg0vYkY!XXt_HhjhfB|AmP4-SPd+2RNoKE!k!;Mv zJSSUByOxVB!HK~+9N2N8mM~;s;BM6}Ou#8Iy4JAQ6x&LAkN}F^83vzaR-W8p5Ydhf z%uLJrp9G9w?Y4nBf2-?;M3{fKDWEWFHO{D@ouztlSfTCdr zyVdQWB)Zw3&Hdh~7^=(T6XS(j?o5U~eb@XzxJAGO`MwaKK8_b3W25Ek5<;x+NPu~O zNSPzRFkBDOynA_st|WK`TD2lqQy(6d5BctU!id|!>rO#a0J;74R!o`ry4 zS3n-pBUG}H+Zq%#@zBvJSoMmAo$>xHT*blhjfjb@(oYzSHH+vtR&AS6Zoc2>rtN9n zb^V6H8rOzOXCQ)-ZQH?U5(+Tm7R0<#U;+4;s=B zK1Ti+{5s`^J0U~Ilt|LC-%&wL0jZvYGc^k(mkY@Mu3#M4Rkv6=G_uS{q@YX2=ry54 zZN2xyeC$S~%g>Fm=pUfrq$I-va+|V)VAn<#&>#S?N2TR2LjP(9=ahCjD01G*O!4#k_CCkGI?@?@1D+Gi3ea> z1C7sTT2$Ly5fv|Q&!Hs|&R7<2?MF*26+?J?YCF`w_O&ZQ(d<$~(snxgnZ82%Io)n# zj$u2rWo0C9rCnvr2K2|iJD=1%(FeC5X;zE{6;O22>Q-S>3(Eg+wQd(V5PaZ>d@HoX#l8!{*7B8AQmK0mthQdRk!NHEvlZWMTV@tv&i|w z`OIktSosRoXGRG*w>`eGWYYZ(9>jQWkbP;BNVzf6T+fu-i==p-tnuPJOde0#UopRmGjka@UUq4P1}4zxt`&HVcCAD`nh#N5wa258)In*oalm=G`U*!EWK?e;IWSad$NJ-iQH??!K)Czo=eYd2bpx{_;Vg!rc zf7#cTh@R#SjzSWLSljCy;w_LlL8eS1iQ8Rfs8<<-enT)xoPvc3$gFDpA_Y6aPXhp& zO@%3&05Xq0Q{8Qm;U^w~?6AcBgl3%h&+olYu;QAV{TNwl?@$Axw6TXm($pcWvaueu z#uqBumb1!H!M!bEGQ&+KxL6FJV$?0?RB(Ic<)^S`kE92wFrK{ z6_n;W`1)+2-${XU9(0y&QMD*`#ib}?VtcJF{33@pgrcV{$_ zCRwt^^BXUw#o{N`AF$Zkj+xaj_7f+za)uJe=smne{nAytQ)hn(uKQH?YJZ5l`Hr8t7S&hPHwoLkNpyqQTnM=ZP@5P)rlU z_-6NWk-hff!z|l)y@st1N;igq!c#|H^z)2C8ywL}8Z4=0`VK-052mLg+E^y6sU_bh zCaC6y)U-#W+9o)N!4+ZX-z&(Qz!6(jkaW5!1qxxku0by!+b+fAta1LaM1x(<4gc5- zaG*NI0IzJ3ezdoLtWuHTLbswgFn@!Jfd(t}wSr>!Rk#t$v!Nz?$0PLY_4Mr@!Aqd*Sy+1kl^i$x&JNh~_%Tb-t-~JkQs@HQ` zl;RUdBwcNZ`4jh~aHY3ibXV=@A}=zGevj|aZX+)`hV<`Z2W-9wtd3@~ghDTf-D2i} z#Ah(xdkbwY)gwBoynln0Rm`1Bhwlf6RM>mju+}NS{k!_O;4`c{h1mRV&9F?j@u7Pn=SoJYF z6LrHSsB{j|2c}XAAs$33{qOc|*G-g2I!s72AV8*kF)RlD?HG;nJYRHX>}9;Y)GPx_ zY}+1arq2N;+T1AL@n~7X34>Tem-}wnAK8n}4{;15o@)K(NI{>a_ONk-m&{J@ zA|;Z7$iTN<2KbNN_Y_n-c?%Qr+#*GZGj@|?f3(yvhfedVgvEw-(r>|z_K$r}#p}G% zJ^BR|a(|ZmIyWj~rcwE|{Rky>e=@9`qI-ge284wwAvF;Wlb2OOjjtkMqwS-ZefNE2 zZ%9UIwW#taxC-!h_f0hDT+s3pvK`3*6CMOFQ@L6U^uQ7IgvW8=f)%nb;e-n&Uvorw z`C48XiI$1>+apt71TO)pQqf%0zI4dKNobKI8UeWKqUyL3V}8)P^XA311g z!rXz&(0}b4SE_j^p_KS~GiLcxH8tf`Kity_-w4ja`lL6J0NOM3YZwm>(lDaZ#&<=` zJ~amb^S{1imyYC!Y~zT)#&8Jdv%dWtH|;OGlwYw8W(CNtmosDV`d5mMQ1gf>4hJtm zetzahC>1}Bs8R`&Gn#P_Ak^1>@$~#Xl|CF>sc!>zzd&ASv=Sr9S8=4}T2{E50=V&@ zIQ#2cEPH81Ge+a)6XfxN)hn4g$@rIb zk&!KU0zvnH9XchVBYGm}%prM2OA9TE&*MCKYD52)58+fprx55EwqRIW$u}7IA#Z%_ z-9W_UZ~ggCw8q`LgO|?&ZIg^JhsqNH4N^pmJS~Ht)8POwSbA-4r(Pa>&^3Bz$>bHz zm7kVKk(c7>jh8-^ZNgl-6HcugGKHSDA*;=Sr->dR;>EitLttxvI4I-jFUkg*+nwmSfa5a#y{y*pk6S4V zKMriZ4mDsR4;1y`pDmaBUm0T>6EXnEptaG%CP~^##rTfSrICcTkcrW{W~FOz4?_JPBqm4Fgaf3Xic$5h+V{{4L&>x9_?Pm`Z9lO4@*ZD9E0HU%w%?sQ1ilG*zoT+wU+S+H; z6xu!aE$$zQKOa1=5f^u2Q{#rSf88#C9f`4DC7jOcN8I3yBg2^Dn?%s&6X0%T)l}=e z((E^mQVt`b4H;gAI%Pa2Bg)lnosw*NAKu1+|RdLR}=_zlJN2?9{i#%tf8^mg~ZEO0}* ztq{l~J5{kp)jAe#;SS->Vpe0^GOL}UH^r%?>{fb}lMMnAwHsp^K0i64%k1>t-1*Cs zutwQODtmIJET*_Rec{N3*71G6P-j0xw{TOh+DT=Iz>_=WzC2EFzj}sf^+@?x1Nwkd ZD03LMpN(CTMVEB(zwNup^B?w=`Y$PU&}RSu From 75a8c69e3a1f7a65669b52a5848accee0c1ac26f Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Sun, 11 Feb 2024 23:07:34 -0800 Subject: [PATCH 3/4] Use key ID in RemoveKeyValue finalize operation --- ledger/store/src/program/finalize.rs | 5 +++- .../src/logic/finalize_operation/bits.rs | 24 +++++++++---------- .../src/logic/finalize_operation/bytes.rs | 12 +++++----- .../src/logic/finalize_operation/mod.rs | 8 +++---- .../src/logic/finalize_operation/serialize.rs | 10 ++++---- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/ledger/store/src/program/finalize.rs b/ledger/store/src/program/finalize.rs index a3d4f6d7d1..4cad599083 100644 --- a/ledger/store/src/program/finalize.rs +++ b/ledger/store/src/program/finalize.rs @@ -264,6 +264,9 @@ pub trait FinalizeStorage: 'static + Clone + Send + Sync { return Ok(None); } + // Compute the key ID. + let key_id = to_key_id(&program_id, &mapping_name, key)?; + atomic_batch_scope!(self, { // Update the key-value map with the new key. self.key_value_map().remove_key(&(program_id, mapping_name), key)?; @@ -272,7 +275,7 @@ pub trait FinalizeStorage: 'static + Clone + Send + Sync { })?; // Return the finalize operation. - Ok(Some(FinalizeOperation::RemoveKeyValue(to_mapping_id(&program_id, &mapping_name)?, 0u64))) + Ok(Some(FinalizeOperation::RemoveKeyValue(to_mapping_id(&program_id, &mapping_name)?, key_id))) } /// Replaces the mapping for the given `program ID` and `mapping name` from storage, diff --git a/synthesizer/program/src/logic/finalize_operation/bits.rs b/synthesizer/program/src/logic/finalize_operation/bits.rs index c912fbf223..16d17b9c21 100644 --- a/synthesizer/program/src/logic/finalize_operation/bits.rs +++ b/synthesizer/program/src/logic/finalize_operation/bits.rs @@ -62,10 +62,10 @@ impl FromBits for FinalizeOperation { 3 => { // Read the mapping ID. let mapping_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_le(&next_bits(64)?)?; + // Read the key ID. + let key_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::RemoveKeyValue(mapping_id, index)) + Ok(Self::RemoveKeyValue(mapping_id, key_id)) } 4 => { // Read the mapping ID. @@ -130,10 +130,10 @@ impl FromBits for FinalizeOperation { 3 => { // Read the mapping ID. let mapping_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_be(&next_bits(64)?)?; + // Read the key ID. + let key_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::RemoveKeyValue(mapping_id, index)) + Ok(Self::RemoveKeyValue(mapping_id, key_id)) } 4 => { // Read the mapping ID. @@ -182,13 +182,13 @@ impl ToBits for FinalizeOperation { // Write the value ID. value_id.write_bits_le(vec); } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { // Write the variant. 3u8.write_bits_le(vec); // Write the mapping ID. mapping_id.write_bits_le(vec); - // Write the index. - index.write_bits_le(vec); + // Write the key ID. + key_id.write_bits_le(vec); } Self::ReplaceMapping(mapping_id) => { // Write the variant. @@ -234,13 +234,13 @@ impl ToBits for FinalizeOperation { // Write the value ID. value_id.write_bits_be(vec); } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { // Write the variant. 3u8.write_bits_be(vec); // Write the mapping ID. mapping_id.write_bits_be(vec); - // Write the index. - index.write_bits_be(vec); + // Write the key ID. + key_id.write_bits_be(vec); } Self::ReplaceMapping(mapping_id) => { // Write the variant. diff --git a/synthesizer/program/src/logic/finalize_operation/bytes.rs b/synthesizer/program/src/logic/finalize_operation/bytes.rs index 88ba12f30f..0477bbb597 100644 --- a/synthesizer/program/src/logic/finalize_operation/bytes.rs +++ b/synthesizer/program/src/logic/finalize_operation/bytes.rs @@ -50,10 +50,10 @@ impl FromBytes for FinalizeOperation { 3 => { // Read the mapping ID. let mapping_id = Field::read_le(&mut reader)?; - // Read the index. - let index = u64::read_le(&mut reader)?; + // Read the key ID. + let key_id = Field::read_le(&mut reader)?; // Return the finalize operation. - Ok(Self::RemoveKeyValue(mapping_id, index)) + Ok(Self::RemoveKeyValue(mapping_id, key_id)) } 4 => { // Read the mapping ID. @@ -102,13 +102,13 @@ impl ToBytes for FinalizeOperation { // Write the value ID. value_id.write_le(&mut writer)?; } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { // Write the variant. 3u8.write_le(&mut writer)?; // Write the mapping ID. mapping_id.write_le(&mut writer)?; - // Write the index. - index.write_le(&mut writer)?; + // Write the key ID. + key_id.write_le(&mut writer)?; } Self::ReplaceMapping(mapping_id) => { // Write the variant. diff --git a/synthesizer/program/src/logic/finalize_operation/mod.rs b/synthesizer/program/src/logic/finalize_operation/mod.rs index 2baed2917f..f5130bb8aa 100644 --- a/synthesizer/program/src/logic/finalize_operation/mod.rs +++ b/synthesizer/program/src/logic/finalize_operation/mod.rs @@ -30,9 +30,9 @@ pub enum FinalizeOperation { /// Updates the key-value leaf in the mapping tree, /// as (`mapping ID`, `key ID`, `value ID`). UpdateKeyValue(Field, Field, Field), - /// Removes the key-value leaf at the given index in the mapping tree, - /// as (`mapping ID`, `index`). - RemoveKeyValue(Field, u64), + /// Removes the key-value leaf in the mapping tree, + /// as (`mapping ID`, `key ID`). + RemoveKeyValue(Field, Field), /// Replaces a mapping from the program tree, as (`mapping ID`). ReplaceMapping(Field), /// Removes a mapping from the program tree, as (`mapping ID`). @@ -63,7 +63,7 @@ pub(crate) mod test_helpers { /// Samples a random `RemoveKeyValue`. pub(crate) fn sample_remove_key_value(rng: &mut TestRng) -> FinalizeOperation { - FinalizeOperation::RemoveKeyValue(Uniform::rand(rng), rng.gen()) + FinalizeOperation::RemoveKeyValue(Uniform::rand(rng), Uniform::rand(rng)) } /// Samples a random `ReplaceMapping`. diff --git a/synthesizer/program/src/logic/finalize_operation/serialize.rs b/synthesizer/program/src/logic/finalize_operation/serialize.rs index 253fec5709..7eb28bb103 100644 --- a/synthesizer/program/src/logic/finalize_operation/serialize.rs +++ b/synthesizer/program/src/logic/finalize_operation/serialize.rs @@ -43,11 +43,11 @@ impl Serialize for FinalizeOperation { operation.serialize_field("value_id", value_id)?; operation.end() } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { let mut operation = serializer.serialize_struct("FinalizeOperation", 3)?; operation.serialize_field("type", "remove_key_value")?; operation.serialize_field("mapping_id", mapping_id)?; - operation.serialize_field("index", index)?; + operation.serialize_field("key_id", key_id)?; operation.end() } Self::ReplaceMapping(mapping_id) => { @@ -106,10 +106,10 @@ impl<'de, N: Network> Deserialize<'de> for FinalizeOperation { Some("remove_key_value") => { // Deserialize the mapping ID. let mapping_id = DeserializeExt::take_from_value::(&mut operation, "mapping_id")?; - // Deserialize the index. - let index = DeserializeExt::take_from_value::(&mut operation, "index")?; + // Deserialize the key ID. + let key_id = DeserializeExt::take_from_value::(&mut operation, "key_id")?; // Return the operation. - Self::RemoveKeyValue(mapping_id, index) + Self::RemoveKeyValue(mapping_id, key_id) } Some("replace_mapping") => { // Deserialize the mapping ID. From e231cb7f1c7279f51df2cd3c624424bbc142bdec Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 12 Feb 2024 01:09:26 -0800 Subject: [PATCH 4/4] Regenerate expectations --- .../tests/expectations/vm/execute_and_finalize/test_rand.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out b/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out index eb372e7191..94690f11cb 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out @@ -19,7 +19,7 @@ outputs: test_rand.aleo/rand_chacha_check: outputs: - '{"type":"future","id":"5655280628674362392666464396476127281186411758739892961608160465159658100070field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_check,\n arguments: [\n 0field,\n false\n ]\n}"}' - speculate: the execution was rejected + speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: