From 82e32bb90ee37288a02146491e6ce6eba2fde039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 2 Sep 2024 17:48:35 -0300 Subject: [PATCH 1/4] Add long range fork rule --- operator/mina/lib/src/consensus_state.rs | 120 ++++++++++++++++++++--- operator/mina/lib/src/lib.rs | 24 ++--- 2 files changed, 121 insertions(+), 23 deletions(-) diff --git a/operator/mina/lib/src/consensus_state.rs b/operator/mina/lib/src/consensus_state.rs index b6d49e141..388519880 100644 --- a/operator/mina/lib/src/consensus_state.rs +++ b/operator/mina/lib/src/consensus_state.rs @@ -1,40 +1,136 @@ use blake2::{Blake2b512, Digest}; use kimchi::o1_utils::FieldHelpers; -use mina_p2p_messages::{hash::MinaHash, v2::MinaStateProtocolStateValueStableV2}; +use mina_p2p_messages::{ + hash::MinaHash, + v2::{ + ConsensusProofOfStakeDataConsensusStateValueStableV2 as MinaConsensusState, + MinaStateProtocolStateValueStableV2 as MinaProtocolState, + }, +}; +///! Consensus chain selection algorithms. The [`official specification`] was taken as a reference. +/// +///! [`official specification`]: https://github.com/MinaProtocol/mina/blob/develop/docs/specs/consensus/README.md +use std::cmp::{max, min, Ordering}; + +const GRACE_PERIOD_END: u32 = 1440; +const SUB_WINDOWS_PER_WINDOW: u32 = 11; +const SLOTS_PER_SUB_WINDOW: u32 = 7; #[derive(PartialEq)] -pub enum LongerChainResult { +pub enum ChainResult { Bridge, Candidate, } -pub fn select_longer_chain( - candidate: &MinaStateProtocolStateValueStableV2, - tip: &MinaStateProtocolStateValueStableV2, -) -> LongerChainResult { +pub fn select_secure_chain( + candidate: &MinaProtocolState, + tip: &MinaProtocolState, +) -> Result { + if is_short_range(candidate, tip)? { + Ok(select_longer_chain(candidate, tip)) + } else { + let tip_density = relative_min_window_density(candidate, tip); + let candidate_density = relative_min_window_density(candidate, tip); + Ok(match candidate_density.cmp(&tip_density) { + Ordering::Less => ChainResult::Bridge, + Ordering::Equal => select_longer_chain(candidate, tip), + Ordering::Greater => ChainResult::Candidate, + }) + } +} + +fn select_longer_chain(candidate: &MinaProtocolState, tip: &MinaProtocolState) -> ChainResult { let candidate_block_height = &candidate.body.consensus_state.blockchain_length.as_u32(); let tip_block_height = &tip.body.consensus_state.blockchain_length.as_u32(); if candidate_block_height > tip_block_height { - return LongerChainResult::Candidate; + return ChainResult::Candidate; } // tiebreak logic else if candidate_block_height == tip_block_height { // compare last VRF digests lexicographically if hash_last_vrf(candidate) > hash_last_vrf(tip) { - return LongerChainResult::Candidate; + return ChainResult::Candidate; } else if hash_last_vrf(candidate) == hash_last_vrf(tip) { // compare consensus state hashes lexicographically if hash_state(candidate) > hash_state(tip) { - return LongerChainResult::Candidate; + return ChainResult::Candidate; } } } - LongerChainResult::Bridge + ChainResult::Bridge +} + +/// Returns true if the fork is short-range, else the fork is long-range. +fn is_short_range(candidate: &MinaProtocolState, tip: &MinaProtocolState) -> Result { + // TODO(xqft): verify constants are correct + if tip.body.constants != candidate.body.constants { + return Err("Protocol constants on candidate and tip state are not equal".to_string()); + } + let slots_per_epoch = tip.body.constants.slots_per_epoch.as_u32(); + + let candidate = &candidate.body.consensus_state; + let tip = &tip.body.consensus_state; + + let check = |s1: &MinaConsensusState, s2: &MinaConsensusState| { + let s2_epoch_slot = s2.global_slot() % slots_per_epoch; + if s1.epoch_count.as_u32() == s2.epoch_count.as_u32() + 1 + && s2_epoch_slot >= slots_per_epoch * 2 / 3 + { + s1.staking_epoch_data.lock_checkpoint == s2.next_epoch_data.lock_checkpoint + } else { + false + } + }; + + Ok(if candidate.epoch_count == tip.epoch_count { + candidate.staking_epoch_data.lock_checkpoint == tip.staking_epoch_data.lock_checkpoint + } else { + check(candidate, tip) || check(tip, candidate) + }) +} + +fn relative_min_window_density(candidate: &MinaProtocolState, tip: &MinaProtocolState) -> u32 { + let candidate = &candidate.body.consensus_state; + let tip = &tip.body.consensus_state; + + let max_slot = max(candidate.global_slot(), tip.global_slot()); + + if max_slot < GRACE_PERIOD_END { + return candidate.min_window_density.as_u32(); + } + + let projected_window = { + let shift_count = (max_slot - candidate.global_slot() - 1).clamp(0, SUB_WINDOWS_PER_WINDOW); + let mut projected_window: Vec<_> = candidate + .sub_window_densities + .iter() + .map(|d| d.as_u32()) + .collect(); + + let mut i = relative_sub_window(candidate); + for _ in 0..shift_count { + i = (i + 1) % SUB_WINDOWS_PER_WINDOW; + projected_window[i as usize] = 0 + } + + projected_window + }; + + let projected_window_density = projected_window.iter().sum(); + + min( + candidate.min_window_density.as_u32(), + projected_window_density, + ) +} + +fn relative_sub_window(state: &MinaConsensusState) -> u32 { + (state.global_slot() / SLOTS_PER_SUB_WINDOW) % SUB_WINDOWS_PER_WINDOW } -fn hash_last_vrf(chain: &MinaStateProtocolStateValueStableV2) -> String { +fn hash_last_vrf(chain: &MinaProtocolState) -> String { let mut hasher = Blake2b512::new(); hasher.update(chain.body.consensus_state.last_vrf_output.as_slice()); let digest = hasher.finalize().to_vec(); @@ -42,6 +138,6 @@ fn hash_last_vrf(chain: &MinaStateProtocolStateValueStableV2) -> String { hex::encode(&digest) } -fn hash_state(chain: &MinaStateProtocolStateValueStableV2) -> String { +fn hash_state(chain: &MinaProtocolState) -> String { MinaHash::hash(chain).to_hex() } diff --git a/operator/mina/lib/src/lib.rs b/operator/mina/lib/src/lib.rs index 957bbc278..e7df68d82 100644 --- a/operator/mina/lib/src/lib.rs +++ b/operator/mina/lib/src/lib.rs @@ -3,7 +3,7 @@ mod consensus_state; use mina_bridge_core::proof::state_proof::{MinaStateProof, MinaStatePubInputs}; use ark_ec::short_weierstrass_jacobian::GroupAffine; -use consensus_state::{select_longer_chain, LongerChainResult}; +use consensus_state::{select_secure_chain, ChainResult}; use kimchi::mina_curves::pasta::{Fp, PallasParameters}; use kimchi::verifier_index::VerifierIndex; use lazy_static::lazy_static; @@ -62,10 +62,16 @@ pub extern "C" fn verify_mina_state_ffi( let srs = get_srs::(); let srs = srs.lock().unwrap(); - // Consensus check: Short fork rule - let longer_chain = select_longer_chain(&candidate_tip_state, &bridge_tip_state); - if longer_chain == LongerChainResult::Bridge { - eprintln!("Failed consensus checks for candidate tip state against bridge's tip"); + // Consensus checks + let secure_chain = match select_secure_chain(&candidate_tip_state, &bridge_tip_state) { + Ok(res) => res, + Err(err) => { + eprintln!("Failed consensus checks: {err}"); + return false; + } + }; + if secure_chain == ChainResult::Bridge { + eprintln!("Failed consensus checks for candidate tip state (bridge's tip is more secure)"); return false; } @@ -242,12 +248,8 @@ mod test { assert!(pub_input_size <= pub_input_buffer.len()); pub_input_buffer[..pub_input_size].clone_from_slice(PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES); - let result = verify_protocol_state_proof_ffi( - &proof_buffer, - proof_size, - &pub_input_buffer, - pub_input_size, - ); + let result = + verify_mina_state_ffi(&proof_buffer, proof_size, &pub_input_buffer, pub_input_size); assert!(!result); } } From 3bb8196b8ec2d7cec6f761ffae7cfcfdac7d7440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 2 Sep 2024 17:51:55 -0300 Subject: [PATCH 2/4] Fix clippy --- operator/mina/lib/src/consensus_state.rs | 5 +---- operator/mina/lib/src/lib.rs | 6 ++++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/operator/mina/lib/src/consensus_state.rs b/operator/mina/lib/src/consensus_state.rs index 388519880..adb0e9323 100644 --- a/operator/mina/lib/src/consensus_state.rs +++ b/operator/mina/lib/src/consensus_state.rs @@ -7,9 +7,6 @@ use mina_p2p_messages::{ MinaStateProtocolStateValueStableV2 as MinaProtocolState, }, }; -///! Consensus chain selection algorithms. The [`official specification`] was taken as a reference. -/// -///! [`official specification`]: https://github.com/MinaProtocol/mina/blob/develop/docs/specs/consensus/README.md use std::cmp::{max, min, Ordering}; const GRACE_PERIOD_END: u32 = 1440; @@ -135,7 +132,7 @@ fn hash_last_vrf(chain: &MinaProtocolState) -> String { hasher.update(chain.body.consensus_state.last_vrf_output.as_slice()); let digest = hasher.finalize().to_vec(); - hex::encode(&digest) + hex::encode(digest) } fn hash_state(chain: &MinaProtocolState) -> String { diff --git a/operator/mina/lib/src/lib.rs b/operator/mina/lib/src/lib.rs index e7df68d82..408aef57c 100644 --- a/operator/mina/lib/src/lib.rs +++ b/operator/mina/lib/src/lib.rs @@ -1,4 +1,8 @@ +/// Consensus chain selection algorithms. The [`official specification`] was taken as a reference. +/// +/// [`official specification`]: https://github.com/MinaProtocol/mina/blob/develop/docs/specs/consensus/README.md mod consensus_state; +mod verifier_index; use mina_bridge_core::proof::state_proof::{MinaStateProof, MinaStatePubInputs}; @@ -13,8 +17,6 @@ use mina_tree::proofs::verification::verify_block; use mina_tree::verifier::get_srs; use verifier_index::deserialize_blockchain_vk; -mod verifier_index; - lazy_static! { static ref VERIFIER_INDEX: VerifierIndex> = deserialize_blockchain_vk().unwrap(); From 7d89a32c90cc2b5cdaab9ac2c86c1c84bbeadc4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 2 Sep 2024 17:58:44 -0300 Subject: [PATCH 3/4] Better error msg --- operator/mina/lib/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operator/mina/lib/src/lib.rs b/operator/mina/lib/src/lib.rs index 408aef57c..4bcbffea9 100644 --- a/operator/mina/lib/src/lib.rs +++ b/operator/mina/lib/src/lib.rs @@ -68,12 +68,12 @@ pub extern "C" fn verify_mina_state_ffi( let secure_chain = match select_secure_chain(&candidate_tip_state, &bridge_tip_state) { Ok(res) => res, Err(err) => { - eprintln!("Failed consensus checks: {err}"); + eprintln!("Failed consensus checks for candidate tip: {err}"); return false; } }; if secure_chain == ChainResult::Bridge { - eprintln!("Failed consensus checks for candidate tip state (bridge's tip is more secure)"); + eprintln!("Failed consensus checks for candidate tip: bridge's tip is more secure"); return false; } From 6554ca0c8fa08fa972f70bd7e969c2aad0b77f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Tue, 3 Sep 2024 16:00:08 -0300 Subject: [PATCH 4/4] Fixed mina and mina_account tests and moved test files --- .../test_files/mina/protocol_state.proof | Bin 48342 -> 0 bytes .../test_files/mina/protocol_state.pub | Bin 1056 -> 0 bytes .../mina/protocol_state_bad_consensus.pub | Bin 4184 -> 0 bytes .../mina/protocol_state_bad_hash.pub | Bin 4184 -> 0 bytes operator/mina/lib/Cargo.lock | 4 +- operator/mina/lib/Cargo.toml | 2 +- operator/mina/lib/src/consensus_state.rs | 36 +++++++++++++++++- operator/mina/lib/src/lib.rs | 36 ++++-------------- operator/mina/mina_test.go | 4 +- operator/mina_account/mina_account_test.go | 4 +- scripts/test_files/mina/mina_state.proof | Bin 0 -> 48342 bytes scripts/test_files/mina/mina_state.pub | Bin 0 -> 1056 bytes .../test_files/mina/mina_state_bad_hash.pub | Bin 0 -> 1057 bytes ...TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof | Bin ...73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub | 0 15 files changed, 50 insertions(+), 36 deletions(-) delete mode 100644 batcher/aligned/test_files/mina/protocol_state.proof delete mode 100644 batcher/aligned/test_files/mina/protocol_state.pub delete mode 100644 batcher/aligned/test_files/mina/protocol_state_bad_consensus.pub delete mode 100644 batcher/aligned/test_files/mina/protocol_state_bad_hash.pub create mode 100644 scripts/test_files/mina/mina_state.proof create mode 100644 scripts/test_files/mina/mina_state.pub create mode 100644 scripts/test_files/mina/mina_state_bad_hash.pub rename {batcher/aligned/test_files/mina => scripts/test_files/mina_account}/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof (100%) rename {batcher/aligned/test_files/mina => scripts/test_files/mina_account}/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub (100%) diff --git a/batcher/aligned/test_files/mina/protocol_state.proof b/batcher/aligned/test_files/mina/protocol_state.proof deleted file mode 100644 index 12d53de93d6143ab554142ca16e364e715a627b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48342 zcmeFa1yohty8plFZV*Z7?(P-@1f)Y!5Co(_x;v!1OF+6Cq)Qq>K)Sn2@~`Kdy^pWH z_rBaa?)m-4y~jDmX0N^Zu4nfAJkMNfK`L0~WD%}xq}gTDMo|TSISqV6ItjffCLxSh zn!Y$DN~f88aCK$Z76$dWPU_7v@&LMDxkS{M;B^PhbX&-0E&wn+B&Ki#TZxOp+KZ){ z_Z3UgAvAxF=r0<$P7;FtI?URDOCqtd#;(fYIonfA=!g7+bZXG~?k~0xD6T~F@o1JA!4f8R z>QrK%=b)Td`|8IsF42tlSXi*EUy%($(2GKcV;ie;%fH|W=|xrJYe=Ms%stoc5e-s1 zoPT~ZK>A)YOxVpO_Pq>~FZ7y~kBu8m*V1duH5!h=5B4f;q@&au9hXz4@kyI?XcuTl z=UR*-T!X z`~aVM2)_@i?}_MdKLG$7Lr+A0%L@W=P6@ha-DAXS>KQcWlvBeb4jNK9OE`!?U5fSB zY|jOs;v^ml-iLW&TMwaFWhf7g3r|CrtV&T|FadS3!&y!~V9ukhO;6iWifN}mz0b0K zPN)AJ`>(I&8<;Yok_YTKn1*g0u;p{PLxEe=kKypht1-B+(bHP)7Mu+g%_ zouKZnAgSm_un_LckE~CLZ+(1|&P$Zx?T>pnNMh_Jw;!?tc85p0FOd@psiNL;<1$Co zIBpUKV&PKeNel_rlr)7KBR=S;l)9jxpIs}S+O)!hc)9EkVA&vB$7>*XzQ;LiIw4fYa|!(>6Il^fDDO#1Q7>SUONJ?Je0L zZrPYfXC9RV&nybWZ6uH?UAUrOBA@oZOm8Y4P{$F?$S{~Hex+RYGU^pWjnP19YJea2 z?B^(Mk~PRLS1aCDLkk1*2$7?kNq(a4_||zgVu!;ErF};lpS;y{b9p2hf#c;GYqAcG z1_9o0gD-5%EUij?63NskMHXL&^vobRp$;@o7c#p@B|9kenrn-p$`!y-SoG9HaAaLb zEa=I`gTvcczyN{oDwF_@Q(x5+75Wg+E+L9|i7bz2FUY z`v$Jt*ZOAf7TBdSsVC4@^W^4|GkrVx_?^BwU zl9c~A>B1&vJszu*n|y=DjJMz`aFNrm0hQJ%@Uy=6GMnE1#Q8P%KB~kQyvaL_?rCk0 zh|(H!ziu4zEgt5d_0jRK?EUDKA{SoeqlcD8W^GWvjE^Q+(l&Z*;UCdN^GkhetqKf> zwKtwdWb>bUzK{>)FO_?bg?cq5HxQ^hE;UI0v;Akojr9F5MGLEuHlU;-&^yJzdolO| zdGzJz$EhCkw!#0bNApDzu$c@U-Dbp%J&Gf*93UsnR?68DIydd3UykjD`C0F{e&+a8 zer^WdW&}D}sb5(4uyl{%)JO@eXJ+(>jt}`~J^pMk%DPGW;}6Iaw@EfzuOC_}q)5tK zWpKbCpao}5aQ&>WMyp-+qV9Wepu_aZK;d(^BpSs)RICS+q)EZ~idFc7pY>bNGIcrQ zZZR!KWQ{-ef z`MP?_dC}DDKihxYO>G26jVbzt9Wp32NE%O?_0bgQ*0V^Ox2K*=j_raoDI-hc)i3j_KHLvWa*b50 zj;w0ZKstw(Q*+-+FWK!3Cj|ldPF)`IXZtc0u3OH|GZx0aj9E46`+HJB9Cjg+3j0V~uQgSwwya+L@Xov|I{y5Xpw~X^ke<2A-b=P{eeqlCx z`Y9wXlV^ogcX4HOLZLwU>~&HL&oA{|iF3|;%wk;-k3{`xq>&$)U4}$u{g^Dr4D~`S zM8bpb=kj;izI>DxK*PGw#`3R}xsrqxd5XdiT zq+o<%Um2n*6&`+J$5erswsXV#*?u6GV4Ya|h#mMQEuB~~vG2mH?HgB-!PgCah1VO3 z>A%$1XZvbfPUGNI3;zUfM_MTi=acDhhq|+4PfZ~o-JTrX&-S&vEznh0>Y55RlvkH0 zJP1^`Eock)A+cRmXf0{N1AdwBgc+RGJ-Bu}xO}*iz5Jn$ur7vQ`umi;w$XG8^&%kw zKieN0NG)^JV?3=jnD^?=6n_M+!;am}+aU!L&dSo&+WPQkJsjl%_%mm)(=?>Cg7%D?@dQIte~TzJ*GitR^dp z*b75ib;EiaG%)$WMU3v3^&cPC;@H4#?_G?zdcris_>7At>14~89*qK>O*7&3h+h67jmpQ#_v-G1TeKBZ#NoPV)Crn(+M-TX&CkpEmU}hkG;d@}~ z@fY?UOzunxqAZm7AYw*y*g@1of2gu~(SS9;1<%jzlj>}-0kvv=@zoR`GjlcrkuJ1G zWGLPNW%hDpvNxt0{AWFUyhvo=v)B5ae6=$WI*1hy2lBAJ9a^1iKVJA&N0@W`tbgDk zqi^!E)216+x5K*Yo$nJCRT?}cIl~a-RKj)t?10OVop6i7iH-<|;c)(xJEQ8w50=Kl;4*WjqHTqLAy-n#5`+mYufLzE3w%KxOi& zhZo=}M2SslvE%%?JnDIUo1-?%RMU{m2)^mV$g2;}x11UxGqm^Lm+LQz@&2s0Z<2jZ z=Mv&cn2DiOyK_huoBb?~mV}`Xk^dPZhR>H@`YXrV`!h^S13EM>W=)>!rdgU!I^WZa z2rFD!jTRwlh+pccOUT%i}`XRFtK!YP{)v+a$0_FW+io{ahZ$+qZ`P z`4JD}wc@;opz-Vh^2G$Pc$0*_E;!tl=If|G>pwH|3>R>H9L~ZBDoH2NqcDTCkV$r* zM=l8RF|9gP`GrS_2*H)IZ#IWlwU^uJ##QK1Q^uQ(7MZ%i&A(npkiGat4>=+*z_#Kx z`AK|w0fyhnXsx7wC}$|WcV@$?nM!^Cm-Z}G`5fUGJIyhW6~3EQm03%mQ;mLByU$s1 zM4PjKc}f3s`Nds7D8?wcPV7GI^(2Upwu~))u$QE!K7GKzs~bj0`HMdgcuuB5a#clK z#@vKxikVx(^MOg8QkkJLY{Au>hx|Fy&-NoiSLi}N-61R;FXmJDN{mRuL4;j=E}I`L zc3og?5cy^ND;K9o`EsVREabT>VMWz`i@+R$iJn^_(N{5O(?W1#{%rq=mkX(0!9x+k zxUT0V3+4a#2s+-w%&WerP>B znlz4q?#rkpXFMHj=(<@R&GVKG{Y4)VR;%uX?7VO8NG=^l0T$3|2&=|o7Lrvf!rZ(r zt^dn>H=UK@5MYR!lo^?iV(}T^%GyttdP5Om{i?i6;RW90FXhiSyCTpW49z|ylaItZ zT-Ki8p-ozNUCp{8h!tRF`t=vS3{k?^b2wD*%6!_n<&}D;Ol9yuI$sFQ#e^|5h?;Bm z7hY89p*KlIwC=x1j(sncDXJJ5EeKO)FI_w>fDw{}mIn26`}iL>F(dHf3!X}x%Bid9 z#Lb%1RF2I9;zKyUQn5gg{jBf8s&zfC5*mw}hG;kOtc^7?rNDpGP}ot2p4Q$ZGW1J* z*MdK=xhiuekLSuy%fO;pKD5gqI?5lw=v00cB8Mybi+`T|sM;-s_U5o(!kz_Dt-K2^ zN47@HRZfuSC|X_lY3nckbJfFvh1f#kz2RnNI=MCd$4+|{C?v%k`k}}!b(CAV1V5Mm zEOoda-ZnKaj)mAJDH~UJe1OfIY@FCub{^S840rGse~dF@l}U)t_5q4lrAwkhA4|qt z64n<8GBV!!Wa_%*1;6+kR-Z|r;kB^X-3WbnOmcMuRUlNH(3<3+iSsIE-TZHV@vlaN z)ix3gx@vB=EeSK(#F5^4zVd`WNWZBiF$zR;s{W;am$tAOPT>LIU#AqTBe2&|KEfLo z4J>ZH+k0{rgBc3nPzkDcX$mqw~=5#LmfUHjn5yqLNX)?PB=H_P~#C zz^wuqShsFYB#C!`hPII0rO(|yLKH?g^tK~bk2Sb;42g+>x`Z<9a<cOD$j z9?n;1I{bHKb@emPDE#ME9;MXcDTNkLF8jyT$|g3?lL2)LXX&RIS6sba=etb9JUrsm zEj5@hRdH+jBz>06rZS-Nb-9BxuCxU^zXd~;`e2OO<%J-(a|Fk_IhHg#PK~h%+M-jm zj(YrN-geOOYed?_s7)3ZU|}`!17J zebrQ^$8|aF7&x<9s=Nv~F+MB&;#mXZfkFlawAWE<@yKptL-tdnn+ZE%@~9q4XcNP= zHj0uB|Ca!`7Y~8D?fmJ);u1Y*(&_3M2k;~hEZ8K%>YGQg!JG(P$XX$SKwTc95N-di zAt^z_hvo&7XPPy!!*ZTUw%#>3pL}heA;182MNIChLXvHZ^?*4t~v&u@H*? ziuox#P{+b;VjSi!lDCLz8l=)Psko&W@!9q$cx)DdgtWy=j2WoIT0-4PE5XU+oZ`7= z7f~(%-_vZZ#Dte((=(*tJaoYW>H;*Ba^XhVx>}s$@kv4}5}H^`EIXTYTig)#LarSs z8Gt&(!qW1HD4!)CB`JRKT56(xbi8&^-N}?^OCtNFYBr$yzLXGx01HVtn5cW zS0`WNgiC959a50=k=G-I52{DGr~VI z6SJ-=G>J!A0s)9lcX%eaU{+tUNoMk5TK0SlK<)Bn?o`~EXulV;Sa7XD`Z~QsVL0jT zgQ)iccVfav0qL#6XRoOSQ3*FE&&dWpR&Uwx0n0~ZT$AG|Nf7;`q^(sZv zvR#VHH4?N=)&bl_JFzKTouU23Zu>s$)TGr(nm@S<<>PYkyd9=U{L>&5Ys7WN;BzrxnT8>1^M(%$}(EwVnv;_Pjf3)gx8Qee@Xnqipl|gM`N%Zzb*;hN;y$<9p-sgJKGySD7{{{=2 zrIZtxFKHdt2Q5X1Xsp)A<-Q?B@}1}pA#C_-JPj*SQARO@I6$3SXjO1&SMjGQCAN8Y z_1fy;;b9S^_eg^i9Us?jQ-+X$I*y{-Ijnu&3l`_L$PdSJvLA95%6JSm>Yv@*p@#%t zfdO@JS99zxzH<63hxKfsTX1d@&-FE!pSZrpPTG|(r__fnX z^}SC+IF_CyE!NeM$YFMG(11ENFD1`TIOEs6FO9-{V3uDr)IO7=KVIWcY+N+$CC_7F z9}BctKH2RWq~v}D8mG`{869j~R%nROb%S+cRIAD*Q)@E>VMuhA4=Q14UZ4W=U8O6W ztV41uPQEQ-vhp6_PahSGk6(P_Fp`1HYO5H&KH6B++nXQ>;@jlnaBH?V zhPq$QQf=oEtDmFRpxQv!sTt*%XT}`sQ_y;V&%h8j`WPv{n0l?eJEZl2*-b>r!Z~UM zNgO@KyV+_`zHZNw)gg}Ti3<@$(px0bD;tMHq@)1E0zudD{RL5sSit%c3X2&T^SAnj zNnf5keZIV)lhl^HUdXLf+eKmBf7c0W7bq_w0pSaST;xMaA!dY+DW2TeCq_f?K2rN$ zjboZiR6u)4owv+(sCs&V7H)flJ2!RC$yVbRC+b~J6I_864>dvaEw|#`fF)U%!9ZBM zJc6EdN2cvN7&4}}e9#_pN}0(t?{>X4QjT)P=4sb)-Jh1l|4E~ z04yKtfMp4iGv-s&d5w1!vHc6nF{X|UEU2eQvpG8cMVO#H-KD~Z`d z(~)5(#xHHSr>|ce#(@y16U{oa3m4fn+lLUO%)7{v>rmAOPxFZN5HY z5ntI@vUNkCYL9!DBDngWlxsjK;~+^Wf{_4qSzBj>bxaV$ZoG%(P=HgZa%)A7GgMTr zS5Lyl7q{0yeng}Fm9Vm5Up9v2hWU!G`7yxE(&Q9$KGf3{JX}hM6S6 z9;U}T(scClWti3+^*OnSKa2Yk0$QJIT0=1CX}ca&?z{Ft9Lb^|?lEO#5H|Qjv}YG` z2BL%dt>3Sqo#kx;ZxsiGSwarW?R!Ef^}|niYSrXYfB?^3&?WAUUX=*P$J)4;ku2Ra zx%uI$u$QEcTfC?J`q}~xh)kgMr48@=!dci2sZruaf?h!ULHVQlJ0ZW~o0@Z*7XP5W z2f%uKQWZ_KWFmjQ-n1hdyq2?>1xa?YdY8gqX6-fJlQoF~)VZGVc#$hheLC{_n7U!m zTts*q02@DVoX)!#i-1@%1G1;qPeHVdL*HkLtJ9fXifl7LK`P`xt;CH6=?(U=Km@ez zmUghAi_<(@N2uUe;+@|>%G)+|etFcr#u#|Y6ZC-twC=96Ef<xnFX=x=7BOGr5CE&2rI0(@7V125B4%wy?AH=@IHlfu;s?9-uvbl&K6E8}o$#EYd_@!|SuN`m?O& zm8g0VLgFLp2pG^h8R^fYG5n>AeU526e7}b}lD^yJniBr%`Kz~qsZ_)Dpg0fiYMydz zcvLq)yCH<5BuKeA;>8`+?(l>0Q+Exe{LH$ufIC$4uarN0Tt3Z?^r3smiook$hNHfam z-BEKEhZ1OhWRfl#_r=ojG6!baY-M*SJ!Fq99uQ5Try+CfJeoHKt@qP$M1=>T0Mpxr z1+v+6?_7g^2Fpr@fL#O3`EtWhF_3>%!VycFSoZih9RG3>30YSGDK28YFhgvi4MfVj#veyWC7*=R;KdsM9( zWrlzr(N8pHYR@&I-Z_zZdjuaZrmsnS(@0oFwcWQJG_F*AA4CN~r0uaVRymDZh^l$&ddNLMuCsj>5JlmYT7V6- zC*C2Y_;~QT&=%e9bN|IS0iO8zaeE{m&W89_kE%uPBcM(K9z0F{R`UV3JK3&T*y!wT zN5oXkL)<6wrO4JTt7Ra6ZQ=MOIqL*>L!Fq?x`N*peO%%(3lA}xwe~tL4@SNSh%*Ns zP0~XaozI}cN=7TN*6IBk9V8}I#E-79{pJ)%NkDO<GYuDJNR7E3hJb&rNSD-psu|G6tIu)ZDzFf^afCxk*d3BP(^&0cU$AxhB< z;POkYXzeUolMn-SU6w33Q8p9X%XlvyE-1P0>pB_utnnMor>v~MKNd;{t&?CDF>q_i zN)_$ZSsI6w>w=5#*$jo4`R3+N#N?Fq)j|0Z5||kuueU7jpY}6QvD>@anP-ufW3&=> zmY^S6KWhj15nh5aMcKXKu}AFds?WeD9@V-O<2b$@0EfhUkkpeN4Dy@6^(n*hU zXSVr<_{0-*tM%9xg4IO{Z2AfD#k!bK0Dn)w`q<>0U$w86y`+7F6K~DAxyb60mlcSd zx%sp#+EP9j9yE`602l&JvPAaEVb4rx_H3{d^@5^bdP!~5Xx=@;!^Hq`#D=zUzL9xn zmR3+{Nw-G{Q|Y)EWx4w%WnWghi4qqYq~jY1yi#RT**W7Ur&WMy!)d`;x+==eW(;^a zdi!!E6Ld?fpg8;^qYhm6qeH-(p=Y%9$_9cW(9pZ>nIw=!D-jK#xC;dgu7?ii9lSH~ z>SrSn@;8+%kB!FC;zoTS{rY*))0lwuWuYb0FAwfM4iXrpwPSfESYG+oEl5dky*vqw zPM*sWw7$s~!NYh7cj9X(ICr9!* zts4!m7KOuyhI4JF5@8Eydi`tIZk3cNHx1fOy^vl2kbn1}wYAcDfRcz?6Saf_a~>6p z@U%Zei!t!YIL;Gk_i&J3A*oa_Pn1#*TBk>n zt}WFJO&Fs~hpKdi>@guqLuuW;omt(=50BF#`$7EQlxHsa9D1m1ecQRb5fsC{`-b7o zoxLLX4&pKnphX0}F~sRjw> zMwb|DNS`u^dA(%4N+*!6^v|-+^|NT=Z_Xhr(W?sPHHpv|je2Rmqtm&pjxBFrnEXEcCYTG4}@WeRT(SP3Jnf zqv8POd+x&1bYo^VggAb;gW)@JHMcE3qR{I%rd$88oepmeG_FXyWRNP56;`2C`lGo^ z&q8z085Rw}WF$ptzx`)?Pj-1V=4UiX$~f{#k1a zHtZ6PumXId^MLx`llLHgRn59vYnd3r?LxqGMYn$C5K|-qS2Mo~49zUi;vx77+9x-> zb>5pJoDR}I_;@C>{X8DRkiNvAPd{!Z>td1YaS>{T5d9VaLGV7u>`j*LBVkn182yQc~PN5&c z3P8F$Y}WX?yQs#aTY^YWEh!uC04Lm%5)3#FwBp>fPlrrKAxM<9!moHJgt2MW>?|HU zhfzzi8cRw5@ndf93ZnvkFXee1Ntjz>=tVr&Z%|--eouIg%fKS#J&gHY_ zd$f>UEKA9@Mx#k{$at1;6!tQ|#Ox2mziiF0$^#lRSic zkokBE8$et?eVD<^oI^Pmwan(ax%igisba+n-D!1$%-)_qU7QBUFQ3w0OX&XqwG(SR zA>||s{lo&W7T3K<+nt$f5nb~s15{s0pVtE#7h>%2Q6kk{xf4G1G*&bvcvzo}(xpi{ z7}-Ib@x{?CU-2tn77cb+NwlOmu;XLLF(MC`mDaY5c&PFjEjwzX7|dWjH%@Pg>WWLXV%af@h*xgtWTxyu z<9P#6SgnOqd+YCk-+RUA0oJIu}`NPcd&y&V(^^Y=J`t9-`PuR#?fw+(K zqS_m=$+Vu1n{>|`M_~2i<=AJUIHzlDt40zgdVP=|7>=lkWLWh+yGfhIw;jEkG40Dm za`1F2Y%!L6n_~Y2$WK+W&2kidyXRR#><>BpwMcknY9b6^MH&3E{?*lZ*gyBlXCbk_ zD3$A?u(|f3!}{Vyk0?FGGRJ6;Loh9i|L4$a-x@C}nZayXU-VfikM<kC`?Pr1?un+6J%@-!ps6ZGYeIC@X%AhRWFN%h|G<~d12?>fvEuuN+FGi_aKf=H; z(_*HVUIs-`NTESaHJ=WX1|c4S`~&=k85Q}xk?7!Z>rZOsH0tUHV|YT-=$lZsv=%3O z?wi2*+vz4W1(!Lhf>C7=!=WhU|59?rddk-g!T z9ck#aPG*s_xH#4CkOJ+BgioKVZf7E|TIh{y(AIFAb4W~i&}!K)kRu1^2qevrvluA=v`xYjs+6lD_`iipFOOAamj_FTt^8NgTDMJAb zV3bY5<+5%S<<78zM{V{eJ;C0oL;nlVEdTfFwfoMYzv?xBP^q}wKL!SHMEqf#{5WR* zjouV#K#hfah*KX2W(S3Eh#Ih?H&T(4z8vb^Az0PwL=eZ~W;QX*3+*GZX;o zTiyiUUI^b_-_!TU>ma|qAilkzzrDVf`TH^OyYIgTekS^M{5=tEe#*(GBvtvEfG?zf z*kG|`p;aMEouf>hjP@#B69FKc@^afC#u)Xxb|)18Si$>#^zE1z4pi0^B4ZMqgQkY5 z!Z!gJr4d2ZBr6{c-+$%2p>sTke^!eoya^#SH?0bau@&+npuckOOfEbI#tcFjE4d&Yu?axDQCi=;Ou?d{2=;UsR4k>WT+%6c##zrvhLi4 z0+fzmaW4NpYdEnRACsrn&zr%8KSJ*mu>bRV=$FfrLRHH0BH6jaWe@qAWcy;jp@Df+ z6m+5K4bSrckiY&RyDf2Q`R(zxfo4Lm5+8oii-&@wsvL2S5Kmt^M`4lx^Dpbkiml?q zAfb+9J>PiwfSs$V^+igy>lZ!t>ePz)W6z?Cp^)~t*7!~$A! zn`??|Ba&fby)<@+K($KVB6K1WF-6UI6C*~@!}>&*|YpTQfSy;t}1z zrB^hga4dEKevHU-_)2s=XJC(i4K!xR%}mqeZc#7Nb1&os59fx1(?ogn-$_Ik8= z@E58ggYm?j0=oz7 ze}wyY$p82m*k-hXpZkS2`PnrCHCI|>{QH(EOm%9l%@<5_baB=^}`_sc^S3bJaed_#4(|_Jrj>*%FV%t>Vq0ejz~cCt$CRtB;Z{~4QY=? z)^B2`5a&juxCy0waS4s73y4M_2MPbu;=N!mLBu<(Ng+9nsnuA|kN09y949R#30~t_VxWis2X!@$lQn%wW$Eq{MTYR;N0Fp{chSM3 z5GCPDh>iIiTP{GI+Tq}wgvG8URVsI+%?14XM+o#9sgX=`wPUD6r59nKE9>`#{r_}~ zc;Cn#JIktXF^0@|j|XKDb3(tH#Cn(|gX%;2l*N2k()B;Dz~5K*?-e7aBw?Q??xsJ1 zR^h5%qCKJeeAJlib$~#{!>V+BNS*|`PN^tPJ2Ui%*2gQfLsX!HIuV=1A}v8BwRt?Z zKdiU^5gBk)!B4a&#EV0dhzrQQueHuJybj$z33=6IN}XczzD4sEB44oBC>FFf_8ewK)4K^HiAA`sBEgrt?`7CXlF9`q$H#LPK#{NCBKl}mqhreO} zFM<8^kFX!7p?|Y%$*n^*wIp~W8Qi1N;~k!m<@??fJGX&LzZV9?aB3@m&te49ybEIO z1qj%kr;U$A{qtT`ot0p>-Xdt^a)1Gc^=R|o-V8Xc&J6==d0*HQD`k66H6bv8uS?WkP!(iZ z$V>^Mzr^UR5UnQX*V+MH{`(F4|I3m6Z`glh#1Dz+hvWb3@V>hL$i{uo{{wo#fM@-0 zhP{xb&>vu*AFM+QQ$FduJiLEtQ;<07--u-!57@ilF__H8t?)JKkkh6|5Kk=3;!zl7?#X9F=%^pCJV`T_PwzhVC`f&G^sVV`Wu_sW&z zuA#Gd28|%2gr&Nc*jL3`ClgbMOvXOl0tp0rnPgjhN~M!(d921&K+XHe&;*3}7c}LK zSFswe$ut}OdBx?@fG&A{hQ}XF9amaGZ1v-)!e;Wt8@X0`u`8ac^l9GvZR109uQiJu zaD*)zSRd&~R7i!$FkSjK$9O&{jxrGtDc}T7$os+`I)c`)?=ghQc0janKiXY5U65l6 zB6eg&8bN)%&k)=K`W>tjD~?GobJ>?o(|xdCu08^=Si>?@EAkT;^9rI-o1 z3wl1%^EIIVus!-26%06E4jrqIJP6o=5M>-1KjG#MLrxl>QR_QP1xoNUYh1&VgM@!+ z@m|~byo#xZQ41@H!ZnImLI8#fqAY|LFzZGcI9m>I!kQTWW!RTt>&}i2SE}Lfes&8e zdBKqqU$pz|MhKadZ>LhK

