From 9dc29bf3f79bcee33259e6e7e37b1f40f5af2df5 Mon Sep 17 00:00:00 2001 From: Phi-rjan Date: Tue, 27 Feb 2024 16:50:07 +0100 Subject: [PATCH] chore:: backport #11609 to the feat/nv22 branch (#11644) * feat: api: improve the correctness of Eth's trace_block (#11609) * Improve the correctness of Eth's trace_block - Improve encoding/decoding of parameters and return values: - Encode "native" parameters and return values with Solidity ABI. - Correctly decode parameters to "create" calls. - Use the correct (ish) output for "create" calls. - Handle all forms of "create". - Make robust with respect to reverts: - Use the actor ID/address from the trace instead of looking it up in the state-tree (may not exist in the state-tree due to a revert). - Gracefully handle failed actor/contract creation. - Improve performance: - We avoid looking anything up in the state-tree when translating the trace, which should significantly improve performance. - Improve code readability: - Remove all "backtracking" logic. - Use an "environment" struct to store temporary state instead of attaching it to the trace. - Fix random bugs: - Fix an allocation bug in the "address" logic (need to set the capacity before modifying the slice). - Improved error checking/handling. - Use correct types for `trace_block` action/results (create, call, etc.). - And use the correct types for Result/Action structs instead of reusing the same "Call" action every time. - Improve error messages. * Make gen Make gen --------- Co-authored-by: Steven Allen --- CHANGELOG.md | 17 + api/api_full.go | 19 +- build/openrpc/full.json.gz | Bin 35157 -> 35489 bytes build/openrpc/gateway.json.gz | Bin 11916 -> 11848 bytes chain/actors/builtin/evm/actor.go.template | 14 + chain/actors/builtin/evm/evm.go | 13 + chain/types/ethtypes/eth_types.go | 58 +- documentation/en/api-v1-unstable-methods.md | 52 +- node/impl/full/eth.go | 61 +- node/impl/full/eth_test.go | 40 + node/impl/full/eth_trace.go | 761 ++++++++++++++------ node/impl/full/eth_utils.go | 33 +- 12 files changed, 760 insertions(+), 308 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b1c8cb84..6663cf6aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,23 @@ OPTIONS: ``` +### Ethereum Tracing API (`trace_block` and `trace_replayBlockTransactions`) + +For those with the Ethereum JSON-RPC API enabled, the experimental Ethereum Tracing API has been improved significantly and should be considered "functional". However, it's still new and should be tested extensively before relying on it. This API translates FVM traces to Ethereum-style traces, implementing the OpenEthereum `trace_block` and `trace_replayBlockTransactions` APIs. + +This release fixes numerous bugs with this API and now ABI-encodes non-EVM inputs/outputs as if they were explicit EVM calls to [`handle_filecoin_method`][handlefilecoinmethod] for better block explorer compatibility. + +However, there are some _significant_ limitations: + +1. The Geth APIs are not implemented, only the OpenEthereum (Erigon, etc.) APIs. +2. Block rewards are not (yet) included in the trace. +3. Selfdestruct operations are not included in the trace. +4. EVM smart contract "create" events always specify `0xfe` as the "code" for newly created EVM smart contracts. + +Additionally, Filecoin is not Ethereum no matter how much we try to provide API/tooling compatibility. This API attempts to translate Filecoin semantics into Ethereum semantics as accurately as possible, but it's hardly the best source of data unless you _need_ Filecoin to look like an Ethereum compatible chain. If you're trying to build a new integration with Filecoin, please use the native `StateCompute` method instead. + +[handlefilecoinmethod]: https://fips.filecoin.io/FIPS/fip-0054.html#handlefilecoinmethod-general-handler-for-method-numbers--1024 + # v1.25.2 / 2024-01-11 This is an optional but **highly recommended feature release** of Lotus, as it includes fixes for synchronizations issues that users have experienced. The feature release also introduces `Lotus-Provider` in its alpha testing phase, as well as the ability to call external PC2-binaries during the sealing process. diff --git a/api/api_full.go b/api/api_full.go index 1cfa8d05e..7fae00fe6 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -875,9 +875,26 @@ type FullNode interface { Web3ClientVersion(ctx context.Context) (string, error) //perm:read // TraceAPI related methods + + // Returns an OpenEthereum-compatible trace of the given block (implementing `trace_block`), + // translating Filecoin semantics into Ethereum semantics and tracing both EVM and FVM calls. // - // Returns traces created at given block + // Features: + // + // - FVM actor create events, calls, etc. show up as if they were EVM smart contract events. + // - Native FVM call inputs are ABI-encoded (Solidity ABI) as if they were calls to a + // `handle_filecoin_method(uint64 method, uint64 codec, bytes params)` function + // (where `codec` is the IPLD codec of `params`). + // - Native FVM call outputs (return values) are ABI-encoded as `(uint32 exit_code, uint64 + // codec, bytes output)` where `codec` is the IPLD codec of `output`. + // + // Limitations (for now): + // + // 1. Block rewards are not included in the trace. + // 2. SELFDESTRUCT operations are not included in the trace. + // 3. EVM smart contract "create" events always specify `0xfe` as the "code" for newly created EVM smart contracts. EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.EthTraceBlock, error) //perm:read + // Replays all transactions in a block returning the requested traces for each transaction EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error) //perm:read diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 1120e15f258405ee24852391827c0392068fb38f..4f23171f06f487da20031d59d6e0d6fe3857ea5c 100644 GIT binary patch literal 35489 zcmZ^qQ?MXGx22D5+qP}nw%NzFZQHhO+qP|^52pWn?@Ua@#MDDYRz6l`?#i{-`tYM5 z0RHRxz3%aF+G=kE|5R1*^vfnGaW|QeK2$H$^N>E|*7UY9Kix$>%M~CYF_Z!10kP0d znsoCE3CU`QD5lU(WjtGs7B#Z;Kfl#y$BN0ry(C6@mpjXE>RH*_ymIDFkG445HxDzu zEtnNNBR(MnMn4UVXCSNwq39{qo29Xn8aa$LL z8!@?Z2V&%WEO#2>fSu1cFWhoKbOO3|TG@=l=O2B}j21fdM~CV5MEBe^zbur-3x@N9 zgxYjJc=H#A6o2!+()fNOb!QCuVIKvS8Qo(%pui9W|NdG5rGT)wNBZg}Tf>P1*y2LA zgM5x02mbvcCs>KWLKDmU`fA2|K zJ6>b`csLR-+cG?Gh6>U=%U2f3wn_jLD}#U`9D+m0qfHlL%m9G190$xJV2HlbO_FOn z8Um182@VZ-7aH2I&SRqC5Adb!-G8$s7od4=*MRsmMuX>m!<3F9B}U@UhRhUN;OY!h z-V?Uk=`UE~T)&0)^+6xDXVg9ed{OLgpm=C%dXf6V?yM!j^t@=}flzE4GVje#h5HqP zyZib?<^4e8{rr)Jx#cH>i^o=VOu#1qcYH7b;SKdg<+*a5@A>p4Urtyy5&yw^lH>pZ z%v6f?51WuJ+kynHbDGbvzikTI^TnPb(uT|VVO#8e*n}_7zhala->?&ogY(N08dbc< zetxj?6}U71#UpNHE&ZJvyUF?HWh_O4$z&>OGQ?D_mEYfZ=SW|*|>vZnXAzzM9_Jv$yOQgqh)ADWBXJnH{0PpZ@`mWxj zimOhqF{it42Mpe&J+`jf+RdZ9wp!}Mj)ubP*s_#Sso-`uh{wJ!_?4LeV)o zW6!$)4`Vn2#%gZ?nd2CMfiPDA3g3qX66*pCFuEiF>ut-{GXti#YgF4WjIlg(xDIcv z@j2VZW4{r#pON|xgCck%m5{~DwsP%MYkkU2W8=(x4)qlT?eE8SB=u|nz`efP_uI}d z|3>Zpj=`HdU;eUY$Iky@S;ssOo5cOvJ~KSa0tS@nENU18M`7dG7czT z4G8ecxGwdOo$mK0=bkf|^uw29a|Nbe!NFuh z_J-_UIRNN7??g->J^^}&%(DjMl5dqBw`61N3&FJkv}Y1*KtnADM{LZe=r9D&!tVd8 z5r~2?RgCwLMieV?7;gvx3gHrRfMn^$=Lda=;p<145U2x}gb7rl3~hrk0zT4*P279a z^Z50U@Z+=lW_~;nlK$I$Z{lwz=3i^K2K#X5v;Mzf&)jkPPR=N?VifJee#DkCuH1P;7kMo0f`Ci#vnXXg zi%djBO8mX^N+!1tB?v_5LgD4;eQ2^#d5pSFK4Ms%%*D&X@y@=e3JQu8vhs=z&*jL` zVuKe7hfKPHzdtK8b32DpvNhJwR(!U1uU@G6r@V)Y{x+c|g`3bZIp}rC?ujM*57nD;SqEn!H`f~ z;5mwRUHt18&fMzj9fFN-{B*lH;K{N7=6^}`?)1~dk;A^$K)&Dje_eFA+KQwg}oeGS&$ZxL}Ws| z6@Z(Dy+Al~|85N6$ZiNL)p>MdetZJL0C6M@Nzw+DF?@4+Xa=2&WU`U)B+Sf&=N%Cu z7vn|<=!owii5A7u%NvAg1haa8LvwkjF!m!f6Km$(DHIJ2n9F!AD%} zAxn0j6lWL&jM@UBH`$xau@CzIaeszmglkU@q(2(qNM^V$6z~=i*f^7e~Ke-x1zCU>y`vny*+rK)wfOLO50qW-O>E!zRh3C!H)6L`U z=LtE>7bI-&;p^%BdV7t58(D5n*+DdHwbH ze3|KON?{ffZEL2Rj}ncO0+#>)2McseqI_6*J~eTm$v+wTsaR=hbK4T}dpvFo>HhuN z^dyeLK`}i|o%veb4Smk?{kO?LSM?tLJVc@kZddpfQNF>ks5|T$S7>ZrUN0BiB66t0 z_g)f=#1$?%Nsw-`8*%#vCokvN=KWyaZQ-2_V;?t+$$5;NnQgbHujB2PndrMK;puJn zxs^X-5!;vD`Oa?t8}8~0N!cp`=a-Dx_FI^!XeKYvRvb%MiY?uPQ0oV1Y~3bd;?k3U zF{&5yUWK}#b|g^?8n*J1)fC8iDXQ95e!-LFLY&zj@paX@tKuqf6+hy1VsnKEa6Yz3 zoc6`swrEyz+e{`6X)#rmwu)}95|g(5M{fP>%xC>V-3wpNt^~ZkVoOj}|Jv^TRrf}I z@{#NoY{h=$BUvWuC9b5{Qvce1ez~~qD8UnjDk!^rZ~uM?6@uc#RoJ%(c4GQ)O7`JP zyGWvaiSiT&G$-gruWs$8*ll#r!+x3z{O``}odue-kUcf2ZyT{WueC7hAMdGmwiwLb zmBbZBQ?g9Ei5*d1w4~hU>U5NprB~)U38S13gV^h3B9)TdR@V(&73;J&s>Zek&xMyL zd4XQ3vFyxqlpU?A*{k3|D_EqL95q74?IuTHdcR~UWo?mVIL2s*Aw2ml$F!7muWsx~SI9Ph>}Qz5oW8Iq$h|qOvuSj&L?@R!G)_lgJ{{in_Jzi26w`8EsbO#EIE0iVU~V z-PBi-%d`XiMChvwkeGBmmzU@#)tla$$%`at$v-pzjWg-joh$ws8>8xAOisocFpOsu zRpD18iZ&TgVsvUXkug*kz4cNW<1kG^sx#| zFbaWsPM?`b#j{ZoC0sL=M-o>YOsFWd0W=OiF0P_T4$-<*3G5og=#8=gzI4>)XuM8w z9qCK6f^}OR@zjkPb3I|#)W{@#H?Arw>RBHcsSu45^Gfp6q(SW4YKqJTN*tM!CqgD{ z>V&p^y2S_|CXlS-?<8t2LO)Vj zbOLP@`+b6YZ)O7b@jNYK0D|MHnm}XWQ}qGXM9ylClSoLDAu@xUA3tbmvJ za!33Fzq-hn-T(mnJScI$^q$jkaHa=CMb>BagbtEVYDu9)jr(2gT#6qeQYH$2Tndn>2oo~(( z<*TZsnm>mPngqMH3Zze$}X9GvoQbQYVLDaEx+vw##OVK`hvl zc`9zz34$Agn1i-GI(ek*(xp~u4V|7Aq03OnE5j_GC#Z2$Q?f zl;fQN0>C+;R2Hm}Ovxg2^1_6@14YN}fsKP@LN zdn$#q@d>QGu`?>W-2b{tRJ17^R*puFRA)|g2C|Xa1(ei!rKX)R`ildQNxlJgj?rvz zwU968&Wx67G5PQaOYOi!Dv&q`=BO+I*3kMxmR)3>XqiqvH>W?Cavn*_T7UG%!+)w0MxaA<#$XDnvqg;I&%PhJ3-9Qe zb{ANb`{o-8T>!m?ODIT2)ZcYH4tkiSrby@m<-B_pn?)Nx9pEAyx4E-6ya3f?pi9us z2iCKHukYJC(n<7C`dm@PyH*Ac(;?d3VlJk{01sETG}+dmzGN%33IK@aNR9JC@d6eg znm5!*cqEfUbZYNYFM-?RP}~_dC>q2y5WidljM%Emq}JPD0Ym9}0OrSIze2XZGkr-f zYlqW0AEBNLwW;9ikvL=jnHF~zsrPpnXFOUr{MP~~XImQsd?t6wKf-r@U*lhH{o)Ue zFYp`hv5H#&i5x$tJh6(3JBWBa;?5?pf3R?t4GrHT)J@z|v;opEX~Y~aX4>rc&0rmh z*1A3>WB0H<9O)ePyV?f8XY4RMoXf1G)}1@X$iKYaC_&oZtAa9Cw!fGoC0bvkP0w>w zkdM88pWdemaYje2WY{tD@!?>P1&wDHP82TlrFj36`^H-^nBBBZ#N9I5ajm!Y)J&E! z`C9B>zH!N2ihcO;)ig*6Lp&IpcZ$7m_SDmNHMydfgCvjArGZEoXWNv^7m1yRT3}e~ z1Lh@vCILZs6yQ~HsE+u9fM3cwP>+XsQfQX~e<;zz2nb+d~*GA4t2Q@ zgAB&l(i^UWqYf_=`nQP#ua#;Or(?pfrF^IS)=9rByWdy9#tFO2H97sCOJ~-ZJO%rs zf+zn)MMsWnU4b(Ek!@Ujy<=r8tEV@Ewo)7g6SgixZtliFnK00z349w(@4qfgTt!pe z%ugx;s!2A%qd+y2X%!nA8b42xKV5l@oYP?B5H2%=z`>1G+shlwqSEE@JB{ylUb^gmM2Pf&_p*& z*CZjtBUY1cI{8dtt1D7AUeUhA=#jWRn`p3fg(o!c z%KY{a^C1XCV=+2PF@0nr{48Rk|E&V;>a$nCVCGF#ZNGZ^FfOJbqmisx&nxSJ6&bc_ z)M?i!z@fZyn=otF8_(7~KvG^h(aeN+|J6L-!0ie^}Yu zWGs@T#XDYt@j6Sfq$=Ie;-*!S23KU1&VHOCZ0k{6L#7iQ$aXR(G4ZB`z%VV%Zj&b}s_q}dvP~OC3ohxK z!tY8J*o$Z<$FoRancx(nI>|+IxFQt-y1?9)EcR6nFV#ur3wE(WzI;B@dFvM~og56w zO_qh3N>RQ?X}Y=@zW0rYpU;1CO%s+;oriwnD6Q;`&ymAXUdY8hvuaKp83 zZOfPT*Kg$tcl`HPI^CtWt9@RaOU>E0_{f_dO!n*Z=c+5X>lv*})9Vhzk)ru|U``GN zS;yOa5o-EW4PC&DySZ=aMyH=UgNcHv!mq{7zx3v1JXIlMIE6Qt22PP^w{QdV`Q@=c zS;g;@UxA=ObGT}Oohw&BD1H~2lQ`YDyfqCg^AtV&Be}d~p&n9jYCla&@gXB{xiRq$ zwJ20ZkH`l^vrGRdx};P{b{(@z#7gJ#4WGrCth}FAg^IQJUect1Jtxxws(2n%x`39l z*_Nr)_FXL%($^KGRUr&@-kL5KEq$IcLzVoHkknBPe$yQ2-{cWS!$mOhaX?+YM z$@<)MIk@;KBShveGNFC>mL5xaW>rcK{PsnghXBJaoBQ!ju**qbTS^Bkp8y%K0CuCE zN>9jEDbr1h%fT{FLX+M&J%h?up*=fk+ z){k$B0%sPT!?>`j9)jXMQnz~vlpaB=Ms;~1?Je@C2ptkdr#X*m8IK8zAVvJ44o?95 zhlnmLLf&ir0cg#(2_}8gmzmDz%21xCV$YOr?1-D^jI5=Oiz?j`Y?II~92NYD?{IY4 zcaJP>f)4ix`nk{FT)JY}wGkznHP4faz(6`I9A*kE#guO36XefDLBvgi0%8DO`dRE`FA=Wa{YsGXrbaLY0MF+Et^jBX4y3k+s#`b-d6T)uFkv#y7|#iyS|+Y9z}Xq zmcU)5bkSw{5vozf3)eB(B=kzHnjOspnu!h+T>4h!ov1syW?m!Xj447RIHih((R~})JdmUo?l2==pJ81N<1(e$$(>@lYq*E zZrwu;0{&|&?7v?Jx9qP|MLbCKFgRL$$C~8??dZJ`KEmrRGT1}Oh&Iee2I0lR(?{yj z7}kiwqETKX@^C|XfYP6Q)yxV+mR@sq?z~Yql|r;e-Mwju5s}6uLzc7$ccAlGHY@R% zYS~hhFg?>FsZe%K@;(VFl~1$o1p-V(_Xxz!^szrJRH-c7c%I2|fp=Be52BffPL;_; zRrl(JRMDRh*qvV>lhi{W6L@2Pd>$7$h3~il=|+&NCkxB-EEH>&)w*2PHYvAlarTG? zPl+tW1W7RI7!;nLX-tft82V(&ueBNPu+1%%RhUL4qz%R&O0}tgZLq9=YfhG|&|H~p zQmT@GPxJc(@?0+7v+ydi<(Z|JzLzqY=gKH+C**8Qvt(PBT=PWpwY8KuZBNQ%NrL?q z{GO3-(7!^+o2lAM%rJPmzVH}_9BpgfBx{x^|IfWE*>!u}x z)nZzxBXyEvA_Pb50;y;hBU%XLs(6VPdG7 z;A{Qv<*gF50OnCBrX;UYkL>Xfqme!!3dpbm60iUdlawxs%VI%8dZ8Ob{(QG#Q%8g< zNggMUJn2Iu4YVn_q_nQC%xL)r^UubHcXGBa?O%249k)CV;}cis4)WI4EmfbJ?7f!> zE~5}l5|c;<7MJMMuQQi{zCu4Pm%5{QCpGSD@~4TYoxatGzr)$>87HYsd$0tHMwzAe zKQgTCJ!>~IjFR7z9l&bW@T-Ysw^|+`?2ZNMR7E~du@xU{WS^w7atr-u#%NnjmbN*9 zrnl=5PCB5>HZnPgXt84Jh<1A+!#1AlgZZXI6xhI5&W7qXnpI@ROd}qu$7q@j(ZX}W zwx9iAqz|NNy-36TiV1dWBBId!0Dz;yXJGAwNHqs4`UWIiTifk8)`>pXZ?05M4PsFb z^5I#3U6RNqHMsPelrgpmdP|NQ7|o+fw@eLXt10WGfNlv+nZ(FVlN_KzAvjd3&3AWm z5JsL_xZdhse&_}ayHYTL=}V%JSbLudYxPI9>kg6594&kPE$T@spvMIli|t0L+zL$czUgTXYS!p~i~iLSVqL z^hXk1D;>nhrY?AstV{Wmc^- zKHme%<}W5@F7u`75#?sjtJVbFZc*dN^&7;QXA-E*Q1Lo>_vg;QobSnIMkdSnFbr+D zdlH*!sAm%1W@vAwWNiOD6kKAQ{I&S@I&l^Z;vX(R5s>+X@gb2C1vIv>QBfq4g?L~z zILuFZiZoY%9Bi3UG-l0d6UL+wng1Rv6&aPXn|9QgltvPtZwLGO)F)T!geERut9EEA z$I#pu%pj=%`Yz^hJ%R%VcS69dFl*VH=D}2>BDaIqlAUMDAm%9y;5#ZZ^pnS54Xg5) z^oLkTMHu)KkccoyqddFG^7(drdVbs$4IS-X!BH}RU<2>wrEw$44^p~ znf7B91WepY40dD?#t~owhRcyFNmP~uVE~ToYfF{mQD-O(e0CZsfk~Wq@qFu=MIbbP zey!og=olI(?~4NKX^UOj+roTt^Bgj?v$HE>U%xe3QX=(Z-RPdUS@o6=t9|ymm`8oE z<|7;zJAt^cdy|TVCd+$@6oa2q3xL#5ZB{Myi^72F9ydj-INeUPm62R zsZdwERB(&}qT|Js+s7|&LDG2)2V+t>fkxeA&@s&WL1Fww5H7H2|9kBV*axVWx9hkz&7 zUO*gb6`DFA2pt*3j?w6gw0-c0REv+@#y2~Kh=i^&Qv!z2g)0XBuA0*6Svqzs=W&9O zrXB;PU1*tkp|dcX=PA`UUCTi~5I$b^v|WPiMWiAElyMIze?NvW&-aBJh`Pwk>iF^eYy(XnoW`~s(%|*ev;%oEZ9OHQz zf7m6wVji`z13G)(yJkCjZ2EYl7+skm4OU8aD{ z>|+-V*}H(M4J6~$s#;_!a%9@-3)(5)q|`1Yr7H%J@6(id-NNU< zX4zm(WIQ>`wv&sJ(9r8#losPFk|CYhIhZM?*K8PFMj0t+%#3>#XGEhVx=7gT!v8Tf zXB7!pQU>ddN=M^;Oviitah7HW+HQVU1rmM0fz<(GGgn`A*h|+ek7Z}NU9yOn^EPU> zndW3dGg1mib1#ca1Wo+x);*4IdJ>0}%Df->964FyOBHuU{C^?h<|Ix^k}6JRc)c5E zIvbfppC$?W3hOr;VF z*?kS=Z9n>RcgO9+vA*Z`SUx?tB3t$fm@3ppRz0hPcI;U23k#GEP5(8~{{#k@6;o|4}A zN@M=S7h??H0<<*AgNdS{QY^Czb$AG=7vISK+C50^RLu|s(bG6iRFI2QR#W3 zGk+PFGA$9^Ly#k6I|E{(!ZdyQtIk$(v^FJ34Ni-*9n8_bj;CSPYd9_5U$wE$09NO7 zTvP6=h2}jK$wO+|vS7sfxY-?6=V5zA0uB2l^8(&;>)W?(DdsV1?Tyy{(zwA{^4x=! zIOUKJ-vHRfK|-ov;QQUx@6zd{mJhi}|3%Ixqi{nv&F8Y!q)Jr+yEy)pnhBZkN7AMq z$N0@6bu&xTsHv||l=!7&XM=1lm+rb=^hK4oI;AXlN;V;6{*_JGE6Xs-@zKVVs#;nO zm_sbg!^NBo_2^UD=5K`!uU~!SOn>?y>K#O>IngE>igBZM&{YfTyGdJeA|l-NY1z(~ z&QVHdZl?Ww)ii!8P@i~Hk%cHe(pz-H=1g_7Pq<1tc9}$&ri-!eQiJtZ!2BqW=?RkcmrqPtpLMtM}rQ5`GA_sE@ZHxF?n)~`Ar4#zN6YrJ)OG{~2&Ncf;^478VR zyT^2a;=Nt;bu7_xK9k^Nq;^;G6GM9B?WL)+uBKo`JSghYB`(_JTh$+wg{qs}nwfa3 zhZ8enL0ddmFxxdRhBffkJ{ng;TKKD<^{ZhmeAO=xA~kWordX*kG^Jcw2A*`;AbV_tB?^!6Q*stYnlu%V+V2W;xyW> zXN%oWxXXnm^toIn$E~2h)F3sS2lFD>3PSU4*NdE>Ye2mf@=t!fwQg;P)UQUh=vBWM z)u3DVXk3kG(XV=Lcwd>8G0j|fkM5q-plwW3E#+mFD(9A2u3#oZpZ1f9u`+A?F>AL=fW`e?F(_-rp)X|Gs3()ieI zo-uw1_n<-hjD<30s}_Hdj2!Nnye_5u=~F=Oq@_o25oWy=_ayyJ=+vXlD8H%}BO(LV z?D$t&RJ9FC)@1ZFW_nm1oS!;KjBfOwvRpX$!@K?(c5ezsslzhEd8D`ZhCo2(4-sG0 zk(tVI!19hi(0cN_P27K#3|X)U#nQRs8IV6LqU-q5;7y1EXC<7N)iT90v9yjX2o-IU z!JI5OxSpiYO`taP16MzTz>M(c1wdvQ$BsECqSa?Ej4XKcR$W2sM)|-zAyOYSFr1Y+ z)NX_0-zb}+zX{fo%MbrEv81LhyPqn!T<(hO5>AsxijdX}!cNr}bflm?EKr%oYQUU)NEV5=MNhBqEbe2PQ|R8>UcZR zjhT(%YOqH;4Xgiux7^7~uU^}9_LDVhA1W@f`TlREWx0SY)1OUr9zNnIZz@sQtleLt ztvYN_U8d9$Tq@|gg!pB(u`e;vX}UxWjJ+<&Dep3MU+zV7XY!$v6;(f3H22n!5ozvD zG53MPSvKqT>Z7V6Yr5-gjL5WSOhX*cT!cM7C=4^EO-21blavI>M+-39vIvMscsqcQ zF#j@F-ccGo*7E3#qL*B!j;-}>Z2Y8rJ9K?rC(NDNk)qNaP6MdJGaPRP>1=qa9?nLj zb8v*hbos-2iht@TY(agus3W&HuuN39Mk`u-z;%Li~QQ&L@;jwr%uFcUIy$(KAv2ol`LZ$CK!qBH3DBwMa#T-kibjW0XjZi>( zn_mI#=17lbB9nIlZkz~>@3W=;7bH2WsTJ(s9CYkQpCQVWUYlHtFXYA5;0mDIqWUQzvbjGRWQ#c7xFO`plKG z$6C|vFBBVqW~H*}rO7e_Q;nISH_`#e`_uCgm3apOp~&fTJ6{UNhT#F}G?V0q_>)+H z%ipy1^#^8@hKG|v`i?vPrq=m(U+W=b5}ycuFnucc7f_PmaKji3Qigv@^M(zl=tf!z zPm=FH$H_k)bn){^rVqB(POy4}I;P}0dN2Y;!ti6cUFp_6Wsm*WGiqZ zcm^~9m^zs5$AyZ&4v;nM7evvosj`bG<)1=0Yxg2pYJ!Rm?>|`Buol6&Btq|QFUE6a z%!??ack+?o0s#nJ1M$a4me7I!<~9oQlm92g-$W^Rg$2GZfxeZ^{4N6v>I+e|Oz8ap z8nQ=#&~JL$k)I%Z#}oO3;n4A~uD^~VDrxxk;8mZ-rUn%k;-?II=Bp$RM$$SAg}{6z zn81DfZyA5v+;J4CBqk85w0u5*)91^ee&h4hbIF5{%7V~|u>geb^d{|kdO%T-LC@j9 zYCjQz9sMJYLIOo#w@y5_JITIj?L9spb|x-PRz}v2s0lx^BY>_1ye%z&fAIJYzaRW7eYeDgyUCmzorn#CFwM z>y$iFiQ6iV4-vhywysu$FI?%}qed!r0MO9If2;Hfd#1Oc72Kj766;3UI=35gX zK`UGYa5zn+>*D>{DW*ei-KIA0@|uK7cob?I=mI)rH!0sIec>744PUu+yyV+3df!pp zVfh24LA;=Y^^{+aK3x zhloreG?4+xm*8Ax@gCk+;Om{3Tv`_S1@C;pSNimR#D_NdiUoxU$9R5*T%avr>?i$7vI0g_qg6 z89-enn^A|_0F}AlDOkd8O1{*GR0H&xH7+6BdXOZS1Wp5lJ~Y`AnqgK4e577%#+A1^ zv8;PL1S1VKN+pbYl2+z~dYJZ>YExi@j6;~F7$@ZO;IIOjx1^nKv(J6eyRS>vSB1WX zaX0#GqtHJt@*P^Z)_g?~Z-yfm6V$1g8z0me$^fYqP{WFa+R(Er##Yl$a`i4P`zPvW z9^f(3j4rT}9Gq&C3K{Bido7iY4ILU`?@^TwgX)t720Fa6mYB0rT#HVuvfPEDLliJA zE3qi&1}`5F<0X-IxE!afP(-PLHG=t#c6xZayln^ny83kZZ=pa$ql*oC!j9wu6<;3AI zX2%b8utMjI)?%4Od;-4eygrTBV=>`(QUIfgK`?@S{@(7w@iYu}u0(9?4bJs*R}S?i zXE=yV+ml?0d$gaQT3UHzpr1$@pIfIqj-I7K73q`zH`3kM(g?D9h)T9A9 z6Qon;RJgG`w>RoyzmpAc5B_HmxRJSi10P-piQw(-dx3WY^S6Z?qaC=DdH6Dsju{o-`g$YR1%t_I@066#Nx^b(Z$hdxN%P6JNDHQ6N)J|9oxAAPB?bj`O*{$|dZ? zo?T0^`osn1BfT-x{YyWvjA+RAhzS|}QC*P7NXGAgt_TLmSe|qkL?N7FECBbJBKCpG z3;}HrGWYI4Jl;V(JO#_3&c#G$rdaSY{qTiyyOCl10FM>SmW;W)I<)$?&)N)2P_^2c z?D~!+iXF9u^aY&swKaoHq4z@;ojr*th?Is^utj8=)zI1%hA@4L{B(#8^ghSQ9QS9| zSQVYY`D(U^)Yw+Edp?n+)f?5yxDcdhNTKe3(4^1!#B#TG)e2g|YIy(L9JsWGosAR{ z#`y-m-6;&)=B>Y5ho7t%{=M|8gZ@GNmRIqAbC3LuWwRqaVf7#)%6|>ay6U8O65z>Q z0mZYsD|x#aq2HBK((WQ(L_(Riq^nx5HfoBr=|S1b#1i^TnvuXaun+biyv7@dhmzM_ z3(K7F-Cvn15A%|ZHsH%HhG>=mOt21rd@TiLXEL+R75V0?5qnWM(A)tmbZw3;W$RG zib+^zH1ZBI?j5TGV64U_fSIoUA{bZ8rx1KB@366*{nzyQk| zYdV_ozX6@o+mdbFu>B+o)_^~aDKGl1K`7XH?t03m_oXD{X^C2QhIweSf%2-Hn=M+dk$m6C+#Ns8TPi6$+R52F$mpo(p z?pJ4ep+$SCByft5DwuNxRQ-honD(Wd0NKSUP@ugt;p>(t~L>q*}EdEjXZ!#ytT*}rpyw*21S>9g}G1Q>{I-WJdZKw#nkAGJilMJv< zh#+L`rt*da?2WChdur;#ZO@>%*(D~+{|7jUWc%yq!d=$u`SCw=301m*U=1+{uGFzw zJ=QlUY(&++(-=Wm$V#spH!}cRh7hWXTLL7!K-^UoC7;Ziik} z!YagS`Y27=9`=ELd<5qeteFBsr|Anq7go`Kz?+o2|CQk!KcgntPIKJr5!tVZJI?`D zrtdsIi;OZU9p~|Rpi=Hw5G*b1PW|d6`nce_I#F@X>5_dx4q6bU(Z98gIF~ zV)mM~3s*j3U-6)<=OXE2d#v)uG>KTHzctHQ%P!-W0q@B*9eN^h&DsSAL`% zkwJ5ix?IxM$PO)bk$Oz>eL;e6k8?fP^M|1;8UYA2v;WC!Dz zeN^=1cPIcnd?8TFY6k%HtFRF*C1XUrc&G6OlV176}0HDvE3 zS`(Pr97n}wn;n}RA4VQcAO2pj!<(V_(RUNs2FXDj7k;o`rC#^+B*NTjRx6}R*5dUp z*3blNs%F@cUQ!7mo+8Momx~yM_}6jLNQ?CnGzbtDI0?{_z(cNB1vZ=ePh$xaLp#!p zQ%+#4t5mIDx6hGr+cIL&FqYTs*xcAwC00u{y1s#JSp6k+OE#$qtqTSxJd$-}LTh_M zuzhH6Lj60o6vX6`Ox~Q~Ijwpb%TPOJfx%He^0%>Cs10g|%DHO3MyM^;`AR|`+Wxil zdKUx`B9?qya7*R+BMU=dLp~ zlPafq;oYl#VAxTHVSpHWM~y#qw+=^oP@mSM=OI7+?PCqcN%K^ghi5-l+{ z6CHhP*TNE?J_a(!KRk@6t1q*|`-Z%MfL8iZ5N(AQ{!nDHhUSGc{*l#=@}N2Oz?g2* zb$v)x8Nv(vki}z;C$3B_z+ya8UAr8CrSZwp%S;wc7j``l_iIARQrz_`6yBN>tGpJc z%7-u$@b$2Ne=x=hasLOMsUmcUwk%5lJS z>`fP&til4&5jd9f0J%IVF_rWst1y&d+=9niI0}h??X6-b69LSl(ubS#z|+Cf=iqeN z)1Q8H4*L>BO8>PBh*Ui;H^e>5@GYm#EneXYpvM_+aQ@gup#MwK&oh?fO5aJG8PuWw zCi(Buw^0cE^ZrzTH*W1>Glw{`G7S3!weQx0||sv+}** z!oP5Ls%N~9A^LBCLc^m1YpfqNy?H&T-Kb(P(g!o9+1W$@9Jxkj(f*lFneES*d@>l~ z^`iUtB-y)GgvSvDY#w+*Z(w>yn0fsPrJ``ghSE+1?qf?c!QX0A}@6ecMheb}Ab? zQ*iW{c{^JPGPIA1tjsjGP43_`I%^tITclnK>}H!YSFF^kG_kGKyy`l8)O}9e&HJcs zHWxA1U=nLGO0=v`FEx{mYbJJ8Z)mJ6sgljnJa=IP$odnXaiAV{Qr06}PKaV3lEIYL zNP>z>ndlSt38cC)Awb=BWD))sXXg+kO0=!%;wjs^88iYX>YNt=g{ z+=z<>*td<85;8cjcOVj&gOV*p82G<>2m$~pgPz8)931!g=Bn8kim0TD2hh_#Q+nmE zvzu#P*a)-cg}S>MY^9NDWnT}oHc3>^+Eos1oic$_(pAYOlL4VCCi9P$W79|7JG+^s zUIJWeH%)@WB(&j>uY-pbift;Z#yIcBQ*8~#Ic7QC>Tu(s;ra8DC@ZHa4V>qB$125` z+tAJHv^}I7Z+7EPoo?EB@Q8Dfc!nO!nLBYq*2@hE6WHPuxrei$a_f!_dDq0v{U z2W}VApGL$vuw9PJr$5n7i1b|14f^3Fr4>8niX(HJ`oR&+OcZ+K!)yEW%yS|mYhko@ z(hMa3_OHR)6*WotpWn7X?jRII^HENq6bOeGl+pk1>g5-Pgg+WvvA(vsFr6gw%Av^V zCQwp`RQ_N(y5b(~nuFZrX_=TCFW2JnLc_(|BmdnF+A(L2!xnSWTjo2`uPE}$ zY1}r9+{_g`$nTyp0>4|aPBr`@spl@Nn<2-8YmX3LBXpOJD*A1TL)V#K2oczVzxB@v zYF-t5p60TtcBNkj%9G~O8q(8sqF#=Y&ZU}8Msc&E;xClf!;DKZe@A*b%bpFxtb3r2y!91*D8y)+-{>DJnZk2xBj>7`oG-RX{_6 z3Z35Oj@CxKTp$t($kd{5aq1Pt>wPwWOGED%5E)b^wcWbVZli889Q)jt>dPUpRXjTT ziV!DVxf7W>Xcpey9mXDm6qBwQulWni>$5l8ffiUS|H6*}ZM4=VVgR#6u)0n?qeXKFuq_=}jAUx-eIm*Z}WL zj+ZQNn!j(z14%>}L)GJ>A?l1As(q{E1Qkaqa+siQeh-9xd~Dem+; z4nMOPu#YQYP)-SDQO`Azjv)gF3#MW02KY?YBJq1X!XS>(J@ml2^?lKgCglz$FerbE zs(5-O)&=_%y;+_1aR;ysiRbj?OfyeeNEXtHSgIO07|l9sBmZ>-RpUSVF$u4*2rU^) zP>(fJZS}i@-ZH=+S|%7i7`c36UiWAQaj`v4#RytOQhRc zW59ijuU&0y6B+(6I*M6J>#w$l&-w@l|Gb3eRB$e(OUP(@v-`hYeNfG9D*ui__$|q*awD(J4bU%prlg!GF)sZ=*Tsn(||`0g|dFmzwB$E;LOl=g8a=gEgyfZbMrzTPo!UE zjWzG2K_-QMUXELJAmfW&h2f1(UD%vdM7FTa?V-NgPjNTAb)TpIHLsVVu5?dVbv-(5 zKM&{%H#(d6)f_3L-?gBX?QKff*eq?s90{yV<^Ia%bh9N=<_LN-m++`K zzOAev7TC%R=as-yr@|H1n-W>gCc>oG^DDBLm6I^_=*FFY14*CJD5y%Y{Chn6vwZem zz@%N(_tMsvuIrzeNBZX$s6JfQ7mE96X-?c)1Tf2_T2R3gdDcF5M*TPnpij{)U{OC1 zg4hs*{H%D+?%xo57b#G71*(&W!dx0<4l=NyG`d3vhiS!ewB^6B2pn>5g}EUyCV)VP zwP19AXoXaeQ0dZ>;%edh(_dExD)@JIXeXU5$VZqYOS^uGUGM zgyX)NakAREgCq{+WJ`Fc2dqO6G$(p9&^_Q&szh($TDih(-Ak>p9%&qC1MX0(GNz`^^b># zj91u4>&QRZn;o#a4~tU&m6>=?r@PpG*;NHPU*|4HJl};dPxsiMs;j1G*)qLq6hoCsiPBq)d zbMkP)e-lqb#qH1GPQslxA4<&uD~W5*5)5`_NoYlyzG#RoJcLwc1DSg|ze)?i=)|(_ zq+i;8)g=Kk+(3QaV+E>DQKw^5WhzACf^)@YnY!r(JqZ!ERGcT<(YkVZgFYD?kD`M= zI;2g6gs{@__9p~=k5HhYxU3{Z7sn4yKArUNf9gx*t$d@xXVtZoxqQB&&p$P;T!H&VJbPWjS58J~!8V$1vQ%#@o zce@^9V0C{)w)C(fAK{JJ2zgCOtBIB(Mj{23B2GoYDjE507mn2}j^S&8qAINF)y!F%rS-Jbf;G&xe>U84?EAm! za;J2V0sh7^y$e5nslJ0P7*KHMoTai!=$KknHZd#Z|HD4D5iu#dN8`_8W&SVh6GxOn z{O}Tjt?tKc8^6tFL~2J02k-)!yamvj5!D5>r6_{U`tSTf|DG&+Ks{Jmc|UOdF@ zQ&$!?8=aAu2%rC| zfU-j<`tw(!qLAvFKwJ+cgWWx9o~>;7ae$-|FNT870JUQx6g-yfkHYXN;&z|KYI?C! zF5?8$%3weI{b!LArugwI&?QY|Bl%fGa<2Y{1V9%jEwS@lZs@)gWnJY@0zsYG0ah8uzb-@bBMQR?f zhbvF*Ji_&Ic+$2%7ZFI(R}#~shoe-jaV29G(#aKXQI~B=9rCQfaLr&OBkhNx-;vkT zNm(0K;$%-LPh?&n)vRQ{cF=F8LFddR>JtnCT7n7No<3>tl*O@b|63C zv&UyC)>Qq0h_I*n31LCA;SFh5vITzth`0rgRUy-JdOZ8#-sj5U&$h|T#-l-{ZF|Lq=@$x?udtpKu z8WJRZl&T(+oY_vi10_=7fjPKD@=xVnDH<|G@ra1voxcN3%qC7{!Uctb4eUO2%&K?V zRWFQnyDkz8q+*Q12Pq=U8RZ*3e)$%zD0gA>Lo8f#!DQ8CmM+>uqc%%>@4;!R3eJ|9 zH_}TQ)RL5lbxigb=)}72GKh!DODj2^=0->g{lMuB(=v8`*h}Xw+6Ba02G+Y-j~kPp zKI70my3W128CD@S1Eq(BJ~%TsRJw~>@v6eD?GRVrIMZzL{zi^<<7<2kp!0-z z9HlhBy#v+=h7Bcug)=PL_r)h{$>kx#-Tg8W$*P>8clFAgqqR5n^(`T!@O7z|!$W1m zgmOwA2kU&ch}$P@drOJ8cEVLwWeRqtVzys6-|@WYV9-EubZvj}`f$^^Y(V1p5ph$Z zUYo-t>b!=SB|%kCHPmW)}i=tvY6;|64Bc%OxoGT?}|T=#CEpzHB+F zY0eV@Wb?F4xt!Cy5U9uU)uO-*#=1(prHW!wM$=)Nzt`&j7qB43!m^#oRf1tG+}3R@ zW6*VwIRfpt;s4FMxfb!<3zCh;D&c25c2sT2Cm9&;z$|-!YZ#lC zF<=A`u^%trr`ea0KkGQqn}Ayww?DDnJ0ss;U&O7>q%EaHFY0(EAzRz-^YMe5RAaEE z?wJd_sqLq)mxVs@ysr_YxCfH|3eim3hKeSd^zN-fKPra&KRAz>>Vf4 zg%p#NlzQ`v26*Ip^F%j@F$Bsj%_}q_{-$~{w$e9P*NN0 zZAARS0Io0D5A_^|NcymqKqMlCeuqHh5{Se@V~d^~(k@TZK&(klm2{rJpLSW}lOoni zFJ~t}+v{b2V_9OZ%x&m^aAD0O5r1hW_D?oYn)VYmBc52W?Ai=!YZT1ajZxu41y zDd}JD0KYVJRHSjppbx87 zQUPM-GYFh)01y+HOlci283#8KeahhK8OF#4G}9q@Es0vtf@smSPO>ouQ*N+h-=7HWu2Lh;y=WwgPB!YnZCenx-1{H@W^+>C+7 z(Cex!9i-!veZWEe*QdaYkICFBFYdn{J1j}ZSEm+$+u+{ zwiCf0I(Z#c^4?WTsp>Eb&kE+GxUcPEQNIH3?5yr}T?wO*^=(O?5(Cnw;&|vZDVC#c z6PB0!lsnu^$XY2N=7Oo(d@))5~N>rC-^kJSERzuC*&(DN44o?}0@XF-*@L_oN~t*MfB-)`8PJfb2@(~=)qOZOlK zjwIf-ohG?-TT69j-v5_x7`>=Al<;dwuo+{^=BdS$p&@={69IAaNbtVR25~>&P1{`>Vr@q+@3v zd?1uPDKA^RBFOXsl8!Si^JR=wHiIEZ7Xv>h2f8{#EBJ*xzSFb%e<{-u&!WP(Sa=h14!yp=uYvC{lKzsx0d$kVAJnYKXLcCATX z5nQccj-2KQK8Rn|69G$mOff4;Eh}JJhBMbn_L8c?yLi@O=dfb3mK&4xy|tvyGnuDM|kqlxs`C$NNHyk=>}IbWu(mpgApNTYPVD5^|X zaXZZe$#>qhE(HGDk=h7XN{Yscc!*IW+68+-;h(6cSvS1;>Ie~V6|XgB(IRGpM-jM1 zhfTB~v^K4ct#kZR(9@vbJRV1lrQT_tay>`A$g<@1H5&PbkbZe%EG9K#du*VPYPm26?g85lHP(zU$V-y8sF$(SCsddX4&VQurhx$Oc>exs;t z|E_;l)E$Anvp-U5ZhX<)s@*w^J2O$8IW8xdQ6Iy;fKx##rmzEUd&23o~ zrcE6+a$$&mn1LYtm6$^|ZH^cGIWOJ8Rt}k8#qu($YRpc7Fv005ci8pu1-WqUl>0#V z(RSmI8|7(!O?VeX?D8pToE!F)0BrWBgO)P#c}t*P%iDi)Yw6hdCVuvZ6>=*Cm~#OB z8)cXkneI3SVIJkczyKOiGSs^q0ct>qO5qin7~<#3^4dEuz2s=wf8cqh_wqr$d$#Qe!TrO>le z^{qwy;6k6t!}d_ISy__0qk>S_7U2p0>DbqM(*moJw7-mf2M~xT z1Y;}L<8Z7CX_kZ^RO$Fn|E5FF~{u zV(lt|l`y=rq@)J<9qxw+LyK?HiE&_;utT6h71F(A>Iwjqf5E=S>|1e! z0Oe_Obvp$J4sM&9%oMNaH7I|mAR&JU#6JnTQ(^=D!E%=;8Of5ZRoXCTGhVi6qcz`+SM zn*m>C1bUA2ivrv6bF=dl>8%b+o(5m!BAKP$q)0ZBCVao@1M#Hm!4>`xindfr93*=ncB@PV)(w%Y3Y1-VTkTwW)JCEg#4%+F(f4(= zyJryon@b@b+zhxhdg+!75<8SJ7e_@sml!JqXAig(|Ic?w_mJFg8v!P4<5tf=IYODg_GH#M&NDhLfc9>Oa_Tfzp@#Tf z*@nMIpX-Fu8ESdjrQ|4C*~2uNTS^16GwrczikHsDQPLV? z?3{a=1U2U~DEbmJMlLxACRW17REVt;4c2Sg1LZl&Qxv4mP^IDr4pHWHBjc-}+)7yg z993~k2-C>%omErWULsU2wd5a*n3ypehe}uy2;FOlL2Fm!pZX=P^TlQ>XKWc0Win@! z%bmO~OErw6;PrN#@~N9zYYh*zV4F|Y!pa#)KTT|uNBrF((#gaf5o-}@O6frSLaB-K zpgynX4j^R)59lT}}9rT_J2h?-Ye3qx@E`voxd7L;!gC z^l8Wf;@UP5ysQ{;^;k~Jj3Ti10LvZ2!SJUxuPo7Wm}_GZ`F-cGTFh@aUH-sidh^D( zCUQ|bxDa%W1#4Dr=aw?P1az(9{+IeW!$xCz&fOWb8XzcJoEOfT353yxFqxR&Bwmaw zD9x;88iawK(bVwy^~H=lUKfHu5ADY7?^V~O0}pt1zyTJWFReS^_}f(*SRJQAmU?=Q z*Vo^q<8oeTTyR-Zu9SGj@q}l6+AGpj6CoQzb*LoC!L%S07Nj9jnlo2iLYfJTTb^S= zqrevJs&79&J53KiGRoC2x3o>wDJvtBb4tCZI7L=|jUUL}OPiNg1!ba?$q$x+=jRe+_7_*C>U=anW0z+c;lDq}9JXDoF;8JC%0z6_vG)-nQ%X}- zb(GhvEOezAWR23SysDzlo7}(sn=vLVpqk!XR(|$Mh)Qx9ymnOa#R=k;l?=LQt8FQ! zJ-#n1t(bHq>VKAZFup_vAyQARY5CR$Z!%^;fJesbQ?B(Ns3sOC5#vdE;A=c!yK zu}$O?m@7C&vBy79A>3e{x;2)9ts=&TFwR{*VGLak*e)Ln2>q>NYs|j`=zwth!S>Ug5h2^-S)oO$@!t&M!rp?gFR(L zxomWGjDX1@G)~Pnz~&-{YNh-vJirt)EXP!MlpXm)71bwaYyB#0qFtGX)+?e@X+%__ z2APD+AkX`N#jv+`XuEf)1Y+KfaJ=$Wiy%{4YF!|;NeiEqK+D;U6~A;;pL7hNJ-KeWgTT{hv;Q}FnQMbQ90OQ&8a<$ zD29WTY&4)jl33+LribbfOfWD=YMbs6BEivv>@aYW1wpp96J%FHOf0M6hl_8-iDT%~ z4Tu{qjz0csn6&>laO(9m0vNf_fb)5I3YMbi5x_Ir@o;eez9jEAyF+p_JuEbBdbbhd zHh5;H^m!jk&xGUAu-}4ahD=!Vx`py6Ir_$(`Art+bzOwn>p5DzyEtN$xtWw&y;S6W&ZtY=J)xSu{cUb|#n~7!XPYfY8^nJfIs8730?Z_1@&vi-%|3xwF0Y#8eca zxh5>NZ0)=gNegC@AKB!I5%HVL^HsR zsj)v;l0}f~m7dlfBg&}=cV})g!JLy^+`qdpt%Sz4o)l!&(eIOdtSP_Qreg2R;8O9Z zU+~^2**&vloVx@!(_pfFafOmLPKyt57KuL`eTz>2O;OC~oVc^DP(^lzx}tD!l~gp( zFi*Q|%}oSDtJ9I8!m~LHVfS#sQX7pSh7Ji>;wO%@7@3AKhd!vjVPiYP{rsA={j?Ex zv9b-c#0)hx0!#Z75HxQ5$rjJbt5UnI9@km{iBfGxC*0YkTjzgF9XzD0+!o=Q-$89@^DGIHSySkwv*&p?r?7GtIummCqPDMuHei;L-8#pt3p~ zbdQSCyDH%LrN%{-aub%h?|jt4kycNVp;IjC(vTSJ?D7o% z#^aT=f1x5)-&|yy>g)@yMb%K9Q;hOHAO!{XvDN_d zeLO+8l-5`)bc1A(Z=#;4Fhw(79dBRX`s+%fa%` z!gqz`-}%wCb)Xd!EX%)R^Png?BwIipe=QTV_!J9y@M9-`h6VoNCt!2O$3H^0d|Z~m z`__u}xkwTvV_KwF*1)3ePaficoqOUh>xW*tSn2n1>_SM!*h8Ts=v(-pG9#ku9QYgz zPTpUJzC}GFW6IgvDCBRi-Je9DeXi1N@{7-1xdVZB?P<@wf)TTVd<8?jTLnh;ozs5i z59a004@T&F08(@HnEWtCICJRm5;}eOxncU-bhjOiGU&K)i87-A`+a!a=g*}Z1=n4< z*WWIR*-?t2*iLEAuXt3PqE8{O^BvdEm-i&9y55l5eJTZDjAGN4Kl}w9K7}T z#ZYGn?0NI*j7l}i6(wa=USsCaBjDuY++NSOZ9qI3tS)zD6McaiZ5&788Xfm=GlF4> zkvDZh>j&I8(p(C3JLc^v<=y89|Kuf?*6??)*E9Rx;EqJU-%MqC5xR_ZsTjbL!&*S^ zoQ$Y8Gf6GW1R}>mhZ&XYAYje=n+g<{tvWShuk~mCe(AV(DIKp>cuj$Vzb#LHUw>D> zYC{JxppW?)BIgPwSrlhHw#4VB0l#2{-+>p%F;tw8OpT}HV4SEw-tWll!V6m{F@R=q z;7v;4#m|28*Bm~egPmdzz2^yiC%zLz5su1Jv&F$769wh?!Yn2uCgk5gDLeTBVf=8w z4YknJBJi`&`@TO_bT|bcw^$~D&dK^Dm5gxa$v-D)#q*v1z1|3G3+GN?J+4@4(TE_6 zK%tsV32uYTQm|060pHQN`pPK!LRY{f5G!X4GWxyJqmo$@J$a;W(&(R0HOy&ps-~Ma zoVc~ca~#nfv3J>tt!o?-&l=}<*VT4SN^Hut$WYz&D`hychRV+_tXL+J%2{WyUNCnI z7hlt@w}a8Ro4Pe5TRD#o{VNYmBlpMauoMc4p8kW>`^XSGpE3!};>CDly$_9E3E{$M5}8)GG|K#B4A&RzPwPkL_;2k^x(GBox8)1a6~W`@ zt8PCsejV62IM$uM72g8-C6HwdvCx_#HuN2+q3R*pKg8+YD-g9slg;XIM@!;2ge8DOcth(C6VrVH1cPX4GNN0sF!okr}Cd>qv5%+?QKGa?!!W&0F;}b zQAJ?y}CF9_lM`+bl)Lv6>&? zeRTc5^DRxra69gDVl0-I$rg);;zEl?ela_XYU?BhqoRp;rBb&Xyoqh3nU$7M{OwwS zK}}s#2(hoi_3b) zZaD=9P7td5Wfm-GsqaeSqfq}mS*lPKk&YwKg};}iZNPau;HjjO=Ds(Jh-&RhrZO9@ zQ)$vd`j*X zzmK44#(Bf9uog}Q(=A7IIL^NYep6XSBYN3H$ao=GH>}OB(Jnvvj~^$#Ha~9{zTY=6 z@Ao@i-|j!a5k22I0lObpDFL!6oVu%`?{DWUJlt(>7d>xghP4EYVc|jAnrZu-qy*ZT z3zFH&xyyji3@XwhSl8EA-99fSFIU&!niYVNZJ!?Ig-ah@IP6Nn;F76I);uD1(}OEx ze}n|2h8=JhqD&?i013?kfh)TOmu6JSlf&YFlH_2WUwc)91s-k`kOylj4&EyxZ zFf>w)W@hsVyY~mQQjf^F)HIY9-zV|1<^5H}LI~VM<~0(%;mWCkFC9CE9`tl%Q~xFm zlWD#1NL?X1>GyQXN4>)I5TF1vPj;EXXXU|9$ivb5-`x{Il&X~?>S3(!Fp3?OJP5D< zIeo1!Bbee8Q6o}R=Kox;I!3Zp?5ZlyhoodtU$PwXzUJKTe|A-uX7{V?DW!^A;H2E( zb4~$d^6xVJ&}wI6wrWeK5-Jm&d}OSXalu>&rAQh9&td5QT%lK^q|JB2^bKP`!G$XmCSAysRqK5<14z-PaXp z{|;h++TAGYijx>Zp~`WljpE(g|3%Kz5k>I=vTAB^$w8*hj)3<>+820pvvkV9>tiCc zrIeN#GW;5J*_1pU!K{SmJ+wOmZJ2t(TcQlXm_!U?>6SMhs)6U444_{V@d(DwuTnGR$7&3$>V!(jX)HQ`_5wxv`vX;5gVL}PF+>eWi;Zak6$@?^b|N=u8zynQQf z4khj-o#kCbH0GJCoafk4Mr(-==lYD+CaFlk%gLI#%CY-jCsJb1eL+)UqWy~SwT zUT?i!kaK@fF?MBDVA(gVqjy&Xxt7-UKtvD-MeZ5TqIsm) zaH8sWx+iAY*2I01G~&Oj1C9q#75=V9F}za_Rv+&{6fF=y7qcLVl85Hbms0z1q3{`o z%H%a!_+;udbq7g8Svq84DMOy!_^1mL+NW)*!>@Mm{JG2%1}HkRWO*N1Y9RGs;L-O0`D(2D+!|*xw6HA= zmJ+DdM(1~Q*b-o@8RrY6>FPT8ZCQo2?tbmAL-20q(Cs$ou9wjLJ}>X znY_7ku{8cy_jK{pSh}c~)YEzVZ`cFW3pdwEw#_W216EhPzGU}ylo((GWMmwNp&voC zZckMIe34Q%YZ@RDp_e!`{`QFSGlnL|wPx#uB=j9o$QvTR8zk=I@%g_`GY=-q8&}1T z$)=%y&A7OcW;D*u|M){Hf5F{)mMXy>bR}^#-`NC&Ym;8qXl!hS0YL&pEfNOc|qtvyZ%{<~*r%UeIZkF}jx?v%anRk4I8LB)7 zs+pNzVLFFis(*qwS$&sF_q%AGtzo^4Oo!F5jqwUJ5UOw$AJ1!&e>`rTo5?lzci_62 zpIOCXzZQ|1(xAvVY`WQ++FO?SfCh^}j(JYMPt(FjFJC{Z$|bk#HYt4o(_YA|L7i7m z*&1TaD6nI@8fCA2C@y-*%R`^El}ftyESoOFh2l1deK^u}xmTajnx>o2cN!#>S>%daX}rvT*b-8&|L z1)ar9z{1oTh1vCc%rBtT*I~R4ysN)a`xZTgd>;j(|1)9+fNwbVi~Z@vrpBL`CR|*5 zrpxbZ%*>D|%g9(cO#l7c>7s7{g$AUzP_|bHIrgZdUFkcl5MH~gJG=lp`dnb3A0qs3 zOfbNb&?Ak2CyzjFm%Qr*3SXWP8eOX#U#aS|_z^WWZik6`3OTPyD=gWL_Srcy=yu^o z{|}+W?@%?SRTnKvA*s%)2fbE-K4pkqSV-fBQ+P}uurI))+f1N8BX>SwU=CgUX8CGV;32}KVB^*OsIu!cTU0e z=>~*8ZFdkIyj_^TU%s^18$zZ>N2d&)Svc?C-${UXS0JJ}brpZ<$|ON-8=ZukRN2Ko zbd&V?*n4q*F#0;CVM8gsM0%zG$vbiQNI;{NKoWjGbSx72#!2)kQV#%BBy1@oqPro! zz!Gpi_<1ArJXNb`G4hq;knK z-?TrjFvz0tu+%fiN6kEoF;J>>UV&eo-riPJdRz^x0U?Mtc>mF(IpVJzOs z0nM>Q!4{^KmYBTCRIll1_qYSn%^xg0+d-bz+(g&p0)7`ev9vQ4o`MOAN>Gv|mRGWt7vx zqe44vbMcN})bVXzkL64$;R-EtRO%ZJ%{2C#ut5$KiNFpJndO+6kew-b+j7I2mG3p} zf3kH22l{UVz&7x2uUQ&!Iw#hY)yTi?oyV2#tWDLJvo7;KfCd+DyEUnqX*_<6PooE> z|Cw8lcC$v}9BwDOs3m>)ak<)4;kR_+`ry1n00J*xs~K>8Ko8iyWH3PM5~7140g6{m z<1`%8MB^TLQ?m_b-1`JdK`;Y6aN|4Sq~+v9$&zQ0J|u<2W1wwiNu~oc{#A#7#fm0( zl=;1OprQ5YK*zA{APE6WDPwe02t{$4%PKwI=!@fI;2i%LAmekXvf2w1c@MXw=Asvg zW}WrT|29NTeRaLP;12aoj?(1!N)@u~lVT`qAVAj0MiG%xD7xc&Ol@tlQKMm_7|Sdj z+`K?uK@h#y%`!XAFy3f-_iWFR&Gq2BW*zav!kzyteXIz%uPxMSCZ_M7!IAi|-drx) zC)3$vb0n7(KF`WWdjLEpS+ZCE1j!4boeBH>Ov&yG8A8xz0}cC?CEMBH*h0VS_|a*R4Oyzq%@lvmUgGUVsKhTn~zF|}S03DP*? ztzeX$e~NLq2Ii6SH#U6Dp>V;nbf03GSz*z0zy8+eg-HX!@Z<=X<5Sfm9w- zIeb-w$gUlGEhO%0YyU9W95pj>TT{BmcFnYp{Bq)E1S5E zHeFX6SU3Zbo7)h~9TzRzTp_)3H&S=?VBsxwbXBG;b)V!He@R#0QqO4IAq>yeXQk(6 zaF9@~WOa95D%ob#J5dtf_nP1uM&b;soq~Cvd21w~cm2f#V5W8yf61W{{P<%BV~O}xRk#rb z*8qs2l`pXU6zN2`EZwB#zNH|Sb*!EZ9zesUiaXUTjfc(?47isH)xO8rKcv)}h~K5u zqUE!^Nh_-v^|_6ycC{7dA+%Lchp}reqQ*lvn@H>gfbmq7hE-RB{n+*XD&n7*1&WW> zr~Cgf&)|*@Xl|gp%?ZbPX1yDqFP`bxs+2~xXf>Wy)|PjkBn0I6@;qh68|s;?FGM(s zbZuCahsbMhb#{?6Kx{R!jdMJ_$f?2_eEPfO(}KM&5CJ4-XvphO$xg5`0* zfa9u9Q=PRSN~*@I1|?LFrKu&T7sGdK&qLD|T~Ja@HKy*4>fNcm4G7I->`DZ^^RvT_ z0`@b|Qrc!hstITMgN7r3pIX5NJ<*REz+2;@*4CdQ^@7Z@DG^xGLnZ(K2LFsX7@7Rl zNni@{O6S%d?ne=&Zl^yH8FDM*kUasKdM+k(kafC1MQ#U5R`^O`{M6@ z|K=qj(+Y~IHmu3ScLx+VTXCd)JEz2U)P+#IbV^|oG-Em={@p^T)(4WmtnSasG>Q@~ zOQN=71SeOL7W;_|y^cKX_g`D}AuY#BI?CM&?g{Um6H!(+CKjq&G9VGWIk^YzV}`31&9CZS@^)(&9T zbqO3)&n6~|3t#%Y!Jq{lAw_qOdD3d|`1a3HkRIoNiA%YCpFqGA9~%}Ne2zd3%6SDu z(_xX?r|XU>j-P0M82H3hpk6J=H=C80)Cf=9S2p3t`%IyE*WcNcl;w(gz&oMq3$?yd zn5zfXgwLm+4Hc!8$1t7&4OIy1g2HXFM_P!S#wIt%|6R~V7J%gkc#uq#P%C;c@(f87 zBwr3Q1|;OtDNZ3`6u^chN{sIyWiLWIyFCT13>nF7y&A{;7tV^^{k@Fi{VE#X;VBJj ztRU3NXE^EB*_o^Kcak}`g>SN8PzoUi$G&-1Uoi@!BLsC=_zGPW1C_Zm{kEb_@+zzm zLTux6m`|!qs(S0<6HeZ_nAi%pgU+Kc^|8IIG*ai;9!x{;GxuHBOEg_~Q{W`R)4FEm z8JE8Cd0mHfw0%dZ<%n~z(;0|ls})xAK}nnw|37=Va|*M#>lRMzvEkilYNEp&i|%|e zZCrlM2QwTKWAA3mQw$Le`3 z>HSc`+o4D_TdQma>5=UoBngF;r01F%)4awzZkDG*K4+_R#%9r!^}GS=X)Q`?vX9jn z!#RbR4LN-u5c+G1zu*qi@fPm3%nA2!Px{LrXDlX zrS%m)*gQ-kYsw||eL-n#9Gzc8-1WLzN6^d2`Hsndf767Q^R=MzoUf{BMHG_N_9DKl zXv0c|oHF_ zWI8A5zU)` zf96qqki^PytxoCnsfCqoQy?MHO8xzv##0m@AEgyJ znJOTPLtQ0vuyG*KG5ss`uWSi(9mZp2uDiW|$)&etyWruG4`LY`zqPgfO8)<9YwNxI z|Nm?ZHa@EQzts;jCyuS9i~alU^uv4}VX>vW^A1?^)UI-7I+>nHlvD*V0ku%fNeDT5 z#qkVPmtbt??JC_+G$Bp_laBxd1TCT^2x25p z@s-O-oe6JV6N30c7A>C=g6!*KEIIa!3=R>hP~(XnB+?!vQC z;HKWKVRbxD;xUpZUD|mOz+i#~U5fxOMuv?uK{vz1CZ#YoE(zWV&0bE@!iOw+X2`pRHV}Lz#*RhcLYlp$=*R97Ein z$@XWm&jva6>+WGMN$^eYfGe4)tQCCNB;4~r3@MFPo!Q#7tARyLv?solm~IA{0w4MI zSWJ+-ZDif>;`%M700z()5X$?|tp^C*(zi_>;tI-Rg@ZRWmxsT@C_?-IMvw&lVH#Fz z$5ae|fZz4u6doTF-UJ2~`G(XlCOxmbFGc?A@xW%qjPDrg-*jMym1rSN44KA&Ob`sS zl#-K9HI7G@KcQ-4njfkL;j)K)0)XNkep_?nL#@ptG=fRQ>k`f!KFJ5<$qL~W4*%V9fP(j`pFBVmu41jZ`B0(t7Y=>RxG@h+e9^X*8+8n z(qCw~s#1?hzmr(r0>i6zkM7wN5c3${K#sr^$%GZghFU{FJo)Wpf6}_BwEVG4P}-F) zEg3Oc&_YhTFo0_UxqQyN3}WlX0o0ssJrCi!yE7WWp*ym5)N_#U3rXiirsjPEe==heWP;~XjO5@DgQ6C#p^dI>9BO& zqg&X$Bl%=+`%O)JkzO@;Oxo@rJSIL>9e(^AF1Zk{e+Kb#>f5o*{UZcona9=upU# zYWN-it2~GK>T`h<9pkO;wO>&)mBXi)&dk5hC<%~y@taJFqjD8|hU^5-u*%!;8M03Z z9m0A3@H|E{oXqqOr?R?)%-VCVKS5RU>dGSg!{IzcOT^_{=A!|i~a7TR>Ntxg~WBcxA>B0y7?Edod+Aa+T@tRs{S)groXrSt}(Pay$G~kY;}Q3oe`iuPn*MnLI-zxa8Mr1Do0|G zyYw1n9xemZa|4y3QKwc5Q9wf#gAKs~MbRsLmr)O*GppdT}R!uDVh@2zaRJWZ5w`C(SYb7>rV#Nc8Q!9#m0H9fzP2Q`fGo&1vI>x3l zIxcIJ-J9IJCRfGgc7_rHx92x~Xqe#a}fdUzkb8Weaelnyej`)EC2PUY P00960WdI#R%@PLyX+Im5 literal 35157 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Ðaie^%Nr|LR2o7PY$GRPNAY~b3*Y=}#5 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 U`uXes2LJ&7|041058f3A0N>qPfdBvi diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index c69b25f1e3c06d1bb4766caf7b546dfca2695c73..f516bcce75eca08418be9ecedfb10c26839cdff9 100644 GIT binary patch delta 11778 zcmY+KWl)~Mwxw}*2=4A0+}+)s;Dq4%VK46P1P>0uEx5b8LvVNZ$+@>`=FFe2UHzxK ztE+ac{j3#jIBXD)52R3mvX7%YBX-x8-Rw%9H!{t0#3(8Ai)B)Rf6(CpkDq8@vW~E% zqs12Mlj}N^jx|?jJcoZvjwkX?rx&VLeNwopt7yxEur6Im1g%oPwojXtd~ z+kIbXSz)`(Cn23G5_E5Rx%}bjAmlzy*N-`cGTv7$tcat~2UL;7Lo%VZ=nrA~uXBXQ z5l*#o@E0RPj!APUY`?ufZkb(X^8aj0y{2aMY9q$K1elDLM zuMYKQFt^88Px80Z?b#wE_}yWlr{B!rYr)rxzJccGT%Am!1-7~|v2b0jn#W^#A%)Us zeKTISQBcz^Esgw#rRtW-SXkF4&$-sh<`sHL7NL~DfzR!cht_4D=KQD`I8kBPQ{0tM zR4XB*;phN#5v#k{COmQv1>uw^WRo=^BnWE)+R!G8EHlUiH>G?#q%;`Tk6*(JZ2nGX zE7Ry& zOUECV2iB%7pBdf4z$+8wp*pPI_R;SN>niM}8u!$S%<#wkI!+PGzjs*V=h z%&;J%Apvk)tcTZ4c-WR3d)A=$`;w9O)ywp~>H;d10Bp!V5Psp2ihkAzH;59u@LZ_C zMAZtLa2?6o#`%T&{0-(YhYk!d@A2=F&BvS;&c52z+Z zTq?&Z9|ss;1;?ami=iy1IKP8bvY8ZM@~(t8go_+NNE`Be9flWJ`ddQKoDrx^s!EfQr(q0e`CU3FB|9mtF9SRS) zb*0pmFwe@uB>UMwUpP3a4t5f@w@@*dn*Bi-7qK(`Gn{S`dP=M@XVrivN7H}93QqYz zye~{0RlHBs-WoLNJ0$Rx26rm3&ln&|qSjC4es}BtvEae6g?M;hfw|hzg+k=;bczLq z`_dJN_u_Wo9ku@{9D1?1{Q4<`?DY82#+LGeDdT1;DLPGQd4y z0+p>JOWAy20#VV3gLH3hM#I#<=GMXDKv_(Pf2YSN9M5DYx_x@1bcjF>;~)THFW-gm zb&SABuFUbGJ+M8ZR=OyfA6e`C&Xg{_lgd28NJ1ZWP#9qXo^kEZksB;M%G~NnBs%Rr zuw4~?&8lsZTFP_1LB}R+kS2_*)(Fg2l%Zl_n%^s-;9#|~XJM#ndr~G5(e+9vIN^fB z*{C2jYa**C`%y(x7qv+u<>3J?*}q;Gn!mCWYR4S$P*=)oCY_uV{!9!!_bBQRB5^mpr8w8 zGE*9{MZdU1FaUQ>tzRr^WIlJu`Ps5miQQVJu54k)fm~z+1-vtp`ObAmg

