From 33ca808b45cb5e9cf2e27f741b0f6e42d97c276b Mon Sep 17 00:00:00 2001 From: Kirill Date: Fri, 12 May 2023 15:40:22 +0100 Subject: [PATCH 1/8] Update CODEOWNERS format (#903) --- CODEOWNERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 269fcde7..6e2d363d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,2 @@ # CODEOWNERS: https://help.github.com/articles/about-codeowners/ -* @sept-en -* @karim-en +* @sept-en @karim-en From 418ce551bb04a33267a10c2d713c64f048f9a3d5 Mon Sep 17 00:00:00 2001 From: Karim Date: Tue, 6 Jun 2023 16:01:39 +0100 Subject: [PATCH 2/8] `eth-types`: Fix `GasLimitExceeded` error (#896) * Use `sha3` for none wasm32 builds. * Update contracts binary files. --- contracts/near/Cargo.lock | 11 ++++++----- contracts/near/eth-types/Cargo.toml | 1 + contracts/near/eth-types/src/lib.rs | 25 +++++++++++++++++++------ contracts/near/res/eth2_client.wasm | Bin 199882 -> 200983 bytes contracts/near/res/eth_client.wasm | Bin 205356 -> 206906 bytes contracts/near/res/eth_prover.wasm | Bin 170818 -> 171157 bytes eth2near/Cargo.lock | 9 +++++---- 7 files changed, 31 insertions(+), 15 deletions(-) diff --git a/contracts/near/Cargo.lock b/contracts/near/Cargo.lock index defde257..d52c6094 100644 --- a/contracts/near/Cargo.lock +++ b/contracts/near/Cargo.lock @@ -1133,6 +1133,7 @@ dependencies = [ "rlp-derive", "serde", "serde-big-array", + "sha3 0.10.8", "tree_hash", "tree_hash_derive", ] @@ -2018,9 +2019,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -2771,7 +2772,7 @@ dependencies = [ "ripemd", "serde", "sha2 0.10.6", - "sha3 0.10.6", + "sha3 0.9.1", "zeropool-bn", ] @@ -3924,9 +3925,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.6", "keccak", diff --git a/contracts/near/eth-types/Cargo.toml b/contracts/near/eth-types/Cargo.toml index 154be7c3..83785559 100644 --- a/contracts/near/eth-types/Cargo.toml +++ b/contracts/near/eth-types/Cargo.toml @@ -24,6 +24,7 @@ hex = "0.4.0" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] serde-big-array = "0.4.1" +sha3 = "0.10.8" [features] default = ["eth2"] diff --git a/contracts/near/eth-types/src/lib.rs b/contracts/near/eth-types/src/lib.rs index 544dc899..c2fb72f6 100644 --- a/contracts/near/eth-types/src/lib.rs +++ b/contracts/near/eth-types/src/lib.rs @@ -10,6 +10,9 @@ use rlp::{ use rlp_derive::RlpDecodable as RlpDecodableDerive; #[cfg(not(target_arch = "wasm32"))] use serde::{Deserialize, Serialize}; +#[cfg(not(target_arch = "wasm32"))] +use sha3::{Digest, Keccak256, Keccak512}; + use std::io::{Error, Write}; #[cfg(feature = "eth2")] use tree_hash::{PackedEncoding, TreeHash, TreeHashType}; @@ -368,13 +371,23 @@ pub fn near_sha256(data: &[u8]) -> [u8; 32] { } pub fn near_keccak256(data: &[u8]) -> [u8; 32] { - let mut buffer = [0u8; 32]; - buffer.copy_from_slice(near_sdk::env::keccak256(data).as_slice()); - buffer + #[cfg(target_arch = "wasm32")] + { + near_sdk::env::keccak256(data).try_into().unwrap() + } + #[cfg(not(target_arch = "wasm32"))] + { + Keccak256::digest(data).try_into().unwrap() + } } pub fn near_keccak512(data: &[u8]) -> [u8; 64] { - let mut buffer = [0u8; 64]; - buffer.copy_from_slice(near_sdk::env::keccak512(data).as_slice()); - buffer + #[cfg(target_arch = "wasm32")] + { + near_sdk::env::keccak512(data).try_into().unwrap() + } + #[cfg(not(target_arch = "wasm32"))] + { + Keccak512::digest(data).try_into().unwrap() + } } diff --git a/contracts/near/res/eth2_client.wasm b/contracts/near/res/eth2_client.wasm index fe169405310396d3955f17bd220553d1dd56fc4e..71a3691792ff7122c6b8d58eb7517c113e65e902 100755 GIT binary patch delta 34315 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 JrC$vE{{e6)wYdNQ diff --git a/contracts/near/res/eth_client.wasm b/contracts/near/res/eth_client.wasm index 0a840f850e06d3185b82d156117f7a8cbdac570e..3f9fb9910f2ac94fafb1755de2e39a837ebb2b24 100755 GIT binary patch delta 35923 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 Ef8#w_`v3p{ delta 34070 zcmcJ&3!F|>)Ia{L{me7BXPAS*+>GZLhLPL2%l)`Ti9{Ev5R%FLk}jCRU@9~^!ya-O zQRJ>s<8DNnG8jb&xg@EOq*9dMckOe|GtUfq-}m$X{Po#$&RTozz1LoQ?X}lld!MH* zg<-4rgssmK&Z~h}jCVwORB2)TS6c8t{N)$mj26xpN|h^HmP(g)hs6a_X<>Zmte$hq z*@uXXwyxO;Rj5i;A}3L4@;J*nDLg#9TtYbyIm5#liGM_8jelHT=OmhBcmpFsvd-^v zxKkW@c229nNJ{yK$f1)vmCglT30M}m#`S$*_le`TxE}d6@WBrPdtPxh%yRt{xW>6t zbb6q}2G=~XOKcZA#C361ToZqYwa!nRyPV6NtDSEK>4t{fK=D*fL{WB4Y(PQawFjHfUg6u23`(48Mw-| z-8Ca{X5dcOF4voZJ6w6Lt**~pdt7^6zXV=#opxP!opb%@y5PF#`p0$3b;fnx^^@xx z*KybPu0LHjTz|R#cAapYbbaee4NME16gVYtcHqXqj{?^PZVKESxIFMg;M;*K0)GqK z8n`=fPvED4djmfUycQG~dgfs0l|VVWI>m&~otB#FaJW6>5gwPe*q9mIgx)be4St+5 za$-Z;Q^>KYAn-V}ZN}ixrZm@x3%j4@$g4*v!nhh*iI(S-c83#X`r&higc(FjJ}fPW z=H)oUI|DEt)+Wd_O>VkWj|sB!qCGbwSklM0MFwHk$eq=rM( za5nV@7)z#?GbY!HkKAk`8;MA7fJY>XSTqx;{X5OrR;w3nHY(IM=%bvKwI3(iZBX3? zkY%H~UBXtSfn^WrTC%p*m|6EB`ouV1*PC)^3Zorp`1oXgbLyVts;T(raEF21L)u;i zl;yHpKgh#Kg=za)R-6x{wvO3xhXdd)koLKvFM{`S!+!ZExgB?T?k(vxNmH`)IP`#K z4u`v(S?2=gO217bb?WGjuyDq*q^jWh^Q0_eVf`dycD)fHhZWBbZMP9x-!R5cNiz1= zA5L40mJJ3%ZBOeIle42iJS*(khH-T=%^^11P{Q8Lyz4aDUELwtc$^;ba4CoYSpnKy zW90SnM%zZiYyHc`qTOX2`lfgDKweo}%3X4}8*m{ETmTAT=ul{lajH=h2)umb<=|p_ z<3Yh&%r+k}mi!iBv}w}FMvRan`-uo+c9Ze~Be$YSE71SYq`CMrO&&Uo+19k_lSa_} zk(6tA?tj+EXllN_6r5|;H$Zm(g(?^u?{7(2#binvR zPs006eJ6csY;8NX+;p=8;chM6eA`BH(gli;S9el?Y_pj(04u0`zS+ps2^e# z(9(^w?dBSKyUr@Fg0ZAslVW)ut-*RW#PO4K*S)+fXGUF)zly$oG;K!71PxIrf2{nG?)&pj7kI*BN^*l#1UNW5ghH1~r z2{?-wTUY{nOkpzuEL!80?n$UQXI1yp!r0uo9!cZp&TTN1wH}nl{HGg0bO)ZUU)ieE z31gwJ2uOxeIO9@p`U+x0Q~8;<)J!kq8$z;rV zrU5O;`TQ9y6(1P|&o(#u_I^vOoof8r`+54@c=G8upvOI3#fa^nM2n1v`zKnQ@Z2<~ z8LSVp6PB#+;l3N0{i~skt^Mmmh&fjV^rOJ7Bq)XCuE#Kmn)DA33Dkt2-Nqikr<3nPs4BfZEA9M#C07Hk?w+auQ}fu*NMmBVxxG3sfvIIS?Qjv8*f zG^iJ_g@bz1XoJF{jN2mvkw4=3s=&^9zN<-_6FRgV=2cGDVM(F{UA)tSIcrmXXw|(A zb;~lAeTA`QUC_2pGCVI-wJ0{I*54Rh(wK)=`^UE*Q>-@yA zg8t=G*(A7=dy~Zp*O`YpgTe8*7vmySOT3l}eNQG&3oHr72QRjvb;hCO%0`#rp+T>^ zm~#^zKRh&er3p_mt_;7=7(3)qLmM*(R_XmQY4}@n>{>Vk-;9l;w{rd(yO&T;-ng$J zNcr;Qa``-6piU0GX)^v`G2CO+dd2Iu%(Ta$%{QKWB@Wc%UilP8wB@UH#4YH# zX~z6l8?m|`dNqb0S6+>cJi!Z)o=RT$Q+fs^>kMeOr{%=IcAmIM@PvAi)^q{^_{Lud z3`9_~?h|V9Y)qNZfLQA`PJA$;h}NlSUCG)$qio7ESi(l6l&?|JXS%oq64NZKr~Q-$tb(`wsTDt9_>2P#8~>&>x;Jg`eQ|h6b zN2b&=`qfJ^R!^BiQ;npwrSRJhr>(@mrA%EyX@+;&M6Q3yv<~!z@x!!Ulws)8mt(5_ zIK3+hG)@12X6KwsKSd~!_r@;zBxmxQ!v%)z+RTlhT0ZLv)~&g3dEhVPzBLvN*3Otf z+l*BiiL})?oUxSNGhUvZhzY-B_9MVtn_UB}#lGE`8}0e_6X9D~{dqlfv5xF8w!B@p zthMUvo8~}@`UQu!)VTTfqo}p3(T%nni;O<_`>%0dS$mND2%BX#Kr_QKw}ZUaoDa*Y z`b&|2U03JSpdCi^+$3=I(A-WS%$$2D*lP4yx#2#FqBTaMY*`#F{AQQk8ylKHDln?dPcp4os8S_s~QUzHlXi~LksI0XXnQux2jR)ohJ01(fge` zhI3K-gk{QjInbI1yGH$Ihh}4-(v0~77-PtyYR1!xD;v>EVvK@C_ZfMM>lulQ8ybIQ zdyUr?w=}G~{DRUEH zta?{7`YvbyeiJPYO4bB-!myB0)lA^A#E}C@OQ8tTaRWSFvbGp)HqwL1FAeVPH4ru%%Q?_+@ zg=hoar5esh+BzPE`V!Pho6j2)UaT0xpJNVNp<8^U(@!}QKYE*uT$$V?3_{!7v6!)& zay!rk(zX}}cf`<-#?Lz{TMmm^2!D@2clM$OA3)b$>uT38sgYsVkv)|<}psPme=R0V%(fW&Ix@N5WB3k7( zFm8O&2^9LiVYW|@ zwii^Q^~Q;UCiJdRZvSubc}(A-lvCgSK02n?u#L68@jZqsU^z)VP^*mPiRfP_Y&@_7 z4{Qvx8-ogNFcJ>dg{gS#U~Np3DF>^;+O9n4DP@yf#f)2T>^xKt;hSF%MH%shmC&I! zg%8sQ#;n46D3e#%5`O2ug{>jMR-l8Yd8q9@$~RVJ8yLO6jHb25rNc}ecO=2s|7G-l zmS}EdeN~p;w^}^))kFVD-M~0>*uQ=~#Oe)t+x%!evDoDvEFw55ZC-w9gqA?yhLjsIbHriY~wt5bpMs-B(mrt)*}v*-Z;~ z3qx;E4Qud~Q_ZZHhkUL-m9^fD_TN^A6o!0T3+gcMTMzoTAV))zdy!6t+EB$>n18OcQHN z`Tl-hZgza%6UL|9g=+ZQ>_Qs$&^s?oLmxZ-&{58wj-6Ki51r|~oU#|ANCgCYp)D9GmR&%wkRUS zy!7Q@)~>zM#dzh{Di-CMD{dp~T9=4ryhvb$a@2NsSR=4+I%VWts}OOHJ9W2=?0c2i zcaIEX^0jgZl5nN(-h-sm{<~x_3V{y4px+{eDhdiNE&=CFmZwKktV}9HK`qa3$-{^v zw#obaiwtN-SQ)$sv%&AFibVv=qr)v6ZiFSVH!=4s+BSX~{iei-Lz9ig^<(KPqw)1- z(20@PtJ~9IgvtYThFD(LsA(W)AQ|0w4+v(-E|l3KMkn%t;uhRQ-`snr4udt~AB)YiCq!z&I)5A(sc4rW~@o-Oq`A?W`W}2Hd0oTl_do0{uBkrH>e(k;dPs@}OJU-Dd zQ1Gv?o_wqX+r)@;ziXa z+T=%c67SoL?*Ep*&t?gs1TB}Vh<3Bi*KlSBv?b-Qfp-M2w9Q7wztJIzJlgFZ&2iWA zGFqdWH9umL3M!9^F7cmWJyprj+S6*EDBj=#8$)h4q>aXs+k0r^oaZTnHq7~xUZah2 zG|^l%!6)L-13BEJfy-t?uc z>!$K4$GB2R+^i6q#y!$K+9x~-JHQ~R4DAkf=>Ic2syA}Cn|hbMsaQ6woQW#aD zPjb74QD0}I8b1VG_4B-Vz^Od58BcAV+#60c=@WS^oO(3Oxr-WHRdjc#fqgXctkNRH zPIy;>=n1+E<7CFabFJ#~fI!gFRI7};tCiHsQ1yuQoN3#;jf(P!e5eeqrviDa42`9) zp?L8!vn+i;U&~hI=s?Roiprkq>q8Kt<1y>Ye+KAgt~J+rkK%D*zDHR2y|Qxzy^NYZ ziJ(<@3@cBI@F-P*)?;CnJ1bDdpc`iW@>B(i^q7EMUA|Ras?g1hy|R2odJq~Y`&Fcf zBFzF<@Oe(jsTHYDiVp*?2(Ki=j>x zOnU(i7lgpmNB6QqlC@9dTQO8U$kfGfnHoz`^6MB%_G9g#IEs-2V(F=pxO1_TYV~r9 z99)TNVW8$#qSeLe;-SjJ;wS-+%s5JHk$s1DsJUz|Y`U3i4=1KS93MT{LhqF~;;4~d z^^Gf2La?>`Og7HWDkop6Oywcn8I`FuZIcC+5m??YOM4)NT-n)!*>^+^^3bbzob$kz z9m##jOCKou6SjZEwK=bB@$ff8Q9`{B2%hU?Yo>-$H=d%Q%2CStvriQ z%b|(Xn9j<dSj69>YEZ-2^lhqWF$!zJR~5YwbWzoj zDUa2l_kyk~^0hMUKI%wk8O`Iy7k=1H~^ze4B`FjrY*A2-M zh@3$CFUZhZUFE~I zX;#pARb{4Z*?{WFa&>58_+mCu@X6p*!ONX1v+K|k)s@|f4*)Y*=!Je!wPNapa&9?? zCq`UdYHxKu0GQ&vKQDLIrJ8pgtB53;6O@_9y#L5zX-q%Mdi80l98!;Z1#Pr4^yU;n zd*s=A7@a*P&XNT}^bmzo-7xLvToiRt&@x4$`u1ngioIOA^b2=6QVwfQUFGa%e*ONnnceRivTk#72U+b(C6JW56iPHse*QZ$G#LFu)x>Rppvy)!_aM# zEn87!*hP~Z`lc_G{aRsO9*}EVQyu#4|5B^xe_3nfMdrm_L3v#`fPn{uNlMxc`CDsx zpZ?07--benZWe83YnzUH1zDvn)d)^yZnayJrS}c0E?;Zw+vds-+ETp=CA8es`R;O( zPF{F+s_bo4ohbEoRKAAkpoQ~o7(Tl{W0K$FCV-jq4v~J=AMrUF99% zE&v{(SsQ-qX2dl1PTb~heYN(Ee6T%r2|CZD+7!94Jv9xwu7EU&h{5;aX`gV79(@@< z;iD9Gpg!V{X|i5Ns(_8Q?A(!Rmdo42L{V06)Q(&J)tYpf-;vfb)yogimg+ZlgQ_vC z20sup5p< zN*4d6GtP70ki#FO^Ypgt`4G)&Wtbdzf;}PAnmE%rqJIW6*{P@F1dgcQj$Yc zZ%Sh2{H`>i#UGrBYGKMCyH4@pp3)GZ$KBSU{jRdgFuv&oZ?F@r=!wam@U{+5n97zt zy1}r_kfD#zDDlr^Iq?zl2AP~pmhV48Z!@x4cR%EF-Dzq{3He#vrK&-WwFlY6LK$2Z z=Ks_;tIoT&B%gnjs`UO}2n-g-9um9p)IE97#45#^yhE_(AEik(H!^8sk%7Z?Tg9{Z z9k_IUVl=I444Kh`22-Z|y9Yf=Gv&XJ!E}u2NgERGDw8{!d+;&JF^d(1mne~Y{BcUB z>NiYYv?5j_O-_RG@SAPvPtqouE%jcsCMMNXVV+sgz%bY#Vez|GhCD?NMVS)(Td6V> zobOiQPk@##hdxEo;Tf#UdNo^Aa_&>~j5d!eb(e;9#mIUzDV@EkfAvdjPuLh>MPQ?4 zE)ICGyXD8;%--;tf0v*4rlA2dP?Is~OmjK*X=+yYf7wA(Ez-%*$5xONpP|^eP0Xd) z9yJzlxb-{}!^|w=^(H1nbsdMS2jrvAP^WTtDI&+WrfPn4C!eAEG)sm*OHm274yLOW z(T+gc<78pw!_QKK(r+n|a|8)1&KWuDS@Oo31g4Y)&(b1?BVX=&7Mn!N$-5*=_kqi2 zxquNRoS-Xyxsg=dLHbEX_oWfx>pz1iIE=|pSoe8-vBCd9UhPXY%M_?Q3>!xvNV_>z z*6N2Yu8@8DQTfQDELXo++A1~5`GT*M$?SeqH)Y>puG?+i%Y!uz<@2c>3R%jB3}NId zg)HYo1~W3N1Tu(`Q%fKN8F~3DZYa`M+{MTvDJ8H0jLlQX@;*{0BbO;;tPhFnP^4!n zq~=3fo=QM+W1biKtuMLFKqw623u#PiM+41c(5k6&|8q1%Y?xyFa*A)O^0hyi(VwC# z=CGu~-TE0NU$0)6&!y+dUHxeYt;?-503H|uDeVSQ(@x48@Tw@V$D#ehGLOc#8S~QG z(Q?e#35WO%Gz2Oydf$EY+-^NdEjX7^TkBg{khd8?$5c5zU|!dg+T}oU6kpAC^2@Es)T;a>N2Y=R5Q#8mcZ`!YU!W#p>lEYLzr45_=av~SkXu}tVl3(OsQl#xswQqtkrfA1 zUAiP67);~5e{y*@qYnO|`4tSR{j3FFt;axT=bZIyoxrnc^1r=kGIiS=c& zeKK`>#^jS{V7$7Eh{0%#01B*MV^}|safOV5d1DMu<*JAU^B8MZZP>^L*irm;zB82< zwVm>6GF5W#RHA?>)wavX7pZGd+CFA7Qx1KR+R^)R!;ADnci&Vk;5^%=_`0P^*x2<9 zac7HRuPSU6{jiCZ$wR0OeJ)oGp(ga1{B8&>4$3^hm2Z@<52Xhn!b3xeZ-UB;L#b`h zMk}x0FttVKIE>l^?Xhq(hf!SQCDjc`DiSUj9eqmt^R0>J+q0mB^I6 zhSM|joy;9hn}e-Zr^pRSRGD{2;lXggd8hh?Tswkh#ad09^;#(Kc8G%~-otFkikkn%adNwemEMi+SYD(G&+` z8a;+a#is37;!*^-p^BgdPYnDC!_I!i7;5h`u-DB|lQ+lEiSh@y09<@%47NW3`s)*U zq4{|%Rj0$U+)H!|+a_%seMeu(>*J`iuaZ5gxp}h7%M{J=jF;)@pu;8$@{5;YJ-(7n zUV+9Ok*~c%EqukUTgCRiLiIp$;}vQcw9zWo;8m*G+*Yk+CZRd=bsKyBuGmbg(s{4a zq@Xk<)(z788WqqndF3^F!KX^kjK>15a8=~C@zkl6rlLtihDM zC*XFGRWxe?cB%I8VRL(*jGsue=u^32A}zrj>5)Q1eRJfZ8dQ5W*mI;f)}AB9vGyFX zu(C`l-RIt+1{kBIeIq-jLWo=B%c(Tcz1_s~8JDCc=E>J5Q7)a7`edq+a+<5q$qVzr)i4wmP-Lw(6{;d7M&y`Tk%hg;kX~EQQnV|% z3f!(c!>bBn%PahAfX3lMyT@LlQd8xRlc}7xN!3tV&sX)XgmrBcRjP(?Ai9X9E+SdW zll7-iBAt`Hr_k&aTQM#jx*K!1iec@(7sEp7o%#&5%-Bx0U1z~vOBch2sp2OUVWu3H zMlCAZt>pW6_6@;TxGTsrX$VlBm8GVVCu)HzwO);z3W8hy>tC|tRBF-XLzUt5S#S?w z<*->>U5vG3+>~BlpW%t%#x#0V z+sz=Ffhnl%aA+UNH>Xj2iYnmOc!83Zt!~TD zG@G*k-y0ag?f7JqF?XY)^@U6rxv^az4eL({2Z<;!+1j>gTi zaKv=&Ra9NP_sCjXshRvIomz-rrpSI5sj0X;MZR;9RwBISd4t-y{Vw*)VQ)|dd zCmJjVzX=<9O{Tp`jhd$(VSZ!vJ;(9%Ev zSzH!Vy~hk{5^f`Juvpm1ole+O@{O~NQ>tp$h*^p%l?3S+H6`N|cpF4|sd6j3$zO2I&3Lgv(44+7mCs^NP zaaQjw$oqRa`Yi;#?TRm2Rjhl9VpCEru@xTk7u!{a^eXz9VpzL^6~#ESYbcJjX*2IC z_!TA#(^BtKcFwLM-$pB}UBxkr-!U05U%$zP8B{CrcT=yh$@Dn1KWrsK49e$JLncD| zTmG6s<8aJ5cs8}Hl&5-Q-v+ZAO*i`}ch9EBBh298*bOWY|h=y;mXyiXp+xo)mJc?-UL=4 z5tpnLu#GvlU7O0Fd!b-!VSRuTG>5(p-gc6ixIIOFKZlZ<{lijrCpbhKv$xuDE*3A$Ltd^{ z9VA4(UdIKd<9BX)g6~U+0GPDu~9; zlYh*mdLf5TF#->`sk&d` z+F4X7TB^EgLfSZh*`olHe2W~AMFVQT!;C3y;wTcYeQcj`Fg}wrz(2-W{RzO=5XM5i zmicv4p!$G8m%CsaW#&8_M9yM*-JxxkpUs0uc3L{;tCPj-3zWcSrSE*4m93KR%%^Ge zu8e<&8dA1=;vGth^wS$O4TnwOx^%Mkmi+A<9LnYLh6&=HD(fwvmeEDpgZ>oL9+|#? zYPhnP4dao%5%P-#a8(Or>4j7~!Y5Hx8BR8n%ufr;3q1*e5$+;BC)5us;m(!g7E-mM zFAjs@JwXa#oOL%ZIt6Dhx1gu|ov zWaMIch!)8Ki^&sul4qrk4|vo~XQPywXnOV;V71?6ooqPgE9K+am~ors^lX|L`GFb$ zf`^1S(fbNuIjokome9kH-K$GrKc~uVOQ;pL^Ea1JKhM32m^I;2PThC0!&vYxmAZHB zyWYhfdbd3LF4gjyQzgRDc7g`Mu{z*QHR66;h!mPAclCt_)P5=TEw$0&(5ZX0#d5<^ zsuHxEQSPS3>AEqcJ}#LZBjc7)FfEtWmr;D_O}^|r2Z}$jj5@K>ELlcd-DaitN9f zTGB4LWH~hqJH{o=;NT^Bb~%nS56BI_;B&mN6%^TXt;q|E-MZrHQ6J4rW4xD4K#9g< zSrgHQzaxZrpuJVCy}5oyu~)`4OY-b!idGlBBGS$>+aYR}>DSfxACYTTP*m@kD#wab z;g*+vY+;psdgBvPxL=@Jm zujZ$X<#?)|ni`-LsM`2&2Qda%tPdz=KJx1A$Bj*bZX z*tF;UYX_}1#vO0c26ryS4r-po#zwPJ>0U|i#@WcM^L{P8CD>^cTA|#x5)*8{thfqy z9u6_1@lNea*?AQ;=x+Dbs?PFYY;KBU|C{#G_o{8Ve--t27ji4!P*1RSSTXs@- zCtIw8@jf6&t|Kq%GuBZ9bn&xwkiucva6NgWPI6UhA8=PU{)}9>o)UvjFqQi`pVuA) zMMsO@$;<00p@QXEdx~~T{PnC%+(3h{+sfF0INjMa_QhY9kA6sRh;wP|ct0wWa;Sdb zHC46T^)|)c)%97MgCO@s`ArTkwH4q80b=B|jZ}kvlIu58Uo0ABKB5{?m;SRCq0@LR zal5;iF+SO5DZb==_yR;cU9S9ys*34Y^ZHSQ>qDlKlg5i4VaI;RgIok$Lzpr)IAO{o z`Cf4=3~yx0>HdlhZfR0P#zj{PhTxo4c99%HLut-GQ&Z+30w1Hb~mf(z_Wp zH(ie0Oy#2ANB`P zpW1@)nJUw^P=~TJ?%1 zN3D+dpbn)1aH$kgdMjG)#(Myq=xcKRc4|`n>Q8y*GUL=2Tu`sYkI44?45Vhr8{26Y z)VS|Y2pX2!NtG(3GBxbG=hP7)AIxo*iMw#5KTmeuMU!cPJhTh3?8}lqp=1-P z9t~4$x1aCd{&Anr?h59{}t8V4j*ja^%@WX6Zn5ur5bqeFp&;o_=Z!A?|tRo}U*2UYb z64oJiP?NZTU+-9sJ1wxoiv zv8W1yld{{V)V#F1H{)d^)ifFRy0Si{_H9eFV|t{Urk?YrC;_fkD)yS$6ciWQ>s#CY5 zdhX;YMG!pD0KZzR56 zzbv~I(EUM&m6a)wZx!HpBtM;nb3uMvKm!x(s*fpT$p$Z)Soy+!dWEv&x&1htT_npN zprq&($}ad;CtrLWw!O~*Y#$cOlmpbh!y@Jf;bzz!9DD@e=1LH{onEpqj3VDvRErN* z9UKPZ5R~uius4t`gAY=Tpe(bHY2B9I2uu_aT>F~pZF{Z8`!p(?a zKLk#ju}$_v;G|jTp?(OQG7EgH=xe4@7><~Q9#Vt}!|^iTmGI!hTzTRUI=oa?`jVnM zpW)SCuc>Fv;L)-M2BbIva%d~mC_8IAv{DYy2AYJ|GGPA!-hgPc%v_69rhZ9LrHkQ~ z$>m>C{pz+b_}IHcDVJZ#2wpHae2e|h(z#zzM4gqYPRNSKgWn-DuwK+yu_ChVS2Pek zS@9Lc-Dmn8@L+h0jXweAFtbMrC=3;;gYN)srM&tTZb4_shYwSWm}6?VZOg#c$kYjk z_O4uZ7{1$5S$G)h-20M_&;ZTsjNn=cY%P;xkKpLh?+2UK;aWlV*QEEiRX+WVVv_Y> z6?5q~inWT*;LY12IFIE6TU0Hy_qh8!j75jAzSZ)gDn74-KE8Vt`*TB{JqrJ2xpW^x z?7*k13m951e>+Bc22e2z87kz^b>QU+WnIhVK!}i1c;U1h2t0A`{ zH$6G=_B)9Q)zRle^^)r>IJZ zwFrcjk#C)(c$_75KZ#h*0Xh97-B<499i{fDQpmrEd^!3Qm6ddosshpZ6ppE~<%eeR zl?=_0%quynA;ukVL>rVU`#?L5$_wf;6wsV7pZi-g*%a`vo^UsvX2Ol4tLB08R;xC=S zDdm0{coq`fFKeEqYEc`_33-oWlHh|%N!{)F4rp{VCZG1PSpeF>C&+r%Y;cF;ki%zT z9XHE9JE^?+<&M_{oAx;q$3xqd73NvM*AaLYc<`aL)X&iq6*l=Q#569daP2v&7-*I^ z^gk;GT176Nqh8n|svX1;E_v@A#9QCdqhWiPKd7T`pCoY&vQnv|T-0qwakt5u=dlaj zE&C$JdyA(<2QQYI0QGeoTN~0oW%_9BXQuhC4F$-L&(r?W`JBV1hspNK+23PRxkdfr zo7xAd>=OH+99icAHd=*hbB7JXtB7ktc7EZ_it^hF)B_`_HYs0o6Mh?;!&C3NNioS- zh{_-$s(?+(gQ4c`2?pm28Fvv2!&l}$rI7b2t3;vN!nD2TR;7@)DpB&tkMsrt6WCXL zQ1RG%5NR^Y1zzDY>m6NZs{-TF=x1uAo5rPuL#-;L6|zvVsE~F@y^)gEFZ>Qe!}uTk z-mli4uB(Z)eCvu$fL@aE!lU40Gr>=F60eF3}hCgB*OB_F`L~bOoPv zVN28X3N1rDQWsb-eHF=8ztEttlO>d+sadXkAlqk@bzQ|U9hJ4N(rNlehW$!Uc-Cd3 z!~An~>?7-r8jj_RXrd5+7RxEWQtPYiCP&&J z+FxYsZ`ARjf-Kah3++o5BG|z9jRzD8u^GM^c9;QeHRpOcKe3skGFqMQqp6&%XPY!~ z&2JRY&sugddJSzzCAzNigto2+`B8YbkM^=pSMwp7p_yqQgHXRNkEPPk5y z?dB*_m#+t?(B@8!hQ%Eh(d}mO+aJZ+Ja(Pp>t20_MG@#Lt%Pw#A^%W+T_(G?7|_0w zHGZcU%+n6P!y%n62mVg|a6)**;f8daQn>_soH48e=N`>vd=TEAil5w7Ua~uDH zMq;O?eaCI#w|Cq;EmAqt>%@UvN@El7I7<;vOVNh&{R?B42h0prB0z`gG&TXorrY&+ z&;bR&=BcJq95D6&hjJd5&6|JQKE{~|otin)xIuJ*1*SS7;GS}1Tt%=PWiZ1aQN&2( zBR5E|zG6Pe%{csZp4BBU=@xK4B(~`WC6wO4V`3h_Ikffi=Nsg$ea##pU6qEzd`T6s zcQQ8iq=}XH|3&FO^AX80xPSkqIQjEm2qI6HP5#CJ-q zRje?B6+xZlsk?dR;ob~6>n7E#tK<|Ps2o@I&Vz@ItD}<=7G$5v!a{z0U}G4ZA zOX-oiI%w@g9S<6m5glt*rn*7-K0qM`ryL8lnO`ZSq*nLZU$@x{j#;$Jag z+aE1I`DF2@y?4b1w<;DwRs-p1>?% zY!MV39U%I5vN`3GI?m61LCECYieu5g*Ijx@0m6!SMDzhBg^spCG#9gNRtF)+r zZ-H~GhKm|hxp*%~PZ{ljEbP8y$|0Jl>g%}FM1_(?Lb(W*=%OM8Wr~W(Kg)=oJkk%B z6=(Si(06TfZiEnsD!JsbS3kPz4Ink@xLM1a~t{{%R`oKaJuQx&V zZOzgSPuPn%Y}2)|+CtekLU=3BFJ9gUn&s!q>c!t|bsOue z2=Q&o?NvNZvHF75Jo>iLUCoeQNiQgdJ*lubc`SxaU&FMG^*nz1YA96LCVKi>e{2>* zxQ3W-V>LAi!+r9do7<*>_>5|n95`G4_Rm0psC5m>rVhyool`Eo4`AjE7DQax4yi#2>2})nbYBx8Rb))2n$NM;& zYwFIv8X}-1QI!%zvSv-u+EPoq)gl_Zi$%(mDd*G_>n+=oncJn7Xf5g%*J?krWyyB# zNgmWn_Mplwb;N7;w8WXRYhCfW-GcnKuE?=Xj*EY|(%=7xis1!U4y-=R4FP;m}Q5}h~ zJCgfw1MwR9Y)zILoRYR?MKP>xYc>_b+O{UY7}mBm$NaJIUrHE_Fi)8xRBn$(V(~kRc-uO-JYkK+4SZRnAHz3$Y#m~ninyX&%=2vglDeLXr5M&hc1JF+ z79*PqofhWiG!+v?u(?WvMaa6XM8(`knv2``<$cwWJC({-ytpE+tSM2+Q%b+6N-ef9 zrFfDkj8*C$roeCNSXy{1<*v5njz;fMVbL7;?}qQ76Ky>B?FomojeJ-a!%FCV(LiL% z!@Bs*w`w0~EBf>A)yf9#1^>L39M)d6c)a*byF(S=NZ~`v^=u<-DYLw?6vmb^F#MzH zoUy{pnA<_rqtm(dJBVF`&(N=T6seRa$37s&;&)qqen1=(HBWByuQU{8ZxzFE!!x!k z<0P*?X18iD&&RlRAJ(2;`NgpIRNPbyYfsx1#jv(JkyQ+ya>7+a07)xkcw zj3*rHeApUKh)jJ{lqzR2ftv+R{iI1RvmX^dv%b#kVd`yu57DarC6#GwApZ`_t&$k) zhyL{$JGrxSWz(MGBg8$g^b`%DlT{uQuRpLQ4_OHHhGCCrGoGi&?S2lJMf7D{g=XDZE{4i|{RxpzxZD3|FVPE+)xE@5xPh7al;E$a7C$A**GS!k z!e+EV?VDVXv$?tCR@Bx*U1oSso_Y#fob=p~-e5lH{Aa37+2d)kMx6gVS3Dy=6T$!N z=FZ&SEf4h(UC=^YU+CBkgrob4S~xJ7*;hPYVXIZI+K=a}0{AI%8PZR9#m(LL+*P!s zwKBP%s8{i0Q+@cd3kRgI4dSyhDL?FoUBUHT@{fKZiLS~u&xvZ3Cc8c-;&Jvh@;T8Q zKZH>n`R8+@Jw7~W(I5Wb$z8JBbHWSKl>XvnJj_du14INau6hTEdi9o>`$@#S*ck9; z``EMToS! zRMz}?(H50Wd|r%4&u>022F3YGxbyOZnvcZenoJ!eYNN#3L1HcL;y&|&$QRdl z%j$#0M%*7gIT-z)EdLoS(t^yvpDxpr(Zp1_FIn7=F?YQv#__mLd=XowbXj=_mh4-3 z(lZ3t%zF$G<#X!{!^@c2#ok>Y z6jW&Ya^D^U)6rb9?+w$nYmlTj~2l|PqnzbsDB7joDuFy>##A72r3 z@JM-8NctkT;%kUQ&{jzkA^OSV#iL=Vd!cRCY*(|O6yI^Tvc){heO|qcpOB6TivpJn(&x8dLAN7XemvZjRM&@P3#TY$Yo$~ zD@+xaL(ZFXJ=!6=hhlW9P7}}CQ&Ub8>%vtuA6F&tLm!?{-1mNLx@ZLj%$%+i@T2J> z2cj9AE_!*>l|@AlU@UN&USk@rw3snmo0iOm zx?7Z~Ffcc{BVHFh$bF1+K6$=0*P6W#^ivgE)=ay-_6hf5I_88CDdcS267ax!<8I3Bb2 z2s2nqU-UIU_mF<>D8GE-#J!bOZ;9IXttezTQNN*{i-j(~V#GS3U0}}nw;*uz0&68D zek&s#pLo8R0ZV>7_h1Gh_%MBehDZ@B@;OLWO}5DtTfEuEkM=xh{Xnbe@3#FmD}zP}aEWMKxkMEx;D@<| zvrH}!_pYe)v=#W|%b9xNLGF~@O`ZV`STWpXH|48uSMFI&{`|(0I2#4Fb3Pij6}VNU z6Ljj5l<$hXsC3pnU#%P;Gcj}Jh^1m)xK$}Wnq{(iGIE(nsZrc}K~z`2hu0(XmWen1 zlNykZkM6U{pU%)Cx@q32Ey&FP1duYVvW;G5;3m6#zP%llS}zIeR3Qt*e& zAFo8rHD8`t3D@Kk`TI)IvCK}c*}BmpaN~8C?6OLX`%kG9_bXW{l2(gK=vd{|qDse0 zT%$V83$9fJN^Fr-0uZ$Qty6)&v{p$`H{9K(;qYIE10U8Z##o=kg!vKf*!DC9m zua*>IH1_)1hP73+tJWeGe{FTIlHcm!w( za<1BjvjA7}gWm<5z_4s_7)w^9Tya?Rsh<{CytED5rESSFbH@+f?; zhBEu8coVWmyW^k_L33DMRo5Oujc5DdZr+` zkZgFm4a=vGqyJ51{&CTyj2GBoB$j_XQWdFvBk%*iGVL3&yV9FgHOJ$?HWdy>IXwNT ztIE^@(NczdElSIECq!_Wh6$z^co;RLhBE&IT(*WX_@sJtIw|_3RIO$bH2?vRmJPSS zdlf(UY>E5}fIWWs4D%GR%Qqm0QeYcy47jvkerv!`+8(|FIuND&2s#7i31e4atCJ1e zgK5L|U{r$ps4J*#Vu?x--qYN)3S`&P8BXQLYd-3-|_+yZbt zKe#1e?qE+j{#(&5#U^_J=ny}$WWb4j@QZ-Umw^50d2;fsuEq#t@8Id_7_Ju4gvNQ5jX+*s?b0XU$*?`$@+VGMR`R`hAHPG-s7H)MUf0$K9iBaG)Oo<_A|=VJ&6vg2WcH7uH;s^2zY{4~SVx@4{}t z==%fAUbf8oL9{NDouoOQ0L@w?ws+a`;t!&K%AR_rSzUzghXZZHQ5ZMo#vg9z2gf3x zJ8tJ!0?dZVhP{B4ii_Y?L><@Ft zY&bNqcs|2kS-1sTyi^(RGnRnya>UP~fvZa+%~4fme-%fuU^O2{pM%zLQpc?0U3*w$R6GFoenCxM=W z>ez{~VK%VrM%XYLSZ>aS-zfoS17^Y7`D}6g%P%cXAL>{I1nYQ4Zopqqo|LQYOhs7& zyb_!RuK>&@#m-+=0^SRl7e71y2;d|?cpqS%Lw5c_z^qX=ETA#ySUVpg3Uo1hwC z{|1@>W_7XiTLDf`aBj<+qBM!C?Q$Q!g%|naKf;sJ>;Y5mW5$jcGSKrEDu>*(o zAGjJY54~OI=rN;G#`Z^R+mOM7-)+R0!NZ54+96{H9tMspwHgA(;kXDK>r9gML9O`t&rzAbBDYtYQC|I60 z%u31A&xTt9<^|KAoqm9sUArsK;k`c+GsRsSfP@|uqj?_iAPa{_E5+{%czbNv=&>V4 z3?DUS;DBN>7>vAjV@Hn}K2&wOSYC2&mjGu?XUe+Hnqx82>quje1|#)A>WI`FDG|v9 zG5r6OQdGs)AJQD>kiJCv1Zf@8LZl3&$w)(y`XN1zq$AZrs)Q7dbn8LQ@io#Sq^U^5 zke);8h13nHHBur{I1(XUM~BWJ9YfmQS&j{MzMoR@5lk_pKe}m-ACQhA?M3w!} zqzt5~NUtFcLmGhe1kyuD&5#n2qLBiSZgkZgmyy0lI*D`$X)n?`q@_p_X)4kLq~Tq) zW{&=N>4~HxHAXrN)vAGK98wfg7}ARvO?%c1!TV68VX|+iv%FfI-O?H088r zN-fmcj$V{KL!H&JpBf+P>{e!APfacGJW*L;2j-p(bxt8%-R~RbtcyoRn6oAx+rpd= zgcLreDfi}O*`|UsN}dXHhRcSfoE4GZrIfREik<%|Dsmy&@Gh%z8~zJ$Prv-X@y@o_ z&L_+|-tyRRC}98k+$G>J6MoKDpi~Kh(k0-B0Q2;-8yE=KpMjBptNP`?1XwYgJEXL; zo2y@^XEb*D921b(7})R!cxOg!cx4HARS9@?33!bS%h(8K>oRsV>wM@T5zYqnY&7?h z$ION+0B-9Cx3TkOVFZ5Xx09?@-q|3W0at;E;=PVd&+D##YfqPew*h{@ zkNzvbyad?gPn-Gj+w#tYkOh4-f4@3qicp|$YvObGN$NDNJ^CA&pBV<&WFE1rE^Eu5MJnVS@&G z1`ZqG!NNK4WlvM!S(AGRqMZ*!&H%_dzXZ>kc#gLuj{m=j^HtgR zrU;a)Vw|hR`GK-mth0Vd@no$vhOh+poPZoGJJh^MjWL70-bFW?MNua9% zJrPe{ey8Dy`ayQRlCui_zelku_aE4ST@3XHwGPG7fc!_0__-{%u&OiJ`TqdT@+P|g diff --git a/contracts/near/res/eth_prover.wasm b/contracts/near/res/eth_prover.wasm index f839f476c5443d73e10d4d1895080f9d1de43671..1b0a7cb9a38ce8b639abea3b31a6ad777e6e544f 100755 GIT binary patch delta 29564 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 delta 29085 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

=Y{+jcZcZ~!x5(FM~F7vgpFl;V~m6A zBEp|5pKqkSp6;;>pTi4zsT0+3Ikaih<>2uYW1M+CQP|%}>p6I7xxNdY)7B5fjD2!_ zQ~yB57_p%_%`}#8Xzqs{N`DzcHeRQR9Qsx6aP*#Usk z%WZL~R_U9So)4K}nRc0jV2;ZRV&1sujJ5`i&<_Ujs5w}{95w}23y!!jH(o6~NcUM0 zG*2uhg+rU8lmaNk#`(f&AFGfI?Yci%iZ~YJ6)ECikT%z-vTZ14)T!J0M_(vQqewzP z@!PiOAwP1ZJ7Z8Nx!Nriq5tm{$=E(9{AE*XkfLSi2iz6V}eMHxeO0nqzJYdOaHvj`1FH&1M^;E zS%-|8yYCeLOgFOjR(1wyr;VE@>mc-gb9WTw8hduH4$NA{WG@+yA9~CA&=|{yp8RllV4hX3*GH8R3qJZ$TEb=%V>N;KpmtXG{TH_jA1w&XRb{ss z%MLX%-u`%M*oRiU1J{6ArO4>G=fRrmczKrOf*a>KP+yg&+NaDIJ~G40IdJeh_RNYc zW_AdW;Ct*(n6pbmaJtuPY9ogHb+O3!c5mI=c3bKvF9sf7&Z3rBI*OuKjUM}F8aey= z#$PdWtTwk$O}2XFxN&1&)A;Nas%RMkODC@u^w{sFz|)EaH+`b9|I_Ti>#J3}j0Zpa z-6y!$fiy$xi#3)VSbJNMK1;c=ueLGgpr^|1#G3UoXkQiZxyOh(l;tP;Lg0Bz?xN3+ z(Q;$_7sq|l4_#>(jL=7!1?S`#(O*8CP`2rukM8!heg2nC6UtV?qOclo@_Fp5k-j<{ z{puYmFmk_+qm{;nuan^N4t$-|cnjAmjfaB1h*g;;y!gaRQ$~OtfD$&9Py{3belAkW zHu@fIhS+(*(U_1TvoI>9uQr}NQUmMEqeqkDO4so(vPt=^>(~6hOZNWHl3Q9+QG;)) z!%wXJsg(uie^Wj1@G3M;+W>5eaqXK%w+w(*-`1riDtG?3X;DfQdR@3}gf+#i7wi(8 zG`{(^M&PQI%xI$#aI8h(7WKW!=zQ$Qu-*Kvd-c-_x5H@pU3%DNHa+a;n8J4$8^60d z-u!;uG+2B5dYuT>warGv_fN#FS6ROKQFVh^=#a7I`);x3_c}#IJmaXz)TO;)R5)HG z>@>Giujv!n-lxT)wP{$q`#9jJ~|a{>^oV-&h+|c(o*B&Q{%$2)|z!XyGGU2xbue=^uCe# zLsv`>dw%F8c21YSb;2G+{nOFWOBF3k&#=Xvfmc<%KL_{oL3dvbU<)6Z%K4Nux zB28_w)?HB545Q6Y8CbcMj^Gm{#4Tgy_bc->y!6*Z$TUR^nXahPyou$60(y1c=hWi1N$yV$ z>Cx*B>>w^ujr8hURQnDac|TXDgU0Tk2StBr8nHdTwa-o1X!H8O%6_4&$!`OZQ=V)= zRSfTf5aY{p)x@kBhSnn12>YdC{2^76hk4S!ECPAM?m1)JF9Yc?qTM9pcffOHoJKW_ z2Iu=?v6gc_6}zbKo}W_f#TjUT2TCknSFDtHn&0;5?PcWtP+4lRYJ-yzqilr4-^tRi{Vj9@Q=`z@2 zg{`iyGC3F*FE+=PL9I(qh%4)j<(GyUZGHLUhfp%__YQ$Y7Nax2S1n}}gNB199?N)w zam8Qmf<75`xohB3MZL`^xI6$WvhXYK`YLkhN*eaKg8rCaPNW&V`a*%X{%9I+iL~lu z5?GM{b4W4j{5jH=RIv2VMihUL-G}yxRRUXEsGL>ewDI%RPV|RSzvNB?ag$0W#Gl`w zRHKMp?8seAj7JEXEdIK~=VOm4!X3r~e|?KhyGGX{@a%l87Ph@dU%QTNn2f()#cDn1 z`ea{;>l>N%4rAW+@pRF+dHt?BcE@ipb1WOg3MvER6xzeGj7LMD_Pa6RM*qMfMfR!j z<&9Bb(D9#6*m#}wPaB_rW0rtJ|1?6r^Jde)rB;b{H|w^xh0XOBrrX&4x5Zw!8oBD` zw7~O<;*%Ha(RcKxd_hokS)Zu0-G}l?qSkiC5u&bTy3)zJjTqWEx8ZfhaoI*t(?tKi zG%0xJ5fs*fS&4bZ?oH$9S9N4NC(Wmm@>3@*ry@DlMWcPg=Y;BKd!X3kzAV-rK4r1? z@UgJ6zMJZJjwl=839Up9aZ{s^FH8%n?F>qE%7YClPHuD4L$$s(=`hm&w!d0AyzF@$ zx`91uvghu>hPI$?0C z?Hh(dT%~Sp^JYH|zTQ0O&sRUekX~QURkXX9g#)t-&nkLdJpL6S?Mg7glI($3ZW>2~%c^4J4CwzVLJ6z3b`l2#en|76n zm0CD;iSdOFxo>lsL_LSgYCGiEaB3cFBhPZXZT3e4DOfgYOA+$(aB3Eqqw;3Tij}B0 z&6a~IQH|gn)o_>glAK?Oo~gLdoOapOvtnZ+s3#OVJc3ev4LE3uHJyWQ%RO;h>?Ny; zUqnz}@Tnh3v4QzkEqX*k!87E7NU9%Zb2(zxUha#e_)J?1#asQFq@Q3&udW{~gS8nf zE>jJgLs_g%n|)iIFSZp}N4X=L#a0`wur`Z5R(*3T!~47-->ppbQVi3SuyFM{v_(F< z!Z5VMUzoqp7R%5mnnHPUW)!te*sNOfuBB94Xo1I$^HoMANFS?zWkK5|nuCDJ?cU^FF1*r70r@j8~Y*Jc>wUyGO3V<OHVqDNCKXiVjM`H(Xh@Q<>^Jde)CIncf_uH6=q|w2gsF{M1gGO{)Y!ns1X^ z?vJ7Ph##}T$m3z@E4e`qPpaWP9Wz2(rj*B*1^C85kbPF>PwD?H9G(iyK2K?-q4E*h zItHqE|MT90d?uFK1g_e__1q|T#L~l6RWY<;Hx9%OGK)mFQn^ALkj<-5ao{1whXhGI zj%v!}IJltCW$QS)JN^rmft8;d=aT9W5O0kS1L2I8$5A!X_b@p&d~$df0-GGVJjN^EqQ;a0qmz@7|8e>M^S8^@3w$u_#D)iW=IG*j0_bcY8~YNmb=bCkAJ)rUGx!}P8-$I-Fs8;8EfS|3;O zlKeiDTFXg^u$^OaQ6klVH{F(q$o6yjXCh^mnS8R6D4u?muO`tzv2BKN=$AxUtvXfq zJ8o%UtlJxH-y;d%uIgL5`gm7vt4`xGRnLWBQv)Yu8Rno0flZe}_{8p{NroMb+h<@? zqckG~yBU5EEWQ-Nr_BwY@fn)MSp}?I0r_q+HKA?t*JOk+?@3P$YE)rAcdNeJp%u$J zYmgDDG^yvl$DO@Y{#1i%(TB2PO-hB<+SjCcF}qb;Ng1)WQvqxMAIsAW~ohtxT^+)hn8sVEtq4?36Fnqdz?s z4mQ41Vik2)@E$IyyR{SY=lYaJ3k$ssr~=X3vTj3~iiOVW4WY_>xvwF0sdJjWh+f0? z()z7~RG(W65_pC-skD?%%cH3@;O_m5gJ=7%az$o2a|+RysuET00yq|FnvoO$Pm82^a#0F}t-#&qxfd(4hvJG5?gc$HBuXM7@= zfT?L~mVv7vb|ct#E}a9H?&KDQoAom?S0+XlD@?F*5Bg>X)OmB{AWVm(?^U_hmZ7JT zLqD=>CtDEgQh6%u&XuB2+bmd^!xL2oi7wkbgVAM*zabxOLbW>{+y#l)6W+paJ2up_ zK45I3e%>F;@q?a~<)#e%vrEcg?Hc8ne5~5v9&7VmY{}fv0)FS3+~0y)cDSOd zi^)pGZjf0Xu!P2R*XnfABr+>#nrEK4Y-w}hj;BHw9AiI8)I zp}%BED`?@Ge6khQr}=ViD@wd=aQS;HthKUb)z(-5{fT?Oaq^SaRGVhWE3Ih|l=(m# zsx5M|<=_y)bv(6X3s|lUT4s%=Bw8Uaw4vk#D=sa!Fa4z=9B=&AFiLiAORYl|??DSO ztZ>_Czbtl(NSW7`+%&ClOg>a_JX|74isx-e0!MIBBsEUJcKWG zM!qzP0_8X_Rj9X&@wc1e7buo$cDJT@DVMdUbTP-g#4P)brjW|gVjHdovlr*Zq&+8F zb)cRNRw@R(3^muA*euu9FfI|3B5yM@!cu~DFI0Zrfx@cI;N5g9%-8ICYnA{_O1Dml z0k1MAk1=>zd<*s>Yn8Cl34XN+!_OsSt^g&}jPntN#aC_NYVMTF#~_NxlkbnA&Xw|S zVX*L20^b#}a!QxetFw*fuiqszJHm8U$mJbrm{^%DAFN0%0Cwm^tII?xxJOb8_(9_- zRyMkW2H<JhaGgEJHi zkbF7+PC7;#<;X6mUXI+`1+l~yd94dIjW}{z)q*Qz)ndEUyCO8(A|LBY)2UFN>#8;+ zs@z2xCRD2u9HCvE60iNn6Ao0U+r|e&EVmXGaS2p2EbL2R{n4 zQemq2VP-2#tRLo|Q_LsC5A%z{nDb7iCCm?HVm?urihjk4ZozE21(SCRW}d=Wlbovb z<&#_?tJ0YY^|nH_^AomQVIuu7H%@S|WIxPBh4HWAF@^CLR;)1A37V3XuP~NgJ#tw$ zYSTv9m1Zw;F>@g{LKL2%y~W0XiC({=Oo`XGxTd?|W3EaL`yd20(cP(YNKqCD(?l`| zmdfGXsdYtldY{Nnszru2O}^Qk?&w%f4tg0O#|iFoe;I@lWo0l0ulKdLW%C|%NAM-p z%fZ@$!t5T@$k{1tFIUCBN*m|(jPzFEyRo@t@R44Ro>vA_0W_OUj4bJewQ$~#%xI=; z-J6e_3d+Cladjwrl0(Zz|_fj<< z@}PzM^j?Z$QP^B1Oz{Z zlXRR4Lx(#1wCysn57iFbV-}LV`(W>Cn|!Jd4Gqj!xNUO4BUBx~zM1w2wG7?NB5^&} zp^G#jcMgQp9P%LMhRRa27B03VsNj!wcM#_lZg1^{UW=OEJ7;<>|r80qd2A zNN;IZ5tJ@HYx9oGiTce2MVZ}jDLYSDKwW*$IlsGAT&FW}0ahAqX@8g`jVEFOg-);C|E} zX8CA8Y7>`pmUUqJ682xF4LP*;xSShFP^n{0aAjYVDBo`(uGy z_6J-tVE`==N6yJ@1E@o?Jtnp)LH61fK^jgO^?XyhtojJWS1;xkaKG9Ci{B)=*evaD zv9wuke+29IP4e0!2t9Yn@{@k!*%mJOgq(tj%TFylRAR zILmYxfLCSl5PCLZ>qUUR+h}}0?L+zIP^unm&1fOv^1Gpw6tVOcx{nkcmP}s`#V*ED z*={H`1C%xlP?lU~LK2WTaY52BYKqJf2KQf(Lrk!5I(b8jF8FG2_Pjj#7*-4=5;xJk zp<8a3bDVSXZprc0H&_l%rmc5g)k{{ZlQ>?`w7DvLy~vVIii70qlfPwPRVptJ~^Cfim%J8 z#)AG(rsTQ9(7%n1<7Ja}lre0*Y5}Dm;SR@CoHT+Owl{x91V<8tqhR(Ypt8<667l;T z?L3!F0#408UUwR*0X}Ki8pQ_2MVUK-`ZW30Cx98*0%o#Qr*CJ)(}FilZH~sp7oufq z2Dt^8G|!-i8eCIMR87>+H+ThgopJxMr1~y{?hVPlg!aI^OBaznM^ZxQKU~&h9w{7` zPmY9{{v;mYX=s^i{BmoF#j^L}jcZ4^>oqz3g9k=wFt{N6};A zJO3r3y&3GkMEpuVGn#5*t;{Q7c(FaBvCr$<^{q383@pyoy6lE(a_PeE?`&&b7H;OS zGE}Evq2FgLjdWc^0U2G9+KFrCs!aTuEnlceuR|IZYbo;KB#OIriS{Qi(Nww;7e+a-B>boj}d>S*$is8;9s1IzS!QxPLLd;evwtBBi8P znaJ{$i~PR%_MS|Aj^@xpS@axrtm#`Eb79O5eujdBpb$)zDdNg5*=Z8(#ePNT9!NB%c ze3eUxRD9xv3r+erGW$t{SS9kUC#gf*6I_Wh`QMs_`RoBZkQ4Rx<8?793H`yMxNp*M z-HG$AWXXn4QOyL~C1953<|pBy?AM$vCOk#$!z{h>&L6b$k}Q6T?(8;~tELO>y3(M) zM6AzOC~P9}PSYX=v@bYUEp<{_IjTYIH-B<5rm2QsEi#~eA$vbfRsR>-$pu-JONs&i z$Og-;Ri#3-ALO2=scDTIvl7}(t6qHXiYsTzI?Y(^N16Bx#dP{ov2y#G0ETw;R1aCz z<085(7C-klE3Fv)AfI`Lk{WKl#*GT_l~w}t6!IPQbeq*JVnDkgKYfPcFp7VE2D^5f zWbm^zm|l@1pQSsoPw>{Wl-BpsUm!I5Lug;CmavV&jUH8Utvj%oq0yi0J>g6FhUc;W zshrfOQc~h!-c2^ox*{_;hG$!g&(LubnZK@ImDy9Vq*+zM)qPj)o=S}~FL4?DCjJ7) zqo_8UE7BQv(0Npy;LJp)?$9&SOu*|5B_7qH1Lyk}#*!JB^Qwdk(JO>1fU#$7K3=p- z0q~Sc)G!>k{@;}Iy6w98%l1{AE1^>>$7vRbCa@k)?2<<_sei~>ZZ=2XLf<0wEQ$=A z%W8!p`e#v%ibuHN=20OoP00mWlvw{|#(~ck9*=rmeS<1sFZFEfQWGn`%c2~g|G-Jj zemQ;`jesS5JB_?JLb*PTUb!W|s?(vXtSa)m=~SzMH7L!#XA^Lm6X<>x!bYJqYu@A4 z_shmJsBWrKMN)tY+ts)7y8*hRtI`KL;0o&l`AGq3>?-HYprqE>Y_)7(ZnJ%uwz(%% zpC>u>%DzZU!ZHR~?Dc?DVXj$C^KUI=d=m43_zzAHXIP>r#cl z4g__>Y~X^Cu{&qyvr;~sO%3l_!}_iQWE~*+M}zQ0?B)Jz2CBg)2q5P=9OGstVf86L z&!+0MPX3uqk7FUA=7bH*oCn{(&IxgHU?rtdf|>$0*i(S_Ia-2!LY|xa zW{vWJe8Y2L{aeU!q4ZCN6_WM?-x)5kx;@CU=R2`ll=*e9ARPF_pJi096F#_<+;k_6+5iVgDNwyOlB5YndenzMVy)b_98`ATlG8(iL+_F z9L<#0WSdNW35(Koh4;LK)ljvv6(&7%q8IJ9tG!K1Ny)x8?vl7;Qm#k^E`k}jw8+)P zrA1`Y%XB{4X-Hk&I7hUN}L(GYXZFDQe1?PS6`urt9_vKgS>n! zM@jR62h|bA2XfpJszM*gIZG(9cX3%-A868=AVmO6fBHlaNXYO**gFhp~tKtu#&yz{UQ}^7;w1_}Hat!JAm9 zswkGPirJV_VMQ|b4Qd{^$IMoJz4nzisC-u@`D#~W+QXll@#BtieyVyoBH8CHYHyjE zExDA&Zf2>KY?H-r(Pqm{Y%82nK{bqoL%+8C$`bk5<3yGsp$)k{#5MJ}CTt2Tc{Uu5iFEN^oaxRn@%JNNhu@ zS}M~r^8_e2UzPgM!i2KnD~wg@Uxv5eaImauf97rd#Vtbrg<+{p|F_^<=wKnin8%$R z1W7vLoo04o4j0 z)c2IpHtX$(zuvsS^gwvQ8E4H5S$97*qB(^F_R~%hCG(~CGyE$}Su*c41f|mpqYls! zQFrMQwm`cRE1+~y84QcwuQ2dKpHotcEC%#g{p>6Lrkl@@USB`rkA>+T!mW^(l>|Be zbBxpX)hqLTs}og>rzhxpRQP3&Bzulr?9WWMM@LQ>tUZ!SloXqTJ?hSu!P+DANPHQz z9RTbxv4x$!z`zLHU^cpN&|xAGGkpOXk~h((+9jOA%Wc(v$UL{@615vj~qV_2Vv88A6_R=Dw=* zY|?qLfWWqUxHk+FcgRL>uv~wXLL;n7;JSlTUux3JeMj*R1g?{X-zahMdks~>`VqG=b-UtOjPr$A zxeV!v`j#@--3ptepEa?v>UX%I`w9p4p7TOBtRX7P*hZpSa5I5LCBnv6rJ1@~*;m7o4Xy=%O% z91Ug#3tUq|Uj^z5{4ogY1N9u)={(h_RAO&r2J*E9tVl}aQ|GB>#1*r^AW(wSLwH@4 z1?O=e=v{gKJoWAHSDA9yp}Lh(DaFCtFq`=+l=QCL^D8}rCU(9+k5%=taO;b?5BL-d z8%n(3c0>Fp7tmqv%90DTi4MuN7hzw;a@-|)8^43A`5SqIKT{n?xOSa;nWAL+Z}e!8 z+4oK%PnQJqb8L=@eEI59P)0JepXKldz)5DSu~S3e zz;7J!F8Pbr!Y(^qL)ey6IOiI*r%HdQvg*eY_^AL^{(lr6`x}~#H`^D2_VMXV+4jke zHz+2^Y%E&y=?%J@K9Vv25Z{z;^A9X~ublP|b!=C{`rzv|E^G)V2CxS+mya0wDL~#R zmk*P5>DZ^@JhYT5*y1KS=A0aQ69eP2Ja&`5r7JIP6;Hv#G$HXKUVBMM zx>7h;h(1K8ALuP>`8+QE*$uPD6qnY>w1WF?d%;U4mOydj86Dx$#BuyO@r zWo1pgg8SKxVVoz z**r7A6?(Lpg_R@3H440BwJWN!7#*0U9PFQRc4g5*lx&x~D~k+%r$&k7N=LS{2JHBU z^y}N@qfw$7=RX%E`iSdA@_3Yp2|R1k$$z56(YTkkaFy!m7u0(<>2JNmh+R(2kiSQZ z`gKY+F`T0Bd4u1}gns5t{&+)ZhML82`5A{Ln7Q7Qcg2Vt%vGPqh)y)KFe(S;PBWt>Hj?dtbCz4vH6T%Aof9p&k%R^Gi3!g00Q5d1B%Hk@9$g7y|pqt16Pv zujy4qD{tMXeehTiM)TODFls++MZTY>>z`Ez~M3&T*|aCrHciZzT2cJ%t}Um zYnPqOap_3UUdf8aKk?^vWMFQ`*09$xQadj{sUbFCV{b}L(STMJuBj;|Q^Zx<-Mjhf z9e&*lkKHf@9gwq8wyY!SNh1Y~eOGQz5pz2D5uXOJA83`mR+by)rN2ut$1IL-)fSDw z@pNsGR<#@p6!63Bmo4guyZc)mh*1}y=dn>~wlZKnXdBd~{b_cCenW+Zb%C+MV74$& z@bR=o!-v1PU}gnP-`5evu}8{q=w)&zKy(a&tFIog{RzvKx?4K(7(qVQemF2!v5iE+9y%dJ;Us6SM;WrILN5UkU zkovzXaW9OzT_dqJveYoJ3z>yw4O_)ujl}A)H4}}|r18x}^*hao*bXQUvHEl@;mgLG>cUMfyFe`Hl@GOV62K7PfnF~B zrkVKDRc*EHnAm89wz4d^LY``C?aLcx$oOjT_bN2MAqGZ7re- z8|$K9U}pNH;q@myIWB!-!-*4yHXJo#NP`Iz9Z!d9j!1{Yp^?K;6>l5v4LH^ho&-1q zaMwm@sR?+ytW=G0jhm(U49;373m|h&0@>JkSGPuBW_;SJD-f=?B^wNNyw>e$EHW4)=%* z3X$vY5lzBt1096KZL5P+S6;kFOcaMAfvwDfB za93rsopGSmkX&+YFVUV{@{IYa)mu!-43091nt*^i(uUjMoAqnMC(Gsk1la4B&v3LK z+yshe+p^220j}r=w+9S+9pWRfH+am5p$>}ua9V+X`{!%X1T#O{1jlXAN;fhkDZ)8;n7iJr`UAQ1CP5mzH-X}C;7o| z18(65?+480XO*wx__Qp-aR{)tl)&M_VB-#aQ?`Ck)M^_PuQ@6Jtb{jPrCpDXAma|Q z;i(wTOy>`~<;`BAR&N`%G{7A6Hk=0-r{TUL%gg1ju;2!uVUNvTpdnJK3~P(w+er3o zEBaBgEO-d9Z6kU0AyF%oO_Be&BO1%G1H~P3Y+n&3&L_yMzT)1>{`ox8n<6zcUB%vq zMTDH)QA9M#uc|o)BBK~wcq*~sU4ZMCgINdp^67`g$VNS?X^sa0K8?h@Z8#I(ZT;YE ze6t<(kkS1_bLt^`_JiN-Av61lo_HPTC#tJk-9hDO;x>PWT*I^vuC6*_aExUW%avgYUs@E_iSW)Ep1t{UW$=2x7zRvDvO{ zm_0U2v*9J>;5@*raXX)#l7IP?W$B|F>w&1{SKtl6wb{!1WqO;K*0LNZ){PBwD8c^7 zhF6t?KLX65hMoT<;8Z_&A7D0WJO2P+wkjJIuo|?nqYn`RL~B2Snt=TUGzZKUV>4(6 zxCX<8PmdM&U#fTu=ZwQUlx@bglkRfucu_s`sWh`YCOtlGRJwQa;0YrJkC_CrT;SP< zjY*%v;iE4nA9x-ikB`ALXpt8K$Kun+JU;p`zFEZR!Q&h!@a@F+#Psoxr;iz$ejYGe zgw1o}qzRdi4~4Yr$Y7i3Id0O3v17n?)Z^)q%}u73AYd>H0>`E_4)pv6gArpM^E&PT z9+8z}=VjaaOB$?>0YG!knTr%pdKD} zk8pU#K9PsP06+XA_+}S7NVabW=hw7w4t^|M6}1DwA;5PV zF=klLi9^Q@g98284n^KDB)jg&c6d|9PV}Zvm@syNw|3JO9RE2STUwin+<`aC8l66R z?1U%1GI5GXsBi>G9tyvpkQ^{Fxw{&N*itq zxEf&p>O2aVt7|vqF?9LUk{9#`1rVSV<${XA67;O zV~}TtE2`0D^2QdVS0Nl2BD z1k%M;n&Ug9gGjrOHXNIj9-AVnd4-%@jYh_nf51=7n%3y?CAh9mVv z(vg}Xd68m}ZnThFo)K#@A8fBVx*(+?)k2Cv3PAd!o#yx%=>*b2qz{p{BW*%jg(Q*Y zAU%aN9O+@CJCIr+)kms<6ps{+6o7QGt>*Xv>1(79k={dkqpjA;u@WDPkftF`Mv6ol zf%FJcU!?9xc9_2}l#=vZ>gx;2BFco+=_MT!*vJ?!h_THAe&FKa0fPz=qf1 zn=5L=ua|?@mxDKygE!i+?3W|jhudu4@S)e|h$f9}G`Eub%!Z=?cl3ih*!eQ-c?82b za^&-(Nv2Kx9diBa`h7XLI(!t{jZM#Uu)nna<=`T~UHs_30L=5RUH-V4FB4{q8o|fz z(Nx@6WLna&*`ks-c8`2wwrI@n4YNhZ$~H|V3UcSvZqUH-o^;L;_hp{!i4hAF^@4}M zn?uVSSTg@51Ba&g-fHPOGJTkL@FZ`oTJ^l$t^6K%^JM)D7s4Nx;r_JwFy0}f5MvsJS)17{9(SR8=Mc2cSPQo(F;VE@M8dZK>UVxUA&75$1VVG%#SN`MU&v+ z4`^ytH(egj#o})jKpuu2VTasef0$+4a3AES`oYc6DwbmB54B Date: Fri, 9 Jun 2023 22:30:37 +0530 Subject: [PATCH 3/8] Added method to check state root - ProverV2 (#875) * Implement storage-proof in `verify_storage_proof()` verification and changes in `_verify_trie_proof()` to prove non existent values. * Add tests * Update `eth-prover` contract binary file. --------- Co-authored-by: karim-en Co-authored-by: Kirill --- cli/index.js | 14 +- contracts/near/eth-prover/Cargo.toml | 2 +- contracts/near/eth-prover/README.md | 28 ++ contracts/near/eth-prover/src/lib.rs | 97 +++++- .../src/test_data/storageProof.json | 25 ++ .../test_data/storageProofWithFalseValue.json | 26 ++ ...storageProofWithIncorrectAccountProof.json | 26 ++ ...storageProofWithIncorrectAccountState.json | 26 ++ ...oofWithIncorrectHeaderExceptStateRoot.json | 26 ++ .../storageProofWithIncorrectStateProof.json | 26 ++ .../storageProofWithIncorrectValue.json | 26 ++ .../eth-prover/src/tests_storage_proof.rs | 296 ++++++++++++++++++ contracts/near/res/eth_prover.wasm | Bin 171157 -> 176678 bytes eth2near/Cargo.lock | 4 +- .../eth-proof-extractor.js | 46 ++- eth2near/eth2near-block-relay/index.js | 4 +- 16 files changed, 655 insertions(+), 17 deletions(-) create mode 100644 contracts/near/eth-prover/README.md create mode 100644 contracts/near/eth-prover/src/test_data/storageProof.json create mode 100644 contracts/near/eth-prover/src/test_data/storageProofWithFalseValue.json create mode 100644 contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountProof.json create mode 100644 contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountState.json create mode 100644 contracts/near/eth-prover/src/test_data/storageProofWithIncorrectHeaderExceptStateRoot.json create mode 100644 contracts/near/eth-prover/src/test_data/storageProofWithIncorrectStateProof.json create mode 100644 contracts/near/eth-prover/src/test_data/storageProofWithIncorrectValue.json create mode 100644 contracts/near/eth-prover/src/tests_storage_proof.rs diff --git a/cli/index.js b/cli/index.js index 0bca6b41..2be6f803 100755 --- a/cli/index.js +++ b/cli/index.js @@ -37,7 +37,7 @@ const { } = require('rainbow-bridge-testing') const { ETHDump } = require('./commands/eth-dump') const { NearDump } = require('./commands/near-dump') -const { ethToNearFindProof } = require('rainbow-bridge-eth2near-block-relay') +const { ethToNearFindProof, ethToNearFindStorageProof } = require('rainbow-bridge-eth2near-block-relay') const { RainbowConfig } = require('rainbow-bridge-utils') const { UpdateDagMerkleRoots } = require('./commands/update-dag-merkle-roots') const { @@ -649,6 +649,18 @@ RainbowConfig.addOptions( ] ) +RainbowConfig.addOptions( + program + .command('eth-to-near-find-storage-proof ') + .description('Get eth-to-near storage proof for provided storage key.'), + async (contractAddress, storageKey, blockNumber, args) => { + await ethToNearFindStorageProof({ contractAddress, storageKey, blockNumber, ...args }) + }, + [ + 'eth-node-url' + ] +) + // Testing commands const testingCommand = program .command('TESTING') diff --git a/contracts/near/eth-prover/Cargo.toml b/contracts/near/eth-prover/Cargo.toml index 238887c8..cde31403 100644 --- a/contracts/near/eth-prover/Cargo.toml +++ b/contracts/near/eth-prover/Cargo.toml @@ -18,7 +18,7 @@ rlp = "0.5.2" hex = "0.4.2" [dev-dependencies] -hex = "0.4.2" +hex = { version = "0.4.3", features = ["serde"] } indicatif = "0.14" lazy_static = "*" near-crypto = "0.16.0" diff --git a/contracts/near/eth-prover/README.md b/contracts/near/eth-prover/README.md new file mode 100644 index 00000000..6a3d0f7a --- /dev/null +++ b/contracts/near/eth-prover/README.md @@ -0,0 +1,28 @@ +# Eth-Prover + +Eth-Prover trustless contract to prove the integrity of data (proofs) provided by users and relayer trustlessly. + +## How To Generate Proofs:- + +- Pre-requisites before calling `eth_getProof` : + - DATA, 20 Bytes - address of the account. + - ARRAY, 32 Bytes - array of storage-keys which should be proofed and included. See eth_getStorageAt + - QUANTITY|TAG - integer block number, or the string "latest" or "earliest" + + +- To generate proofs one need to call RPC method `eth_getProof` [check-here](https://eips.ethereum.org/EIPS/eip-1186). + + + +## About Parameters of `verify_storage_proof` method :- + +- `header_data: Vec` : Rlp-Serilized Header data from RPC call to `eth_getBlockByNumber` [check here](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber) +- `account_proof: Vec>`: Buffer data of account-proof from `eth_getProof` method call response. +- `contract_address: Vec`: Buffered data of Eth-contract address for which we are prooving. +- `expected_account_state: Vec`: encoded account state made-up of `{nonce, balance, storageHash, codeHash}` +- `storage_key_hash: Vec`: keccak256 of storage-key in `eth_getProof` +- `storage_proof: Vec>`: Buffer data of `storage-proof` for above `storage_key` from `eth_getProof` method call response. +- `expected_storage_value: Vec`: storage_value against which proof is to be verified. +- `min_header_height: Option`: Valid-till block height for unlock. +- `max_header_height: Option`: Currently set to None +- `skip_bridge_call: bool`: whether to make eth-client call or not. Always take false. \ No newline at end of file diff --git a/contracts/near/eth-prover/src/lib.rs b/contracts/near/eth-prover/src/lib.rs index 5b1b14bc..46e98532 100644 --- a/contracts/near/eth-prover/src/lib.rs +++ b/contracts/near/eth-prover/src/lib.rs @@ -138,6 +138,71 @@ impl EthProver { .into() } + /// WARNING: When the value is not found, `eth_getProof` will return "0x0" at + /// the StorageProof `value` field. In order to verify the proof of non + /// existence, you must set `value` to empty vec, *not* the RLP encoding of 0 or null + /// (which would be 0x80). + #[result_serializer(borsh)] + pub fn verify_storage_proof( + &self, + #[serializer(borsh)] header_data: Vec, + #[serializer(borsh)] account_proof: Vec>, // account proof + #[serializer(borsh)] contract_address: Vec, // eth address + #[serializer(borsh)] expected_account_state: Vec, // encoded account state + #[serializer(borsh)] storage_key_hash: Vec, // keccak256 of storage key + #[serializer(borsh)] storage_proof: Vec>, // storage proof + #[serializer(borsh)] expected_storage_value: Vec, // storage value + #[serializer(borsh)] min_header_height: Option, + #[serializer(borsh)] max_header_height: Option, + #[serializer(borsh)] skip_bridge_call: bool, + ) -> PromiseOrValue { + self.check_not_paused(PAUSE_VERIFY); + let header: BlockHeader = rlp::decode(header_data.as_slice()).unwrap(); + + if let Some(min_header_height) = min_header_height { + if header.number < min_header_height { + env::log_str(format!("Block height {} < Minimum header height {}", header.number, min_header_height).as_str()); + return PromiseOrValue::Value(false); + } + } + + if let Some(max_header_height) = max_header_height { + if header.number > max_header_height { + env::log_str(format!("Block height {} > Maximum header height {}", header.number, max_header_height).as_str()); + return PromiseOrValue::Value(false); + } + } + + let account_key = near_keccak256(&contract_address).to_vec(); + let account_state = Self::verify_trie_proof(header.state_root, account_key, account_proof); + if account_state != expected_account_state { + env::log_str("account_state != expected_account_state"); + return PromiseOrValue::Value(false); + } + + let storage_hash: H256 = Rlp::new(&account_state).val_at(2).unwrap(); + let storage_value = Self::verify_trie_proof(storage_hash, storage_key_hash, storage_proof); + if storage_value != expected_storage_value { + env::log_str("storage_value != expected_storage_value"); + return PromiseOrValue::Value(false); + } + + if skip_bridge_call { + return PromiseOrValue::Value(true); + } + + // Verify block header was in the bridge + eth_client::ext(self.bridge_smart_contract.parse().unwrap()) + .with_static_gas(BLOCK_HASH_SAFE_GAS) + .block_hash_safe(header.number) + .then( + remote_self::ext(env::current_account_id()) + .with_static_gas(ON_BLOCK_HASH_GAS) + .on_block_hash(header.hash.unwrap()), + ) + .into() + } + /// Verify the proof recursively traversing through the key. /// Return the value at the end of the key, in case the proof is valid. /// @@ -184,18 +249,23 @@ impl EthProver { if node.iter().count() == 17 { // Branch node - if key_index == key.len() { + if key_index >= key.len() { assert_eq!(proof_index + 1, proof.len()); get_vec(&node, 16) } else { let new_expected_root = get_vec(&node, key[key_index] as usize); - Self::_verify_trie_proof( - new_expected_root, - key, - proof, - key_index + 1, - proof_index + 1, - ) + if !new_expected_root.is_empty() { + Self::_verify_trie_proof( + new_expected_root, + key, + proof, + key_index + 1, + proof_index + 1, + ) + } else { + // not included in proof + vec![] + } } } else { // Leaf or extension node @@ -211,19 +281,23 @@ impl EthProver { if head % 2 == 1 { path.push(path_u8[0] % 16); } - for val in path_u8.into_iter().skip(1) { + for val in path_u8.iter().skip(1) { path.push(val / 16); path.push(val % 16); } - assert_eq!(path.as_slice(), &key[key_index..key_index + path.len()]); if head >= 2 { // Leaf node assert_eq!(proof_index + 1, proof.len()); assert_eq!(key_index + path.len(), key.len()); - get_vec(&node, 1) + if path.as_slice() == &key[key_index..key_index + path.len()] { + get_vec(&node, 1) + } else { + vec![] + } } else { // Extension node + assert_eq!(path.as_slice(), &key[key_index..key_index + path.len()]); let new_expected_root = get_vec(&node, 1); Self::_verify_trie_proof( new_expected_root, @@ -253,3 +327,4 @@ admin_controlled::impl_admin_controlled!(EthProver, paused); #[cfg(test)] mod tests; +mod tests_storage_proof; diff --git a/contracts/near/eth-prover/src/test_data/storageProof.json b/contracts/near/eth-prover/src/test_data/storageProof.json new file mode 100644 index 00000000..3a3f7cf1 --- /dev/null +++ b/contracts/near/eth-prover/src/test_data/storageProof.json @@ -0,0 +1,25 @@ +{ + "header_data": "f90217a02feb03d38518e6941c0852c64a9cc06be8f0caed9357d0c45136395110ef4540a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794388ea662ef2c223ec0b047d41bf3c0f362142ad5a035630b01ab13a7f864f9c86f2a2d7ac497320594f92c5868e17063260beba833a083c4eeccb9dad0f16ca684785dd347c70e3c35573ebb38b6db5550d5e2eb2039a0f7679d652f72b54fd7c579a4738ae4d47c53213f266b5a2c2446a53386d17000b901005f04c0c31260591c81984881b480200041180c10098408d4d8840434c215211800660401002162160128100000c44bf4c0c20080061022544a185e0081242a000030000c4444811c600840285d0480624449060340cc6092080220a6000002050a0012428300a20010281180141408049801084502684280311012320608114002000a60802220aa29004800229100280001208004201140009140144462000502a0881100002810134340008b06402082004040224030080091406a288609021291480200194c49160440b14017660c4440018812086589620a005c0c0068839838ab040040a40754492158c0112414c892141012082040020a4a2102800040308381979a8401c9c38083972d598463ec1de09b4d616e69666f6c643a20636f696e62617365202d20676f65726c69a0fbd610d479f34d78d3c1ee5d525906e119babfa742966dfaabfba6ffc6499c3b8800000000000000000c", + "account_proof": [ + "f90211a08f3ec3607756301ad7628386a694edef062c32c0af69abdd8582733411fa6f4aa0e9ad940b31824dacc65417f2ae3aafe394949948f5805e645f6a5d7e7f0a5f28a078698a03fd4d2d738df437e1d39ac6dbe2b331474483083ecacd9270227adccea0b13728bf8c7541aac2e5f15840030e1a2a1d8546af961d2c5fe3cec61eb52136a041e20da27ab9f63b643aa550bd5494f42eb980e728499362807ca4a3d20bbd71a0544dfa7c44c6f4fc4318e6d42c8baa7db02467e31bdecb39a5b5c35dc9d75627a082e724d82008044c2339c3518899c58fa94397ec9b754a84ee6862ed980c506fa09858c9a0c3770fdcf0a95ee8657db7e5ff2813a5ee2b02bd2d550602ccf92ceca070c39b9018c1099644f6c8302f054b889f0d9c1c43561193af08c60514373a86a05147dd91ed6576bcb99c84b82e21267336fb5e7b6532bbc3bf3f153c44c7dd8ba0996167eb0ec29dcf3dc5564335936c857a16381f6cfc41e898ac427d5096f763a061cc346b3b193043469e1e63078e26bdffdc77fb9b7e03376a5d04a2e6a8bbd7a05ebe3f8899a1c9ae5c6f519c21bab07f380bc24eacd32d4915efa30990373347a0537e35aef2230294fb0150b5100ce1be4929181b2cbe16919ebdaf5455980a6ca0b11e4d342e93978e8ce006c6dafdc11a4626043ad6cd29c3a20fcaf7469e8846a0c2034f69510242f1af24e3cf53bdf8013959107de3863457d1759a0607cb42bd80", + "f90211a0cb604e92bfce9e89c58adb96d031edd6773b5ea79468c361c11bee3834ad38f7a0c3600619870fbddd0d3031662c20d4f07a7e8879715221e1cf2a27bac8252e84a0b42bfa4ca8a0f93155decb6566a0bfe41da0f0805f50bf22e582fbe09dab761da0f01302bc5b806c36dab88cf8fc3e720d2a9ea8b8c615cb2d6a61e516e7d568d5a0eb7a165077f85af7e1529e66bd052e211e3b0e591459a6b917b3a67b96e6c300a099b855be27efd92907fb6671240ad9b5a194aaaba80ec57f780f7f5132679279a076caa859434ddcc7513f2c40bbcdb0d3c92ef7f00f5575e5103683ed3f12d7aaa04b1f24333d5e1ff59bc1f0e68a4bffc09a109b59b281991e1def7d9a4d304683a01d24cc1c910469b1d5daf5c1ed9a0ff4b90467671498592b2b10bedb28594afca0f6c8564af03a1d6fa2203ad17d1c6cbbf608baed014de79c85c560149bac34a2a014a2351fb2913c7eead2607e6e821cb861a0acecce7e8d6b3eee285cd069b0f0a026385df23dbeafd3adff1c5537bc9b47716c3149c4d557cacaa31f67f8eb854fa0d759139f6c612b3ad3a4f1930a20f5bd1bcbd7e5595ccad018f066cde7cef5b7a052a24711316c1bccd8b72b59e1e0da3bd3254258651f42c468dbc06d33a5ece4a047f3cb14ec806f64d4bdeb04a60aef31966f50b2b191c9d5f697e01e5bc47654a0003d585567fb4aea17878d81f6c8e95e38218216e31263d85b01e387dcd12b6f80", + "f90211a07aa1913685063febef9253361de62ae7177722d980431ad433b6b2a2464d3c04a03df3486d470dc33c576fa0442eeac73b28032d892cee651cb5c8a714ba958f66a06482a869a326022a5fc40172cd9bbae5920b85a4138273da18eed05d2d75d97aa02a026697251d16fce297a1ee61d123da79085dc24ec356bff0f48f5708b04975a026cab39115772141ab3560790f604bf798b8d8744574ec842f57acba1bd3529fa0b78a5d4dcc2f37bbc0e8ba50727e7d08b143080aa2f93355f890bb7a615dae92a005b2270294d81e96ee9c7258f82a4541ec7a6a4eccf5de6fe54821d2e297d8f4a0d8d4d961a8e24b1e2886ee56762b1cd7f77e0ac76f9095636e9a008986b2028ba0eb02ba490b14fab24930230234056ed1cfaaf91fa4a57d9b9a7a178abe1cf3d2a0ba993d463bf76b12d4702be9696e0a1236ab7cd38e9fb590496151e4302ac7c1a08cbbd58b931fa2111148bed4e38c68e827b9a155c1eef0e63f43aa263cc10acea02e9bf22e9f981f53ed4856a0020449dc813cf444781b51fa3eabe13e0232f966a0a3622e12dacf5a9d1df00fe7e59326e1e96f1455492d72e39d5b6bf5f00eebb3a0a52a0b202c7059b5621fc10fd2921babe2c27934fae2d0409cbdc5b76d6b41a7a056aaef786ef7c8b3bda6d9ae2780478a1edc82b1f22e606bd3defe34a9cdeab5a0bf81e0ec8e926a748517a28422ff88e4a3f138a6f9175249c207f3178900bd9380", + "f90211a036e911e298a20d166922b7cb0563d3bceb8550b4adfa9fe08d8ca0a3c6d7ae86a0b9b9ac2b7a0a7c4d415787487e231900a10407acd166e92295ada52ea762c472a03a996e1b0ec3e2bddb98e7767e4666bcd40fa2273e0d3f52fa430f9a46938e7da015ea238cec5879fa069d204e93ff3c951f99d63407860df1882a2c59f325052da051fe87082dd2a2ac9e3610f6a85daba6468f7be31bc0301d3bafb579031848a2a01dfdfc623921a2948b00c4e0eab2d054293ca4869e09eaa79cd88ae492728788a036828736fa97fc9f14f0471b2cef6d6de6ed8e85f60581340e32314f55426d83a0e060a030a17644b352fd5d809fbffab09e4854e5cf79e907775571e72efdbe65a0b99a9776ae25aac78712102d448bca2ad2b0855d9485fd3e5aabc755a857ea1ba09774c71fdeb56de7925402760fc787d0f81a7e9373f017cbcdbba81b2c12df33a0af0f67963ad8a449e4ad7b613c58cb40ccf16786659ca716e9083b981138d2efa09bdc7b5850cd1050dddbc864a0d391312343fb542944cf0409f97ff2213b9f5da09792e17ea99e242aec9465df7f1b2b77e4c2ba916465d5b99702f4c6152bd82ea0dd32ae4192e7f1050eecd2573cc2c324fbbf6bf98cc61a6511920e8ab32091e5a00b4230a149ff4dca81cd7682536de8b1be2fa715bcafb967c35156fdc626dc3ba0b722557e1dc96d95b6af1aa5871ff90d300ce8632102e6b23e7e5d94101702ad80", + "f90211a096da0777dbb2f875bd357722a4387a78ae24efe13e04ed75f65b2c991247203fa0c0082d34071d1d65e712999126ac28e277b079d939821eaa755c4ef0fd2e5baaa0d088ecbd4b6bb84c6fa211bc81474c05c12ca2694faf0b1a2ecbde0bfe6fa3a2a00930aa5c1b70190cd2231cc759fec0c863a2e11bc89b1685d17da64f6bdc5e72a010b3d58569454bcfe1e6c9fad76e7034972f2abb6a3081b3c6b057c7d3151e2ca0868e866d17747182e462be130ceb1b0b3b5011db9f10f3fc8a00743c50497eaaa0aff0dd0b6a09d0e5659b96333f74fd56545addb56451693c1daeb2dbd7fe4470a07094c93901a37d76cc1ce99891c7419188b9dcabcd73075525a844084574c697a0cfd98d359eb86b3cf4531a0ddfa5d1ae5e5cdbed5f3a6a39daff489b2c862ed5a00f80e0d59b59c9e9e27aba7ac54d51f35750c45d45fb3d46c2cf31cb32a8e68aa02a5c88410b94694ae8882eda87af1c56616cd475b0b7feb2306da3959b322418a0609c5a3f274c1d31fa9b4d3c4492b4811c374e4d3d08ca5da98da012a489b273a0df38f9ab051dcee8d4f1a00376b01acecb3b7e9dbc40358c3d6d5958193e0329a0a274c42f4ccef6f20a413218137c6ec00ac7e3fa172f61a7c6487497fe427daba0961e5aac1726d9598c446db66425f7360f87fa5feb744adcfaf19e783cbba1a5a0b5c730c7587872bdc05bd0786f6fd897332d7d2642f953fa019ef58d4e5ec25e80", + "f90171a02a6e86561c33eacbb1826e9832a25f9f2841c281c9e6b6c18c95ce713dae6c868080a0807528ab397894421968b62bead3b9dd446bda7dc79a5b6ec5a29bd3f19a10c5a0072bce4e78f01cc370c9d92dd39bfcee6059d2e60a95135867991c59184d219980a0415df007b0977e95ba9b3d86b64bae14c02250b3da81f81bed47973f9e4a55b180a0e45736d96c006965b5cad5ec8008d31eb2c34e00c36f677b288701f76f43d627a055324754b7752c9149df27e03392c0598ec89f408040b15140a679f02e695017a04fc91448749dcab3e66cc8e45eb8d85a416fa3a33f8951128d17ca208bc3bb38a085a91d9af48d4f428da097b31c09b3f6b27d38212678a30ffd100364546a4d1ea0c60b5a89f1f89e97528a8b352ed55e5de2e7b963d73ba7de9e922c0ae964e816a048ff598a81a0114eb4afe71ef547cf6fecbb970310ef84049c9353d01c17103aa02bd17f471f58c435c937e6457a8a8a7ff7163263be197ec547241bc4791536b18080", + "f871808080808080a03f1587ebf71f19f47449b08f0960630ddbd60d045ea68ee7d89fb1c5682d215a8080808080a06e1618ec47442688101bd341cb8627739ecfd6fc1f793b69191dceeed18a19348080a05344081f911ad616b960a8f2841eb55f4936a97ec5dae614e726c8c0d51e0eff80", + "f8669d3e3757038b7fea6585ca2d0a3dacd72d84bf0c7b916f169cea0348681bb846f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75" + ], + "contract_address": "00763f30eEB0eEF506907e18f2a6ceC2DAb30Df8", + "expected_account_state": "f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75", + "storage_key_hash": "7bef74619139dab09d59cafa630682f8f30445738dcfb7147514aa27399ae2ee", + "storage_proof": [ + "f90211a07c66fa00b691dc5c5a66e43831b9922316c8740c3c5235e7aa705cebefbd478ca0bbf8c0df9d3837792180786e217cbcbfb6cb6c1ee790ec0dba83fc05248f2627a036b93382543cd1737ddc32dbc8cd4326da47551be33e3ca75af3ea98583edd93a0c024e6190b7ce41e20f27b5cd512ebf50d6c60a1467f3cad8acd46da3a4d3861a04134b666e4a8e3e28701e33bed36680ae025cc5f89f8d29457975148338017c4a0ad773b24d54d681b3d712d913c0bf515407818845922616360b9b5a381cd6299a076515bac0f65924da357aba2f6c312472a9ef94d1c459f2cd0380b84a91d46aca0a3501be4fecb38f8b48131e0f8f63d6be379248ffb7d6f27c6fab26314fd8396a0324a3b32bf60329775f3383b6c98e99683df56a0933516032147008d544af343a029f967b2d7ed040cda92ab4905f2976636a7bb16ba850679eca942e02d5b3458a024bdf35e1d8fd46cdee76420d508c722d7f47825356620c266094f6c66c67f7ea0426a496a8633ec2771fb15f58f646bf689eda39af535bcb9b316e9e601d1a342a00d9cd9aa39cdd4a91bcd4feb8c73db017dce78ec82ba6f14287775567615f247a02f3d28876d69fd8945b3fdeff87186bcb97c236ccefa3b6182507bc6e504606fa03b4078e843b8927c29753dfc91a44c246cb22ea3673a3bad8dab7c8f6b8ce226a061983eaffadbdc7d6e7a0f9d9f5c1c64f983a4a6724aaa2126a0b6c03c984f3280", + "f90191a015203b1feedefc3d12d0e185733524b4e2e5e8c2bdaf7abff246a1fed7ac95e3a0493a8147104d998868825ea6deb1322aae76680d265471262e1767a23bdd1a7fa09b406baa1899b648205b0dd527c9bbde6ada6e3b4fc531a35bd2537d8db733f7a0426dd1071bf0b88c5742facc7fea20e28e765ab489cfdbdd5153e15ea3e2b32ca03edd49ea3795ac11d96e7290b12c1040c1e483c90462e720c7f1d16f873dc751a0132bf193ced5ce4fdb9c534386d84cb653c802dc21694d7dd78863921fea2acda09c60c4557046c9882148d3470e3fde97e88e5d35bd25e1a3cc94384e66a7af1080a0dea2418bd69d857116931f580a50c80761622d7488224a24b233bd4eaaa3c3b7a0bacb8d28242096ba6306d1c073fdeacd9bb5df804e3426c3c945f37836db68e680a08da1ba6ee52fb112c7f4707b78e039c8b52647ac5ce1122f7191356387dc169380a0f00a423bf08615d7c08955ea29573cd2a20d6d19d483ce4116333353290eae0ea06dd01d697beb2d96a5a41e803708b1d2cafd5992d80f7bf6d796e6aead4989ed8080", + "e2a020ef74619139dab09d59cafa630682f8f30445738dcfb7147514aa27399ae2ee01" + ], + "expected_storage_value": "01", + "min_header_height": "", + "max_header_height": "", + "skip_bridge_call": true +} diff --git a/contracts/near/eth-prover/src/test_data/storageProofWithFalseValue.json b/contracts/near/eth-prover/src/test_data/storageProofWithFalseValue.json new file mode 100644 index 00000000..45b7d58d --- /dev/null +++ b/contracts/near/eth-prover/src/test_data/storageProofWithFalseValue.json @@ -0,0 +1,26 @@ +{ + "contract_address": "00763f30eeb0eef506907e18f2a6cec2dab30df8", + "storage_key": "ec1c15ab7b2411ecf8987e39d32202848ce2e7f3ad10aa6070664c6e9368916e", + "block_number": "8492954", + "header_data": "f90217a02feb03d38518e6941c0852c64a9cc06be8f0caed9357d0c45136395110ef4540a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794388ea662ef2c223ec0b047d41bf3c0f362142ad5a035630b01ab13a7f864f9c86f2a2d7ac497320594f92c5868e17063260beba833a083c4eeccb9dad0f16ca684785dd347c70e3c35573ebb38b6db5550d5e2eb2039a0f7679d652f72b54fd7c579a4738ae4d47c53213f266b5a2c2446a53386d17000b901005f04c0c31260591c81984881b480200041180c10098408d4d8840434c215211800660401002162160128100000c44bf4c0c20080061022544a185e0081242a000030000c4444811c600840285d0480624449060340cc6092080220a6000002050a0012428300a20010281180141408049801084502684280311012320608114002000a60802220aa29004800229100280001208004201140009140144462000502a0881100002810134340008b06402082004040224030080091406a288609021291480200194c49160440b14017660c4440018812086589620a005c0c0068839838ab040040a40754492158c0112414c892141012082040020a4a2102800040808381979a8401c9c38083972d598463ec1de09b4d616e69666f6c643a20636f696e62617365202d20676f65726c69a0fbd610d479f34d78d3c1ee5d525906e119babfa742966dfaabfba6ffc6499c3b8800000000000000000c", + "account_proof": [ + "f90211a08f3ec3607756301ad7628386a694edef062c32c0af69abdd8582733411fa6f4aa0e9ad940b31824dacc65417f2ae3aafe394949948f5805e645f6a5d7e7f0a5f28a078698a03fd4d2d738df437e1d39ac6dbe2b331474483083ecacd9270227adccea0b13728bf8c7541aac2e5f15840030e1a2a1d8546af961d2c5fe3cec61eb52136a041e20da27ab9f63b643aa550bd5494f42eb980e728499362807ca4a3d20bbd71a0544dfa7c44c6f4fc4318e6d42c8baa7db02467e31bdecb39a5b5c35dc9d75627a082e724d82008044c2339c3518899c58fa94397ec9b754a84ee6862ed980c506fa09858c9a0c3770fdcf0a95ee8657db7e5ff2813a5ee2b02bd2d550602ccf92ceca070c39b9018c1099644f6c8302f054b889f0d9c1c43561193af08c60514373a86a05147dd91ed6576bcb99c84b82e21267336fb5e7b6532bbc3bf3f153c44c7dd8ba0996167eb0ec29dcf3dc5564335936c857a16381f6cfc41e898ac427d5096f763a061cc346b3b193043469e1e63078e26bdffdc77fb9b7e03376a5d04a2e6a8bbd7a05ebe3f8899a1c9ae5c6f519c21bab07f380bc24eacd32d4915efa30990373347a0537e35aef2230294fb0150b5100ce1be4929181b2cbe16919ebdaf5455980a6ca0b11e4d342e93978e8ce006c6dafdc11a4626043ad6cd29c3a20fcaf7469e8846a0c2034f69510242f1af24e3cf53bdf8013959107de3863457d1759a0607cb42bd80", + "f90211a0cb604e92bfce9e89c58adb96d031edd6773b5ea79468c361c11bee3834ad38f7a0c3600619870fbddd0d3031662c20d4f07a7e8879715221e1cf2a27bac8252e84a0b42bfa4ca8a0f93155decb6566a0bfe41da0f0805f50bf22e582fbe09dab761da0f01302bc5b806c36dab88cf8fc3e720d2a9ea8b8c615cb2d6a61e516e7d568d5a0eb7a165077f85af7e1529e66bd052e211e3b0e591459a6b917b3a67b96e6c300a099b855be27efd92907fb6671240ad9b5a194aaaba80ec57f780f7f5132679279a076caa859434ddcc7513f2c40bbcdb0d3c92ef7f00f5575e5103683ed3f12d7aaa04b1f24333d5e1ff59bc1f0e68a4bffc09a109b59b281991e1def7d9a4d304683a01d24cc1c910469b1d5daf5c1ed9a0ff4b90467671498592b2b10bedb28594afca0f6c8564af03a1d6fa2203ad17d1c6cbbf608baed014de79c85c560149bac34a2a014a2351fb2913c7eead2607e6e821cb861a0acecce7e8d6b3eee285cd069b0f0a026385df23dbeafd3adff1c5537bc9b47716c3149c4d557cacaa31f67f8eb854fa0d759139f6c612b3ad3a4f1930a20f5bd1bcbd7e5595ccad018f066cde7cef5b7a052a24711316c1bccd8b72b59e1e0da3bd3254258651f42c468dbc06d33a5ece4a047f3cb14ec806f64d4bdeb04a60aef31966f50b2b191c9d5f697e01e5bc47654a0003d585567fb4aea17878d81f6c8e95e38218216e31263d85b01e387dcd12b6f80", + "f90211a07aa1913685063febef9253361de62ae7177722d980431ad433b6b2a2464d3c04a03df3486d470dc33c576fa0442eeac73b28032d892cee651cb5c8a714ba958f66a06482a869a326022a5fc40172cd9bbae5920b85a4138273da18eed05d2d75d97aa02a026697251d16fce297a1ee61d123da79085dc24ec356bff0f48f5708b04975a026cab39115772141ab3560790f604bf798b8d8744574ec842f57acba1bd3529fa0b78a5d4dcc2f37bbc0e8ba50727e7d08b143080aa2f93355f890bb7a615dae92a005b2270294d81e96ee9c7258f82a4541ec7a6a4eccf5de6fe54821d2e297d8f4a0d8d4d961a8e24b1e2886ee56762b1cd7f77e0ac76f9095636e9a008986b2028ba0eb02ba490b14fab24930230234056ed1cfaaf91fa4a57d9b9a7a178abe1cf3d2a0ba993d463bf76b12d4702be9696e0a1236ab7cd38e9fb590496151e4302ac7c1a08cbbd58b931fa2111148bed4e38c68e827b9a155c1eef0e63f43aa263cc10acea02e9bf22e9f981f53ed4856a0020449dc813cf444781b51fa3eabe13e0232f966a0a3622e12dacf5a9d1df00fe7e59326e1e96f1455492d72e39d5b6bf5f00eebb3a0a52a0b202c7059b5621fc10fd2921babe2c27934fae2d0409cbdc5b76d6b41a7a056aaef786ef7c8b3bda6d9ae2780478a1edc82b1f22e606bd3defe34a9cdeab5a0bf81e0ec8e926a748517a28422ff88e4a3f138a6f9175249c207f3178900bd9380", + "f90211a036e911e298a20d166922b7cb0563d3bceb8550b4adfa9fe08d8ca0a3c6d7ae86a0b9b9ac2b7a0a7c4d415787487e231900a10407acd166e92295ada52ea762c472a03a996e1b0ec3e2bddb98e7767e4666bcd40fa2273e0d3f52fa430f9a46938e7da015ea238cec5879fa069d204e93ff3c951f99d63407860df1882a2c59f325052da051fe87082dd2a2ac9e3610f6a85daba6468f7be31bc0301d3bafb579031848a2a01dfdfc623921a2948b00c4e0eab2d054293ca4869e09eaa79cd88ae492728788a036828736fa97fc9f14f0471b2cef6d6de6ed8e85f60581340e32314f55426d83a0e060a030a17644b352fd5d809fbffab09e4854e5cf79e907775571e72efdbe65a0b99a9776ae25aac78712102d448bca2ad2b0855d9485fd3e5aabc755a857ea1ba09774c71fdeb56de7925402760fc787d0f81a7e9373f017cbcdbba81b2c12df33a0af0f67963ad8a449e4ad7b613c58cb40ccf16786659ca716e9083b981138d2efa09bdc7b5850cd1050dddbc864a0d391312343fb542944cf0409f97ff2213b9f5da09792e17ea99e242aec9465df7f1b2b77e4c2ba916465d5b99702f4c6152bd82ea0dd32ae4192e7f1050eecd2573cc2c324fbbf6bf98cc61a6511920e8ab32091e5a00b4230a149ff4dca81cd7682536de8b1be2fa715bcafb967c35156fdc626dc3ba0b722557e1dc96d95b6af1aa5871ff90d300ce8632102e6b23e7e5d94101702ad80", + "f90211a096da0777dbb2f875bd357722a4387a78ae24efe13e04ed75f65b2c991247203fa0c0082d34071d1d65e712999126ac28e277b079d939821eaa755c4ef0fd2e5baaa0d088ecbd4b6bb84c6fa211bc81474c05c12ca2694faf0b1a2ecbde0bfe6fa3a2a00930aa5c1b70190cd2231cc759fec0c863a2e11bc89b1685d17da64f6bdc5e72a010b3d58569454bcfe1e6c9fad76e7034972f2abb6a3081b3c6b057c7d3151e2ca0868e866d17747182e462be130ceb1b0b3b5011db9f10f3fc8a00743c50497eaaa0aff0dd0b6a09d0e5659b96333f74fd56545addb56451693c1daeb2dbd7fe4470a07094c93901a37d76cc1ce99891c7419188b9dcabcd73075525a844084574c697a0cfd98d359eb86b3cf4531a0ddfa5d1ae5e5cdbed5f3a6a39daff489b2c862ed5a00f80e0d59b59c9e9e27aba7ac54d51f35750c45d45fb3d46c2cf31cb32a8e68aa02a5c88410b94694ae8882eda87af1c56616cd475b0b7feb2306da3959b322418a0609c5a3f274c1d31fa9b4d3c4492b4811c374e4d3d08ca5da98da012a489b273a0df38f9ab051dcee8d4f1a00376b01acecb3b7e9dbc40358c3d6d5958193e0329a0a274c42f4ccef6f20a413218137c6ec00ac7e3fa172f61a7c6487497fe427daba0961e5aac1726d9598c446db66425f7360f87fa5feb744adcfaf19e783cbba1a5a0b5c730c7587872bdc05bd0786f6fd897332d7d2642f953fa019ef58d4e5ec25e80", + "f90171a02a6e86561c33eacbb1826e9832a25f9f2841c281c9e6b6c18c95ce713dae6c868080a0807528ab397894421968b62bead3b9dd446bda7dc79a5b6ec5a29bd3f19a10c5a0072bce4e78f01cc370c9d92dd39bfcee6059d2e60a95135867991c59184d219980a0415df007b0977e95ba9b3d86b64bae14c02250b3da81f81bed47973f9e4a55b180a0e45736d96c006965b5cad5ec8008d31eb2c34e00c36f677b288701f76f43d627a055324754b7752c9149df27e03392c0598ec89f408040b15140a679f02e695017a04fc91448749dcab3e66cc8e45eb8d85a416fa3a33f8951128d17ca208bc3bb38a085a91d9af48d4f428da097b31c09b3f6b27d38212678a30ffd100364546a4d1ea0c60b5a89f1f89e97528a8b352ed55e5de2e7b963d73ba7de9e922c0ae964e816a048ff598a81a0114eb4afe71ef547cf6fecbb970310ef84049c9353d01c17103aa02bd17f471f58c435c937e6457a8a8a7ff7163263be197ec547241bc4791536b18080", + "f871808080808080a03f1587ebf71f19f47449b08f0960630ddbd60d045ea68ee7d89fb1c5682d215a8080808080a06e1618ec47442688101bd341cb8627739ecfd6fc1f793b69191dceeed18a19348080a05344081f911ad616b960a8f2841eb55f4936a97ec5dae614e726c8c0d51e0eff80", + "f8669d3e3757038b7fea6585ca2d0a3dacd72d84bf0c7b916f169cea0348681bb846f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75" + ], + "expected_account_state": "f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75", + "storage_key_hash": "15a27ce2832510d333b3cc710b4318654c0a1aae29a95174980029b9efdc451f", + "storage_proof": [ + "f90211a07c66fa00b691dc5c5a66e43831b9922316c8740c3c5235e7aa705cebefbd478ca0bbf8c0df9d3837792180786e217cbcbfb6cb6c1ee790ec0dba83fc05248f2627a036b93382543cd1737ddc32dbc8cd4326da47551be33e3ca75af3ea98583edd93a0c024e6190b7ce41e20f27b5cd512ebf50d6c60a1467f3cad8acd46da3a4d3861a04134b666e4a8e3e28701e33bed36680ae025cc5f89f8d29457975148338017c4a0ad773b24d54d681b3d712d913c0bf515407818845922616360b9b5a381cd6299a076515bac0f65924da357aba2f6c312472a9ef94d1c459f2cd0380b84a91d46aca0a3501be4fecb38f8b48131e0f8f63d6be379248ffb7d6f27c6fab26314fd8396a0324a3b32bf60329775f3383b6c98e99683df56a0933516032147008d544af343a029f967b2d7ed040cda92ab4905f2976636a7bb16ba850679eca942e02d5b3458a024bdf35e1d8fd46cdee76420d508c722d7f47825356620c266094f6c66c67f7ea0426a496a8633ec2771fb15f58f646bf689eda39af535bcb9b316e9e601d1a342a00d9cd9aa39cdd4a91bcd4feb8c73db017dce78ec82ba6f14287775567615f247a02f3d28876d69fd8945b3fdeff87186bcb97c236ccefa3b6182507bc6e504606fa03b4078e843b8927c29753dfc91a44c246cb22ea3673a3bad8dab7c8f6b8ce226a061983eaffadbdc7d6e7a0f9d9f5c1c64f983a4a6724aaa2126a0b6c03c984f3280", + "f901d1a0269a0b881e99b091fd1f85a9e44ee4daf1bfaa127412213b0ec1edacf2fcb4e0a0e7f129286b917093dd713ebf19c11b699dd3b7e2c8dd81b96da000d8929e6bd7a042e1e974e7e7b3829b6fd86c08ec48c92789a4c5b29aaba295ac47eb78da8979a0af69958bb871e61c3dab996738ae596fd6d8b0c6dd126361053ca23c67576aa6a0957f511c654ba45de24daa58d5069b8e854e1af4230f5e00ff80942f32179f9280a002cca7c62c8aaf39f3300a3694c5df5909d2365d68935dead512cec79b859546a0c150cdf6bf843bf02c321ad13d4b680a5ac6816a93b607b68b3d2944645cc573a0d44663526783865e11155d5490966374eaf24421c59522f6350769715d83f5f280a028d3420f6f3cfd2eff10d769032ec92a9ce6a26004a4b5e432577f7d218cb8eea095fcf2b12e8b70bb0c075d41576e00242769a18622ab1d936326fa053aeaa501a0ecf0ef75da3fd6cd5bc5a73049bbbdedd2fb0ccdb86bb07895d012b1b93354d5a02c8f51d330045fd36258abd5dc39dbc9ac14103ca91925bed4f55066f7d51830a024fff2a5c88286da53434ffeafc0962a9c2230a26c303850a04853096882be92a0a0eb992284319d09507645086aaf48f97428294e89aab782574993ed0543caef80" + ], + "expected_storage_value": "", + "min_header_height": "", + "max_header_height": "", + "skip_bridge_call": true +} \ No newline at end of file diff --git a/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountProof.json b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountProof.json new file mode 100644 index 00000000..6ac907c0 --- /dev/null +++ b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountProof.json @@ -0,0 +1,26 @@ +{ + "header_data": "f9021ba0695d799c7fbeda2651dd907991909e4ae68612851ce5398f2efc9506e69247cda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b64a30399f7f6b0c154c2e7af0a3ec7b0a5b131aa0eea9136af6ad8b65ad4c2184bbe6ab400f1ae214ed069d56d89639d7329d083ea063bbd1ab5c4e3922601b38d701e091e1ad3bc30a8e6e6a166728a6b5c9a61d31a0108126d36fb961af5e2d8359a6fced486e368965bbcba286205983dd06011aceb901000120011010a05000008a4800841200c0042918c020a44820008210109a02018c028d000000004001009a014c1085c000430019108410580008041204143226407a2001200470804449a0620802440121001124020cc07a040318018480a146110002528216204104220200806080086020c018a02000120020204818800000504604c1200000202100004003a188820624281c212102000901010d6051ec081002001a0000c8041010806460121600222104002188072024090001c60020088d2060c8ca500a1224161090040c82620c014060040608011048a1401010803004ba159d5800002802000300c241100296888004086a0030c015003b0212003004308380ffb58401c9c38083f281638463e31ac89f496c6c756d696e61746520446d6f63726174697a6520447374726962757465a086a600953aa2865ceb8c7a6348f388aaad93ca30c4a7dc718479ab45d98d8ea488000000000000000011", + "account_proof": [ + "f90211a08f3ec3607756301ad7628386a694edef062c32c0af69abdd8582733411fa6f4aa0e9ad940b31824dacc65417f2ae3aafe394949948f5805e645f6a5d7e7f0a5f28a078698a03fd4d2d738df437e1d39ac6dbe2b331474483083ecacd9270227adccea0b13728bf8c7541aac2e5f15840030e1a2a1d8546af961d2c5fe3cec61eb52136a041e20da27ab9f63b643aa550bd5494f42eb980e728499362807ca4a3d20bbd71a0544dfa7c44c6f4fc4318e6d42c8baa7db02467e31bdecb39a5b5c35dc9d75627a082e724d82008044c2339c3518899c58fa94397ec9b754a84ee6862ed980c506fa09858c9a0c3770fdcf0a95ee8657db7e5ff2813a5ee2b02bd2d550602ccf92ceca070c39b9018c1099644f6c8302f054b889f0d9c1c43561193af08c60514373a86a05147dd91ed6576bcb99c84b82e21267336fb5e7b6532bbc3bf3f153c44c7dd8ba0996167eb0ec29dcf3dc5564335936c857a16381f6cfc41e898ac427d5096f763a061cc346b3b193043469e1e63078e26bdffdc77fb9b7e03376a5d04a2e6a8bbd7a05ebe3f8899a1c9ae5c6f519c21bab07f380bc24eacd32d4915efa30990373347a0537e35aef2230294fb0150b5100ce1be4929181b2cbe16919ebdaf5455980a6ca0b11e4d342e93978e8ce006c6dafdc11a4626043ad6cd29c3a20fcaf7469e8846a0c2034f69510242f1af24e3cf53bdf8013959107de3863457d1759a0607cb42bd80", + "f90211a0cb604e92bfce9e89c58adb96d031edd6773b5ea79468c361c11bee3834ad38f7a0c3600619870fbddd0d3031662c20d4f07a7e8879715221e1cf2a27bac8252e84a0b42bfa4ca8a0f93155decb6566a0bfe41da0f0805f50bf22e582fbe09dab761da0f01302bc5b806c36dab88cf8fc3e720d2a9ea8b8c615cb2d6a61e516e7d568d5a0eb7a165077f85af7e1529e66bd052e211e3b0e591459a6b917b3a67b96e6c300a099b855be27efd92907fb6671240ad9b5a194aaaba80ec57f780f7f5132679279a076caa859434ddcc7513f2c40bbcdb0d3c92ef7f00f5575e5103683ed3f12d7aaa04b1f24333d5e1ff59bc1f0e68a4bffc09a109b59b281991e1def7d9a4d304683a01d24cc1c910469b1d5daf5c1ed9a0ff4b90467671498592b2b10bedb28594afca0f6c8564af03a1d6fa2203ad17d1c6cbbf608baed014de79c85c560149bac34a2a014a2351fb2913c7eead2607e6e821cb861a0acecce7e8d6b3eee285cd069b0f0a026385df23dbeafd3adff1c5537bc9b47716c3149c4d557cacaa31f67f8eb854fa0d759139f6c612b3ad3a4f1930a20f5bd1bcbd7e5595ccad018f066cde7cef5b7a052a24711316c1bccd8b72b59e1e0da3bd3254258651f42c468dbc06d33a5ece4a047f3cb14ec806f64d4bdeb04a60aef31966f50b2b191c9d5f697e01e5bc47654a0003d585567fb4aea17878d81f6c8e95e38218216e31263d85b01e387dcd12b6f80", + "f90211a07aa1913685063febef9253361de62ae7177722d980431ad433b6b2a2464d3c04a03df3486d470dc33c576fa0442eeac73b28032d892cee651cb5c8a714ba958f66a06482a869a326022a5fc40172cd9bbae5920b85a4138273da18eed05d2d75d97aa02a026697251d16fce297a1ee61d123da79085dc24ec356bff0f48f5708b04975a026cab39115772141ab3560790f604bf798b8d8744574ec842f57acba1bd3529fa0b78a5d4dcc2f37bbc0e8ba50727e7d08b143080aa2f93355f890bb7a615dae92a005b2270294d81e96ee9c7258f82a4541ec7a6a4eccf5de6fe54821d2e297d8f4a0d8d4d961a8e24b1e2886ee56762b1cd7f77e0ac76f9095636e9a008986b2028ba0eb02ba490b14fab24930230234056ed1cfaaf91fa4a57d9b9a7a178abe1cf3d2a0ba993d463bf76b12d4702be9696e0a1236ab7cd38e9fb590496151e4302ac7c1a08cbbd58b931fa2111148bed4e38c68e827b9a155c1eef0e63f43aa263cc10acea02e9bf22e9f981f53ed4856a0020449dc813cf444781b51fa3eabe13e0232f966a0a3622e12dacf5a9d1df00fe7e59326e1e96f1455492d72e39d5b6bf5f00eebb3a0a52a0b202c7059b5621fc10fd2921babe2c27934fae2d0409cbdc5b76d6b41a7a056aaef786ef7c8b3bda6d9ae2780478a1edc82b1f22e606bd3defe34a9cdeab5a0bf81e0ec8e926a748517a28422ff88e4a3f138a6f9175249c207f3178900bd9380", + "f90211a036e911e298a20d166922b7cb0563d3bceb8550b4adfa9fe08d8ca0a3c6d7ae86a0b9b9ac2b7a0a7c4d415787487e231900a10407acd166e92295ada52ea762c472a03a996e1b0ec3e2bddb98e7767e4666bcd40fa2273e0d3f52fa430f9a46938e7da015ea238cec5879fa069d204e93ff3c951f99d63407860df1882a2c59f325052da051fe87082dd2a2ac9e3610f6a85daba6468f7be31bc0301d3bafb579031848a2a01dfdfc623921a2948b00c4e0eab2d054293ca4869e09eaa79cd88ae492728788a036828736fa97fc9f14f0471b2cef6d6de6ed8e85f60581340e32314f55426d83a0e060a030a17644b352fd5d809fbffab09e4854e5cf79e907775571e72efdbe65a0b99a9776ae25aac78712102d448bca2ad2b0855d9485fd3e5aabc755a857ea1ba09774c71fdeb56de7925402760fc787d0f81a7e9373f017cbcdbba81b2c12df33a0af0f67963ad8a449e4ad7b613c58cb40ccf16786659ca716e9083b981138d2efa09bdc7b5850cd1050dddbc864a0d391312343fb542944cf0409f97ff2213b9f5da09792e17ea99e242aec9465df7f1b2b77e4c2ba916465d5b99702f4c6152bd82ea0dd32ae4192e7f1050eecd2573cc2c324fbbf6bf98cc61a6511920e8ab32091e5a00b4230a149ff4dca81cd7682536de8b1be2fa715bcafb967c35156fdc626dc3ba0b722557e1dc96d95b6af1aa5871ff90d300ce8632102e6b23e7e5d94101702ad80", + "f90211a096da0777dbb2f875bd357722a4387a78ae24efe13e04ed75f65b2c991247203fa0c0082d34071d1d65e712999126ac28e277b079d939821eaa755c4ef0fd2e5baaa0d088ecbd4b6bb84c6fa211bc81474c05c12ca2694faf0b1a2ecbde0bfe6fa3a2a00930aa5c1b70190cd2231cc759fec0c863a2e11bc89b1685d17da64f6bdc5e72a010b3d58569454bcfe1e6c9fad76e7034972f2abb6a3081b3c6b057c7d3151e2ca0868e866d17747182e462be130ceb1b0b3b5011db9f10f3fc8a00743c50497eaaa0aff0dd0b6a09d0e5659b96333f74fd56545addb56451693c1daeb2dbd7fe4470a07094c93901a37d76cc1ce99891c7419188b9dcabcd73075525a844084574c697a0cfd98d359eb86b3cf4531a0ddfa5d1ae5e5cdbed5f3a6a39daff489b2c862ed5a00f80e0d59b59c9e9e27aba7ac54d51f35750c45d45fb3d46c2cf31cb32a8e68aa02a5c88410b94694ae8882eda87af1c56616cd475b0b7feb2306da3959b322418a0609c5a3f274c1d31fa9b4d3c4492b4811c374e4d3d08ca5da98da012a489b273a0df38f9ab051dcee8d4f1a00376b01acecb3b7e9dbc40358c3d6d5958193e0329a0a274c42f4ccef6f20a413218137c6ec00ac7e3fa172f61a7c6487497fe427daba0961e5aac1726d9598c446db66425f7360f87fa5feb744adcfaf19e783cbba1a5a0b5c730c7587872bdc05bd0786f6fd897332d7d2642f953fa019ef58d4e5ec25e80", + "f90171a02a6e86561c33eacbb1826e9832a25f9f2841c281c9e6b6c18c95ce713dae6c868080a0807528ab397894421968b62bead3b9dd446bda7dc79a5b6ec5a29bd3f19a10c5a0072bce4e78f01cc370c9d92dd39bfcee6059d2e60a95135867991c59184d219980a0415df007b0977e95ba9b3d86b64bae14c02250b3da81f81bed47973f9e4a55b180a0e45736d96c006965b5cad5ec8008d31eb2c34e00c36f677b288701f76f43d627a055324754b7752c9149df27e03392c0598ec89f408040b15140a679f02e695017a04fc91448749dcab3e66cc8e45eb8d85a416fa3a33f8951128d17ca208bc3bb38a085a91d9af48d4f428da097b31c09b3f6b27d38212678a30ffd100364546a4d1ea0c60b5a89f1f89e97528a8b352ed55e5de2e7b963d73ba7de9e922c0ae964e816a048ff598a81a0114eb4afe71ef547cf6fecbb970310ef84049c9353d01c17103aa02bd17f471f58c435c937e6457a8a8a7ff7163263be197ec547241bc4791536b18080", + "f871808080808080a03f1587ebf71f19f47449b08f0960630ddbd60d045ea68ee7d89fb1c5682d215a8080808080a06e1618ec47442688101bd341cb8627739ecfd6fc1f793b69191dceeed18a19348080a05344081f911ad616b960a8f2841eb55f4936a97ec5dae614e726c8c0d51e0eff80", + "f8669d3e3757038b7fea6585ca2d0a3dacd72d84bf0c7b916f169cea0348681bb846f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75" + ], + "contract_address": "00763f30eEB0eEF506907e18f2a6ceC2DAb30Df8", + "expected_account_state": "f8440180a09dc8b927bc1f203931c70cc3850246046859c40e0044964753b28ff41285b75da0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75", + "storage_key_hash": "1c8ba9af7041ec3098c4d818db9972f67827520c1db7d022f6c3041b6f40ecc3", + "storage_proof": [ + "f90211a0786e2b7a3a24cfafe31c1cac9b0cc4b57cfb9e27264b9aeb8ba52d48181fd013a0bbf8c0df9d3837792180786e217cbcbfb6cb6c1ee790ec0dba83fc05248f2627a060d5477cb7243063a66f6533e342632aea890e13cf45c0144ad7f8254bb74242a02dd5604620fcf3990474b172d1bb5653bf7bfc9ee1d269e765da3f7a91ac2ec3a04134b666e4a8e3e28701e33bed36680ae025cc5f89f8d29457975148338017c4a07bf7ed874ff02f5938267592e1a3cfca0ca8d7d4b6fccd617b815fad456c2c53a076515bac0f65924da357aba2f6c312472a9ef94d1c459f2cd0380b84a91d46aca0f49dd3a32c4adb7b6f02188b32a7823c79bb5b2ed1f3cdf4da11c36304ae4e25a05ba06e342a112365ced395b4bf830d148ad1e6a787912a9a603293a4e079e3f5a029f967b2d7ed040cda92ab4905f2976636a7bb16ba850679eca942e02d5b3458a024bdf35e1d8fd46cdee76420d508c722d7f47825356620c266094f6c66c67f7ea070a8abf4345f7148bbcbd0f443fe00cfed0a17ab828b7051cb3ede4bee4499b1a00d9cd9aa39cdd4a91bcd4feb8c73db017dce78ec82ba6f14287775567615f247a02f3d28876d69fd8945b3fdeff87186bcb97c236ccefa3b6182507bc6e504606fa03b4078e843b8927c29753dfc91a44c246cb22ea3673a3bad8dab7c8f6b8ce226a061983eaffadbdc7d6e7a0f9d9f5c1c64f983a4a6724aaa2126a0b6c03c984f3280", + "f901d1a0269a0b881e99b091fd1f85a9e44ee4daf1bfaa127412213b0ec1edacf2fcb4e0a0e7f129286b917093dd713ebf19c11b699dd3b7e2c8dd81b96da000d8929e6bd7a042e1e974e7e7b3829b6fd86c08ec48c92789a4c5b29aaba295ac47eb78da8979a0af69958bb871e61c3dab996738ae596fd6d8b0c6dd126361053ca23c67576aa6a0957f511c654ba45de24daa58d5069b8e854e1af4230f5e00ff80942f32179f9280a002cca7c62c8aaf39f3300a3694c5df5909d2365d68935dead512cec79b859546a0c150cdf6bf843bf02c321ad13d4b680a5ac6816a93b607b68b3d2944645cc573a0d44663526783865e11155d5490966374eaf24421c59522f6350769715d83f5f280a028d3420f6f3cfd2eff10d769032ec92a9ce6a26004a4b5e432577f7d218cb8eea095fcf2b12e8b70bb0c075d41576e00242769a18622ab1d936326fa053aeaa501a0ecf0ef75da3fd6cd5bc5a73049bbbdedd2fb0ccdb86bb07895d012b1b93354d5a02c8f51d330045fd36258abd5dc39dbc9ac14103ca91925bed4f55066f7d51830a024fff2a5c88286da53434ffeafc0962a9c2230a26c303850a04853096882be92a0a0eb992284319d09507645086aaf48f97428294e89aab782574993ed0543caef80", + "f851808080808080a05a173679dbc21d5c5b16c40e4d0fdd5ec92f602c2db2adbe71c9d4b2aedb585480a04cd868f531723c2438dce2df71b16e2d4d6f49299867484a662073b40aaac5ca8080808080808080", + "e19f3ba9af7041ec3098c4d818db9972f67827520c1db7d022f6c3041b6f40ecc301" + ], + "expected_storage_value": "01", + "min_header_height": "", + "max_header_height": "", + "skip_bridge_call": true +} diff --git a/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountState.json b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountState.json new file mode 100644 index 00000000..c02a8710 --- /dev/null +++ b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectAccountState.json @@ -0,0 +1,26 @@ +{ + "header_data": "f901ffa0fff0b83c7645333f372718f1c53b7275d83f89ae974940820a39ac43b9e88a11a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f36f155486299ecaff2d4f5160ed5114c1f66000a0611e6617bd56b23286a317a8cfe78274a76f9624c207ed9f567f12db53026cb5a0f8646c32c2cfb4064bc2fc092a73adf7fa8f05fe62dec656a550d09ec1b8a898a05d94e5c456f59be6084dc832d24de0273ceba6c841308d1908169a043ac6baa4b9010015a42a6355a47214801c1c81ac5150030184014530904810240b0054e81b750a00eea0040008415010180084206402d4410900a0160000f098085c041124a202103041109462923cd7a4210b020630260004831a40c0602409411184000212058820336a2200010000001080c413080009010c40614862983802923088102107268882692a90e80620424822678040210010100860151208240118f3956204050a2c895371808a101203140032034260e0f114027206246000a1c04a2132a922e66088322108090a110810a0000be40086a8101030144dd05003506248146614ba11280ba0201102780011e1814102058801000900502202024304301a39660230838182ac8401c9c3808401052eab8463eadb3080a00a58a400a5f524d8df4b7140cc35bf2b4fe9dfc2a12a1cf52f526d627aac3db3880000000000000000820357", + "account_proof": [ + "f90211a09f2010af3cc9c6d2ff727c81f7524ae503f90284e5cb802f6fd9358c163e198ca08548267c53e930b5a18b2364c5cb3aff3c14870ac2275eb6f8a54388a58b5567a0f71f37002acc0a2eaa7b540cf6d14eec6d1a0c0e05fa47294c17f1b313b5c8cfa03b6953e75441ca9a3a1cf4cfd1143357023b305698259217d69b2fc2ce60858ea07c2d0d986052f90200e3281f14f40dceb8a85547a681525a798829b2ab0818ffa0f185ab5dae7b1d6e7c2aa2bb4dcc03392baa732d9184da8fc33ca551616356faa02ccea0afc5e45712ee6485a78cd2912535198470651a554e94b453aad8cbd60da05be29334f4504f5f47f44ce970827664704d584a526a5683e0f26e5cd5041a25a0d81ab119c255376982d1f8c955bb0841386be0105e1ef6680b601c004ed8d415a07aa76afcca71c9e2230d4bf53bf7f2e31d350ee3c78e96a798174d4f55e584ffa0670b913a9ac9a6dbd871a40279b57953673946e86ccd05d95633ebc5bbe5b188a0f8a4eac59ac78af02c47e6102f7193e2643d3358bbd79ffd2f1a6d0f0f0c165ea0758266147704772c0a26c73c2b15f6fc1333d9f06d61f0a98b11911cdc0e6de4a0dba0b5a5c9cebe4a50b996e436845d0de0f703df346711d836b00e25f6d86bd4a088ca6ad3f65bd25c9c1b3fc1adba9805150dea0469555c2e2005c2e57fcd3003a0644ac23638cfd5d2bf7be1a18245245b9491bbb07b4ad041b7779a7bdb5025e580", + "f90211a0a1f7aac2995a5ed36bebaed5271dc61ac2388ee098dda2dd3bfce1ece0bfa829a0a8ae801f8cb8734df7b4826aab3c0f8daccc64effcf9497872c3bfcf9963c8fca037bd182a4739e2c71e97316b3cbee78173bd35bb8b3f60ef84e20c81cccd6b8ea0d3e5a8fdf0b394b753d56a0a07e60cafeed93ae896e508a2834657f4cfaf4e74a0bf5811b7827b6887a2afe150e9f84f01a9eb35eefbcacbce534e6cb574175632a0493c6adedeb34305ca3c8b0be070789f2b3ad5eb05a4faa3863c4dc335fb4189a09ed60b16f83213a33aeb53a77c14a243888e20238ab51bf364fcc1ffe6966153a0c6b9a7d02f4041391b21c85e9310cab8fa08e0c02ce7ad1bb9545e81d0db7670a0866b77b81c0a64e84035db172b1a479292b2d190228001ae276784fee258c607a0b426825472c8c661b05879c3757b958901b39ed09265724b17361cd0f15f74c3a061170e214ffcb0f8a2a17b8a64d6f4e588b0f9d64b1b78a8f860ccacd3922369a04de8f9edb1ad322a3568ac471831fbf175efd1c9b2b02b5d9d10a184d54b73c1a03a70896331cef4434e0a395595fe548cedb5c71529421a19359e42ca962429a5a09ffb6c4bedd8d72d73d3a0c87f71f2a41e9955df5fb5e483aa6c4a2ee8d45b26a0db4b26c625be8cc1aa9d17456139c8d5143c445ef877769050222b2fac5f929ba0c3afc1c5f13607cf561a073a6f341227a90376e87e48c54164eef19c51c5cd2780", + "f90211a0a728578ddfbd4e3fa913f10f73f4464fc95a3277ac3783078d07534872f60c8ca0bc6c1301ed405c0ce52e31bd667abe0d559b71d5c6ee515b4e977f4c1b7d2de5a042cab541119e6e1b305fc51bc3a9099a7ed323bcaab1b103f4a09c5fd1a5ffa9a0f29d1a4e35bb3cf9f17a3033f26bab8ac56e6abaf2df83d0878e9d45e4dbb262a08373516dca2167359f81c6086d086f9f6b647f0a5323a670271e8fbf4b15cd47a0acdfebaf24830b92a3deb6e44422afeef55efce4d0bbf0913216d9156459e41aa06bf7ec716d7579c4b784db41b0f3549c1aa033956968642836c37e0348a09bbfa010ffffce72a9f81a7a5491087febd53178879cfe59fa7645b9314ce07923f496a0a3a18069f84b16289144769be298aeb15cb78746012ef3c9893113109ea26163a0c872f57c7064d3ecf1e0dce8b7f2d31e151fab8c1048bce5e021fb5cc25e222ca0441bb13319c322f67c4cea9fe9e7ff4c81061b5b80cbe37254deffae3bfb3163a03b2bde0648f7489fea985da3a45c2d7b404d0dcd70eb62097dd0d76860acaf3fa046e54b2e41afe0594e4b32bb68f890eb2be0c522177a0098d9e209cd61fa52f9a079d38c8ffd67624fcee4d1307761bebe7f869d3f4046e99daf27bcf303a5174ca07a2c3cdbc8e4a22aa5ad600411810e4025ef84b79f132a4b75a9406f1cf60926a0529c91b9cc16adf0bcb72bac2ba86dd5e035e3e689ace0d4809ee6552a64119480", + "f90211a0cd42164ae552d0d13db9f9cf38653c224a34d604a9db71748e312248b7a3af38a0184e6eb3ea4728266438c0b7f687f62a96d6daa740711a678e1e0edf33361489a03c764463c2172ab6dbec2c495c2cf13796512cb3f369a10dbc3684bbd5fb4018a015ea238cec5879fa069d204e93ff3c951f99d63407860df1882a2c59f325052da0ab5c18775aa03057f7ade4b6bffd094cb5112bd47e80d576ac2415eb33ae9654a01dfdfc623921a2948b00c4e0eab2d054293ca4869e09eaa79cd88ae492728788a0f4e962298ff3966fd3cfeccc21a74d0b1a8e39d14dfc3a68d1f941e57ad917cba01fabe2077c23f5bc163eee76ff628c03d6d45b94445bd21df4a9b8c647b5a10da0ef92e8b81eea7608968d2272119cb6be77030b85de6cceca3b9d4acde44c1a2ea0d2c9d3bc2a51638936232907f2daa0a23325421ca4efc57248674081889f8832a07e75144a554963f4cb7088c4809cc8d14aab35fcfa4fe2e023ae82e45b65929ba01d11f73ff1b0c64899fde18ad85b08bbb7b3d7a46cda25a9c8668665e8bdb706a0be6a24e94b1689142dda1b4ef3750ff486f990d4610b1878b760404a468e59a7a02690ac779ae564dce3567fab4ca03c7b5f56da23d882b68be067dafb0829fc08a00b4230a149ff4dca81cd7682536de8b1be2fa715bcafb967c35156fdc626dc3ba0d1fea826722117b8482d59658586a2802577a9d9114d5d8791b93364e998732d80", + "f90211a096da0777dbb2f875bd357722a4387a78ae24efe13e04ed75f65b2c991247203fa0c0082d34071d1d65e712999126ac28e277b079d939821eaa755c4ef0fd2e5baaa0d088ecbd4b6bb84c6fa211bc81474c05c12ca2694faf0b1a2ecbde0bfe6fa3a2a00930aa5c1b70190cd2231cc759fec0c863a2e11bc89b1685d17da64f6bdc5e72a010b3d58569454bcfe1e6c9fad76e7034972f2abb6a3081b3c6b057c7d3151e2ca0868e866d17747182e462be130ceb1b0b3b5011db9f10f3fc8a00743c50497eaaa0aff0dd0b6a09d0e5659b96333f74fd56545addb56451693c1daeb2dbd7fe4470a07094c93901a37d76cc1ce99891c7419188b9dcabcd73075525a844084574c697a0cfd98d359eb86b3cf4531a0ddfa5d1ae5e5cdbed5f3a6a39daff489b2c862ed5a00f80e0d59b59c9e9e27aba7ac54d51f35750c45d45fb3d46c2cf31cb32a8e68aa02a5c88410b94694ae8882eda87af1c56616cd475b0b7feb2306da3959b322418a0609c5a3f274c1d31fa9b4d3c4492b4811c374e4d3d08ca5da98da012a489b273a0e57f95cc7d072bdd273c4bf504fbcabe2b356236151e53bd53af301fe794e34ba0a274c42f4ccef6f20a413218137c6ec00ac7e3fa172f61a7c6487497fe427daba0961e5aac1726d9598c446db66425f7360f87fa5feb744adcfaf19e783cbba1a5a0b5c730c7587872bdc05bd0786f6fd897332d7d2642f953fa019ef58d4e5ec25e80", + "f90171a02a6e86561c33eacbb1826e9832a25f9f2841c281c9e6b6c18c95ce713dae6c868080a0807528ab397894421968b62bead3b9dd446bda7dc79a5b6ec5a29bd3f19a10c5a0072bce4e78f01cc370c9d92dd39bfcee6059d2e60a95135867991c59184d219980a0415df007b0977e95ba9b3d86b64bae14c02250b3da81f81bed47973f9e4a55b180a0e45736d96c006965b5cad5ec8008d31eb2c34e00c36f677b288701f76f43d627a055324754b7752c9149df27e03392c0598ec89f408040b15140a679f02e695017a04fc91448749dcab3e66cc8e45eb8d85a416fa3a33f8951128d17ca208bc3bb38a085a91d9af48d4f428da097b31c09b3f6b27d38212678a30ffd100364546a4d1ea0c60b5a89f1f89e97528a8b352ed55e5de2e7b963d73ba7de9e922c0ae964e816a048ff598a81a0114eb4afe71ef547cf6fecbb970310ef84049c9353d01c17103aa08d1d7f774f6570c92fd5d70617266469dade16fd9e5cad87af44c15fa34d075a8080", + "f871808080808080a03f1587ebf71f19f47449b08f0960630ddbd60d045ea68ee7d89fb1c5682d215a8080808080a060abf60878dd69cb6e3a7bd92aeca7514df19f822555e528101da922493f6a758080a05344081f911ad616b960a8f2841eb55f4936a97ec5dae614e726c8c0d51e0eff80", + "f8669d3e3757038b7fea6585ca2d0a3dacd72d84bf0c7b916f169cea0348681bb846f8440180a0e4acc7f2f495a3bd919d8b5c2b2ab1446a293d16b7981141cf6f3594c26554b6a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75" + ], + "contract_address": "00763f30eEB0eEF506907e18f2a6ceC2DAb30Df8", + "expected_account_state": "f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75", + "storage_key_hash": "0f9e5fde3c4a1600408ce3ebbd6a720b7491c663bef3fedcf7835dd6863fd34b", + "storage_proof": [ + "f90211a07c66fa00b691dc5c5a66e43831b9922316c8740c3c5235e7aa705cebefbd478ca0bbf8c0df9d3837792180786e217cbcbfb6cb6c1ee790ec0dba83fc05248f2627a036b93382543cd1737ddc32dbc8cd4326da47551be33e3ca75af3ea98583edd93a0c024e6190b7ce41e20f27b5cd512ebf50d6c60a1467f3cad8acd46da3a4d3861a04134b666e4a8e3e28701e33bed36680ae025cc5f89f8d29457975148338017c4a0ad773b24d54d681b3d712d913c0bf515407818845922616360b9b5a381cd6299a076515bac0f65924da357aba2f6c312472a9ef94d1c459f2cd0380b84a91d46aca0f49dd3a32c4adb7b6f02188b32a7823c79bb5b2ed1f3cdf4da11c36304ae4e25a0324a3b32bf60329775f3383b6c98e99683df56a0933516032147008d544af343a029f967b2d7ed040cda92ab4905f2976636a7bb16ba850679eca942e02d5b3458a024bdf35e1d8fd46cdee76420d508c722d7f47825356620c266094f6c66c67f7ea0426a496a8633ec2771fb15f58f646bf689eda39af535bcb9b316e9e601d1a342a00d9cd9aa39cdd4a91bcd4feb8c73db017dce78ec82ba6f14287775567615f247a02f3d28876d69fd8945b3fdeff87186bcb97c236ccefa3b6182507bc6e504606fa03b4078e843b8927c29753dfc91a44c246cb22ea3673a3bad8dab7c8f6b8ce226a061983eaffadbdc7d6e7a0f9d9f5c1c64f983a4a6724aaa2126a0b6c03c984f3280", + "f9015180a01061b943f8579b3fd877fbb9f5a796b40bad0e3c4cf6543287843cbc393e928da082da424f81780a75ef25a30590a9e5ec85637cb96dd708eab214029bb7324363a0809ffaa235bdd55f80127144f1918251205617992df98a93e871be18a481aaba80a0e30a57c48730f365adf774e3306ae2fd27abc854dc628b29c3b8873818e22adaa0aa6b491b53c837a2d87a4cf0e7995ce65030583199b48597cde9481d64e46deca0dbb86b57d06b8e9098b6db1d33c0ea963bf767f36e0e30559e64df69ab23d80180a0abaa7983dc34ba047258543b43cb5791d9fc73820c5103feaff960c35e2d2b4680a026f6892a3438aac58a8dfb5eeeefc1dc391e520eb1a401cc2a3a16ff617e3a578080a0d77dc10b28e64185d1d0306fb29003c89c300ed9041b476c08074161510b3670a0b36ced44fa006dd920a4f0281d389ecee50f66bd99f964ac50934065c5c873d680", + "f871a003c2a7f927a157d07815fdd586453a7f82223b912344dcb85fdb717b268cddb98080808080808080a0ad44120a824ee96076f8c53f155604f1e778eb0c678303eb680b69e3b72d7b9f8080a0dd6eb7d9c298eea97e0c3779437f0247e76237d430aeee5c9676830ed4e19e7480808080", + "e19f3e5fde3c4a1600408ce3ebbd6a720b7491c663bef3fedcf7835dd6863fd34b01" + ], + "expected_storage_value": "01", + "min_header_height": "", + "max_header_height": "", + "skip_bridge_call": true +} diff --git a/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectHeaderExceptStateRoot.json b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectHeaderExceptStateRoot.json new file mode 100644 index 00000000..1b5a9cd1 --- /dev/null +++ b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectHeaderExceptStateRoot.json @@ -0,0 +1,26 @@ +{ + "header_data": "f90217a02feb03d38518e6941c0852c64a9cc06be8f0caed9357d0c45136395110ef4540a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794388ea662ef2c223ec0b047d41bf3c0f362142ad5a0611e6617bd56b23286a317a8cfe78274a76f9624c207ed9f567f12db53026cb5a083c4eeccb9dad0f16ca684785dd347c70e3c35573ebb38b6db5550d5e2eb2039a0f7679d652f72b54fd7c579a4738ae4d47c53213f266b5a2c2446a53386d17000b901005f04c0c31260591c81984881b480200041180c10098408d4d8840434c215211800660401002162160128100000c44bf4c0c20080061022544a185e0081242a000030000c4444811c600840285d0480624449060340cc6092080220a6000002050a0012428300a20010281180141408049801084502684280311012320608114002000a60802220aa29004800229100280001208004201140009140144462000502a0881100002810134340008b06402082004040224030080091406a288609021291480200194c49160440b14017660c4440018812086589620a005c0c0068839838ab040040a40754492158c0112414c892141012082040020a4a2102800040308381979a8401c9c38083972d598463ec1de09b4d616e69666f6c643a20636f696e62617365202d20676f65726c69a0fbd610d479f34d78d3c1ee5d525906e119babfa742966dfaabfba6ffc6499c3b8800000000000000000c", + "account_proof": [ + "f90211a09f2010af3cc9c6d2ff727c81f7524ae503f90284e5cb802f6fd9358c163e198ca08548267c53e930b5a18b2364c5cb3aff3c14870ac2275eb6f8a54388a58b5567a0f71f37002acc0a2eaa7b540cf6d14eec6d1a0c0e05fa47294c17f1b313b5c8cfa03b6953e75441ca9a3a1cf4cfd1143357023b305698259217d69b2fc2ce60858ea07c2d0d986052f90200e3281f14f40dceb8a85547a681525a798829b2ab0818ffa0f185ab5dae7b1d6e7c2aa2bb4dcc03392baa732d9184da8fc33ca551616356faa02ccea0afc5e45712ee6485a78cd2912535198470651a554e94b453aad8cbd60da05be29334f4504f5f47f44ce970827664704d584a526a5683e0f26e5cd5041a25a0d81ab119c255376982d1f8c955bb0841386be0105e1ef6680b601c004ed8d415a07aa76afcca71c9e2230d4bf53bf7f2e31d350ee3c78e96a798174d4f55e584ffa0670b913a9ac9a6dbd871a40279b57953673946e86ccd05d95633ebc5bbe5b188a0f8a4eac59ac78af02c47e6102f7193e2643d3358bbd79ffd2f1a6d0f0f0c165ea0758266147704772c0a26c73c2b15f6fc1333d9f06d61f0a98b11911cdc0e6de4a0dba0b5a5c9cebe4a50b996e436845d0de0f703df346711d836b00e25f6d86bd4a088ca6ad3f65bd25c9c1b3fc1adba9805150dea0469555c2e2005c2e57fcd3003a0644ac23638cfd5d2bf7be1a18245245b9491bbb07b4ad041b7779a7bdb5025e580", + "f90211a0a1f7aac2995a5ed36bebaed5271dc61ac2388ee098dda2dd3bfce1ece0bfa829a0a8ae801f8cb8734df7b4826aab3c0f8daccc64effcf9497872c3bfcf9963c8fca037bd182a4739e2c71e97316b3cbee78173bd35bb8b3f60ef84e20c81cccd6b8ea0d3e5a8fdf0b394b753d56a0a07e60cafeed93ae896e508a2834657f4cfaf4e74a0bf5811b7827b6887a2afe150e9f84f01a9eb35eefbcacbce534e6cb574175632a0493c6adedeb34305ca3c8b0be070789f2b3ad5eb05a4faa3863c4dc335fb4189a09ed60b16f83213a33aeb53a77c14a243888e20238ab51bf364fcc1ffe6966153a0c6b9a7d02f4041391b21c85e9310cab8fa08e0c02ce7ad1bb9545e81d0db7670a0866b77b81c0a64e84035db172b1a479292b2d190228001ae276784fee258c607a0b426825472c8c661b05879c3757b958901b39ed09265724b17361cd0f15f74c3a061170e214ffcb0f8a2a17b8a64d6f4e588b0f9d64b1b78a8f860ccacd3922369a04de8f9edb1ad322a3568ac471831fbf175efd1c9b2b02b5d9d10a184d54b73c1a03a70896331cef4434e0a395595fe548cedb5c71529421a19359e42ca962429a5a09ffb6c4bedd8d72d73d3a0c87f71f2a41e9955df5fb5e483aa6c4a2ee8d45b26a0db4b26c625be8cc1aa9d17456139c8d5143c445ef877769050222b2fac5f929ba0c3afc1c5f13607cf561a073a6f341227a90376e87e48c54164eef19c51c5cd2780", + "f90211a0a728578ddfbd4e3fa913f10f73f4464fc95a3277ac3783078d07534872f60c8ca0bc6c1301ed405c0ce52e31bd667abe0d559b71d5c6ee515b4e977f4c1b7d2de5a042cab541119e6e1b305fc51bc3a9099a7ed323bcaab1b103f4a09c5fd1a5ffa9a0f29d1a4e35bb3cf9f17a3033f26bab8ac56e6abaf2df83d0878e9d45e4dbb262a08373516dca2167359f81c6086d086f9f6b647f0a5323a670271e8fbf4b15cd47a0acdfebaf24830b92a3deb6e44422afeef55efce4d0bbf0913216d9156459e41aa06bf7ec716d7579c4b784db41b0f3549c1aa033956968642836c37e0348a09bbfa010ffffce72a9f81a7a5491087febd53178879cfe59fa7645b9314ce07923f496a0a3a18069f84b16289144769be298aeb15cb78746012ef3c9893113109ea26163a0c872f57c7064d3ecf1e0dce8b7f2d31e151fab8c1048bce5e021fb5cc25e222ca0441bb13319c322f67c4cea9fe9e7ff4c81061b5b80cbe37254deffae3bfb3163a03b2bde0648f7489fea985da3a45c2d7b404d0dcd70eb62097dd0d76860acaf3fa046e54b2e41afe0594e4b32bb68f890eb2be0c522177a0098d9e209cd61fa52f9a079d38c8ffd67624fcee4d1307761bebe7f869d3f4046e99daf27bcf303a5174ca07a2c3cdbc8e4a22aa5ad600411810e4025ef84b79f132a4b75a9406f1cf60926a0529c91b9cc16adf0bcb72bac2ba86dd5e035e3e689ace0d4809ee6552a64119480", + "f90211a0cd42164ae552d0d13db9f9cf38653c224a34d604a9db71748e312248b7a3af38a0184e6eb3ea4728266438c0b7f687f62a96d6daa740711a678e1e0edf33361489a03c764463c2172ab6dbec2c495c2cf13796512cb3f369a10dbc3684bbd5fb4018a015ea238cec5879fa069d204e93ff3c951f99d63407860df1882a2c59f325052da0ab5c18775aa03057f7ade4b6bffd094cb5112bd47e80d576ac2415eb33ae9654a01dfdfc623921a2948b00c4e0eab2d054293ca4869e09eaa79cd88ae492728788a0f4e962298ff3966fd3cfeccc21a74d0b1a8e39d14dfc3a68d1f941e57ad917cba01fabe2077c23f5bc163eee76ff628c03d6d45b94445bd21df4a9b8c647b5a10da0ef92e8b81eea7608968d2272119cb6be77030b85de6cceca3b9d4acde44c1a2ea0d2c9d3bc2a51638936232907f2daa0a23325421ca4efc57248674081889f8832a07e75144a554963f4cb7088c4809cc8d14aab35fcfa4fe2e023ae82e45b65929ba01d11f73ff1b0c64899fde18ad85b08bbb7b3d7a46cda25a9c8668665e8bdb706a0be6a24e94b1689142dda1b4ef3750ff486f990d4610b1878b760404a468e59a7a02690ac779ae564dce3567fab4ca03c7b5f56da23d882b68be067dafb0829fc08a00b4230a149ff4dca81cd7682536de8b1be2fa715bcafb967c35156fdc626dc3ba0d1fea826722117b8482d59658586a2802577a9d9114d5d8791b93364e998732d80", + "f90211a096da0777dbb2f875bd357722a4387a78ae24efe13e04ed75f65b2c991247203fa0c0082d34071d1d65e712999126ac28e277b079d939821eaa755c4ef0fd2e5baaa0d088ecbd4b6bb84c6fa211bc81474c05c12ca2694faf0b1a2ecbde0bfe6fa3a2a00930aa5c1b70190cd2231cc759fec0c863a2e11bc89b1685d17da64f6bdc5e72a010b3d58569454bcfe1e6c9fad76e7034972f2abb6a3081b3c6b057c7d3151e2ca0868e866d17747182e462be130ceb1b0b3b5011db9f10f3fc8a00743c50497eaaa0aff0dd0b6a09d0e5659b96333f74fd56545addb56451693c1daeb2dbd7fe4470a07094c93901a37d76cc1ce99891c7419188b9dcabcd73075525a844084574c697a0cfd98d359eb86b3cf4531a0ddfa5d1ae5e5cdbed5f3a6a39daff489b2c862ed5a00f80e0d59b59c9e9e27aba7ac54d51f35750c45d45fb3d46c2cf31cb32a8e68aa02a5c88410b94694ae8882eda87af1c56616cd475b0b7feb2306da3959b322418a0609c5a3f274c1d31fa9b4d3c4492b4811c374e4d3d08ca5da98da012a489b273a0e57f95cc7d072bdd273c4bf504fbcabe2b356236151e53bd53af301fe794e34ba0a274c42f4ccef6f20a413218137c6ec00ac7e3fa172f61a7c6487497fe427daba0961e5aac1726d9598c446db66425f7360f87fa5feb744adcfaf19e783cbba1a5a0b5c730c7587872bdc05bd0786f6fd897332d7d2642f953fa019ef58d4e5ec25e80", + "f90171a02a6e86561c33eacbb1826e9832a25f9f2841c281c9e6b6c18c95ce713dae6c868080a0807528ab397894421968b62bead3b9dd446bda7dc79a5b6ec5a29bd3f19a10c5a0072bce4e78f01cc370c9d92dd39bfcee6059d2e60a95135867991c59184d219980a0415df007b0977e95ba9b3d86b64bae14c02250b3da81f81bed47973f9e4a55b180a0e45736d96c006965b5cad5ec8008d31eb2c34e00c36f677b288701f76f43d627a055324754b7752c9149df27e03392c0598ec89f408040b15140a679f02e695017a04fc91448749dcab3e66cc8e45eb8d85a416fa3a33f8951128d17ca208bc3bb38a085a91d9af48d4f428da097b31c09b3f6b27d38212678a30ffd100364546a4d1ea0c60b5a89f1f89e97528a8b352ed55e5de2e7b963d73ba7de9e922c0ae964e816a048ff598a81a0114eb4afe71ef547cf6fecbb970310ef84049c9353d01c17103aa08d1d7f774f6570c92fd5d70617266469dade16fd9e5cad87af44c15fa34d075a8080", + "f871808080808080a03f1587ebf71f19f47449b08f0960630ddbd60d045ea68ee7d89fb1c5682d215a8080808080a060abf60878dd69cb6e3a7bd92aeca7514df19f822555e528101da922493f6a758080a05344081f911ad616b960a8f2841eb55f4936a97ec5dae614e726c8c0d51e0eff80", + "f8669d3e3757038b7fea6585ca2d0a3dacd72d84bf0c7b916f169cea0348681bb846f8440180a0e4acc7f2f495a3bd919d8b5c2b2ab1446a293d16b7981141cf6f3594c26554b6a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75" + ], + "contract_address": "00763f30eEB0eEF506907e18f2a6ceC2DAb30Df8", + "expected_account_state": "f8440180a0e4acc7f2f495a3bd919d8b5c2b2ab1446a293d16b7981141cf6f3594c26554b6a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75", + "storage_key_hash": "0f9e5fde3c4a1600408ce3ebbd6a720b7491c663bef3fedcf7835dd6863fd34b", + "storage_proof": [ + "f90211a07c66fa00b691dc5c5a66e43831b9922316c8740c3c5235e7aa705cebefbd478ca0bbf8c0df9d3837792180786e217cbcbfb6cb6c1ee790ec0dba83fc05248f2627a036b93382543cd1737ddc32dbc8cd4326da47551be33e3ca75af3ea98583edd93a0c024e6190b7ce41e20f27b5cd512ebf50d6c60a1467f3cad8acd46da3a4d3861a04134b666e4a8e3e28701e33bed36680ae025cc5f89f8d29457975148338017c4a0ad773b24d54d681b3d712d913c0bf515407818845922616360b9b5a381cd6299a076515bac0f65924da357aba2f6c312472a9ef94d1c459f2cd0380b84a91d46aca0f49dd3a32c4adb7b6f02188b32a7823c79bb5b2ed1f3cdf4da11c36304ae4e25a0324a3b32bf60329775f3383b6c98e99683df56a0933516032147008d544af343a029f967b2d7ed040cda92ab4905f2976636a7bb16ba850679eca942e02d5b3458a024bdf35e1d8fd46cdee76420d508c722d7f47825356620c266094f6c66c67f7ea0426a496a8633ec2771fb15f58f646bf689eda39af535bcb9b316e9e601d1a342a00d9cd9aa39cdd4a91bcd4feb8c73db017dce78ec82ba6f14287775567615f247a02f3d28876d69fd8945b3fdeff87186bcb97c236ccefa3b6182507bc6e504606fa03b4078e843b8927c29753dfc91a44c246cb22ea3673a3bad8dab7c8f6b8ce226a061983eaffadbdc7d6e7a0f9d9f5c1c64f983a4a6724aaa2126a0b6c03c984f3280", + "f9015180a01061b943f8579b3fd877fbb9f5a796b40bad0e3c4cf6543287843cbc393e928da082da424f81780a75ef25a30590a9e5ec85637cb96dd708eab214029bb7324363a0809ffaa235bdd55f80127144f1918251205617992df98a93e871be18a481aaba80a0e30a57c48730f365adf774e3306ae2fd27abc854dc628b29c3b8873818e22adaa0aa6b491b53c837a2d87a4cf0e7995ce65030583199b48597cde9481d64e46deca0dbb86b57d06b8e9098b6db1d33c0ea963bf767f36e0e30559e64df69ab23d80180a0abaa7983dc34ba047258543b43cb5791d9fc73820c5103feaff960c35e2d2b4680a026f6892a3438aac58a8dfb5eeeefc1dc391e520eb1a401cc2a3a16ff617e3a578080a0d77dc10b28e64185d1d0306fb29003c89c300ed9041b476c08074161510b3670a0b36ced44fa006dd920a4f0281d389ecee50f66bd99f964ac50934065c5c873d680", + "f871a003c2a7f927a157d07815fdd586453a7f82223b912344dcb85fdb717b268cddb98080808080808080a0ad44120a824ee96076f8c53f155604f1e778eb0c678303eb680b69e3b72d7b9f8080a0dd6eb7d9c298eea97e0c3779437f0247e76237d430aeee5c9676830ed4e19e7480808080", + "e19f3e5fde3c4a1600408ce3ebbd6a720b7491c663bef3fedcf7835dd6863fd34b01" + ], + "expected_storage_value": "01", + "min_header_height": "", + "max_header_height": "", + "skip_bridge_call": true +} diff --git a/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectStateProof.json b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectStateProof.json new file mode 100644 index 00000000..a46ee4b5 --- /dev/null +++ b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectStateProof.json @@ -0,0 +1,26 @@ +{ + "header_data": "f90217a02feb03d38518e6941c0852c64a9cc06be8f0caed9357d0c45136395110ef4540a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794388ea662ef2c223ec0b047d41bf3c0f362142ad5a035630b01ab13a7f864f9c86f2a2d7ac497320594f92c5868e17063260beba833a083c4eeccb9dad0f16ca684785dd347c70e3c35573ebb38b6db5550d5e2eb2039a0f7679d652f72b54fd7c579a4738ae4d47c53213f266b5a2c2446a53386d17000b901005f04c0c31260591c81984881b480200041180c10098408d4d8840434c215211800660401002162160128100000c44bf4c0c20080061022544a185e0081242a000030000c4444811c600840285d0480624449060340cc6092080220a6000002050a0012428300a20010281180141408049801084502684280311012320608114002000a60802220aa29004800229100280001208004201140009140144462000502a0881100002810134340008b06402082004040224030080091406a288609021291480200194c49160440b14017660c4440018812086589620a005c0c0068839838ab040040a40754492158c0112414c892141012082040020a4a2102800040308381979a8401c9c38083972d598463ec1de09b4d616e69666f6c643a20636f696e62617365202d20676f65726c69a0fbd610d479f34d78d3c1ee5d525906e119babfa742966dfaabfba6ffc6499c3b8800000000000000000c", + "account_proof": [ + "f90211a08f3ec3607756301ad7628386a694edef062c32c0af69abdd8582733411fa6f4aa0e9ad940b31824dacc65417f2ae3aafe394949948f5805e645f6a5d7e7f0a5f28a078698a03fd4d2d738df437e1d39ac6dbe2b331474483083ecacd9270227adccea0b13728bf8c7541aac2e5f15840030e1a2a1d8546af961d2c5fe3cec61eb52136a041e20da27ab9f63b643aa550bd5494f42eb980e728499362807ca4a3d20bbd71a0544dfa7c44c6f4fc4318e6d42c8baa7db02467e31bdecb39a5b5c35dc9d75627a082e724d82008044c2339c3518899c58fa94397ec9b754a84ee6862ed980c506fa09858c9a0c3770fdcf0a95ee8657db7e5ff2813a5ee2b02bd2d550602ccf92ceca070c39b9018c1099644f6c8302f054b889f0d9c1c43561193af08c60514373a86a05147dd91ed6576bcb99c84b82e21267336fb5e7b6532bbc3bf3f153c44c7dd8ba0996167eb0ec29dcf3dc5564335936c857a16381f6cfc41e898ac427d5096f763a061cc346b3b193043469e1e63078e26bdffdc77fb9b7e03376a5d04a2e6a8bbd7a05ebe3f8899a1c9ae5c6f519c21bab07f380bc24eacd32d4915efa30990373347a0537e35aef2230294fb0150b5100ce1be4929181b2cbe16919ebdaf5455980a6ca0b11e4d342e93978e8ce006c6dafdc11a4626043ad6cd29c3a20fcaf7469e8846a0c2034f69510242f1af24e3cf53bdf8013959107de3863457d1759a0607cb42bd80", + "f90211a0cb604e92bfce9e89c58adb96d031edd6773b5ea79468c361c11bee3834ad38f7a0c3600619870fbddd0d3031662c20d4f07a7e8879715221e1cf2a27bac8252e84a0b42bfa4ca8a0f93155decb6566a0bfe41da0f0805f50bf22e582fbe09dab761da0f01302bc5b806c36dab88cf8fc3e720d2a9ea8b8c615cb2d6a61e516e7d568d5a0eb7a165077f85af7e1529e66bd052e211e3b0e591459a6b917b3a67b96e6c300a099b855be27efd92907fb6671240ad9b5a194aaaba80ec57f780f7f5132679279a076caa859434ddcc7513f2c40bbcdb0d3c92ef7f00f5575e5103683ed3f12d7aaa04b1f24333d5e1ff59bc1f0e68a4bffc09a109b59b281991e1def7d9a4d304683a01d24cc1c910469b1d5daf5c1ed9a0ff4b90467671498592b2b10bedb28594afca0f6c8564af03a1d6fa2203ad17d1c6cbbf608baed014de79c85c560149bac34a2a014a2351fb2913c7eead2607e6e821cb861a0acecce7e8d6b3eee285cd069b0f0a026385df23dbeafd3adff1c5537bc9b47716c3149c4d557cacaa31f67f8eb854fa0d759139f6c612b3ad3a4f1930a20f5bd1bcbd7e5595ccad018f066cde7cef5b7a052a24711316c1bccd8b72b59e1e0da3bd3254258651f42c468dbc06d33a5ece4a047f3cb14ec806f64d4bdeb04a60aef31966f50b2b191c9d5f697e01e5bc47654a0003d585567fb4aea17878d81f6c8e95e38218216e31263d85b01e387dcd12b6f80", + "f90211a07aa1913685063febef9253361de62ae7177722d980431ad433b6b2a2464d3c04a03df3486d470dc33c576fa0442eeac73b28032d892cee651cb5c8a714ba958f66a06482a869a326022a5fc40172cd9bbae5920b85a4138273da18eed05d2d75d97aa02a026697251d16fce297a1ee61d123da79085dc24ec356bff0f48f5708b04975a026cab39115772141ab3560790f604bf798b8d8744574ec842f57acba1bd3529fa0b78a5d4dcc2f37bbc0e8ba50727e7d08b143080aa2f93355f890bb7a615dae92a005b2270294d81e96ee9c7258f82a4541ec7a6a4eccf5de6fe54821d2e297d8f4a0d8d4d961a8e24b1e2886ee56762b1cd7f77e0ac76f9095636e9a008986b2028ba0eb02ba490b14fab24930230234056ed1cfaaf91fa4a57d9b9a7a178abe1cf3d2a0ba993d463bf76b12d4702be9696e0a1236ab7cd38e9fb590496151e4302ac7c1a08cbbd58b931fa2111148bed4e38c68e827b9a155c1eef0e63f43aa263cc10acea02e9bf22e9f981f53ed4856a0020449dc813cf444781b51fa3eabe13e0232f966a0a3622e12dacf5a9d1df00fe7e59326e1e96f1455492d72e39d5b6bf5f00eebb3a0a52a0b202c7059b5621fc10fd2921babe2c27934fae2d0409cbdc5b76d6b41a7a056aaef786ef7c8b3bda6d9ae2780478a1edc82b1f22e606bd3defe34a9cdeab5a0bf81e0ec8e926a748517a28422ff88e4a3f138a6f9175249c207f3178900bd9380", + "f90211a036e911e298a20d166922b7cb0563d3bceb8550b4adfa9fe08d8ca0a3c6d7ae86a0b9b9ac2b7a0a7c4d415787487e231900a10407acd166e92295ada52ea762c472a03a996e1b0ec3e2bddb98e7767e4666bcd40fa2273e0d3f52fa430f9a46938e7da015ea238cec5879fa069d204e93ff3c951f99d63407860df1882a2c59f325052da051fe87082dd2a2ac9e3610f6a85daba6468f7be31bc0301d3bafb579031848a2a01dfdfc623921a2948b00c4e0eab2d054293ca4869e09eaa79cd88ae492728788a036828736fa97fc9f14f0471b2cef6d6de6ed8e85f60581340e32314f55426d83a0e060a030a17644b352fd5d809fbffab09e4854e5cf79e907775571e72efdbe65a0b99a9776ae25aac78712102d448bca2ad2b0855d9485fd3e5aabc755a857ea1ba09774c71fdeb56de7925402760fc787d0f81a7e9373f017cbcdbba81b2c12df33a0af0f67963ad8a449e4ad7b613c58cb40ccf16786659ca716e9083b981138d2efa09bdc7b5850cd1050dddbc864a0d391312343fb542944cf0409f97ff2213b9f5da09792e17ea99e242aec9465df7f1b2b77e4c2ba916465d5b99702f4c6152bd82ea0dd32ae4192e7f1050eecd2573cc2c324fbbf6bf98cc61a6511920e8ab32091e5a00b4230a149ff4dca81cd7682536de8b1be2fa715bcafb967c35156fdc626dc3ba0b722557e1dc96d95b6af1aa5871ff90d300ce8632102e6b23e7e5d94101702ad80", + "f90211a096da0777dbb2f875bd357722a4387a78ae24efe13e04ed75f65b2c991247203fa0c0082d34071d1d65e712999126ac28e277b079d939821eaa755c4ef0fd2e5baaa0d088ecbd4b6bb84c6fa211bc81474c05c12ca2694faf0b1a2ecbde0bfe6fa3a2a00930aa5c1b70190cd2231cc759fec0c863a2e11bc89b1685d17da64f6bdc5e72a010b3d58569454bcfe1e6c9fad76e7034972f2abb6a3081b3c6b057c7d3151e2ca0868e866d17747182e462be130ceb1b0b3b5011db9f10f3fc8a00743c50497eaaa0aff0dd0b6a09d0e5659b96333f74fd56545addb56451693c1daeb2dbd7fe4470a07094c93901a37d76cc1ce99891c7419188b9dcabcd73075525a844084574c697a0cfd98d359eb86b3cf4531a0ddfa5d1ae5e5cdbed5f3a6a39daff489b2c862ed5a00f80e0d59b59c9e9e27aba7ac54d51f35750c45d45fb3d46c2cf31cb32a8e68aa02a5c88410b94694ae8882eda87af1c56616cd475b0b7feb2306da3959b322418a0609c5a3f274c1d31fa9b4d3c4492b4811c374e4d3d08ca5da98da012a489b273a0df38f9ab051dcee8d4f1a00376b01acecb3b7e9dbc40358c3d6d5958193e0329a0a274c42f4ccef6f20a413218137c6ec00ac7e3fa172f61a7c6487497fe427daba0961e5aac1726d9598c446db66425f7360f87fa5feb744adcfaf19e783cbba1a5a0b5c730c7587872bdc05bd0786f6fd897332d7d2642f953fa019ef58d4e5ec25e80", + "f90171a02a6e86561c33eacbb1826e9832a25f9f2841c281c9e6b6c18c95ce713dae6c868080a0807528ab397894421968b62bead3b9dd446bda7dc79a5b6ec5a29bd3f19a10c5a0072bce4e78f01cc370c9d92dd39bfcee6059d2e60a95135867991c59184d219980a0415df007b0977e95ba9b3d86b64bae14c02250b3da81f81bed47973f9e4a55b180a0e45736d96c006965b5cad5ec8008d31eb2c34e00c36f677b288701f76f43d627a055324754b7752c9149df27e03392c0598ec89f408040b15140a679f02e695017a04fc91448749dcab3e66cc8e45eb8d85a416fa3a33f8951128d17ca208bc3bb38a085a91d9af48d4f428da097b31c09b3f6b27d38212678a30ffd100364546a4d1ea0c60b5a89f1f89e97528a8b352ed55e5de2e7b963d73ba7de9e922c0ae964e816a048ff598a81a0114eb4afe71ef547cf6fecbb970310ef84049c9353d01c17103aa02bd17f471f58c435c937e6457a8a8a7ff7163263be197ec547241bc4791536b18080", + "f871808080808080a03f1587ebf71f19f47449b08f0960630ddbd60d045ea68ee7d89fb1c5682d215a8080808080a06e1618ec47442688101bd341cb8627739ecfd6fc1f793b69191dceeed18a19348080a05344081f911ad616b960a8f2841eb55f4936a97ec5dae614e726c8c0d51e0eff80", + "f8669d3e3757038b7fea6585ca2d0a3dacd72d84bf0c7b916f169cea0348681bb846f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75" + ], + "contract_address": "00763f30eEB0eEF506907e18f2a6ceC2DAb30Df8", + "expected_account_state": "f8440180a082bab1eb1ecd4b6dccd6d65b93603e6596205eb39ba1e32084c63dd883b17057a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75", + "storage_key_hash": "7bef74619139dab09d59cafa630682f8f30445738dcfb7147514aa27399ae2ee", + "storage_proof": [ + "f90211a0786e2b7a3a24cfafe31c1cac9b0cc4b57cfb9e27264b9aeb8ba52d48181fd013a0bbf8c0df9d3837792180786e217cbcbfb6cb6c1ee790ec0dba83fc05248f2627a060d5477cb7243063a66f6533e342632aea890e13cf45c0144ad7f8254bb74242a02dd5604620fcf3990474b172d1bb5653bf7bfc9ee1d269e765da3f7a91ac2ec3a04134b666e4a8e3e28701e33bed36680ae025cc5f89f8d29457975148338017c4a07bf7ed874ff02f5938267592e1a3cfca0ca8d7d4b6fccd617b815fad456c2c53a076515bac0f65924da357aba2f6c312472a9ef94d1c459f2cd0380b84a91d46aca0f49dd3a32c4adb7b6f02188b32a7823c79bb5b2ed1f3cdf4da11c36304ae4e25a05ba06e342a112365ced395b4bf830d148ad1e6a787912a9a603293a4e079e3f5a029f967b2d7ed040cda92ab4905f2976636a7bb16ba850679eca942e02d5b3458a024bdf35e1d8fd46cdee76420d508c722d7f47825356620c266094f6c66c67f7ea070a8abf4345f7148bbcbd0f443fe00cfed0a17ab828b7051cb3ede4bee4499b1a00d9cd9aa39cdd4a91bcd4feb8c73db017dce78ec82ba6f14287775567615f247a02f3d28876d69fd8945b3fdeff87186bcb97c236ccefa3b6182507bc6e504606fa03b4078e843b8927c29753dfc91a44c246cb22ea3673a3bad8dab7c8f6b8ce226a061983eaffadbdc7d6e7a0f9d9f5c1c64f983a4a6724aaa2126a0b6c03c984f3280", + "f901d1a0269a0b881e99b091fd1f85a9e44ee4daf1bfaa127412213b0ec1edacf2fcb4e0a0e7f129286b917093dd713ebf19c11b699dd3b7e2c8dd81b96da000d8929e6bd7a042e1e974e7e7b3829b6fd86c08ec48c92789a4c5b29aaba295ac47eb78da8979a0af69958bb871e61c3dab996738ae596fd6d8b0c6dd126361053ca23c67576aa6a0957f511c654ba45de24daa58d5069b8e854e1af4230f5e00ff80942f32179f9280a002cca7c62c8aaf39f3300a3694c5df5909d2365d68935dead512cec79b859546a0c150cdf6bf843bf02c321ad13d4b680a5ac6816a93b607b68b3d2944645cc573a0d44663526783865e11155d5490966374eaf24421c59522f6350769715d83f5f280a028d3420f6f3cfd2eff10d769032ec92a9ce6a26004a4b5e432577f7d218cb8eea095fcf2b12e8b70bb0c075d41576e00242769a18622ab1d936326fa053aeaa501a0ecf0ef75da3fd6cd5bc5a73049bbbdedd2fb0ccdb86bb07895d012b1b93354d5a02c8f51d330045fd36258abd5dc39dbc9ac14103ca91925bed4f55066f7d51830a024fff2a5c88286da53434ffeafc0962a9c2230a26c303850a04853096882be92a0a0eb992284319d09507645086aaf48f97428294e89aab782574993ed0543caef80", + "f851808080808080a05a173679dbc21d5c5b16c40e4d0fdd5ec92f602c2db2adbe71c9d4b2aedb585480a04cd868f531723c2438dce2df71b16e2d4d6f49299867484a662073b40aaac5ca8080808080808080", + "e19f3ba9af7041ec3098c4d818db9972f67827520c1db7d022f6c3041b6f40ecc301" + ], + "expected_storage_value": "01", + "min_header_height": "", + "max_header_height": "", + "skip_bridge_call": true +} diff --git a/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectValue.json b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectValue.json new file mode 100644 index 00000000..adca61e9 --- /dev/null +++ b/contracts/near/eth-prover/src/test_data/storageProofWithIncorrectValue.json @@ -0,0 +1,26 @@ +{ + "header_data": "f901ffa0fff0b83c7645333f372718f1c53b7275d83f89ae974940820a39ac43b9e88a11a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f36f155486299ecaff2d4f5160ed5114c1f66000a0611e6617bd56b23286a317a8cfe78274a76f9624c207ed9f567f12db53026cb5a0f8646c32c2cfb4064bc2fc092a73adf7fa8f05fe62dec656a550d09ec1b8a898a05d94e5c456f59be6084dc832d24de0273ceba6c841308d1908169a043ac6baa4b9010015a42a6355a47214801c1c81ac5150030184014530904810240b0054e81b750a00eea0040008415010180084206402d4410900a0160000f098085c041124a202103041109462923cd7a4210b020630260004831a40c0602409411184000212058820336a2200010000001080c413080009010c40614862983802923088102107268882692a90e80620424822678040210010100860151208240118f3956204050a2c895371808a101203140032034260e0f114027206246000a1c04a2132a922e66088322108090a110810a0000be40086a8101030144dd05003506248146614ba11280ba0201102780011e1814102058801000900502202024304301a39660230838182ac8401c9c3808401052eab8463eadb3080a00a58a400a5f524d8df4b7140cc35bf2b4fe9dfc2a12a1cf52f526d627aac3db3880000000000000000820357", + "account_proof": [ + "f90211a09f2010af3cc9c6d2ff727c81f7524ae503f90284e5cb802f6fd9358c163e198ca08548267c53e930b5a18b2364c5cb3aff3c14870ac2275eb6f8a54388a58b5567a0f71f37002acc0a2eaa7b540cf6d14eec6d1a0c0e05fa47294c17f1b313b5c8cfa03b6953e75441ca9a3a1cf4cfd1143357023b305698259217d69b2fc2ce60858ea07c2d0d986052f90200e3281f14f40dceb8a85547a681525a798829b2ab0818ffa0f185ab5dae7b1d6e7c2aa2bb4dcc03392baa732d9184da8fc33ca551616356faa02ccea0afc5e45712ee6485a78cd2912535198470651a554e94b453aad8cbd60da05be29334f4504f5f47f44ce970827664704d584a526a5683e0f26e5cd5041a25a0d81ab119c255376982d1f8c955bb0841386be0105e1ef6680b601c004ed8d415a07aa76afcca71c9e2230d4bf53bf7f2e31d350ee3c78e96a798174d4f55e584ffa0670b913a9ac9a6dbd871a40279b57953673946e86ccd05d95633ebc5bbe5b188a0f8a4eac59ac78af02c47e6102f7193e2643d3358bbd79ffd2f1a6d0f0f0c165ea0758266147704772c0a26c73c2b15f6fc1333d9f06d61f0a98b11911cdc0e6de4a0dba0b5a5c9cebe4a50b996e436845d0de0f703df346711d836b00e25f6d86bd4a088ca6ad3f65bd25c9c1b3fc1adba9805150dea0469555c2e2005c2e57fcd3003a0644ac23638cfd5d2bf7be1a18245245b9491bbb07b4ad041b7779a7bdb5025e580", + "f90211a0a1f7aac2995a5ed36bebaed5271dc61ac2388ee098dda2dd3bfce1ece0bfa829a0a8ae801f8cb8734df7b4826aab3c0f8daccc64effcf9497872c3bfcf9963c8fca037bd182a4739e2c71e97316b3cbee78173bd35bb8b3f60ef84e20c81cccd6b8ea0d3e5a8fdf0b394b753d56a0a07e60cafeed93ae896e508a2834657f4cfaf4e74a0bf5811b7827b6887a2afe150e9f84f01a9eb35eefbcacbce534e6cb574175632a0493c6adedeb34305ca3c8b0be070789f2b3ad5eb05a4faa3863c4dc335fb4189a09ed60b16f83213a33aeb53a77c14a243888e20238ab51bf364fcc1ffe6966153a0c6b9a7d02f4041391b21c85e9310cab8fa08e0c02ce7ad1bb9545e81d0db7670a0866b77b81c0a64e84035db172b1a479292b2d190228001ae276784fee258c607a0b426825472c8c661b05879c3757b958901b39ed09265724b17361cd0f15f74c3a061170e214ffcb0f8a2a17b8a64d6f4e588b0f9d64b1b78a8f860ccacd3922369a04de8f9edb1ad322a3568ac471831fbf175efd1c9b2b02b5d9d10a184d54b73c1a03a70896331cef4434e0a395595fe548cedb5c71529421a19359e42ca962429a5a09ffb6c4bedd8d72d73d3a0c87f71f2a41e9955df5fb5e483aa6c4a2ee8d45b26a0db4b26c625be8cc1aa9d17456139c8d5143c445ef877769050222b2fac5f929ba0c3afc1c5f13607cf561a073a6f341227a90376e87e48c54164eef19c51c5cd2780", + "f90211a0a728578ddfbd4e3fa913f10f73f4464fc95a3277ac3783078d07534872f60c8ca0bc6c1301ed405c0ce52e31bd667abe0d559b71d5c6ee515b4e977f4c1b7d2de5a042cab541119e6e1b305fc51bc3a9099a7ed323bcaab1b103f4a09c5fd1a5ffa9a0f29d1a4e35bb3cf9f17a3033f26bab8ac56e6abaf2df83d0878e9d45e4dbb262a08373516dca2167359f81c6086d086f9f6b647f0a5323a670271e8fbf4b15cd47a0acdfebaf24830b92a3deb6e44422afeef55efce4d0bbf0913216d9156459e41aa06bf7ec716d7579c4b784db41b0f3549c1aa033956968642836c37e0348a09bbfa010ffffce72a9f81a7a5491087febd53178879cfe59fa7645b9314ce07923f496a0a3a18069f84b16289144769be298aeb15cb78746012ef3c9893113109ea26163a0c872f57c7064d3ecf1e0dce8b7f2d31e151fab8c1048bce5e021fb5cc25e222ca0441bb13319c322f67c4cea9fe9e7ff4c81061b5b80cbe37254deffae3bfb3163a03b2bde0648f7489fea985da3a45c2d7b404d0dcd70eb62097dd0d76860acaf3fa046e54b2e41afe0594e4b32bb68f890eb2be0c522177a0098d9e209cd61fa52f9a079d38c8ffd67624fcee4d1307761bebe7f869d3f4046e99daf27bcf303a5174ca07a2c3cdbc8e4a22aa5ad600411810e4025ef84b79f132a4b75a9406f1cf60926a0529c91b9cc16adf0bcb72bac2ba86dd5e035e3e689ace0d4809ee6552a64119480", + "f90211a0cd42164ae552d0d13db9f9cf38653c224a34d604a9db71748e312248b7a3af38a0184e6eb3ea4728266438c0b7f687f62a96d6daa740711a678e1e0edf33361489a03c764463c2172ab6dbec2c495c2cf13796512cb3f369a10dbc3684bbd5fb4018a015ea238cec5879fa069d204e93ff3c951f99d63407860df1882a2c59f325052da0ab5c18775aa03057f7ade4b6bffd094cb5112bd47e80d576ac2415eb33ae9654a01dfdfc623921a2948b00c4e0eab2d054293ca4869e09eaa79cd88ae492728788a0f4e962298ff3966fd3cfeccc21a74d0b1a8e39d14dfc3a68d1f941e57ad917cba01fabe2077c23f5bc163eee76ff628c03d6d45b94445bd21df4a9b8c647b5a10da0ef92e8b81eea7608968d2272119cb6be77030b85de6cceca3b9d4acde44c1a2ea0d2c9d3bc2a51638936232907f2daa0a23325421ca4efc57248674081889f8832a07e75144a554963f4cb7088c4809cc8d14aab35fcfa4fe2e023ae82e45b65929ba01d11f73ff1b0c64899fde18ad85b08bbb7b3d7a46cda25a9c8668665e8bdb706a0be6a24e94b1689142dda1b4ef3750ff486f990d4610b1878b760404a468e59a7a02690ac779ae564dce3567fab4ca03c7b5f56da23d882b68be067dafb0829fc08a00b4230a149ff4dca81cd7682536de8b1be2fa715bcafb967c35156fdc626dc3ba0d1fea826722117b8482d59658586a2802577a9d9114d5d8791b93364e998732d80", + "f90211a096da0777dbb2f875bd357722a4387a78ae24efe13e04ed75f65b2c991247203fa0c0082d34071d1d65e712999126ac28e277b079d939821eaa755c4ef0fd2e5baaa0d088ecbd4b6bb84c6fa211bc81474c05c12ca2694faf0b1a2ecbde0bfe6fa3a2a00930aa5c1b70190cd2231cc759fec0c863a2e11bc89b1685d17da64f6bdc5e72a010b3d58569454bcfe1e6c9fad76e7034972f2abb6a3081b3c6b057c7d3151e2ca0868e866d17747182e462be130ceb1b0b3b5011db9f10f3fc8a00743c50497eaaa0aff0dd0b6a09d0e5659b96333f74fd56545addb56451693c1daeb2dbd7fe4470a07094c93901a37d76cc1ce99891c7419188b9dcabcd73075525a844084574c697a0cfd98d359eb86b3cf4531a0ddfa5d1ae5e5cdbed5f3a6a39daff489b2c862ed5a00f80e0d59b59c9e9e27aba7ac54d51f35750c45d45fb3d46c2cf31cb32a8e68aa02a5c88410b94694ae8882eda87af1c56616cd475b0b7feb2306da3959b322418a0609c5a3f274c1d31fa9b4d3c4492b4811c374e4d3d08ca5da98da012a489b273a0e57f95cc7d072bdd273c4bf504fbcabe2b356236151e53bd53af301fe794e34ba0a274c42f4ccef6f20a413218137c6ec00ac7e3fa172f61a7c6487497fe427daba0961e5aac1726d9598c446db66425f7360f87fa5feb744adcfaf19e783cbba1a5a0b5c730c7587872bdc05bd0786f6fd897332d7d2642f953fa019ef58d4e5ec25e80", + "f90171a02a6e86561c33eacbb1826e9832a25f9f2841c281c9e6b6c18c95ce713dae6c868080a0807528ab397894421968b62bead3b9dd446bda7dc79a5b6ec5a29bd3f19a10c5a0072bce4e78f01cc370c9d92dd39bfcee6059d2e60a95135867991c59184d219980a0415df007b0977e95ba9b3d86b64bae14c02250b3da81f81bed47973f9e4a55b180a0e45736d96c006965b5cad5ec8008d31eb2c34e00c36f677b288701f76f43d627a055324754b7752c9149df27e03392c0598ec89f408040b15140a679f02e695017a04fc91448749dcab3e66cc8e45eb8d85a416fa3a33f8951128d17ca208bc3bb38a085a91d9af48d4f428da097b31c09b3f6b27d38212678a30ffd100364546a4d1ea0c60b5a89f1f89e97528a8b352ed55e5de2e7b963d73ba7de9e922c0ae964e816a048ff598a81a0114eb4afe71ef547cf6fecbb970310ef84049c9353d01c17103aa08d1d7f774f6570c92fd5d70617266469dade16fd9e5cad87af44c15fa34d075a8080", + "f871808080808080a03f1587ebf71f19f47449b08f0960630ddbd60d045ea68ee7d89fb1c5682d215a8080808080a060abf60878dd69cb6e3a7bd92aeca7514df19f822555e528101da922493f6a758080a05344081f911ad616b960a8f2841eb55f4936a97ec5dae614e726c8c0d51e0eff80", + "f8669d3e3757038b7fea6585ca2d0a3dacd72d84bf0c7b916f169cea0348681bb846f8440180a0e4acc7f2f495a3bd919d8b5c2b2ab1446a293d16b7981141cf6f3594c26554b6a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75" + ], + "contract_address": "00763f30eEB0eEF506907e18f2a6ceC2DAb30Df8", + "expected_account_state": "f8440180a0e4acc7f2f495a3bd919d8b5c2b2ab1446a293d16b7981141cf6f3594c26554b6a0932cddc50793da935ccf915651ad67f6b746e9936fcc5614f0ff492563782c75", + "storage_key_hash": "0f9e5fde3c4a1600408ce3ebbd6a720b7491c663bef3fedcf7835dd6863fd34b", + "storage_proof": [ + "f90211a07c66fa00b691dc5c5a66e43831b9922316c8740c3c5235e7aa705cebefbd478ca0bbf8c0df9d3837792180786e217cbcbfb6cb6c1ee790ec0dba83fc05248f2627a036b93382543cd1737ddc32dbc8cd4326da47551be33e3ca75af3ea98583edd93a0c024e6190b7ce41e20f27b5cd512ebf50d6c60a1467f3cad8acd46da3a4d3861a04134b666e4a8e3e28701e33bed36680ae025cc5f89f8d29457975148338017c4a0ad773b24d54d681b3d712d913c0bf515407818845922616360b9b5a381cd6299a076515bac0f65924da357aba2f6c312472a9ef94d1c459f2cd0380b84a91d46aca0f49dd3a32c4adb7b6f02188b32a7823c79bb5b2ed1f3cdf4da11c36304ae4e25a0324a3b32bf60329775f3383b6c98e99683df56a0933516032147008d544af343a029f967b2d7ed040cda92ab4905f2976636a7bb16ba850679eca942e02d5b3458a024bdf35e1d8fd46cdee76420d508c722d7f47825356620c266094f6c66c67f7ea0426a496a8633ec2771fb15f58f646bf689eda39af535bcb9b316e9e601d1a342a00d9cd9aa39cdd4a91bcd4feb8c73db017dce78ec82ba6f14287775567615f247a02f3d28876d69fd8945b3fdeff87186bcb97c236ccefa3b6182507bc6e504606fa03b4078e843b8927c29753dfc91a44c246cb22ea3673a3bad8dab7c8f6b8ce226a061983eaffadbdc7d6e7a0f9d9f5c1c64f983a4a6724aaa2126a0b6c03c984f3280", + "f9015180a01061b943f8579b3fd877fbb9f5a796b40bad0e3c4cf6543287843cbc393e928da082da424f81780a75ef25a30590a9e5ec85637cb96dd708eab214029bb7324363a0809ffaa235bdd55f80127144f1918251205617992df98a93e871be18a481aaba80a0e30a57c48730f365adf774e3306ae2fd27abc854dc628b29c3b8873818e22adaa0aa6b491b53c837a2d87a4cf0e7995ce65030583199b48597cde9481d64e46deca0dbb86b57d06b8e9098b6db1d33c0ea963bf767f36e0e30559e64df69ab23d80180a0abaa7983dc34ba047258543b43cb5791d9fc73820c5103feaff960c35e2d2b4680a026f6892a3438aac58a8dfb5eeeefc1dc391e520eb1a401cc2a3a16ff617e3a578080a0d77dc10b28e64185d1d0306fb29003c89c300ed9041b476c08074161510b3670a0b36ced44fa006dd920a4f0281d389ecee50f66bd99f964ac50934065c5c873d680", + "f871a003c2a7f927a157d07815fdd586453a7f82223b912344dcb85fdb717b268cddb98080808080808080a0ad44120a824ee96076f8c53f155604f1e778eb0c678303eb680b69e3b72d7b9f8080a0dd6eb7d9c298eea97e0c3779437f0247e76237d430aeee5c9676830ed4e19e7480808080", + "e19f3e5fde3c4a1600408ce3ebbd6a720b7491c663bef3fedcf7835dd6863fd34b01" + ], + "expected_storage_value": "00", + "min_header_height": "", + "max_header_height": "", + "skip_bridge_call": true +} diff --git a/contracts/near/eth-prover/src/tests_storage_proof.rs b/contracts/near/eth-prover/src/tests_storage_proof.rs new file mode 100644 index 00000000..4de322c8 --- /dev/null +++ b/contracts/near/eth-prover/src/tests_storage_proof.rs @@ -0,0 +1,296 @@ +#[cfg(test)] +mod tests_storage_proof { + use crate::EthProver; + use eth_types::H256; + use near_sdk::serde_json; + use near_sdk::PromiseOrValue; + use rlp::Rlp; + use serde::Deserialize; + + #[derive(Debug, Deserialize)] + #[serde(crate = "near_sdk::serde")] + pub struct JsonProof { + #[serde(with = "hex::serde")] + pub header_data: Vec, + pub account_proof: Vec, // account proof + #[serde(with = "hex::serde")] + pub contract_address: Vec, // eth address + #[serde(with = "hex::serde")] + pub expected_account_state: Vec, // encoded account state + #[serde(with = "hex::serde")] + pub storage_key_hash: Vec, // keccak256 of storage key + pub storage_proof: Vec, // storage proof + #[serde(with = "hex::serde")] + pub expected_storage_value: Vec, // storage value + pub min_header_height: String, + pub max_header_height: String, + pub skip_bridge_call: bool, + } + + #[derive(Debug, Deserialize)] + pub struct StorageProof { + pub header_data: Vec, + pub account_proof: Vec>, // account proof + pub contract_address: Vec, // eth address + pub expected_account_state: Vec, // encoded account state + pub storage_key_hash: Vec, // keccak256 of storage key + pub storage_proof: Vec>, // storage proof + pub expected_storage_value: Vec, // storage value + pub min_header_height: Option, + pub max_header_height: Option, + pub skip_bridge_call: bool, + } + + pub fn get_json_proof(filename: String) -> JsonProof { + let contents = std::fs::read_to_string(&filename).expect("Unable to read file"); + serde_json::from_str(&contents).expect("Unable to deserialize") + } + + pub fn get_storage_proof(file_path: String) -> StorageProof { + let json_proof: JsonProof = get_json_proof(file_path); + + let header_data = json_proof.header_data; + let contract_address = json_proof.contract_address; + let account_proof = json_proof + .account_proof + .into_iter() + .map(|x| hex::decode(x).unwrap()) + .collect(); + let expected_account_state = json_proof.expected_account_state; + let storage_key_hash = json_proof.storage_key_hash; + let storage_proof = json_proof + .storage_proof + .into_iter() + .map(|x| hex::decode(x).unwrap()) + .collect(); + + StorageProof { + header_data, + account_proof, + contract_address, + expected_account_state, + storage_key_hash, + storage_proof, + expected_storage_value: json_proof.expected_storage_value, + min_header_height: None, + max_header_height: None, + skip_bridge_call: json_proof.skip_bridge_call, + } + } + + // TESTS + + use near_sdk::{testing_env, VMContext}; + + fn get_context(input: Vec) -> VMContext { + VMContext { + current_account_id: "alice.near".parse().unwrap(), + signer_account_id: "bob.near".parse().unwrap(), + signer_account_pk: "ed25519:6E8sCci9badyRkXb3JoRpBj5p8C6Tw41ELDZoiihKEtp" + .parse() + .unwrap(), + predecessor_account_id: "carol.near".parse().unwrap(), + input, + block_index: 0, + block_timestamp: 0, + epoch_height: 0, + account_balance: 0, + account_locked_balance: 0, + storage_usage: 0, + attached_deposit: 0, + prepaid_gas: near_sdk::Gas(10u64.pow(18)), + random_seed: vec![1; 32].try_into().unwrap(), + view_config: None, + output_data_receivers: vec![], + } + } + + #[test] + pub fn test_verify_trie_proof() { + testing_env!(get_context(vec![])); + let test_data = get_storage_proof(String::from("./src/test_data/storageProof.json")); + let storage_hash: H256 = Rlp::new(&test_data.expected_account_state) + .val_at(2) + .unwrap(); + assert_eq!( + EthProver::verify_trie_proof( + storage_hash, + test_data.storage_key_hash, + test_data.storage_proof + ), + test_data.expected_storage_value + ); + } + + #[test] + pub fn test_verify_storage_proof() { + testing_env!(get_context(vec![])); + let contract = EthProver::init("ethbridge".to_string()); + let test_data = get_storage_proof(String::from("./src/test_data/storageProof.json")); + if let PromiseOrValue::Value(true) = contract.verify_storage_proof( + test_data.header_data, + test_data.account_proof, + test_data.contract_address, + test_data.expected_account_state, + test_data.storage_key_hash, + test_data.storage_proof, + test_data.expected_storage_value, + test_data.min_header_height, + test_data.max_header_height, + test_data.skip_bridge_call, + ) { + } else { + panic!(); + } + } + + #[test] + #[should_panic(expected = "assertion failed: `(left == right)")] + pub fn test_verify_storage_proof_with_wrong_account_proof() { + testing_env!(get_context(vec![])); + let contract = EthProver::init("ethbridge".to_string()); + let test_data = get_storage_proof(String::from( + "./src/test_data/storageProofWithIncorrectAccountProof.json", + )); + if let PromiseOrValue::Value(true) = contract.verify_storage_proof( + test_data.header_data, + test_data.account_proof, + test_data.contract_address, + test_data.expected_account_state, + test_data.storage_key_hash, + test_data.storage_proof, + test_data.expected_storage_value, + test_data.min_header_height, + test_data.max_header_height, + test_data.skip_bridge_call, + ) { + } else { + panic!(); + } + } + + #[test] + #[should_panic(expected = "assertion failed: `(left == right)")] + pub fn test_verify_storage_proof_with_wrong_state_proof() { + testing_env!(get_context(vec![])); + let contract = EthProver::init("ethbridge".to_string()); + let test_data = get_storage_proof(String::from( + "./src/test_data/storageProofWithIncorrectStateProof.json", + )); + if let PromiseOrValue::Value(true) = contract.verify_storage_proof( + test_data.header_data, + test_data.account_proof, + test_data.contract_address, + test_data.expected_account_state, + test_data.storage_key_hash, + test_data.storage_proof, + test_data.expected_storage_value, + test_data.min_header_height, + test_data.max_header_height, + test_data.skip_bridge_call, + ) { + } else { + panic!(); + } + } + + #[test] + #[should_panic(expected = "explicit panic")] + pub fn test_verify_storage_proof_with_wrong_value() { + testing_env!(get_context(vec![])); + let contract = EthProver::init("ethbridge".to_string()); + let test_data = get_storage_proof(String::from( + "./src/test_data/storageProofWithIncorrectValue.json", + )); + if let PromiseOrValue::Value(true) = contract.verify_storage_proof( + test_data.header_data, + test_data.account_proof, + test_data.contract_address, + test_data.expected_account_state, + test_data.storage_key_hash, + test_data.storage_proof, + test_data.expected_storage_value, + test_data.min_header_height, + test_data.max_header_height, + test_data.skip_bridge_call, + ) { + } else { + panic!(); + } + } + + #[test] + pub fn test_verify_storage_proof_with_false_value() { + testing_env!(get_context(vec![])); + let contract = EthProver::init("ethbridge".to_string()); + let test_data = get_storage_proof(String::from( + "./src/test_data/storageProofWithFalseValue.json", + )); + if let PromiseOrValue::Value(true) = contract.verify_storage_proof( + test_data.header_data, + test_data.account_proof, + test_data.contract_address, + test_data.expected_account_state, + test_data.storage_key_hash, + test_data.storage_proof, + test_data.expected_storage_value, + test_data.min_header_height, + test_data.max_header_height, + test_data.skip_bridge_call, + ) { + } else { + panic!("storage_value != expected_storage_value"); + } + } + + #[test] + #[should_panic(expected = "explicit panic")] + pub fn test_verify_storage_proof_with_wrong_account_data() { + testing_env!(get_context(vec![])); + let contract = EthProver::init("ethbridge".to_string()); + // Below Data for Block: 8487596 other than account data + let test_data = get_storage_proof(String::from( + "./src/test_data/storageProofWithIncorrectAccountState.json", + )); + if let PromiseOrValue::Value(true) = contract.verify_storage_proof( + test_data.header_data, + test_data.account_proof, + test_data.contract_address, + test_data.expected_account_state, + test_data.storage_key_hash, + test_data.storage_proof, + test_data.expected_storage_value, + test_data.min_header_height, + test_data.max_header_height, + test_data.skip_bridge_call, + ) { + } else { + panic!(); + } + } + + #[test] + pub fn test_verify_storage_proof_with_future_header_data() { + testing_env!(get_context(vec![])); + let contract = EthProver::init("ethbridge".to_string()); + // Header-Data[state root-> block: 8487596 || other data in Header-data -> block: 8492954] + let test_data = get_storage_proof(String::from( + "./src/test_data/storageProofWithIncorrectHeaderExceptStateRoot.json", + )); + if let PromiseOrValue::Value(true) = contract.verify_storage_proof( + test_data.header_data, + test_data.account_proof, + test_data.contract_address, + test_data.expected_account_state, + test_data.storage_key_hash, + test_data.storage_proof, + test_data.expected_storage_value, + test_data.min_header_height, + test_data.max_header_height, + test_data.skip_bridge_call, + ) { + } else { + panic!(); + } + } +} diff --git a/contracts/near/res/eth_prover.wasm b/contracts/near/res/eth_prover.wasm index 1b0a7cb9a38ce8b639abea3b31a6ad777e6e544f..4872d54dbd6af0407f5cd69a89cd65491da919cc 100755 GIT binary patch delta 42374 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 qJbLno)c; this.robustWeb3.getTransactionReceipt(t)) @@ -127,6 +143,33 @@ async function ethToNearFindProof ({ lockedEventRaw, ethNodeUrl }) { web3.currentProvider.connection.close() } +async function ethToNearFindStorageProof ({ contractAddress, storageKey, blockNumber, ethNodeUrl }) { + const robustWeb3 = new RobustWeb3(ethNodeUrl) + const web3 = robustWeb3.web3 + try { + const extractor = new EthProofExtractor() + extractor.initialize(ethNodeUrl) + + const extractedProof = await extractor.extractStorageProof(contractAddress, storageKey, blockNumber) + extractor.destroy() + + const proof = { + contract_address: utils.stripHexPrefix(contractAddress.toLowerCase()), + storage_key: utils.stripHexPrefix(storageKey), + block_number: blockNumber, + header_data: extractedProof.header_rlp.toString('hex'), + account_proof: extractedProof.account_proof.map(x => utils.stripHexPrefix(x)), + expected_account_state: extractedProof.account_rlp.toString('hex'), + storage_key_hash: utils.stripHexPrefix(web3.utils.keccak256(storageKey)), + storage_proof: extractedProof.storage_proof.map(x => utils.stripHexPrefix(x)), + value: utils.padToEven(utils.stripHexPrefix(extractedProof.value)) + } + console.log(JSON.stringify(proof, JSONreplacer)) + } catch (error) { + console.log('Failed', error.toString()) + } +} + EthProofExtractor.fromWeb3 = (web3) => { const extractor = new EthProofExtractor() extractor.robustWeb3 = new RobustWeb3(web3.currentProvider.host) @@ -138,3 +181,4 @@ exports.EthProofExtractor = EthProofExtractor exports.receiptFromWeb3 = receiptFromWeb3 exports.logFromWeb3 = logFromWeb3 exports.ethToNearFindProof = ethToNearFindProof +exports.ethToNearFindStorageProof = ethToNearFindStorageProof diff --git a/eth2near/eth2near-block-relay/index.js b/eth2near/eth2near-block-relay/index.js index 2560ed9a..216deb17 100644 --- a/eth2near/eth2near-block-relay/index.js +++ b/eth2near/eth2near-block-relay/index.js @@ -21,7 +21,8 @@ const { EthProofExtractor, logFromWeb3, receiptFromWeb3, - ethToNearFindProof + ethToNearFindProof, + ethToNearFindStorageProof } = require('./eth-proof-extractor') const { @@ -311,4 +312,5 @@ exports.EthOnNearProverContract = EthOnNearProverContract exports.logFromWeb3 = logFromWeb3 exports.receiptFromWeb3 = receiptFromWeb3 exports.ethToNearFindProof = ethToNearFindProof +exports.ethToNearFindStorageProof = ethToNearFindStorageProof exports.dagMerkleRoots = dagMerkleRoots From c0d3986941dbf7f730cc3978c8b27e7e292d41fd Mon Sep 17 00:00:00 2001 From: Alexey Lapitsky Date: Fri, 7 Jul 2023 14:57:42 +0200 Subject: [PATCH 4/8] chore(backstage): add prover_v2 metadata (#910) --- contracts/near/eth-prover/.catalog-info.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/near/eth-prover/.catalog-info.yaml b/contracts/near/eth-prover/.catalog-info.yaml index f3128039..7e2bf1c0 100644 --- a/contracts/near/eth-prover/.catalog-info.yaml +++ b/contracts/near/eth-prover/.catalog-info.yaml @@ -17,5 +17,6 @@ spec: system: bridge-protocol deployedAt: - contract:near/mainnet/prover.bridge.near + - contract:near/mainnet/prover_v2.bridge.near interactsWith: - contract:near/mainnet/client.bridge.near From 7fefc9502ede35a9c092c9bce694293d8826f657 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 13 Sep 2023 01:55:30 +0100 Subject: [PATCH 5/8] Update CODEOWNERS (#913) --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 6e2d363d..fcd83a8f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,2 @@ # CODEOWNERS: https://help.github.com/articles/about-codeowners/ -* @sept-en @karim-en +* @karim-en From 5c214b06ba087b24703b99d0c9e602e6fb99d9bf Mon Sep 17 00:00:00 2001 From: Kirill Date: Sat, 16 Sep 2023 22:01:33 +0100 Subject: [PATCH 6/8] Update CODEOWNERS (#912) From 0ad5806595796e2b7ba653cf95cc4365ef9249d9 Mon Sep 17 00:00:00 2001 From: Diego Figueroa <12281609+diegofigs@users.noreply.github.com> Date: Thu, 21 Sep 2023 15:22:34 -0400 Subject: [PATCH 7/8] chore: add testnet addresses to backstage (#914) * chore: add testnet addresses to backstage * refactor: remove deprecated goerli addr in catalog --- contracts/eth/nearbridge/.catalog-info.yaml | 2 ++ contracts/eth/nearprover/.catalog-info.yaml | 1 + contracts/near/eth-client/.catalog-info.yaml | 1 + contracts/near/eth-prover/.catalog-info.yaml | 1 + 4 files changed, 5 insertions(+) diff --git a/contracts/eth/nearbridge/.catalog-info.yaml b/contracts/eth/nearbridge/.catalog-info.yaml index 5ed91d74..e6b8ef06 100644 --- a/contracts/eth/nearbridge/.catalog-info.yaml +++ b/contracts/eth/nearbridge/.catalog-info.yaml @@ -20,6 +20,7 @@ spec: system: bridge-protocol deployedAt: - contract:ethereum/mainnet/0x88f975d5a1153ea92af66e7c4292576a329c04b6 + - contract:ethereum/goerli/0x6f2C9EbFB1e3Ff065E6725A715B458EF13206097 interactsWith: [] --- apiVersion: backstage.io/v1alpha1 @@ -43,6 +44,7 @@ spec: system: bridge-protocol deployedAt: - contract:ethereum/mainnet/0x3FEFc5A4B1c02f21cBc8D3613643ba0635b9a873 + - contract:ethereum/goerli/0x37c2d89b55bfd95532637554711441017efabfef interactsWith: - relayer:ethereum/mainnet/0x015e634c7c1311a9034220c28d3d12b7f710a3b1 deprecated: diff --git a/contracts/eth/nearprover/.catalog-info.yaml b/contracts/eth/nearprover/.catalog-info.yaml index b0192a9f..3ea84eb5 100644 --- a/contracts/eth/nearprover/.catalog-info.yaml +++ b/contracts/eth/nearprover/.catalog-info.yaml @@ -19,5 +19,6 @@ spec: system: bridge-protocol deployedAt: - contract:ethereum/mainnet/0x051ad3f020274910065dcb421629cd2e6e5b46c4 + - contract:ethereum/goerli/0xf3430be687dc5652e3e96a9a7b291b5d423dfc3b interactsWith: - contract:ethereum/mainnet/0x3be7df8db39996a837041bb8ee0dadf60f767038 diff --git a/contracts/near/eth-client/.catalog-info.yaml b/contracts/near/eth-client/.catalog-info.yaml index c718efb1..85b25ff7 100644 --- a/contracts/near/eth-client/.catalog-info.yaml +++ b/contracts/near/eth-client/.catalog-info.yaml @@ -18,5 +18,6 @@ spec: deployedAt: - contract:near/mainnet/client.bridge.near - contract:near/mainnet/client-eth2.bridge.near + - contract:near/testnet/client-eth2.goerli.testnet interactsWith: - relayer:near/mainnet/relayer.bridge.near diff --git a/contracts/near/eth-prover/.catalog-info.yaml b/contracts/near/eth-prover/.catalog-info.yaml index 7e2bf1c0..76e0bd9e 100644 --- a/contracts/near/eth-prover/.catalog-info.yaml +++ b/contracts/near/eth-prover/.catalog-info.yaml @@ -18,5 +18,6 @@ spec: deployedAt: - contract:near/mainnet/prover.bridge.near - contract:near/mainnet/prover_v2.bridge.near + - contract:near/testnet/prover.goerli.testnet interactsWith: - contract:near/mainnet/client.bridge.near From 0f7b70faf3f406162e16c4c839a1dcc5027573d8 Mon Sep 17 00:00:00 2001 From: Karim Date: Mon, 23 Oct 2023 13:20:36 +0100 Subject: [PATCH 8/8] Contract wrapper: move some crates to `dev-dependencies` (#915) * Contract wrapper: move crates to `dev-dependencies` & apply cargo fmt * Add `sandbox` feature flag --- eth2near/contract_wrapper/Cargo.toml | 9 +++++-- eth2near/contract_wrapper/rust-toolchain | 2 +- .../src/dao_eth_client_contract.rs | 4 +-- .../src/eth_client_contract.rs | 18 ++++++------- .../src/eth_client_contract_trait.rs | 4 +-- .../src/file_eth_client_contract.rs | 4 +-- eth2near/contract_wrapper/src/lib.rs | 1 + eth2near/eth2-contract-init/Cargo.toml | 7 +++--- eth2near/eth2near-block-relay-rs/Cargo.toml | 1 + .../eth2near-block-relay-rs/src/test_utils.rs | 25 ++++--------------- 10 files changed, 34 insertions(+), 41 deletions(-) diff --git a/eth2near/contract_wrapper/Cargo.toml b/eth2near/contract_wrapper/Cargo.toml index 261a10ce..1396fa18 100644 --- a/eth2near/contract_wrapper/Cargo.toml +++ b/eth2near/contract_wrapper/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] borsh = "0.9.3" -futures = "0.3.21" async-std = "1.12.0" near-sdk = "4.1.1" near-jsonrpc-client = "0.5.0" @@ -19,5 +18,11 @@ serde_json = "1.0.74" serde = { version = "1.0", features = ["derive"] } eth-types = { path = "../../contracts/near/eth-types/" } eth2-utility = { path = "../../contracts/near/eth2-utility/" } -workspaces = "0.7" +workspaces = { version = "0.7", optional = true } + +[dev-dependencies] +futures = "0.3.21" anyhow = "1.0" + +[features] +sandbox = ["workspaces"] diff --git a/eth2near/contract_wrapper/rust-toolchain b/eth2near/contract_wrapper/rust-toolchain index 588ffd57..f2415f83 100644 --- a/eth2near/contract_wrapper/rust-toolchain +++ b/eth2near/contract_wrapper/rust-toolchain @@ -1,2 +1,2 @@ [toolchain] -channel = "1.67.1" +channel = "1.69.0" diff --git a/eth2near/contract_wrapper/src/dao_eth_client_contract.rs b/eth2near/contract_wrapper/src/dao_eth_client_contract.rs index c7990a59..5f962111 100644 --- a/eth2near/contract_wrapper/src/dao_eth_client_contract.rs +++ b/eth2near/contract_wrapper/src/dao_eth_client_contract.rs @@ -2,9 +2,9 @@ use crate::dao_contract::DAOContract; use crate::dao_types; use crate::eth_client_contract::EthClientContract; use crate::eth_client_contract_trait::EthClientContractTrait; +use eth2_utility::types::ClientMode; use eth_types::eth2::{LightClientState, LightClientUpdate}; use eth_types::{BlockHeader, H256}; -use eth2_utility::types::ClientMode; use near_primitives::views::FinalExecutionOutcomeView; use std::error::Error; use std::str::FromStr; @@ -100,7 +100,7 @@ impl EthClientContractTrait for DaoEthClientContract { self.eth_client_contract.get_light_client_state() } - fn get_last_block_number(&self) -> Result> { + fn get_last_block_number(&self) -> Result> { self.eth_client_contract.get_last_block_number() } diff --git a/eth2near/contract_wrapper/src/eth_client_contract.rs b/eth2near/contract_wrapper/src/eth_client_contract.rs index 1d2666cc..927e0029 100644 --- a/eth2near/contract_wrapper/src/eth_client_contract.rs +++ b/eth2near/contract_wrapper/src/eth_client_contract.rs @@ -2,11 +2,11 @@ use crate::contract_wrapper_trait::ContractWrapper; use crate::eth_client_contract_trait::EthClientContractTrait; use crate::eth_network::EthNetwork; use borsh::BorshDeserialize; +use eth2_utility::types::ClientMode; use eth_types::eth2::{ ExtendedBeaconBlockHeader, LightClientState, LightClientUpdate, SyncCommittee, }; use eth_types::{BlockHeader, H256}; -use eth2_utility::types::ClientMode; use near_primitives::borsh::BorshSerialize; use near_primitives::types::AccountId; use near_primitives::views::FinalExecutionOutcomeView; @@ -25,9 +25,7 @@ pub struct EthClientContract { impl EthClientContract { /// Constructor for `EthClientContract` pub fn new(contract_wrapper: Box) -> Self { - EthClientContract { - contract_wrapper, - } + EthClientContract { contract_wrapper } } /// Initializes the Ethereum Light Client Contract on NEAR. @@ -137,7 +135,7 @@ impl EthClientContractTrait for EthClientContract { fn get_client_mode(&self) -> Result> { let res = self.contract_wrapper.call_view_function( "get_client_mode".to_string(), - json!({}).to_string().into_bytes() + json!({}).to_string().into_bytes(), )?; let mode: ClientMode = ClientMode::try_from_slice(&res)?; @@ -239,9 +237,10 @@ mod tests { } pub fn submit_block(&mut self, eth_client: &mut EthClientContract) { - eth_client.send_headers( - &vec![self.execution_blocks[self.current_execution_block].clone()], - ) + eth_client + .send_headers(&vec![ + self.execution_blocks[self.current_execution_block].clone() + ]) .unwrap(); self.current_execution_block += 1; @@ -253,7 +252,8 @@ mod tests { } pub fn submit_update(&mut self, eth_client: &mut EthClientContract) { - eth_client.send_light_client_update( + eth_client + .send_light_client_update( self.light_client_updates[self.current_light_client_update].clone(), ) .unwrap(); diff --git a/eth2near/contract_wrapper/src/eth_client_contract_trait.rs b/eth2near/contract_wrapper/src/eth_client_contract_trait.rs index f4ce3d59..96c6f77b 100644 --- a/eth2near/contract_wrapper/src/eth_client_contract_trait.rs +++ b/eth2near/contract_wrapper/src/eth_client_contract_trait.rs @@ -1,6 +1,6 @@ +use eth2_utility::types::ClientMode; use eth_types::eth2::{LightClientState, LightClientUpdate}; use eth_types::{BlockHeader, H256}; -use eth2_utility::types::ClientMode; use near_primitives::views::FinalExecutionOutcomeView; use std::error::Error; @@ -25,7 +25,7 @@ pub trait EthClientContractTrait { /// * `headers` - the list of headers for submission to Eth Client fn send_headers( &mut self, - headers: &[BlockHeader] + headers: &[BlockHeader], ) -> Result>; fn get_client_mode(&self) -> Result>; diff --git a/eth2near/contract_wrapper/src/file_eth_client_contract.rs b/eth2near/contract_wrapper/src/file_eth_client_contract.rs index 0314e453..fbb91257 100644 --- a/eth2near/contract_wrapper/src/file_eth_client_contract.rs +++ b/eth2near/contract_wrapper/src/file_eth_client_contract.rs @@ -1,8 +1,8 @@ use crate::eth_client_contract::EthClientContract; use crate::eth_client_contract_trait::EthClientContractTrait; +use eth2_utility::types::ClientMode; use eth_types::eth2::{LightClientState, LightClientUpdate}; use eth_types::{BlockHeader, H256}; -use eth2_utility::types::ClientMode; use near_primitives::views::FinalExecutionOutcomeView; use std::error::Error; use std::fs::File; @@ -67,7 +67,7 @@ impl EthClientContractTrait for FileEthClientContract { fn send_headers( &mut self, - headers: &[BlockHeader] + headers: &[BlockHeader], ) -> Result> { for header in headers { self.blocks_headers_file diff --git a/eth2near/contract_wrapper/src/lib.rs b/eth2near/contract_wrapper/src/lib.rs index 98e67219..edec0a0a 100644 --- a/eth2near/contract_wrapper/src/lib.rs +++ b/eth2near/contract_wrapper/src/lib.rs @@ -10,5 +10,6 @@ pub mod file_eth_client_contract; pub mod near_contract_wrapper; pub mod near_network; pub mod near_rpc_client; +#[cfg(feature = "sandbox")] pub mod sandbox_contract_wrapper; pub mod utils; diff --git a/eth2near/eth2-contract-init/Cargo.toml b/eth2near/eth2-contract-init/Cargo.toml index 39cb0625..bdbd133f 100644 --- a/eth2near/eth2-contract-init/Cargo.toml +++ b/eth2near/eth2-contract-init/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" [dependencies] tree_hash = { git = "https://github.com/aurora-is-near/lighthouse.git", tag = "v3.5.1-wasm" } merkle_proof = { git = "https://github.com/aurora-is-near/lighthouse.git", tag = "v3.5.1-wasm" } -types = { git = "https://github.com/aurora-is-near/lighthouse.git", tag = "v3.5.1-wasm" } -eth2_to_near_relay = { path = "../eth2near-block-relay-rs"} +types = { git = "https://github.com/aurora-is-near/lighthouse.git", tag = "v3.5.1-wasm" } +eth2_to_near_relay = { path = "../eth2near-block-relay-rs" } eth_rpc_client = { path = "../eth_rpc_client" } eth-types = { path = "../../contracts/near/eth-types/" } -eth2-utility = { path = "../../contracts/near/eth2-utility" } +eth2-utility = { path = "../../contracts/near/eth2-utility" } contract_wrapper = { path = "../contract_wrapper" } log = { version = "0.4", features = ["std", "serde"] } clap = { version = "3.1.6", features = ["derive"] } @@ -26,3 +26,4 @@ dotenv = "0.15.0" [dev-dependencies] workspaces = "0.7" tokio = { version = "1.1", features = ["macros", "rt", "time"] } +contract_wrapper = { path = "../contract_wrapper", features = ["sandbox"] } diff --git a/eth2near/eth2near-block-relay-rs/Cargo.toml b/eth2near/eth2near-block-relay-rs/Cargo.toml index ae70a2a1..c25bde4e 100644 --- a/eth2near/eth2near-block-relay-rs/Cargo.toml +++ b/eth2near/eth2near-block-relay-rs/Cargo.toml @@ -50,3 +50,4 @@ dotenv = "0.15.0" [dev-dependencies] workspaces = "0.7" eth2-contract-init = { path = "../eth2-contract-init" } +contract_wrapper = { path = "../contract_wrapper", features = ["sandbox"] } diff --git a/eth2near/eth2near-block-relay-rs/src/test_utils.rs b/eth2near/eth2near-block-relay-rs/src/test_utils.rs index d6756f3c..b8428d0c 100644 --- a/eth2near/eth2near-block-relay-rs/src/test_utils.rs +++ b/eth2near/eth2near-block-relay-rs/src/test_utils.rs @@ -247,15 +247,9 @@ pub fn get_client_contract( Box::new(eth_client_contract) } -pub fn get_relay( - from_file: bool, - config_for_test: &ConfigForTests, -) -> Eth2NearRelay { +pub fn get_relay(from_file: bool, config_for_test: &ConfigForTests) -> Eth2NearRelay { let config = get_config(config_for_test); - Eth2NearRelay::init( - &config, - get_client_contract(from_file, config_for_test) - ) + Eth2NearRelay::init(&config, get_client_contract(from_file, config_for_test)) } pub fn get_relay_with_update_from_file( @@ -270,16 +264,10 @@ pub fn get_relay_with_update_from_file( config.include_next_sync_committee_to_light_client = true; } - Eth2NearRelay::init( - &config, - get_client_contract(from_file, config_for_test) - ) + Eth2NearRelay::init(&config, get_client_contract(from_file, config_for_test)) } -pub fn get_relay_from_slot( - slot: u64, - config_for_test: &ConfigForTests, -) -> Eth2NearRelay { +pub fn get_relay_from_slot(slot: u64, config_for_test: &ConfigForTests) -> Eth2NearRelay { let config = get_config(config_for_test); let (relay_account, contract) = create_contract(&config_for_test); @@ -289,8 +277,5 @@ pub fn get_relay_from_slot( init_contract_from_specific_slot(&mut eth_client_contract, slot, config_for_test); - Eth2NearRelay::init( - &config, - Box::new(eth_client_contract) - ) + Eth2NearRelay::init(&config, Box::new(eth_client_contract)) }