zH+}2mP8?upM4x)OxyxB#>CBKAEt@WrJzG2Q4@!9KC zr@-dWv0-RNRt~3rQtpX2=`gO!IQ^FBIR#}1N2Pj5h!3BdSti^V%aOp-p zKQ=oUOY3#G5vtijUuEMUK$vwb;d$KOxAD(^fc^Pz*#AplKl>x>E6W`!=OWfKKFX9@ z@t9~a_p1A#!ndR<){r1=K1L0B1X?%JF1UTPPdcWPT_Jh}#-#kBU<|F0eAK?W_j@ke zb_2NXFT5A*9guih-s9|~~L`I?M z0=Lad?+W1^{(yJj;z^CKv_#jG3G{yf_TO9U`?dQ&+s3c={r0R68AGJ$pkraW?c#x_ z8o>F(o5UrsL;VGHcg#P){`v>lU;l>vzXbMkKf+$`9DooMKIA1nJ_Loo4Q`k0Ria`# zics$II4Tk^D4q(8=v%LTPydf^&|`2dZQe+scEd(1pnqFXDdZDlRHC@nqkh8k-sziAt``s&VAmYYk(kh$U~dt2T7QYLEuzkJR9cVz#M4*16# zu$}+-?XREitNZoLzkhSz^Zy(hzhVE!cD-+F-dFcW>;L?8-}C>x*Zw!do+!)s53v6v zrLx`ZvBX|3%n;Z?Qjvz3D_c9hx3>kn07e z14cw>L8&3`FttT%h6R{a?Dzk9@?&HVmiEs_@4)!}c_H}sqjvzn|J0**^FPAAnZ!WO zea1{^i%_3Y!tFG~`O%x_H?L3Nk6WOqeKNe*0KoZT;_V4uh0ooH%yG_y7PK$KdCbru zPnnU-Qg`dUmACxQZG1iy{klgIB$*BDE+*;K>d{{rnn)Dm)X{P3&RYPpi4b7-itMRX zP|l*U4L${IceM%F%@~#@_RiZgg^mRz?m}aR^9llsbzj&=T+tj>Rd2dPFv_#q19Uw5L9@wgEG6SCkf_#2CvI4~bBMFG2~mCyYIdb0A_w)C|E>Hz)5Gn98V(Z^6u=6Sw>J z52gs@-w^^5m@1%FIQf9O`$qQv)7ZH0Ha;a%emPv0ZdnYA%$C=#JdY!4r5AZx4cR#q52d(_O4Sx%QS6aTZ9J-^z6&O zSFiom_B^na|Ekyi|9H+`m)PPDu(x~Aj4Wo=!hTM5r(SmV*_lV$jNWXxdASG?o{^S8&Xg>AeS^5g%$ zjSuky>>+-`{$CQ=FZ>Am(x9_4A{3EL65@>ALxv(V*RmD%#JM|?#{vAFqhsZ8V89WL z947{k<$SG1ZU!3$MwbegI{P)H)PIk(-4f+cHcpZWzhMvfLjsQaKYaNoAMUIBlT-ip)qT(Z^T_^xGweMUto{J|+1yvT z*b6KGF|Nvu6d}6Gsp5DI61L;QouS|Btru1L6odd%pd{3Et@)6;7P> zqO)!%n%EVMLw-LI^Q@ph!XEMm*hBt?{l5hEi$B61{c}{9o4MNOPuZ(@VGqJv8xW0# zC(wlFuJ#~t5GXtd!GQC{Nb4l$w%OxjSQf%n6yam4cO15^?QOZV#0hcCaxXXdLBcP@ zn&WZl`nqMiA5?31N8X8;Z^~`1OTuL9gVCiRYhd0F_PXLP8$4nqY2-eZ^PA`+8SRL{ z1g-Y9b93pZwb@!~g0|i73;RR5>XWaJrLKx`=cWfy2~?`JcPghEXP>_sEvG@|x_|;! zlcDy=nwwC3Bw&RshA*lT=2kMgsb*24ZgjN*uf6pgv_0=Pxo?1-V$>ALcFH4imY$F; zyKG*>^2x~fNhr}7peh<@4_lKFDvbkU%k=3g6h5^qG}iJ(PcXUWr?*E9LPxt5tU%pw z*#Cw-0Pt5aB5<_)j_d*VO2GE|EAjt5*z4l@{sH#%0$Rv(p{P$Jy;$cK<{D)Jb`e#w zvlCP1D}q!4@H3z8mC% z6eUu{X8`qLl^P3}A?n6t;B2LMs3Ie;gNQ3`SN{a%Yn3M6hfDUnAYse8x=IHi`XrQ$ zq5gP~j|hhf0uG9p)G1$R3oUA0Q{aBv_yv+Jexz3R(i;m;52_cv109fhs0+rl#@nQg+nx z{36z8wJ*d^^+cq~=>1|x@q>HZ!5zc&Q`)`rfVu*!W{9u+faG>W7pr`0DZ8KCF(ZyDMeq#USCxmv=zqvdPRB5ax7Igc3hH5z8&wtsyK+L*mB?Ej}@ z#QSdJKV|aJR82E5xM_cK@+_HArA5=flEDz=4@PnaK=`}&Tnh1I{A@Ob8A;+rOOch8?gVgZTzi8yL|p+DdO_8J~|17 zyQ9J{Oui5*ZyxHomkGUd0tX03eeqUE`1>|K;t#M#{0;km3GA1DggwAZB+nrk{%U^E z4KC%|W$hla>nH>|0|!_hefX8dYkCmFMao2TCbXZEEUpBvNBBPy*nO-_UP#FM%neW| zBKq2o2Mo9%Ka?Wx#6N(*y6Daq7C!b+aGqCbS@P%V zU^wMsv%U5N{STWYT38Em*(jO9_X7=9ZEspo3b-K(QT1jD%^?l2bYH#(=6he*i`q%H zygG^vHnfsk?FZ-ByJR+D!RRg{e5HfoK)o{u%J(b$|Kx_g^WiOaLG3(I81NmL|}K zAE~nEAFb?ZQrSO2uI!C6yt3m`Sbn~#YF)W>x6W4k#}6}aMJrtR_?GKjoLrk0yt3aN z80)Z=F{@tT{En?An-x13?k{D0c!Ei1c2L;f=ADiS-smr4ujWShST zK6g%RWiKuDVm=GMILoK^|1;WUr#xk`mrw~l5uo1@`}{lS$1m`UTm&2E7z@b8zj;wv zB*tA>bp4pY&%5j{UJ6@oeqXkw&FC|%ARxA~cYnr}yQxe<#v|AB!HRW<&&+u#xaDMa z)#+A&y~mof0^v)kMl1W#%ASFNP#+PN`bK;9z&eHqpg@Egkdon7*(*$)ic;CHQ?k;R zaeBGLynce*rNc9`Tfz^$&z(~I#MAWB!%Mpx8F|U9>_NSIh< zasS%w+5h&-agT6gvwJ5`?5PYwsq6)jDtp1v%AO{b{Zr)1ez5Md=Vo23T5Vz%P%*v# zkM)<_`C;2rnLb?J)|azqhKJGLN$_EJVk`SEkJH{WpJiLQYv&Y3&VsZxUQ_g!%8L9t zF1}QUz6oL*Lr_sM@2N1O;%0ILG3 zBXStuW$l#I8;!lKYmz1$jT1GPc;c=9g`bCdgmWUkiqF{cNDgM+Xk|ZI*^gHC(98v= zV7UV>Kq7-!{ll-acL~OyHTcDG1b-MB^>&uhg@V=2Ougq`^)@7dH{<3!$ zADNXs`kZ|;6L;hq-;5X20@LP%AO{b z{WIjsK3b>B_JH{H8Kq3|h6y=wZJR}vN^gH#nyDwYc^2OeO%X;|ei68zGP}gVa0PFp z^Jbm|P38wPmwATwp1Iz&u+Md;=tOqn6%w`eZf0YP?t}}M zxr)6PDk&>JIp3Cpv-T6KHgo?v*&1F=hf5p3+i1_a2n!CwYU_nN|L3NC7Jt8J-r~mS zCX;{P4`_!^%`B45T$Z%!F-+ZKiNpnBA9P-o{^n`aIj%0I6SAfyerH&oUE2$RMQcjn zbKS&N_S7B_CU(xA*v(nQsvB9ezt@X}Yd0NU)qH{B;mkJny@$Wm*y=5qZJsjcDPvWX z&3X7T&EpCM50}-Jv-D+k^Oqgjc*Xv;ZB?^KC%fT$erClNlN4d8ig)(uxD6677X9%5 zcl6oqg|mDJv6>G$fvk;24f!KQ2aA__|Wq)+i>Gj+8u!prVwS?WcxIXDeVCn?3)&+E#{rEsQgZ2iQN_Z^a-+i^gEjOUw-uLz|VVa zion(Qm%C3boCTS)7eT7*MMf)onpF1Bkt=((+;55xoS1Iu_dPX=o#wH{QbRUCbxGv& zwa41`&))Ds1U@?7)~L)jfot(1@#c@SeV1Q7C;a@5U>1|;0Y0&lkB@2ov}c4BFt19q z&m3Xg7sdKmYwEh0_piR5^6PtV=2DeDlT5xeeKR@Y=IlrBvmd?B9$1bL1PTOIKok(G p4wrGn>c`$kr1o8fqgUMGiYHWY%3^IOUvWEnpZ(~4_JjUDdjPH4VjTbg diff --git a/batcher/aligned/test_files/mina/protocol_state.pub b/batcher/aligned/test_files/mina/protocol_state.pub deleted file mode 100644 index b46087ca52c076d0810b8094d7f78b758a0615f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1056 zcmV+*1mF7`t4_7y8>)Jwf&yNBW!8$K$hwg@)X-Ahc6saT#t8)*t4_7y8>)Jwf&yNB zW!8$K$hwg@)X-Ahc6saT#t8*SAUn`pCP~^9VY@Als0s=Kc@fr!6MBna(Jm+N|0gis zmww)a)ilvA1S=gvjDB|wRZ;^^)32bjS3p7GApbuD$L797@HUU*WODLfN3%+dO)&a} zzLkL%u9Ip$LaR4BQ=ajY;N+S?w^J2B0513-qYGjO=VzfA>Uar3ToX5V4LZP$U^+sH z)#Z@$4_U^Whc`XC@pKh`u)reTCbbqWeXzdhohg175vwhYtF%Cbm1nP0=Y&_z7m6XD z0~9_fRuA@+7i83k>&C)9b=+pKn#tdHFpkrRn(YP@kUKxs=P;caJ3%_*_ftHoD))0V z!Z>&AU*R;u^2pIuV>+V}I#%$oHB>~6WS0XM$H?azW>Sd;pQ0%X1*0WRi;GOvFfex-(IPS>Byow=5esWRkXNd>4 z6q}A{m!>L3+jTvB={}V^a@qZ(v@ZAxW9OAZ9@jE&lsDh_(kQ{p2L~}L6riyBijyWv z5d_)3_0S`V4Du>lli>q{CF{fat|o;U*Ck_}Cko$1P(u>H`Z}M_E_fWW6ha=XQDSr` zY#62Q8s%U)b`HnKfLfc=e$IlgPHGgw9XK2vQLdYq&sFZhh2fzm{hNiK;?qXzmh?-) z5HAb{kt=4(MFVQ7It7hv7e(6m?_?bm*YuVOZx zn62$l{Xh;QJnXbeuk|c&zKl{f9^gE0dg}0F1>`6P(Eh7o1(~RPjAU}1o$fBmpP+9D zpNcy$xOTh{cLBBr=wQ@DeG`zqAbM-UU_mUA`zrCZw&{G4r~8$Q2kVzE7I`qdjRwI( zR6Go|F^374BQtM-K#4N9cj`*`%#b<-&J)(;aV^Z;l`nt)S->dqEVlIdMN0dw8s6H@ z5FJ*wUhK5lyxm)9(y}TJIQRvV-!1tAR0s4O6o)Erq<3tzn8i!+Et`(9x+~S#R+kIE zunz2)76TRd$Era=^MF!&-&Vllhd9J8^*A(i{DBP{8t9({4;KXT@Be6r9hBt+KNuua z$WSkcUFY`+@$@hB<7V#z%?7Euxs(A3aAvGZlrN_=H a*%f$bo}IW*qY!C~inq8zM6AtPnEo1kHv(Y* diff --git a/batcher/aligned/test_files/mina/protocol_state_bad_consensus.pub b/batcher/aligned/test_files/mina/protocol_state_bad_consensus.pub deleted file mode 100644 index b264a40bb7c3f6e3ef35da224cc2afe155de0b67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 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 diff --git a/batcher/aligned/test_files/mina/protocol_state_bad_hash.pub b/batcher/aligned/test_files/mina/protocol_state_bad_hash.pub deleted file mode 100644 index 068de7f96a11848e12768c38d9adca12ab6ca73f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 zcmd_sIq$?q6#(#*5jAv_DS}+AcYPNW;%5(Py>6^SM_ zqCu22@Bt8_B%-52i2X;Y(LV)6!ZdD1Gvj&l-uwOf?;ro>TR-{P&%gh#`Oklwzw?hD ze)^IBhd)KX|J`4{JN^5!kG}oE2OoY2&3JM*U3pq~U@(~oI5!Cp;ZYL0Xa+Z2;fD6O zX_q|dRH>15APgi#w>a*>qc z9CC+`W|04wNyQhZEEVmY64hlySX(|fg>}_2$e&u>xVf&Fg_%Vtjt-H1s}qG1+P6*e zbCIVcV8uKw^eb&w9Faab7b_%3O!NoRMusV6iCB{u(eD z*+i3%3GCT+@8e+Za?I<2%=b7h+OY?4-UeBXPW63nn}vf?%&{~`^|R?>Y}kbhPBU9# z%2SH0_B=oA#Pc?o=OZ-O>4PhURsr&HkP*Yz1(lEypHr+Vn$6h~v_{+I6_&}WLZt0d z#uyq2o>L7*cdfN@kLjL6T_tr?{}Llo!y3)*dT}9!_oKZ`GwXlCZU+A;l|7Yi>zEsp?$3bn$E!2Y;dpha^PS<@q|@wZefQBkUGbc zxve2xk7AG{*C`;NLdsA0C z#+InM6X(ujd^GV&7KS3D-W)d5MgwCP*a=1VAUn$5ir|Q!vBsow@YvNyC*BfatIk0P zD<)P1Y6HUj#FyDZIqSxIg+={_!!|=amF$47L!1PzhpXL=1gTx76DX!<-IY}M%jQem! z5W*p^;cY(bQkH=|D9Z{~nzac-eY=ylecnHe_fG|YB_-8A@a~H}vcs5WfK1-a={A?Y zF5{FIJ5A9gn%Qr1~bE#njqGaTQd95VdjwGJIVWjM1{LyE0!+H_tnx~%s3nQD!t#p+rw z(}*;NsoNioR2&a$7f3j&v*b!tg((=1J6qvQxZq_aO&7pm*Lpg8hmPHA74Qj^4Xdnf zl(|!EPWp}tSM*Wz47XuNPYst6R?m`@ z$qq4h?m!+Mi;zZCWu|d3)}0-xb|_9qM7I-NS_KnpL0#jThtZ2v;+JefQ90Z48M~sc z%CV>R!D77KQt$(JeYBOvvA9+^4zi%SY)$r*<8D?Bv9BDIe`zu@; z09d#Q^oh_$_4+g)co9uTYqmuO=0G`VHiO@6LQz`TBi)npN_r{x1$PRLi7_9SjS27) z7++~FNYN)q-`+wB#UKNxS8*I?SAQ)7{ut@bUw`_m&wuF3m&6`YW=3BQwz%@Z<8ip@*YwGa|+>kuO7a+0+%a3Rk`P5b>;h!#0&TWboZ z8iA;&M}yN{IKXg~u_3o&1RiCv)e2!(14)%VN|hi5t@ zwNQ|z7*GxYy7jSL?CrwEwa0QLByr(>n}(}PE?9Yt#dzk{_5D^bq=%zgWSu5Rt0OqJ zNVY%wed?iz#)!rpp2-LsiXE{hke}^M-vf$BvQs+LWPX2Q&yGrq7?vKiXcF5}&-(RY zp1#teT9m zd-Un8@lNcoIybf*KjWVKR zaVNP!CY+_9Iof&QS}V;N(hehsxyN-8pb#ae^VPkl)P=B0n)5@Uq@(~zV?MAw&@8t; zWA^8`5K_U8ChC0Ct?>T**(GWn5y|O1){OC7mje`3$}Cl+sLtdQfPRJQ&@>I>%?ieq z7OeHnkpEjNtXigGUs|DV*CQY>%iYrS)C3ktYBlr>)S|QDT1B({qB{jv3`r3R9k?&8 zz;SO*0IR`(Rb?b8srV~L+`1#ARqypI$u5#@L7GPosW-G~`v8qj4Y$5oL7@5|Qmylw z6)@NPqCc>dv$X$*R-pU)y{2I{B#DjZ^U8I65cWQYtT$H~;R@-}o^2XCuZ6E*h4=SO z54x{54ZBaaSr)y9Z)(*=;nR6i`-#M#*7bRU8BU);5%c|+77~poFU-i->{T6{(dsl~ zlh+%rLO?6HM4EKLk$JJ%7n=ceaR;#H)C)dQAp(>s*-v+oo66`gs5_YxD&pG(dvsT} JrT?21{sWU5Hx~c^ diff --git a/operator/mina/lib/Cargo.lock b/operator/mina/lib/Cargo.lock index 1d34207fa..cfe7219e6 100644 --- a/operator/mina/lib/Cargo.lock +++ b/operator/mina/lib/Cargo.lock @@ -3586,7 +3586,7 @@ dependencies = [ [[package]] name = "mina_bridge_core" version = "0.1.0" -source = "git+https://github.com/lambdaclass/mina_bridge?branch=relative_finalization#fd359911b8da3039972276c7872e457d45e26646" +source = "git+https://github.com/lambdaclass/mina_bridge?branch=new_account_proof#fea0e6a52fa950bdc60f2afad71ad21c03296a24" dependencies = [ "aligned-sdk", "alloy", @@ -3617,7 +3617,7 @@ dependencies = [ "rpassword", "serde", "serde_json", - "serde_with 1.14.0", + "serde_with 3.9.0", "sha3", "tokio", ] diff --git a/operator/mina/lib/Cargo.toml b/operator/mina/lib/Cargo.toml index fc916dc53..3e0f70d29 100644 --- a/operator/mina/lib/Cargo.toml +++ b/operator/mina/lib/Cargo.toml @@ -26,7 +26,7 @@ bs58 = "0.5.1" lazy_static = "1.5.0" blake2 = "0.10.6" once_cell = "1.19.0" -mina_bridge_core = { git = "https://github.com/lambdaclass/mina_bridge", branch = "relative_finalization" } +mina_bridge_core = { git = "https://github.com/lambdaclass/mina_bridge", branch = "new_account_proof" } bincode = "1.3.3" [patch.crates-io] diff --git a/operator/mina/lib/src/consensus_state.rs b/operator/mina/lib/src/consensus_state.rs index adb0e9323..67f296e7a 100644 --- a/operator/mina/lib/src/consensus_state.rs +++ b/operator/mina/lib/src/consensus_state.rs @@ -13,7 +13,7 @@ const GRACE_PERIOD_END: u32 = 1440; const SUB_WINDOWS_PER_WINDOW: u32 = 11; const SLOTS_PER_SUB_WINDOW: u32 = 7; -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum ChainResult { Bridge, Candidate, @@ -138,3 +138,37 @@ fn hash_last_vrf(chain: &MinaProtocolState) -> String { fn hash_state(chain: &MinaProtocolState) -> String { MinaHash::hash(chain).to_hex() } + +#[cfg(test)] +mod test { + use mina_bridge_core::proof::state_proof::MinaStateProof; + + use super::*; + + const PROOF_BYTES: &[u8] = + include_bytes!("../../../../scripts/test_files/mina/mina_state.proof"); + + #[test] + fn new_mina_state_passes_consensus_checks() { + let valid_proof: MinaStateProof = bincode::deserialize(PROOF_BYTES).unwrap(); + let old_tip = valid_proof.bridge_tip_state; + let new_tip = valid_proof.candidate_chain_states.last().unwrap(); + + assert_eq!( + select_secure_chain(new_tip, &old_tip).unwrap(), + ChainResult::Candidate + ); + } + + #[test] + fn old_mina_state_fails_consensus_checks() { + let valid_proof: MinaStateProof = bincode::deserialize(PROOF_BYTES).unwrap(); + let old_tip = valid_proof.bridge_tip_state; + let new_tip = valid_proof.candidate_chain_states.last().unwrap(); + + assert_eq!( + select_secure_chain(&old_tip, new_tip).unwrap(), + ChainResult::Bridge + ); + } +} diff --git a/operator/mina/lib/src/lib.rs b/operator/mina/lib/src/lib.rs index 4bcbffea9..ad5dae273 100644 --- a/operator/mina/lib/src/lib.rs +++ b/operator/mina/lib/src/lib.rs @@ -195,17 +195,14 @@ mod test { use super::*; const PROOF_BYTES: &[u8] = - include_bytes!("../../../../batcher/aligned/test_files/mina/protocol_state.proof"); + include_bytes!("../../../../scripts/test_files/mina/mina_state.proof"); const PUB_INPUT_BYTES: &[u8] = - include_bytes!("../../../../batcher/aligned/test_files/mina/protocol_state.pub"); - const PROTOCOL_STATE_BAD_HASH_PUB_BYTES: &[u8] = - include_bytes!("../../../../batcher/aligned/test_files/mina/protocol_state_bad_hash.pub"); - const PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES: &[u8] = include_bytes!( - "../../../../batcher/aligned/test_files/mina/protocol_state_bad_consensus.pub" - ); + include_bytes!("../../../../scripts/test_files/mina/mina_state.pub"); + const BAD_HASH_PUB_INPUT_BYTES: &[u8] = + include_bytes!("../../../../scripts/test_files/mina/mina_state_bad_hash.pub"); #[test] - fn protocol_state_proof_verifies() { + fn valid_mina_state_proof_verifies() { let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE]; let proof_size = PROOF_BYTES.len(); assert!(proof_size <= proof_buffer.len()); @@ -222,33 +219,16 @@ mod test { } #[test] - fn proof_of_protocol_state_with_bad_hash_does_not_verify() { + fn mina_state_proof_with_bad_bridge_tip_hash_does_not_verify() { let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE]; let proof_size = PROOF_BYTES.len(); assert!(proof_size <= proof_buffer.len()); proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES); let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE]; - let pub_input_size = PROTOCOL_STATE_BAD_HASH_PUB_BYTES.len(); + let pub_input_size = BAD_HASH_PUB_INPUT_BYTES.len(); assert!(pub_input_size <= pub_input_buffer.len()); - pub_input_buffer[..pub_input_size].clone_from_slice(PROTOCOL_STATE_BAD_HASH_PUB_BYTES); - - let result = - verify_mina_state_ffi(&proof_buffer, proof_size, &pub_input_buffer, pub_input_size); - assert!(!result); - } - - #[test] - fn proof_of_protocol_state_with_bad_consensus_does_not_verify() { - let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE]; - let proof_size = PROOF_BYTES.len(); - assert!(proof_size <= proof_buffer.len()); - proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES); - - let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE]; - let pub_input_size = PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES.len(); - assert!(pub_input_size <= pub_input_buffer.len()); - pub_input_buffer[..pub_input_size].clone_from_slice(PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES); + pub_input_buffer[..pub_input_size].clone_from_slice(BAD_HASH_PUB_INPUT_BYTES); let result = verify_mina_state_ffi(&proof_buffer, proof_size, &pub_input_buffer, pub_input_size); diff --git a/operator/mina/mina_test.go b/operator/mina/mina_test.go index 89317a34a..4fba72c24 100644 --- a/operator/mina/mina_test.go +++ b/operator/mina/mina_test.go @@ -10,7 +10,7 @@ import ( func TestMinaStateProofVerifies(t *testing.T) { fmt.Println(os.Getwd()) - proofFile, err := os.Open("../../batcher/aligned/test_files/mina/protocol_state.proof") + proofFile, err := os.Open("../../scripts/test_files/mina/mina_state.proof") if err != nil { t.Errorf("could not open mina state proof file") } @@ -21,7 +21,7 @@ func TestMinaStateProofVerifies(t *testing.T) { t.Errorf("could not read bytes from mina state proof file") } - pubInputFile, err := os.Open("../../batcher/aligned/test_files/mina/protocol_state.pub") + pubInputFile, err := os.Open("../../scripts/test_files/mina/mina_state.pub") if err != nil { t.Errorf("could not open mina state hash file") } diff --git a/operator/mina_account/mina_account_test.go b/operator/mina_account/mina_account_test.go index cec1d42a3..2390df8d8 100644 --- a/operator/mina_account/mina_account_test.go +++ b/operator/mina_account/mina_account_test.go @@ -10,7 +10,7 @@ import ( func TestMinaStateProofVerifies(t *testing.T) { fmt.Println(os.Getwd()) - proofFile, err := os.Open("../../batcher/aligned/test_files/mina/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof") + proofFile, err := os.Open("../../scripts/test_files/mina_account/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof") if err != nil { t.Errorf("could not open mina account proof file") } @@ -21,7 +21,7 @@ func TestMinaStateProofVerifies(t *testing.T) { t.Errorf("could not read bytes from mina account proof file") } - pubInputFile, err := os.Open("../../batcher/aligned/test_files/mina/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub") + pubInputFile, err := os.Open("../../scripts/test_files/mina_account/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub") if err != nil { t.Errorf("could not open mina account pub inputs file") } diff --git a/scripts/test_files/mina/mina_state.proof b/scripts/test_files/mina/mina_state.proof new file mode 100644 index 0000000000000000000000000000000000000000..c13ba0c52fb953dfb6ce7c6babaa7da9abbc1ce8 GIT binary patch literal 48342 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 literal 0 HcmV?d00001 diff --git a/scripts/test_files/mina/mina_state.pub b/scripts/test_files/mina/mina_state.pub new file mode 100644 index 0000000000000000000000000000000000000000..51ac31aa0ac9bd8188977f85c678bd58ca200675 GIT binary patch literal 1056 zcmV+*1mF8zoYkyVC%zF63>*_gWnlCt%z5ln_bQd<*`uG9EDtpoPo>I>X^YLgGGsLk z>s`J;kBiR`Y-*MFb#|#~n2tTRvzu6AM~eRp`;I@s1q&ma2;^D;ee{FiBVrJxWos?t ze3j!EI22 zz-vEm(rl}tPQ7zVew#ff@NdL^_J_jiDL$TjV7~ys{md-NUKPG@ciyCApu&rQzfX20 zMg~(-PnO>9bth2XFY+K5b5p2y+nm6g0Y%{0dTwhMMeo>pm>=}qL5s4(w0`OH^#ro41hViWc}=DcRvC*VHsnV3_H55`Pp;d z$^-5XyvnhQpM@J$ADx zB9J~xAxWx@nv{GotVozqo*9Tk9g=b}_h|Pe11~_ONQfj5gLp=$%|9IvqC!?F7zPcm zEb&^EWG&bvdUL-w%?TG6VM{hl!0@X8{Mg<+C?M7|tKh!Ort6DAXKh0NZPps%eKTMT zp2W7u!0;1xE(p%MY^Y>RZ%w6nqB#WFMl3C1(~?OgnDd;k^quVo96mFw_z~MSuKsxj=a2HOPhLqCoJ|Zo?C$$f(1CrXfR!POGQH#D5 z%O77?7G`8AntG~js5y7EjjIH!b^Ce>uTl~L-bNJ&_gIXS29HNLBybHijMG-)(A5=Y z=MyxSyas&g+)?r#3`@3D9I>$fsS`O^EbMDd{6-L}${9xil}Xkl8mSHLhi^xVoi5Y0 z1>o25Wypq7lWj9EC#G+|2#5oC1hKZDnrkg5HlHLK#X5!D7T^U@z9lZmjEnhX`zMR3 aTPa?ua#!0SHLd=QjR2_i-H7adbFx1Lmj1v1 literal 0 HcmV?d00001 diff --git a/scripts/test_files/mina/mina_state_bad_hash.pub b/scripts/test_files/mina/mina_state_bad_hash.pub new file mode 100644 index 0000000000000000000000000000000000000000..2c8692a2ddfa9bfffe4a1ecd9e44f8873568a52e GIT binary patch literal 1057 zcmV++1m62yoYkyVC%zF63>*_gWnlCt%z5ln_bQd<*`uG9EDtspPo>I>X^YLgGGsLk z>s`J;kBiR`Y-*MFb#|#~n2tTRvzu6AM~eRp`;I@s1q&ma2;^D;ee{FiBVrJxWos?t ze3j!EI22 zz-vEm(rl}tPQ7zVew#ff@NdL^_J_jiDL$TjV7~ys{md-NUKPG@ciyCApu&rQzfX20 zMg~(-PnO>9bth2XFY+K5b5p2y+nm6g0Y%{0dTwhMMeo>pm>=}qL5s4(w0`OH^#ro41hViWc}=DcRvC*VHsnV3_H55`Pp;d z$^-5XyvnhQpM@J$ADx zB9J~xAxWx@nv{GotVozqo*9Tk9g=b}_h|Pe11~_ONQfj5gLp=$%|9IvqC!?F7zPcm zEb&^EWG&bvdUL-w%?TG6VM{hl!0@X8{Mg<+C?M7|tKh!Ort6DAXKh0NZPps%eKTMT zp2W7u!0;1xE(p%MY^Y>RZ%w6nqB#WFMl3C1(~?OgnDd;k^quVo96mFw_z~MSuKsxj=a2HOPhLqCoJ|Zo?C$$f(1CrXfR!POGQH#D5 z%O77?7G`8AntG~js5y7EjjIH!b^Ce>uTl~L-bNJ&_gIXS29HNLBybHijMG-)(A5=Y z=MyxSyas&g+)?r#3`@3D9I>$fsS`O^EbMDd{6-L}${9xil}Xkl8mSHLhi^xVoi5Y0 z1>o25Wypq7lWj9EC#G+|2#5oC1hKZDnrkg5HlHLK#X5!D7T^U@z9lZmjEnhX`zMR3 bTPa?ua#!0SHLd=QjR2_i-H7adbFx1Q2yy<) literal 0 HcmV?d00001 diff --git a/batcher/aligned/test_files/mina/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof b/scripts/test_files/mina_account/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof similarity index 100% rename from batcher/aligned/test_files/mina/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof rename to scripts/test_files/mina_account/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.proof diff --git a/batcher/aligned/test_files/mina/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub b/scripts/test_files/mina_account/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub similarity index 100% rename from batcher/aligned/test_files/mina/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub rename to scripts/test_files/mina_account/account_B62qrQKS9ghd91shs73TCmBJRW9GzvTJK443DPx2YbqcyoLc56g1ny9.pub