P`^e;V 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�dv%f1mKq42~5sWIZ{O?6U>ug(7mYp7`=LHrB2m@1l`$gQ6 z%)w`-gtGgb(7LV8ihd(%9>~K~3^m9}*_4m)+AMI!fq~?6Q<&vPMC>iPHL%wk3<6Bf zA}J?jR^MC{q+jsCMrR8boCh-ysz&H&I5Wf)2h25H1Ej$dzHpAswwy%*9D6JpCc>7a z6%=k{hsj*QJXOqf{`8hCE5ZrPVnknRTSSsOJCF8)%D?N}wW438Uv4?^+-C!e- zs&;fuy<+qpr(1_GN$3Ens_9R&+neyEEaNN{ufT)XpxnH95X{V;NSoLj-c5?HsR}gsK5s5#VT&ev9q&ZFQbt z7UVKorRuH5RX>r{#X@*k)$LW*I+)dXyfb`@3&@JapH)D-I?V!0Cn+ z(1qE}9@sE_xEwwgjQ&m1Hut(|ezLJ0mf!IQGD=h=ctw)6vxya%K{|bO=0Bm3@mfy^ zE7B*0U(Kj|2gklLuuC~%nX4bt?A^6EXyG`laNU1I7btTCR&FTJy8qo}rZH6c<4@R! zjsHwCp{O&9wGXr_`1Lq-oV_Y=CtAI2eIXSun}==)jXcX|C}K<8+kOwO>4f{!!ig@% zMt~2V9L`tz5B&eC^L+5zu+y4gI8Lm*%N?>|@Usq&f7)ENcG!i#T!F||m%zD=O?(>u zYAE{CK&?sY`InP&r_NBnnHU-NJ5AoF$q(WS_ubEsvujJC2LIiD;J3nV@L&WK&3enO zK}xCf3?$OSgozMKmU-lS0-IB-)cg$w)&(51nqolX%#m zFIz|NVjSK(0F2;?7&(1k9FdvAEt&Z3^Mi8H_}S*4;V|u@g?^gG5#3V!OA>0yM@PLx zwn$(xiCvt2x2WqrP?%Pr-l6Up);9d>&8uj~8>G|HWPuQ<5Nt_XVQockKU&q2 zLyq(Ed!K|k!CuVfwk(3PY^8Xqf~CV=tZ1CPZ&f1=67b!+cL^&v1rc`ha2Hdg`jM;~0~!l-r7Ty$lmW(}vNE-S@-1{0EdI`w!$ z75+qo4YWRgeUVsKtp$Tb=c%8_YQNc1YBlotNGcB;_VI;gRnx@afTIW6y@u%7 z_l1@G&)?D0#+ZnAoVRo1${bxdV{c6r2r+)(a226oHJuh`%)DopcrJT88=@|UA3u%` zJPqqoxpJRRcTe33jSunoC9fKv{a_W>=gUwx?(^G(T$jQwUZxF6TGJ|`IuciFA{&=R zfz!$k&dv5NJ{;N-En_jJ018b`rVM=odKl`c;d7^xlyHd%@v-`mB*MbJ^N)v*yfwD} zq?q{wP*mt|M!>Q1J^WY`9t5s1cDB%ZPt%eg-yjHKcWD11^Eb6@Xd?B06mMSHDfpj% zWg++z>j?p3e_J-e+Wo_h!DgB7Q5{{^YTKi$pXy83{6`X_A&MMAl3zfdkRXv7RtzuL zfLP*9n;iW(1buP8!vVK?S*JlJmU) delta 11833 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 vIZ*=}ln5JeVLu!Psmw!(*<6`u?@?nXB 0 { + switch r := env.traces[0].Result.(type) { + case *ethtypes.EthCallTraceResult: + output = r.Output + case *ethtypes.EthCreateTraceResult: + output = r.Code } - } else { - output = encodeFilecoinReturnAsABI(ir.ExecutionTrace.MsgRct.ExitCode, ir.ExecutionTrace.MsgRct.ReturnCodec, ir.ExecutionTrace.MsgRct.Return) } - t := ethtypes.EthTraceReplayBlockTransaction{ + allTraces = append(allTraces, ðtypes.EthTraceReplayBlockTransaction{ Output: output, TransactionHash: *txHash, + Trace: env.traces, StateDiff: nil, VmTrace: nil, - } - - err = buildTraces(&t.Trace, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()), st) - if err != nil { - return nil, xerrors.Errorf("failed building traces: %w", err) - } - - allTraces = append(allTraces, &t) + }) } return allTraces, nil diff --git a/node/impl/full/eth_test.go b/node/impl/full/eth_test.go index c364a4873..05c3f2575 100644 --- a/node/impl/full/eth_test.go +++ b/node/impl/full/eth_test.go @@ -1,11 +1,14 @@ package full import ( + "bytes" "encoding/hex" "testing" "github.com/ipfs/go-cid" + "github.com/multiformats/go-multicodec" "github.com/stretchr/testify/require" + cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-state-types/big" @@ -177,3 +180,40 @@ func TestABIEncoding(t *testing.T) { require.Equal(t, expectedBytes, encodeAsABIHelper(22, 81, dataBytes)) } + +func TestDecodePayload(t *testing.T) { + // "empty" + b, err := decodePayload(nil, 0) + require.NoError(t, err) + require.Empty(t, b) + + // raw empty + _, err = decodePayload(nil, uint64(multicodec.Raw)) + require.NoError(t, err) + require.Empty(t, b) + + // raw non-empty + b, err = decodePayload([]byte{1}, uint64(multicodec.Raw)) + require.NoError(t, err) + require.EqualValues(t, b, []byte{1}) + + // Invalid cbor bytes + _, err = decodePayload(nil, uint64(multicodec.DagCbor)) + require.Error(t, err) + + // valid cbor bytes + var w bytes.Buffer + require.NoError(t, cbg.WriteByteArray(&w, []byte{1})) + b, err = decodePayload(w.Bytes(), uint64(multicodec.DagCbor)) + require.NoError(t, err) + require.EqualValues(t, b, []byte{1}) + + // regular cbor also works. + b, err = decodePayload(w.Bytes(), uint64(multicodec.Cbor)) + require.NoError(t, err) + require.EqualValues(t, b, []byte{1}) + + // random codec should fail + _, err = decodePayload(w.Bytes(), 42) + require.Error(t, err) +} diff --git a/node/impl/full/eth_trace.go b/node/impl/full/eth_trace.go index 123d96fe1..e4e5d794d 100644 --- a/node/impl/full/eth_trace.go +++ b/node/impl/full/eth_trace.go @@ -2,15 +2,22 @@ package full import ( "bytes" + "fmt" "github.com/multiformats/go-multicodec" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/builtin" - "github.com/filecoin-project/go-state-types/builtin/v10/evm" + eam12 "github.com/filecoin-project/go-state-types/builtin/v12/eam" + evm12 "github.com/filecoin-project/go-state-types/builtin/v12/evm" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" + "github.com/filecoin-project/go-state-types/exitcode" builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/evm" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" @@ -18,10 +25,6 @@ import ( // decodePayload is a utility function which decodes the payload using the given codec func decodePayload(payload []byte, codec uint64) (ethtypes.EthBytes, error) { - if len(payload) == 0 { - return nil, nil - } - switch multicodec.Code(codec) { case multicodec.Identity: return nil, nil @@ -38,217 +41,565 @@ func decodePayload(payload []byte, codec uint64) (ethtypes.EthBytes, error) { return nil, xerrors.Errorf("decodePayload: unsupported codec: %d", codec) } -// buildTraces recursively builds the traces for a given ExecutionTrace by walking the subcalls -func buildTraces(traces *[]*ethtypes.EthTrace, parent *ethtypes.EthTrace, addr []int, et types.ExecutionTrace, height int64, st *state.StateTree) error { - // lookup the eth address from the from/to addresses. Note that this may fail but to support - // this we need to include the ActorID in the trace. For now, just log a warning and skip - // this trace. - // - // TODO: Add ActorID in trace, see https://github.com/filecoin-project/lotus/pull/11100#discussion_r1302442288 - from, err := lookupEthAddress(et.Msg.From, st) - if err != nil { - log.Warnf("buildTraces: failed to lookup from address %s: %v", et.Msg.From, err) - return nil - } - to, err := lookupEthAddress(et.Msg.To, st) - if err != nil { - log.Warnf("buildTraces: failed to lookup to address %s: %w", et.Msg.To, err) - return nil +func decodeParams[P any, T interface { + *P + cbg.CBORUnmarshaler +}](msg *types.MessageTrace) (T, error) { + var params T = new(P) + switch msg.ParamsCodec { + case uint64(multicodec.DagCbor), uint64(multicodec.Cbor): + default: + return nil, xerrors.Errorf("Method called with unexpected codec %d", msg.ParamsCodec) } - // Skip the trace if we never reached the point where we invoked this actor. + if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { + return nil, xerrors.Errorf("failed to decode params: %w", err) + } + + return params, nil +} + +func decodeReturn[R any, T interface { + *R + cbg.CBORUnmarshaler +}](ret *types.ReturnTrace) (T, error) { + var retval T = new(R) + switch ret.ReturnCodec { + case uint64(multicodec.DagCbor), uint64(multicodec.Cbor): + default: + return nil, xerrors.Errorf("Method returned an unexpected codec %d", ret.ReturnCodec) + } + + if err := retval.UnmarshalCBOR(bytes.NewReader(ret.Return)); err != nil { + return nil, xerrors.Errorf("failed to decode return value: %w", err) + } + + return retval, nil +} + +func find[T any](values []T, cb func(t *T) *T) *T { + for i := range values { + if o := cb(&values[i]); o != nil { + return o + } + } + return nil +} + +type environment struct { + caller ethtypes.EthAddress + isEVM bool + subtraceCount int + traces []*ethtypes.EthTrace + lastByteCode *ethtypes.EthAddress +} + +func baseEnvironment(st *state.StateTree, from address.Address) (*environment, error) { + sender, err := lookupEthAddress(from, st) + if err != nil { + return nil, xerrors.Errorf("top-level message sender %s s could not be found: %w", from, err) + } + return &environment{caller: sender}, nil +} + +func traceToAddress(act *types.ActorTrace) ethtypes.EthAddress { + if act.State.Address != nil { + if addr, err := ethtypes.EthAddressFromFilecoinAddress(*act.State.Address); err == nil { + return addr + } + } + return ethtypes.EthAddressFromActorID(act.Id) +} + +// traceIsEVMOrEAM returns true if the trace is a call to an EVM or EAM actor. +func traceIsEVMOrEAM(et *types.ExecutionTrace) bool { if et.InvokedActor == nil { + return false + } + return builtinactors.IsEvmActor(et.InvokedActor.State.Code) || + et.InvokedActor.Id != abi.ActorID(builtin.EthereumAddressManagerActorID) +} + +func traceErrMsg(et *types.ExecutionTrace) string { + code := et.MsgRct.ExitCode + + if code.IsSuccess() { + return "" + } + + // EVM tools often expect this literal string. + if code == exitcode.SysErrOutOfGas { + return "out of gas" + } + + // indicate when we have a "system" error. + if code < exitcode.FirstActorErrorCode { + return fmt.Sprintf("vm error: %s", code) + } + + // handle special exit codes from the EVM/EAM. + if traceIsEVMOrEAM(et) { + switch code { + case evm.ErrReverted: + return "Reverted" // capitalized for compatibility + case evm.ErrInvalidInstruction: + return "invalid instruction" + case evm.ErrUndefinedInstruction: + return "undefined instruction" + case evm.ErrStackUnderflow: + return "stack underflow" + case evm.ErrStackOverflow: + return "stack overflow" + case evm.ErrIllegalMemoryAccess: + return "illegal memory access" + case evm.ErrBadJumpdest: + return "invalid jump destination" + case evm.ErrSelfdestructFailed: + return "self destruct failed" + } + } + // everything else... + return fmt.Sprintf("actor error: %s", code.Error()) +} + +// buildTraces recursively builds the traces for a given ExecutionTrace by walking the subcalls +func buildTraces(env *environment, addr []int, et *types.ExecutionTrace) error { + trace, recurseInto, err := buildTrace(env, addr, et) + if err != nil { + return xerrors.Errorf("at trace %v: %w", addr, err) + } + + if trace != nil { + env.traces = append(env.traces, trace) + env.subtraceCount++ + } + + // Skip if there's nothing more to do and/or `buildTrace` told us to skip this one. + if recurseInto == nil || recurseInto.InvokedActor == nil || len(recurseInto.Subcalls) == 0 { return nil } - trace := ðtypes.EthTrace{ - Action: ethtypes.EthTraceAction{ - From: from, - To: to, - Gas: ethtypes.EthUint64(et.Msg.GasLimit), - Input: nil, - Value: ethtypes.EthBigInt(et.Msg.Value), - - FilecoinFrom: et.Msg.From, - FilecoinTo: et.Msg.To, - FilecoinMethod: et.Msg.Method, - FilecoinCodeCid: et.InvokedActor.State.Code, - }, - Result: ethtypes.EthTraceResult{ - GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), - Output: nil, - }, - Subtraces: 0, // will be updated by the children once they are added to the trace - TraceAddress: addr, - - Parent: parent, - LastByteCode: nil, + subEnv := &environment{ + caller: traceToAddress(recurseInto.InvokedActor), + isEVM: builtinactors.IsEvmActor(recurseInto.InvokedActor.State.Code), + traces: env.traces, } - - trace.SetCallType("call") - - if et.Msg.Method == builtin.MethodsEVM.InvokeContract { - log.Debugf("COND1 found InvokeContract call at height: %d", height) - - // TODO: ignore return errors since actors can send gibberish and we don't want - // to fail the whole trace in that case - trace.Action.Input, err = decodePayload(et.Msg.Params, et.Msg.ParamsCodec) - if err != nil { - return xerrors.Errorf("buildTraces: %w", err) - } - trace.Result.Output, err = decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) - if err != nil { - return xerrors.Errorf("buildTraces: %w", err) - } - } else if et.Msg.To == builtin.EthereumAddressManagerActorAddr && - et.Msg.Method == builtin.MethodsEAM.CreateExternal { - log.Debugf("COND2 found CreateExternal call at height: %d", height) - trace.Action.Input, err = decodePayload(et.Msg.Params, et.Msg.ParamsCodec) - if err != nil { - return xerrors.Errorf("buildTraces: %w", err) - } - - if et.MsgRct.ExitCode.IsSuccess() { - // ignore return value - trace.Result.Output = nil - } else { - // return value is the error message - trace.Result.Output, err = decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) - if err != nil { - return xerrors.Errorf("buildTraces: %w", err) - } - } - - // treat this as a contract creation - trace.SetCallType("create") - } else { - // we are going to assume a native method, but we may change it in one of the edge cases below - // TODO: only do this if we know it's a native method (optimization) - trace.Action.Input = encodeFilecoinParamsAsABI(et.Msg.Method, et.Msg.ParamsCodec, et.Msg.Params) - trace.Result.Output = encodeFilecoinReturnAsABI(et.MsgRct.ExitCode, et.MsgRct.ReturnCodec, et.MsgRct.Return) - } - - // TODO: is it OK to check this here or is this only specific to certain edge case (evm to evm)? - if et.Msg.ReadOnly { - trace.SetCallType("staticcall") - } - - // there are several edge cases that require special handling when displaying the traces. Note that while iterating over - // the traces we update the trace backwards (through the parent pointer) - if parent != nil { - // Handle Native actor creation - // - // Actor A calls to the init actor on method 2 and The init actor creates the target actor B then calls it on method 1 - if parent.Action.FilecoinTo == builtin.InitActorAddr && - parent.Action.FilecoinMethod == builtin.MethodsInit.Exec && - et.Msg.Method == builtin.MethodConstructor { - log.Debugf("COND3 Native actor creation! method:%d, code:%s, height:%d", et.Msg.Method, et.InvokedActor.State.Code.String(), height) - parent.SetCallType("create") - parent.Action.To = to - parent.Action.Input = []byte{0xFE} - parent.Result.Output = nil - - // there should never be any subcalls when creating a native actor - // - // TODO: add support for native actors calling another when created - return nil - } - - // Handle EVM contract creation - // - // To detect EVM contract creation we need to check for the following sequence of events: - // - // 1) EVM contract A calls the EAM (Ethereum Address Manager) on method 2 (create) or 3 (create2). - // 2) The EAM calls the init actor on method 3 (Exec4). - // 3) The init actor creates the target actor B then calls it on method 1. - if parent.Parent != nil { - calledCreateOnEAM := parent.Parent.Action.FilecoinTo == builtin.EthereumAddressManagerActorAddr && - (parent.Parent.Action.FilecoinMethod == builtin.MethodsEAM.Create || parent.Parent.Action.FilecoinMethod == builtin.MethodsEAM.Create2) - eamCalledInitOnExec4 := parent.Action.FilecoinTo == builtin.InitActorAddr && - parent.Action.FilecoinMethod == builtin.MethodsInit.Exec4 - initCreatedActor := trace.Action.FilecoinMethod == builtin.MethodConstructor - - // TODO: We need to handle failures in contract creations and support resurrections on an existing but dead EVM actor) - if calledCreateOnEAM && eamCalledInitOnExec4 && initCreatedActor { - log.Debugf("COND4 EVM contract creation method:%d, code:%s, height:%d", et.Msg.Method, et.InvokedActor.State.Code.String(), height) - - if parent.Parent.Action.FilecoinMethod == builtin.MethodsEAM.Create { - parent.Parent.SetCallType("create") - } else { - parent.Parent.SetCallType("create2") - } - - // update the parent.parent to make this - parent.Parent.Action.To = trace.Action.To - parent.Parent.Subtraces = 0 - - // delete the parent (the EAM) and skip the current trace (init) - *traces = (*traces)[:len(*traces)-1] - - return nil - } - } - - if builtinactors.IsEvmActor(parent.Action.FilecoinCodeCid) { - // Handle delegate calls - // - // 1) Look for trace from an EVM actor to itself on InvokeContractDelegate, method 6. - // 2) Check that the previous trace calls another actor on method 3 (GetByteCode) and they are at the same level (same parent) - // 3) Treat this as a delegate call to actor A. - if parent.LastByteCode != nil && trace.Action.From == trace.Action.To && - trace.Action.FilecoinMethod == builtin.MethodsEVM.InvokeContractDelegate { - log.Debugf("COND7 found delegate call, height: %d", height) - prev := parent.LastByteCode - if prev.Action.From == trace.Action.From && prev.Action.FilecoinMethod == builtin.MethodsEVM.GetBytecode && prev.Parent == trace.Parent { - trace.SetCallType("delegatecall") - trace.Action.To = prev.Action.To - - var dp evm.DelegateCallParams - err := dp.UnmarshalCBOR(bytes.NewReader(et.Msg.Params)) - if err != nil { - return xerrors.Errorf("failed UnmarshalCBOR: %w", err) - } - trace.Action.Input = dp.Input - - trace.Result.Output, err = decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) - if err != nil { - return xerrors.Errorf("failed decodePayload: %w", err) - } - } - } else { - // Handle EVM call special casing - // - // Any outbound call from an EVM actor on methods 1-1023 are side-effects from EVM instructions - // and should be dropped from the trace. - if et.Msg.Method > 0 && - et.Msg.Method <= 1023 { - log.Debugf("Infof found outbound call from an EVM actor on method 1-1023 method:%d, code:%s, height:%d", et.Msg.Method, parent.Action.FilecoinCodeCid.String(), height) - - if et.Msg.Method == builtin.MethodsEVM.GetBytecode { - // save the last bytecode trace to handle delegate calls - parent.LastByteCode = trace - } - - return nil - } - } - } - - } - - // we are adding trace to the traces so update the parent subtraces count as it was originally set to zero - if parent != nil { - parent.Subtraces++ - } - - *traces = append(*traces, trace) - - for i, call := range et.Subcalls { - err := buildTraces(traces, trace, append(addr, i), call, height, st) + // Set capacity to the length so each `append` below creates a new slice. Otherwise, we'll + // end up repeatedly mutating previous paths. + addr = addr[:len(addr):len(addr)] + for i := range recurseInto.Subcalls { + err := buildTraces(subEnv, append(addr, subEnv.subtraceCount), &recurseInto.Subcalls[i]) if err != nil { return err } } + trace.Subtraces = subEnv.subtraceCount + env.traces = subEnv.traces return nil } + +// buildTrace processes the passed execution trace and updates the environment, if necessary. +// +// On success, it returns a trace to add (or nil to skip) and the trace recurse into (or nil to skip). +func buildTrace(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + // This function first assumes that the call is a "native" call, then handles all the "not + // native" cases. If we get any unexpected results in any of these special cases, we just + // keep the "native" interpretation and move on. + // + // 1. If we're invoking a contract (even if the caller is a native account/actor), we + // attempt to decode the params/return value as a contract invocation. + // 2. If we're calling the EAM and/or init actor, we try to treat the call as a CREATE. + // 3. Finally, if the caller is an EVM smart contract and it's calling a "private" (1-1023) + // method, we know something special is going on. We look for calls related to + // DELEGATECALL and drop everything else (everything else includes calls triggered by, + // e.g., EXTCODEHASH). + + // If we don't have sufficient funds, or we have a fatal error, or we have some + // other syscall error: skip the entire trace to mimic Ethereum (Ethereum records + // traces _after_ checking things like this). + // + // NOTE: The FFI currently folds all unknown syscall errors into "sys assertion + // failed" which is turned into SysErrFatal. + if len(addr) > 0 { + switch et.MsgRct.ExitCode { + case exitcode.SysErrInsufficientFunds, exitcode.SysErrFatal: + return nil, nil, nil + } + } + + // We may fail before we can even invoke the actor. In that case, we have no 100% reliable + // way of getting its address (e.g., due to reverts) so we're just going to drop the entire + // trace. This is OK (ish) because the call never really "happened". + if et.InvokedActor == nil { + return nil, nil, nil + } + + // Step 2: Decode as a contract invocation + // + // Normal EVM calls. We don't care if the caller/receiver are actually EVM actors, we only + // care if the call _looks_ like an EVM call. If we fail to decode it as an EVM call, we + // fallback on interpreting it as a native call. + if et.Msg.Method == builtin.MethodsEVM.InvokeContract { + return traceEVMCall(env, addr, et) + } + + // Step 3: Decode as a contract deployment + switch et.Msg.To { + // NOTE: this will only catch _direct_ calls to the init actor. Calls through the EAM will + // be caught and _skipped_ below in the next case. + case builtin.InitActorAddr: + switch et.Msg.Method { + case builtin.MethodsInit.Exec, builtin.MethodsInit.Exec4: + return traceNativeCreate(env, addr, et) + } + case builtin.EthereumAddressManagerActorAddr: + switch et.Msg.Method { + case builtin.MethodsEAM.Create, builtin.MethodsEAM.Create2, builtin.MethodsEAM.CreateExternal: + return traceEthCreate(env, addr, et) + } + } + + // Step 4: Handle DELEGATECALL + // + // EVM contracts cannot call methods in the range 1-1023, only the EVM itself can. So, if we + // see a call in this range, we know it's an implementation detail of the EVM and not an + // explicit call by the user. + // + // While the EVM calls several methods in this range (some we've already handled above with + // respect to the EAM), we only care about the ones relevant DELEGATECALL and can _ignore_ + // all the others. + if env.isEVM && et.Msg.Method > 0 && et.Msg.Method < 1024 { + return traceEVMPrivate(env, addr, et) + } + + return traceNativeCall(env, addr, et), et, nil +} + +// Build an EthTrace for a "call" with the given input & output. +func traceCall(env *environment, addr []int, et *types.ExecutionTrace, input, output ethtypes.EthBytes) *ethtypes.EthTrace { + to := traceToAddress(et.InvokedActor) + callType := "call" + if et.Msg.ReadOnly { + callType = "staticcall" + } + return ðtypes.EthTrace{ + Type: "call", + Action: ðtypes.EthCallTraceAction{ + CallType: callType, + From: env.caller, + To: to, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + Input: input, + }, + Result: ðtypes.EthCallTraceResult{ + GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), + Output: output, + }, + TraceAddress: addr, + Error: traceErrMsg(et), + } +} + +// Build an EthTrace for a "call", parsing the inputs & outputs as a "native" FVM call. +func traceNativeCall(env *environment, addr []int, et *types.ExecutionTrace) *ethtypes.EthTrace { + return traceCall(env, addr, et, + encodeFilecoinParamsAsABI(et.Msg.Method, et.Msg.ParamsCodec, et.Msg.Params), + encodeFilecoinReturnAsABI(et.MsgRct.ExitCode, et.MsgRct.ReturnCodec, et.MsgRct.Return), + ) +} + +// Build an EthTrace for a "call", parsing the inputs & outputs as an EVM call (falling back on +// treating it as a native call). +func traceEVMCall(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + input, err := decodePayload(et.Msg.Params, et.Msg.ParamsCodec) + if err != nil { + log.Debugf("failed to decode contract invocation payload: %w", err) + return traceNativeCall(env, addr, et), et, nil + } + output, err := decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) + if err != nil { + log.Debugf("failed to decode contract invocation return: %w", err) + return traceNativeCall(env, addr, et), et, nil + } + return traceCall(env, addr, et, input, output), et, nil +} + +// Build an EthTrace for a native "create" operation. This should only be called with an +// ExecutionTrace is an Exec or Exec4 method invocation on the Init actor. +func traceNativeCreate(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + if et.Msg.ReadOnly { + // "create" isn't valid in a staticcall, so we just skip this trace + // (couldn't have created an actor anyways). + // This mimic's the EVM: it doesn't trace CREATE calls when in + // read-only mode. + return nil, nil, nil + } + + subTrace := find(et.Subcalls, func(c *types.ExecutionTrace) *types.ExecutionTrace { + if c.Msg.Method == builtin.MethodConstructor { + return c + } + return nil + }) + if subTrace == nil { + // If we succeed in calling Exec/Exec4 but don't even try to construct + // something, we have a bug in our tracing logic or a mismatch between our + // tracing logic and the actors. + if et.MsgRct.ExitCode.IsSuccess() { + return nil, nil, xerrors.Errorf("successful Exec/Exec4 call failed to call a constructor") + } + // Otherwise, this can happen if creation fails early (bad params, + // out of gas, contract already exists, etc.). The EVM wouldn't + // trace such cases, so we don't either. + // + // NOTE: It's actually impossible to run out of gas before calling + // initcode in the EVM (without running out of gas in the calling + // contract), but this is an equivalent edge-case to InvokedActor + // being nil, so we treat it the same way and skip the entire + // operation. + return nil, nil, nil + } + + // Native actors that aren't the EAM can attempt to call Exec4, but such + // call should fail immediately without ever attempting to construct an + // actor. I'm catching this here because it likely means that there's a bug + // in our trace-conversion logic. + if et.Msg.Method == builtin.MethodsInit.Exec4 { + return nil, nil, xerrors.Errorf("direct call to Exec4 successfully called a constructor!") + } + + var output ethtypes.EthBytes + var createdAddr *ethtypes.EthAddress + if et.MsgRct.ExitCode.IsSuccess() { + // We're supposed to put the "installed bytecode" here. But this + // isn't an EVM actor, so we just put some invalid bytecode (this is + // the answer you'd get if you called EXTCODECOPY on a native + // non-account actor, anyways). + output = []byte{0xFE} + + // Extract the address of the created actor from the return value. + initReturn, err := decodeReturn[init12.ExecReturn](&et.MsgRct) + if err != nil { + return nil, nil, xerrors.Errorf("failed to decode init params after a successful Init.Exec call: %w", err) + } + actorId, err := address.IDFromAddress(initReturn.IDAddress) + if err != nil { + return nil, nil, xerrors.Errorf("failed to extract created actor ID from address: %w", err) + } + ethAddr := ethtypes.EthAddressFromActorID(abi.ActorID(actorId)) + createdAddr = ðAddr + } + + return ðtypes.EthTrace{ + Type: "create", + Action: ðtypes.EthCreateTraceAction{ + From: env.caller, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + // If we get here, this isn't a native EVM create. Those always go through + // the EAM. So we have no "real" initcode and must use the sentinel value + // for "invalid" initcode. + Init: []byte{0xFE}, + }, + Result: ðtypes.EthCreateTraceResult{ + GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), + Address: createdAddr, + Code: output, + }, + TraceAddress: addr, + Error: traceErrMsg(et), + }, subTrace, nil +} + +// Assert that these are all identical so we can simplify the below code and decode once. +var _ *eam12.Return = (*eam12.Return)((*eam12.CreateReturn)(nil)) +var _ *eam12.Return = (*eam12.Return)((*eam12.Create2Return)(nil)) +var _ *eam12.Return = (*eam12.Return)((*eam12.CreateExternalReturn)(nil)) + +// Decode the parameters and return value of an EVM smart contract creation through the EAM. This +// should only be called with an ExecutionTrace for a Create, Create2, or CreateExternal method +// invocation on the EAM. +func decodeCreateViaEAM(et *types.ExecutionTrace) (initcode []byte, addr *ethtypes.EthAddress, err error) { + switch et.Msg.Method { + case builtin.MethodsEAM.Create: + params, err := decodeParams[eam12.CreateParams](&et.Msg) + if err != nil { + return nil, nil, err + } + initcode = params.Initcode + case builtin.MethodsEAM.Create2: + params, err := decodeParams[eam12.Create2Params](&et.Msg) + if err != nil { + return nil, nil, err + } + initcode = params.Initcode + case builtin.MethodsEAM.CreateExternal: + input, err := decodePayload(et.Msg.Params, et.Msg.ParamsCodec) + if err != nil { + return nil, nil, err + } + initcode = input + default: + return nil, nil, xerrors.Errorf("unexpected CREATE method %d", et.Msg.Method) + } + ret, err := decodeReturn[eam12.CreateReturn](&et.MsgRct) + if err != nil { + return nil, (*ethtypes.EthAddress)(&ret.EthAddress), err + } + return initcode, (*ethtypes.EthAddress)(&ret.EthAddress), nil +} + +// Build an EthTrace for an EVM "create" operation. This should only be called with an +// ExecutionTrace for a Create, Create2, or CreateExternal method invocation on the EAM. +func traceEthCreate(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + // Same as the Init actor case above, see the comment there. + if et.Msg.ReadOnly { + return nil, nil, nil + } + + // Look for a call to either a constructor or the EVM's resurrect method. + subTrace := find(et.Subcalls, func(et *types.ExecutionTrace) *types.ExecutionTrace { + if et.Msg.To == builtinactors.InitActorAddr { + return find(et.Subcalls, func(et *types.ExecutionTrace) *types.ExecutionTrace { + if et.Msg.Method == builtinactors.MethodConstructor { + return et + } + return nil + }) + } + if et.Msg.Method == builtin.MethodsEVM.Resurrect { + return et + } + return nil + }) + + // Same as the Init actor case above, see the comment there. + if subTrace == nil { + if et.MsgRct.ExitCode.IsSuccess() { + return nil, nil, xerrors.Errorf("successful Create/Create2 call failed to call a constructor") + } + return nil, nil, nil + } + + // Decode inputs & determine create type. + initcode, createdAddr, err := decodeCreateViaEAM(et) + if err != nil { + return nil, nil, xerrors.Errorf("EAM called with invalid params or returned an invalid result, but it still tried to construct the contract: %w", err) + } + + var output ethtypes.EthBytes + // Handle the output. + switch et.MsgRct.ExitCode { + case 0: // success + // We're _supposed_ to include the contracts bytecode here, but we + // can't do that reliably (e.g., if some part of the trace reverts). + // So we don't try and include a sentinel "impossible bytecode" + // value (the value specified by EIP-3541). + output = []byte{0xFE} + case 33: // Reverted, parse the revert message. + // If we managed to call the constructor, parse/return its revert message. If we + // fail, we just return no output. + output, _ = decodePayload(subTrace.MsgRct.Return, subTrace.MsgRct.ReturnCodec) + } + + return ðtypes.EthTrace{ + Type: "create", + Action: ðtypes.EthCreateTraceAction{ + From: env.caller, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + Init: initcode, + }, + Result: ðtypes.EthCreateTraceResult{ + GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), + Address: createdAddr, + Code: output, + }, + TraceAddress: addr, + Error: traceErrMsg(et), + }, subTrace, nil +} + +// Build an EthTrace for a "private" method invocation from the EVM. This should only be called with +// an ExecutionTrace from an EVM instance and on a method between 1 and 1023 inclusive. +func traceEVMPrivate(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + // The EVM actor implements DELEGATECALL by: + // + // 1. Asking the callee for its bytecode by calling it on the GetBytecode method. + // 2. Recursively invoking the currently executing contract on the + // InvokeContractDelegate method. + // + // The code below "reconstructs" that delegate call by: + // + // 1. Remembering the last contract on which we called GetBytecode. + // 2. Treating the contract invoked in step 1 as the DELEGATECALL receiver. + // + // Note, however: GetBytecode will be called, e.g., if the user invokes the + // EXTCODECOPY instruction. It's not an error to see multiple GetBytecode calls + // before we see an InvokeContractDelegate. + switch et.Msg.Method { + case builtin.MethodsEVM.GetBytecode: + // NOTE: I'm not checking anything about the receiver here. The EVM won't + // DELEGATECALL any non-EVM actor, but there's no need to encode that fact + // here in case we decide to loosen this up in the future. + if et.MsgRct.ExitCode.IsSuccess() { + to := traceToAddress(et.InvokedActor) + env.lastByteCode = &to + } else { + env.lastByteCode = nil + } + return nil, nil, nil + case builtin.MethodsEVM.InvokeContractDelegate: + // NOTE: We return errors in all the failure cases below instead of trying + // to continue because the caller is an EVM actor. If something goes wrong + // here, there's a bug in our EVM implementation. + + // Handle delegate calls + // + // 1) Look for trace from an EVM actor to itself on InvokeContractDelegate, + // method 6. + // 2) Check that the previous trace calls another actor on method 3 + // (GetByteCode) and they are at the same level (same parent) + // 3) Treat this as a delegate call to actor A. + if env.lastByteCode == nil { + return nil, nil, xerrors.Errorf("unknown bytecode for delegate call") + } + + if to := traceToAddress(et.InvokedActor); env.caller != to { + return nil, nil, xerrors.Errorf("delegate-call not from & to self: %s != %s", env.caller, to) + } + + dp, err := decodeParams[evm12.DelegateCallParams](&et.Msg) + if err != nil { + return nil, nil, xerrors.Errorf("failed to decode delegate-call params: %w", err) + } + + output, err := decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) + if err != nil { + return nil, nil, xerrors.Errorf("failed to decode delegate-call return: %w", err) + } + + return ðtypes.EthTrace{ + Type: "call", + Action: ðtypes.EthCallTraceAction{ + CallType: "delegatecall", + From: env.caller, + To: *env.lastByteCode, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + Input: dp.Input, + }, + Result: ðtypes.EthCallTraceResult{ + GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), + Output: output, + }, + TraceAddress: addr, + Error: traceErrMsg(et), + }, et, nil + } + // We drop all other "private" calls from FEVM. We _forbid_ explicit calls between 0 and + // 1024 (exclusive), so any calls in this range must be implementation details. + return nil, nil, nil +} diff --git a/node/impl/full/eth_utils.go b/node/impl/full/eth_utils.go index 1e407a321..04e8e4970 100644 --- a/node/impl/full/eth_utils.go +++ b/node/impl/full/eth_utils.go @@ -381,34 +381,35 @@ func parseEthRevert(ret []byte) string { // 3. Otherwise, we fall back to returning a masked ID Ethereum address. If the supplied address is an f0 address, we // use that ID to form the masked ID address. // 4. Otherwise, we fetch the actor's ID from the state tree and form the masked ID with it. +// +// If the actor doesn't exist in the state-tree but we have its ID, we use a masked ID address. It could have been deleted. func lookupEthAddress(addr address.Address, st *state.StateTree) (ethtypes.EthAddress, error) { - // BLOCK A: We are trying to get an actual Ethereum address from an f410 address. // Attempt to convert directly, if it's an f4 address. ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(addr) if err == nil && !ethAddr.IsMaskedID() { return ethAddr, nil } - // Lookup on the target actor and try to get an f410 address. - if actor, err := st.GetActor(addr); err != nil { - return ethtypes.EthAddress{}, err - } else if actor.Address != nil { - if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() { - return ethAddr, nil - } - } - - // BLOCK B: We gave up on getting an actual Ethereum address and are falling back to a Masked ID address. - // Check if we already have an ID addr, and use it if possible. - if err == nil && ethAddr.IsMaskedID() { - return ethAddr, nil - } - // Otherwise, resolve the ID addr. idAddr, err := st.LookupID(addr) if err != nil { return ethtypes.EthAddress{}, err } + + // Lookup on the target actor and try to get an f410 address. + if actor, err := st.GetActor(idAddr); errors.Is(err, types.ErrActorNotFound) { + // Not found -> use a masked ID address + } else if err != nil { + // Any other error -> fail. + return ethtypes.EthAddress{}, err + } else if actor.Address == nil { + // No delegated address -> use masked ID address. + } else if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() { + // Conversable into an eth address, use it. + return ethAddr, nil + } + + // Otherwise, use the masked address. return ethtypes.EthAddressFromFilecoinAddress(idAddr) }