From 0fc857c9e4ad6e5ee6980bd5670f2de29ae0e694 Mon Sep 17 00:00:00 2001 From: skosito Date: Wed, 9 Oct 2024 03:31:49 +0200 Subject: [PATCH 1/5] whitelist spl mint wip --- cmd/zetae2e/local/solana.go | 1 + contrib/localnet/solana/gateway-keypair.json | 2 +- contrib/localnet/solana/gateway.so | Bin 278648 -> 326472 bytes e2e/e2etests/e2etests.go | 8 +- e2e/e2etests/test_solana_whitelist_spl.go | 55 ++ e2e/runner/setup_solana.go | 2 +- e2e/runner/solana.go | 39 +- pkg/contracts/solana/gateway.go | 7 +- pkg/contracts/solana/gateway.json | 528 +++++++++++++++++- pkg/contracts/solana/gateway_message.go | 16 + pkg/contracts/solana/instruction.go | 24 + .../keeper/msg_server_whitelist_erc20.go | 45 +- x/crosschain/types/message_whitelist_erc20.go | 7 +- zetaclient/chains/solana/signer/signer.go | 45 ++ zetaclient/chains/solana/signer/whitelist.go | 81 +++ zetaclient/testutils/constant.go | 2 +- 16 files changed, 822 insertions(+), 40 deletions(-) create mode 100644 e2e/e2etests/test_solana_whitelist_spl.go create mode 100644 zetaclient/chains/solana/signer/whitelist.go diff --git a/cmd/zetae2e/local/solana.go b/cmd/zetae2e/local/solana.go index 135615051a..3e58418cc4 100644 --- a/cmd/zetae2e/local/solana.go +++ b/cmd/zetae2e/local/solana.go @@ -26,6 +26,7 @@ func solanaTestRoutine( deployerRunner, conf.AdditionalAccounts.UserSolana, runner.NewLogger(verbose, color.FgCyan, "solana"), + runner.WithZetaTxServer(deployerRunner.ZetaTxServer), ) if err != nil { return err diff --git a/contrib/localnet/solana/gateway-keypair.json b/contrib/localnet/solana/gateway-keypair.json index 99c8b61dee..daab863409 100644 --- a/contrib/localnet/solana/gateway-keypair.json +++ b/contrib/localnet/solana/gateway-keypair.json @@ -1 +1 @@ -[148,138,110,3,169,253,42,101,79,110,149,110,112,214,41,163,75,28,36,29,241,151,41,200,135,185,252,180,158,191,166,156,119,192,217,18,69,149,119,145,212,43,144,149,176,111,89,140,102,63,193,127,241,148,51,161,170,62,19,196,239,253,6,192] \ No newline at end of file +[170,171,179,164,93,78,137,61,23,64,233,109,110,253,36,57,111,127,55,106,199,85,39,175,73,206,30,244,229,216,101,145,157,23,123,51,143,17,39,82,72,82,114,55,41,2,101,170,230,6,41,179,227,225,43,107,236,186,181,51,118,110,43,227] \ No newline at end of file diff --git a/contrib/localnet/solana/gateway.so b/contrib/localnet/solana/gateway.so index 185b938c3ca936bfc13c831b38af4b826e8bef8a..3f991179619d09e68a922f3612fc85d0aa0ae666 100755 GIT binary patch literal 326472 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

E5GXi zK=JoXQ9dvoPs}6ta6MN7{%HRN%L!W;m6x^u0__0Z(R;uOvSdk#eh=o=Su4f`A7CQKc;-2-n|53KkMOMh>3hL`iAlW z{~}$GBzwB>+}qAHPsRRQ40c%F-v*Ci3p{}KRD*gvs+QJ(nOzVNnRr^i8>cc6RpitY=U`z?0&vY4#*q+q`QF9!9m z4UiZ(ww}#X{d2veQ0@m|B0*t&;(oesCra^j{f^cPH1eQ-qT=^I6WBmN^~R*04dG!p zD3>v4-!b{Vr#sbqF|GHeD7i=NBM%!7C_2xJACrvXVK{Be z7oS@`$8=}8TtD)1imyXo(jU5STPE{K&&Sq4JHd3({aq>#US52o{)5{U=bRC!Wb!s1<#$PHgnm?a{>|v4B zfIbWV=zU#yzf_omF3j(f;R(3_`(2nXC+I%)jaa%@JKC+gTkmxDB2=X2sm5l^qQR(~N}&!@%jIpL~wek3fN zrqe51RDnn7u1^RD^qn)R2fbYK4d3;YKY6hO=LuEdv%tMs`rjusaej_2Y22ab`>9{z zJOR44_1wSR9DBli?y)B4Gsm7epSfu>KMRQw{S@NG@8E)!&}kicN{v%>JJAN@k8PfT z-@`>S)G3`LS5R(YKI)YFJS7)sy@2+ZA2P@C#P8-}c&L*cnKO>4aIl;L;1=rxC2X<0 z_AAbRFsU_QkMc39dv5;0Y9l4_>VM5%ZPf|F5U>ucwUlBdbB& z1IBv9c_gj_^!^3o;ZiU}b8WoJHx4&SbNf0r1r_}~)E_FEhvPVa?IG_0VQl0*A$5A+ zmo0S9{lhXi2v@#`q&O}kUGG{Y z$^+xU^f!TSf{x=A>NNfzz5oDJv`gxEzHP!!>>sG#rRK}z?k*KS$v2u0(|ZKyejTRU zrjm58-Xo+2l%FbRx=%D}O4qlROOH67I>3nDi%9lrxHG8SJ#ae{efFyNNYec#T0dZY znP89d2zC3t8(~i6p~j(8Q0&5;D#tR_4$7LqGpNxjp;_x!df#oCx|c=wk?6TYd@cr} zHhe4bFVwFbmaXRy@cz9C=5!yC+AYdG;ZHqZMdK1Z7uBoMNBP3%ATXT6YT%`NNoA^j z%hrP>sIq#Y8F@*iA5eO~(nC`3RrhSEyfIj6hv-6|Fa5ta@07C#82{CKwrPB{#uX*c zNN$k)L3=T-P(NBL%Nxzb_&<-i82{%nN0BmL_@>SLEJTL&hW$|+|JSK_AyRB-^t?{- zUTKc^khJk%rL%6I@(1B!KI)Wv+OMGfm{VYh`5|+hpK0U23J=Y-b)+)K^1$&ws^kyK zC6sq`F9yTMafIYTu^#{w_2Eu>wA4%n%GC?)DOU^P~onw zNL#GS?24M<#zym0OINcQy*<)-qBVL79UNeRYx zw?}$nkp@U!Yoe?=9_fsiHMX^Mb+(k9igunXYij8#gMhkDL_6DjUD0T3ybKDktg}1b zRo2>ayffUHC=0i?MjOg7b&%_p_9jT(q4wLutu2sz@Bxv=IwNsPL!~J)*Z{sD9rcG} zn6S#q?)Foi;aKU$dJ~cvHtVm8wnyqs2&FsnUrts-6yj>Yc;aQpyE-G0vi9)pElp4- zkkn(HiG!WdwnOb*B3;#1c|hcyEn#d$*lsG#Yr{Q9Bay~yBJE9G%?ElK;CG}^WfU#q zhai@waO+{L<9$#-7^oDeFd3X>z*X3=C%`scA|^k^Ft75IU= zZE0wMU=Cu-J=ES1?d*hHsaA8S@!FPn97_L4q@%l~Gtzhz+F}@LJEB6{)7lvcHzp3X zw{*2Y-P{prtZr{fgK~9UwCg~7w7aQU@zs$;T>ab&@kLJ^6zvXv$D0pDMTw<-9)ZLi z=)pc(4atqgqMgvJjwa$zkWhHaU0mc4n~Z3ZaaNK?BBD8gds{Ib>kKzU^n%~p-O}3C z(ynqJzZS}SAJi|D^S)?Xth*}$x$B~KsG=4%v!@f}Mq8w-rQxuW9WmMO;$`roD+-Op z2OSvtZ$nqy7l*Ff9u|!onmaTXC~}lJ*o7J!p;^aGEa*t*p*R%Xp6;&ZD1;BCoUX1= z6a)d-wl_qeirT_m4b8`n9z~~6TrIK`WU20t#G>(*u4BYY29nXGf(r>rax`?!9%xzZ&`jF9SorT=(YyVTB^!2$E=Ni z^W#@HpZwQPeti4w?VEp0ef3Br-rd^8`)a#c5A8tpRa>Q1nui)&_d%oUq9zz_Z-8`F zwlrdMrY<0yLCDY|RW&t27pOy-9B+BIF~?i_DL8#O;9|>qYj zw^~@>SgUi*vN{Ik8aWn+K4B|+X=-n`>F8^kp(I*c;$25$t=MXGkL{<KbJatBZ*~QE8gWAa0ti z;WiXlaU4=Z`}bS|!&XBCW)q#{#*D{W!4i^Z#=9FDpiiFYZf#8**th?v9QlQ`mBVVA z>gX{2fNqa76--`+5TIh@#37!D!wjcR$s>>_2XT^etfei|c(}Xk1Fsohdv)FB+qNJ4 z(DmON`{&CG4;~+_?C*V#S$aIt6^WbsLA--hJ!#cTSJe7h2i>JJ(FT=Rr#g+u2t@@c zsDn-yCh?W_*AQ-RY{7;TY7EyCky|VP8P6P9*>=b$$ zP$R5Dp^G1j;_@sMPDDEQkbqFbX8^VWx+2gSt;w6&(g>MuIne@Bly=zVh;>G92cyP= zFu6J&Za8V4=x&#bUNhVo5l*Z{8E%z;d)#h--3pv!V+b&gM_|c|i$gKbmYXTIDChU~ z20Y<*2uQ$~*t@`K5$?voY{8x{TC`aSl*xc;8Sd2_+JBARF`}A@z&2033s(ua0EL|o z*lp=-gt7sTuug+KZGl;N!fb$b0ZP*oEuHZ$dxqvsTYUufle&Bjv6g!C1T1B6J&pTG z8TWY1X2>E;_A@)ciC}{z()1l7NGYsqB4P~<5-YR2IBqy(w1&-{o=Ah-^~&T3rra>Y zMOiAxoGp;QNUM1Qwnt=vQ}DVY+-S(?QdCLi z0)yDpN;^ZT9Z(xs<{gnv*cw!e!p4?(LuU(2d0`7@kD9mR1UPdt{VPa@m}2bg8wo*{BJzP8U3Ai!ZU_&p6Q29E~W`@B<<($a~|nFhi}X3b&DM(`g!#)?l9e$&LgQY znr6T-Dd!pI(-_a`%L*uCUxsO~n1h(jFbO%I_%eAoj|^t=s+*H=fX)4ksa6sQ(u*7a zIQ3=%L^-I7biBTslduDQUJl#OJGAq1*@WZp>!iO4W@H&0;mm?0U3w_$0#S_fjIi8{ zH(^f-&pTjj1v5EtT^BXgTyL(o6SyBFJy@a7>lpTI#EeetHp411EKi~!t>UOhZa3pF z&!>DU5orhdn~79@;Mo52vb7hTN7)TOInPXFymLdhAp@xa~IARs~?CuM7OktvN~_`k|CkGPFv> zqJ^0#RkQ7!C1Z49D@0tWQMqPxj)}6(!nC0^?J3rM95xTIa?Hjk>=9zo$u@!ht(gMk z4$f%M8x zbYrv|PE6Y&du8g-0CSoyc9HZLuB)sZVlT8pPzlB)>8XiIDm!50DHtVQ-`yNV_p~Rji*_Bg&h=nLbq!Yd zQJ8N=@Nf&3U%~M0>YPp!2uetWR(Dg@-9;?2gruN30 zV6J*xxZ!yc_{%|DwH{*oi6LrU;yTihX|&(PHyKrULq`5H&FRLqo@v(EtGl_Udfcx)_4T-06alg3d~; zTwY4^iHmJNn?64CGCtN6&(=Js-yfIf81U3mc&u(o^*CqsVJPar1xN%^2flU}Q z-5P-z6E-Vb@nL#_S zv;o)N4i2T83pQhj0R%MMb9qCJ{&2ia-c%6sMK)_8()UH%+vNqEBast0R@x0<4jhce z;mQb11{#`CzFimT!plcCleGIikU`k9f{{p>$zzT~?bUJew;#Io-cCHI4YkA~>fXzN z9yrL3*Wg~~UOXj*0QT&Mdom3$B~KiRr+-_9;Nk%8Bp!it)x+(riG#3dDW`$yU)MyV zv7=pKE6HdRgh@gxTt^T+@lZS5MNz-^Lq&<(1vkMy)lrBS?sOc4BV>pO?hl>BoTo#+ zzB}3#rn@m{48!|1AP*uiABc8$HbnMz#}fyvT|RVyCi^<0@pvS@KXQ8uoKSH^;*5Ee$7O z=mnuvnF|;DKwJs=fmaw|z=Ep_z2+A9le;DNPV>&vQqXUmH(~AFZIE4mkKgYv_iyuW z_wVrU^zZUl_yhjk<^J;W@@?hY%XgITEZ?xy<$hj&Wc?X z6%~Ps-2s1~Jg_aWJ+LFNGq5XA5eNi!?}jAqhUj-g(7VCgZZJ9ld!rzF@gy|f74F2@ z1(pdlE@^|46g)Ns`Fw&TnPll&_=E*Omnn)Cj#LH6o~3*$0a&_`uRv_q9hg(RRr^1w zm5V7iDqD0nZ{51}*5i>TnDD_JC_JbxtyjlZqK;^$WrCcCbrbGpzy;Dv zOzg)vC5glN6`XoQoz!Z$3IbU|Z z;{3+KZ{~c<`EBQS9aElHoj-F=JAYxO+%wMKx_;+axZ#q^uRHw6d*1Wj-nYE{FQ5AB zPu~C0tn8d!mtB6tuP0t{Ur@NK;)a^Lp8fDgKD~2l=>reG?LF>Ailyt~L%o_C>pUCu?G&7S@4#ha4PX03CtbC-H|EVypp>581?x!%G{ z4(xU{cys*AJteNy9!FKceYK~|otvGLU1e@?FU;BHs`RYNb}!5h9je&AXnXcnZ|>=f zk6gXkyJ`8Vi!Z!jMb32)!Tv=nvvae8-VHh33-(^VDeDqXZr1f#4o|+zlYGnZi-O+V z0K+cFL7OXgClR-qI=$TqI*H|3lCk>u;^ZY{_;njz5B{DFWkL5dz1T?tc!CG z=9YSv-93DB?Kv$B%YY@-utahIZyrU^!7YQQPyI&_w-vIbf5Gra^+;_KURNb zPS>T$-{i)k2>y*1LYoXhbx6mDc%$0iATzC4|!Xik^F7IM+nv@xM1bNRg3Z$FU)i2yOu6pmb2Wk!d>WC=~|V&+Hs+?c)97??D8$x z>hQbDo!cB|ogZ*M>weDrTj%dQe{lZMHJkIHp2S-oe#&1{` zzy9)1erj0F{Ss{Nw>3uYee_-L{?gZ9UbJLm-XS>`N=H|G(u56bR#OOk|$F(5K zvADo|TYE*EzxJDwm66CeHZ<%eyj0EbJu%j>v#RZ z@#-!|Zb`+uMXy#ow>Z4Jtnkck|Apb;uP-`tP1TNYDD|c@*B_3S9C`Pr&Kxmb4j+xY za^|S<-I8O*)T`AW{!zH*Uw=|^MnS-2@*=%Qk#4&O6~hM{t3^Am0&z z3UoRh?zN7KR^Pm!GAGAT=yv45SmW93y41U=&|y}92e%h0Dm&L%Y!hV;_{f)434x zRp!_Zp*o!&$oD3v*YOK1Hv9xqette&&vyLC@eX)-1?19Q>T)~Y58)fmkn7-ra(Ay| zSKda*XRfOp!pwGD=33`*crSM>bneIjY3-AL4U6%-qr}QBzq? z*H$QScv%OyKC&E=0-@ZI1rb1*LuK9hYwJ#%{CO1FBOn+&uN*r&oj1O>K4{jLFX^%$!#Im!Ip2~6dI4juwtq5PtD z2AJ9r@(aMr@P|@g1zt)3`VSbVfbHS`0r*0jdwaUqf;rW73hL2R?(FqwMx^01*ppk* z(Wbva+GlD%p>{WWXOhdb{t7TWa#XIT9tO%IeHJaJe{VQO2JVYqF`8G%xne*`X zAHpu1R(5~i2Y-|&yZKLT=6`ify4+uJ$?u?GXm;}{h+wmd;=|w`-ywi%6a1q(w43+Y z%$tXtR=sQGujE4}doDlf|3c<+>N)5vs6Ht56bNlpWIm(phcd()_=t4hto&DjJ5+;8 z$KO7#DZPbtWs0k0zfeZeueQDNh~!1&BIsZ+q^1fUNAZ?W+=fYlH#OqW%=#WUjM z>mYIQw?GI zE#Qqd`&nR;ZD@Sy&2DQhh1>~jZ(kn;w&&+Z!1nwU-IA8m=)Vcr-ro9v?e+CRV0(JL z32bj4zXi6pk9D`|{)51F_ie!HHAxt~@eDA{?U26(jPFn&m3y0>zRke)`o9X;?tf~p zE-&u@dwco30DKVz4*Iu&?fIW!_RH(^^jrmOFVFjc?d|nrz;^lYPr!EhVb<&I;{>q1 zJl+d@sV#lq1BNM>rPhS?_HYK6#=%yHVa=WF=51h3W18K(8O&)swVPLixv65bo8JcJ z6j#++m<%Ze#%Z-)n%n*TBiNeCMF9NKJb-kximjCXGTBe8I=8*?I{uB-=k`DKI{qit zoZEk)3O@+>qj|hNe}kK(|NeC@OFrA}$2LlPd%0Z?@c-8>BL z*Ul6E1~8}gW_Q0igE@XzKN`x5z6{LO1juVXPjN(;6x`@HbyP5QdeeCPcA#@ZjrV9(b<%@4|U90K>K zVoINSOfs1_EAz2;xeRLgq@%wOn4=m89g0UN(h-K9k@gc{KVN@0{z}@9fIZ1xdwrFv z@X?;kNyqSKo|OKFKQw>%$rq%3srrs&65OHs=$q307Wo~(v=2}MOD^iKL&`n6vFB?_ znZE}9C|`}>&qRlyEe3Yf98{FId-wsSN1^u4}z8HTf_3f+OR)0XFvtXY^ zmY~00cpn1y_WW}9p9g!YuN+7itqpzv<}^>mI@zV-w40;Mqq4cHE4|JNfqAKNZ#TaM z%qT5q!9CSA&TpvV8d@cN=`6QQMz{VUld&1q~WIRl^Sh@#Cg)!C{1 zN*|H_DQ;@#Boli2r9H{^7iI8P9u%IphV{M_YJad@wtz|H6Zb>V+^arNF`^m>&Rr-E z%Bj$BzCWKimic_R40DG-LQsO!upNxY!T+*rw;Ex(;G|b)J0-p8E+25?Pl@w zWTc@Xe3A%*m6xf7C0ycyTY+`rWh;$!_zpAaonL|$rcDqv-aD?7cZMNv!>V3Mj{23L zB@QyKWjw|>rZ%d`e~PhJS&)4p<0NCh>Nw;+s00IXj}i#PrF$S#pol~Jbe>_{vtPHL zJfL&mL7fK~4>KN83qgv1>{{LbB;(+9x_uwxamL=my89sGKE~sWy&>kGaUbJx#$H_T zfTH{b8TT_WXW?ZPoAIfhn;~3)s#$$}98Rs|a>Gdn zig7+p;6Qn$W&{}5GEOocVm#6%1ETPZZk_uWhfXtl#$$|U7@K$N{)3ETj0YHxF`i~z zc#j_bbid9ckLqkZrgQ4;ItL!tx&8^AhZv6!==S;V)H(U2&f|>Dcj@-coS)Y1hZ#?w zW%ffl2S1?m%(FW8e?sRW#?y@H0~geO@}JlJ2N@e9x_u$z{Lkq2u~D7-7!NU?WZXQa z`=4Mu&3OE?x_kBc1gpOdeNMMGKd*C)@gU<7#^a3pzMzL!|3#g9822%rVVwV>?%!k_ zVm!{c_9fl_4CCZDvu7Oql5XF_xS#PL0HZrgt74}-Tla~bvFK8=MdvT#`&-5?gxIO z^Yo0){{PfD$#{Zs@VC1As#%?z8JpP-;ehJ9neilJbCK>of4R;v#$$|AjJ+##|AmYv z8Hd!1z$v{0jPqCN;l&t_F-|e|uGak*GM;1{E7ILhFg7pJ?L&;48TT*_st;vSeg{oG zJflSC5aT4{0meg&o7d>!P2hn9D2l&lqs~K&Cm2sNPHocthwxy-7XBdP3C7cmXBelp z=;0ZDo$DD7GoEG~EZ6-HFdk<-#W=-y7%y(w@;kg;=ZW1q*H-F0&bSm0ZfxQ8Fdkw& z#(0A9_@#Py)BAM}9?*G!as5Hv-g~9a0mcK2rx_Opb^m_GRg8^8y88*ng;(kJ!;GgG zS6!{U?`K?#2V1uC_aD|d$av&t-M;V^otqi^Z`JLm80X)n+s7D>F-|e|*6IEW8Ba1E zs@L78825#B`w_;4$94N=#{LG~zW;>IDaKVzy1f?<_-*wuz_|ZSy8Q&>X~rXJAD85x z5!LRd3h1_HmsD8Be@J zw;y>z=fZdD9C)|R!;G8Xqub9gt{v3vM;K3^(e3-+r?dC{Iwu(ip3&_m7*C$n?I%B= zbMRT62cFZ}`$3)kAJVz+!#dLjI`y}nVckCVF`XwFn;+NhV~j@_dq1JOuVrjLuiFRJ z!40LapYhlW%>Acy9%J118Qp%0acoStpZu)OrJvW?{{@{($910hlFnma(b@Q_&H={# zU)Sx&CUg#bL+8*pb)I2dIH}tYen;oY@9LcYeVvm((Aod0&J#b@x%4MG#~25Hs@qR7 zp8QAMzIK}NKj}R5&pJ>3i_QZ-*E#SDotuBDb1x6VC`Lpi$r1mj??Za=_yobeRn6yvD{ zdU(NwI_EFext4JtPq&}Q*V$0t^Co%IT%g;RF4uXGacHG(U%Oi8VaCRVx_uwx+9KWF zxJc(JQ|A%9fMc7Fjjz#pWUbBv>vbM3)wy(|&cV$(8(VZ9@aa6XRp%MT$uix3Kpo&x z`A?VY_JiAWp4g#t;ZB_g8Ru8%_I&}JLzn6tyiDgw#<44O``RkTdvxyGt8;K4-H0jhacDN#~B;%(Cx)EQ#~FJ+q5H359AiAl zc!F{M^Llutj6;lj7!NWYXFSa~e?*Tjz_^}qALAj$O)-T)0FJ zFUYuu@etz)#xsn~r7V2LF~$Ro#~4pD&R?d7A7EV1xR3EL<4MNG1$y|Uj6;lj7!NWY zXPjbOSfIyO#kiSqKjRU`Q;faK_3-_SYZ)gQ4>6u#Jj2*rp~n|w9AiAdc#QEh<9zi2 zc$!ZJ7}qoIV?4sRaFw23KjR?d0mj3O1FQA$`WO!~t}WKx#~3FW50&Wd#~4pA_Nr&# zsJ#4)YZ>=39%k%S&k9m_DfJ8-u~$7aM{F`~W}IX^!+2n`p5I}{Q;Y*!boU{~J&eZ~ zPcoiiZ2I)@;pJ!A_}s^MobeQ6|5n|9knzwC-QL)#^AzLce%*e6@d)Dy#xsly59s0f z8HX4*Gwx$N$aswLB;y&z`3G5g7zY_QGfpxdWIV!nl5vW0{*`)qN*M?Q42Xrp&(>eH7od+0CF|K`>xo14V*!wo!eHG&# z#zTx#jK?0)!<%ND->=&T7}qoIV?4}wlCklq9)2m~5aS-kgN(-+rx+XR8B`kIjHg)q zjH?*;F&<>>eV-m)72|%!m8&B)unT-1xk29WPY`$L)FTgne8Qs2=@f713#(}fC z{}|&z#*>V_L%RO}<7UPKjK>+zFfRRo9)2z3KE@-Arx|;n)x#@gT*bJaagy;M<1xll zjE(2?_)W%DjB6S9Fdkq$!g!ML4CBHN>gfqEu4UZAc!2Q;<4ML2BNJi)l{le+&A#{GY*+fOhyKBe2&G9F@Vd|G!uHKuclvG=pOy~#Mh zIK@@?Hd#khY` zw;y60`i^ez{jSbKjQhW*+ou?he_yxn`3Ic?KhSxCajkmC0L>5j80Syv{;L=_Gw%7Z z?!NFRI#>N#=N`t*uj%&VjQzjS?fV&zFz)-E?moph@JHQ#YF1}>YqYjrZe~2ixXP)! zA7NbR((U^hrx@2}>F%4C=$vG1EYRijXkMRiO z{FS=@!PPpCFrH>yc%klojImLq+ZQtSGmbItW9%)_!wWF(S)&5Vsry8R5}kX<*r(f1l@)z_^NWh;cpR7~>@40mj3O#~4pAo@Q+P1Kq<5I>|jB6R!GwxxWWIVulnDIE{ zDaI+r#+&v0KNPJi&O1af&f~SVvob<})@K`x#d;4l%B09Alhh+|PKB@i5~t#uJRE z7^fH;_pYoYW8BBM zpYagmVaDT(Cm2sNPBHf0ujen$Mez z{fvW*YZ=qKd?~ynv+rX($askHFyj%%V~occPcWWjJjHm1vGEYAU&bcm0OKmgwT$Z- z_b^T}9$-Akc!=>Z<1xmQj8lwf80Wu5FAtNkpK%rA5aW8rF~&*8{fvhg4>KNPJi&O1 zaf-3`t$Kd*85c4(83!1L7&kM9&lYO)lYYj7jE5PIF`i&N#W=;-cvz1=pRvi<&$x@4e#V20hZ&DCo?tx9*m#?s-$KTI#zDsQj0@FyaW2#%J{cO5*ZalyvhXCt zuLL97BL|nkA5g^f!eL^sdI2$Uk13p6?vsrD>va17?Q!59*v!?<=MB z4BxEVk2ChG_id8d?qTfRrrS?nqH}Ff=la7s`_=nqDE&r6xA!tOPU`lPKh$}OaqVw( z`+COx>iKkvzd1(=AY$(Vou?M*Jk7Xtg>LU>JfWU{rto`q>+X|`ht%`1^O(dT#-*Rv;~QZd`i^ct^L?F- zS9K2jMCZaB92L{!;Rxda^*jWnZ@NTxZ?4ff$T-G$knuR&$0~LE6l3!;-M*A@s7kl**`xFDex0Wo=d1hol-?lYB;ygrDaNG- z_4w);4=|o!?7dR=U&XkG@i60Q#%53tuP>zYzzLm47>_efoz&eox9aSV>f9ICd0gFx zr}7@ZL$^12bsqT(ol}e_)O~ddFL0OcKL51NrT6L_WIV*!xL}MQc+|0O#aqJ^{{C$k4hjn}7qdKS5eNZa@!oSh&`#z@g z1mo$C>-MP;odfEdLKOahy3a{mrS5YQhhEhECtuPzU)?t(_k)ak)cr!Tk9|$|pH%nP z$bL}W4q{`zRr{C{uPDqzd*M))qO0o zH&^KPeT*ko>-NTlI{O)iN_6|NH97~@={&q%=fVv-CrfqC->h??y3a%T2{LZBt(Sz) zAyM37eTiIeTc040+14A#DaOe$Fa(A1p?$M${eV2hIA~iBp#7kFe>C~8Qtx*rZvGB9 z0!2LbW1XAT`sb_Zt(}tM?HTr?S)YZ%nVTQs;q9I>#z? zHm}qq#4s3Yftk6@Yc>q>(r1vSs8{tJF49AoI8f*x zf0F+~Gz5ih1>+|F^qnr!UqnYXrGm3e@cVz*p2$CaM~rm(j+kh};Ev*_^zQ;Q$~*kD Q)Yy!yhoEI5fAIMK4_fJMd;kCd delta 73092 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 LNLOaMw!{Au+Mxbo diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 004271c696..4a29ae30c4 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -61,7 +61,7 @@ const ( TestSolanaDepositAndCallRefundName = "solana_deposit_and_call_refund" TestSolanaDepositRestrictedName = "solana_deposit_restricted" TestSolanaWithdrawRestrictedName = "solana_withdraw_restricted" - + TestSolanaWhitelistSPLName = "solana_whitelist_spl" /** * TON tests */ @@ -438,6 +438,12 @@ var AllE2ETests = []runner.E2ETest{ }, TestSolanaWithdrawRestricted, ), + runner.NewE2ETest( + TestSolanaWhitelistSPLName, + "whitelist SPL", + []runner.ArgDefinition{}, + TestSolanaWhitelistSPL, + ), /* TON tests */ diff --git a/e2e/e2etests/test_solana_whitelist_spl.go b/e2e/e2etests/test_solana_whitelist_spl.go new file mode 100644 index 0000000000..5276d78552 --- /dev/null +++ b/e2e/e2etests/test_solana_whitelist_spl.go @@ -0,0 +1,55 @@ +package e2etests + +import ( + "github.com/gagliardetto/solana-go" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/txserver" + "github.com/zeta-chain/node/e2e/utils" + "github.com/zeta-chain/node/pkg/chains" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +func TestSolanaWhitelistSPL(r *runner.E2ERunner, args []string) { + // Deploy a new SPL + r.Logger.Info("Deploying new SPL") + + // load deployer private key + privkey, err := solana.PrivateKeyFromBase58(r.Account.SolanaPrivateKey.String()) + require.NoError(r, err) + + spl := r.DeploySPL(&privkey) + + // whitelist erc20 zrc20 + r.Logger.Info("whitelisting ERC20 on new network") + res, err := r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, crosschaintypes.NewMsgWhitelistERC20( + r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName), + spl.PublicKey().String(), + chains.SolanaLocalnet.ChainId, + "NEWSOLERC20", + "NEWSOLERC20", + 6, + 100000, + )) + require.NoError(r, err) + + // retrieve zrc20 and cctx from event + whitelistCCTXIndex, err := txserver.FetchAttributeFromTxResponse(res, "whitelist_cctx_index") + require.NoError(r, err) + + erc20zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address") + require.NoError(r, err) + + err = r.ZetaTxServer.InitializeLiquidityCap(erc20zrc20Addr) + require.NoError(r, err) + + // ensure CCTX created + resCCTX, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: whitelistCCTXIndex}) + require.NoError(r, err) + + cctx := resCCTX.CrossChainTx + r.Logger.CCTX(*cctx, "whitelist_cctx") + + // wait for the whitelist cctx to be mined + r.WaitForMinedCCTXFromIndex(whitelistCCTXIndex) +} diff --git a/e2e/runner/setup_solana.go b/e2e/runner/setup_solana.go index 8f209dd23e..d5c4bb20de 100644 --- a/e2e/runner/setup_solana.go +++ b/e2e/runner/setup_solana.go @@ -55,7 +55,7 @@ func (r *E2ERunner) SetSolanaContracts(deployerPrivateKey string) { require.NoError(r, err) // create and sign the transaction - signedTx := r.CreateSignedTransaction([]solana.Instruction{&inst}, privkey) + signedTx := r.CreateSignedTransaction([]solana.Instruction{&inst}, privkey, []solana.PrivateKey{}) // broadcast the transaction and wait for finalization _, out := r.BroadcastTxSync(signedTx) diff --git a/e2e/runner/solana.go b/e2e/runner/solana.go index 8ff67b9d72..e4ed5162df 100644 --- a/e2e/runner/solana.go +++ b/e2e/runner/solana.go @@ -6,6 +6,8 @@ import ( ethcommon "github.com/ethereum/go-ethereum/common" "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/programs/system" + "github.com/gagliardetto/solana-go/programs/token" "github.com/gagliardetto/solana-go/rpc" "github.com/near/borsh-go" "github.com/stretchr/testify/require" @@ -62,6 +64,7 @@ func (r *E2ERunner) CreateDepositInstruction( func (r *E2ERunner) CreateSignedTransaction( instructions []solana.Instruction, privateKey solana.PrivateKey, + additionalPrivateKeys []solana.PrivateKey, ) *solana.Transaction { // get a recent blockhash recent, err := r.SolanaClient.GetLatestBlockhash(r.Ctx, rpc.CommitmentFinalized) @@ -81,6 +84,11 @@ func (r *E2ERunner) CreateSignedTransaction( if privateKey.PublicKey().Equals(key) { return &privateKey } + for _, apk := range additionalPrivateKeys { + if apk.PublicKey().Equals(key) { + return &apk + } + } return nil }, ) @@ -89,6 +97,35 @@ func (r *E2ERunner) CreateSignedTransaction( return tx } +func (r *E2ERunner) DeploySPL(privateKey *solana.PrivateKey) *solana.Wallet { + lamport, err := r.SolanaClient.GetMinimumBalanceForRentExemption(r.Ctx, token.MINT_SIZE, rpc.CommitmentFinalized) + require.NoError(r, err) + + tokenAccount := solana.NewWallet() + createAccountInstruction := system.NewCreateAccountInstruction( + lamport, + token.MINT_SIZE, + solana.TokenProgramID, + privateKey.PublicKey(), + tokenAccount.PublicKey(), + ).Build() + + initializeMintInstruction := token.NewInitializeMint2Instruction( + 6, + privateKey.PublicKey(), + privateKey.PublicKey(), + tokenAccount.PublicKey(), + ).Build() + + signedTx := r.CreateSignedTransaction([]solana.Instruction{createAccountInstruction, initializeMintInstruction}, *privateKey, []solana.PrivateKey{tokenAccount.PrivateKey}) + + // broadcast the transaction and wait for finalization + _, out := r.BroadcastTxSync(signedTx) + r.Logger.Info("create spl logs: %v", out.Meta.LogMessages) + + return tokenAccount +} + // BroadcastTxSync broadcasts a transaction and waits for it to be finalized func (r *E2ERunner) BroadcastTxSync(tx *solana.Transaction) (solana.Signature, *rpc.GetTransactionResult) { // broadcast the transaction @@ -134,7 +171,7 @@ func (r *E2ERunner) SOLDepositAndCall( instruction := r.CreateDepositInstruction(signerPrivKey.PublicKey(), receiver, data, amount.Uint64()) // create and sign the transaction - signedTx := r.CreateSignedTransaction([]solana.Instruction{instruction}, *signerPrivKey) + signedTx := r.CreateSignedTransaction([]solana.Instruction{instruction}, *signerPrivKey, []solana.PrivateKey{}) // broadcast the transaction and wait for finalization sig, out := r.BroadcastTxSync(signedTx) diff --git a/pkg/contracts/solana/gateway.go b/pkg/contracts/solana/gateway.go index a8f0c571e5..5049a3c668 100644 --- a/pkg/contracts/solana/gateway.go +++ b/pkg/contracts/solana/gateway.go @@ -8,7 +8,7 @@ import ( const ( // SolanaGatewayProgramID is the program ID of the Solana gateway program - SolanaGatewayProgramID = "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" + SolanaGatewayProgramID = "BaDmykPHVwPQNY9SXQnJU8JPXdN89z3ib7qEfhNfkWRg" // PDASeed is the seed for the Solana gateway program derived address PDASeed = "meta" @@ -43,6 +43,11 @@ func DiscriminatorWithdrawSPL() [8]byte { return [8]byte{156, 234, 11, 89, 235, 246, 32} } +// DiscriminatorWhitelist returns the discriminator for Solana gateway 'whitelist_spl_mint' instruction +func DiscriminatorWhitelistSplMint() [8]byte { + return [8]byte{30, 110, 162, 42, 208, 147, 254, 219} +} + // ParseGatewayAddressAndPda parses the gateway id and program derived address from the given string func ParseGatewayIDAndPda(address string) (solana.PublicKey, solana.PublicKey, error) { var gatewayID, pda solana.PublicKey diff --git a/pkg/contracts/solana/gateway.json b/pkg/contracts/solana/gateway.json index 8747c2ca0f..e183391604 100644 --- a/pkg/contracts/solana/gateway.json +++ b/pkg/contracts/solana/gateway.json @@ -1,5 +1,5 @@ { - "address": "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d", + "address": "BaDmykPHVwPQNY9SXQnJU8JPXdN89z3ib7qEfhNfkWRg", "metadata": { "name": "gateway", "version": "0.1.0", @@ -27,7 +27,76 @@ }, { "name": "pda", - "writable": true + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "amount", + "type": "u64" + }, + { + "name": "receiver", + "type": { + "array": [ + "u8", + 20 + ] + } + } + ] + }, + { + "name": "deposit_and_call", + "discriminator": [ + 65, + 33, + 186, + 198, + 114, + 223, + 133, + 57 + ], + "accounts": [ + { + "name": "signer", + "writable": true, + "signer": true + }, + { + "name": "pda", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } }, { "name": "system_program", @@ -40,7 +109,16 @@ "type": "u64" }, { - "name": "memo", + "name": "receiver", + "type": { + "array": [ + "u8", + 20 + ] + } + }, + { + "name": "message", "type": "bytes" } ] @@ -65,7 +143,97 @@ }, { "name": "pda", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } + }, + { + "name": "whitelist_entry", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 119, + 104, + 105, + 116, + 101, + 108, + 105, + 115, + 116 + ] + }, + { + "kind": "account", + "path": "mint_account" + } + ] + } + }, + { + "name": "mint_account" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "from", + "writable": true + }, + { + "name": "to", + "writable": true + } + ], + "args": [ + { + "name": "amount", + "type": "u64" + }, + { + "name": "receiver", + "type": { + "array": [ + "u8", + 20 + ] + } + } + ] + }, + { + "name": "deposit_spl_token_and_call", + "discriminator": [ + 14, + 181, + 27, + 187, + 171, + 61, + 237, + 147 + ], + "accounts": [ + { + "name": "signer", "writable": true, + "signer": true + }, + { + "name": "pda", "pda": { "seeds": [ { @@ -80,6 +248,34 @@ ] } }, + { + "name": "whitelist_entry", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 119, + 104, + 105, + 116, + 101, + 108, + 105, + 115, + 116 + ] + }, + { + "kind": "account", + "path": "mint_account" + } + ] + } + }, + { + "name": "mint_account" + }, { "name": "token_program", "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -99,7 +295,16 @@ "type": "u64" }, { - "name": "memo", + "name": "receiver", + "type": { + "array": [ + "u8", + 20 + ] + } + }, + { + "name": "message", "type": "bytes" } ] @@ -153,6 +358,170 @@ 20 ] } + }, + { + "name": "chain_id", + "type": "u64" + } + ] + }, + { + "name": "set_deposit_paused", + "discriminator": [ + 98, + 179, + 141, + 24, + 246, + 120, + 164, + 143 + ], + "accounts": [ + { + "name": "pda", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } + }, + { + "name": "signer", + "writable": true, + "signer": true + } + ], + "args": [ + { + "name": "deposit_paused", + "type": "bool" + } + ] + }, + { + "name": "unwhitelist_spl_mint", + "discriminator": [ + 73, + 142, + 63, + 191, + 233, + 238, + 170, + 104 + ], + "accounts": [ + { + "name": "whitelist_entry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 119, + 104, + 105, + 116, + 101, + 108, + 105, + 115, + 116 + ] + }, + { + "kind": "account", + "path": "whitelist_candidate" + } + ] + } + }, + { + "name": "whitelist_candidate" + }, + { + "name": "pda", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } + }, + { + "name": "authority", + "writable": true, + "signer": true, + "relations": [ + "pda" + ] + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [] + }, + { + "name": "update_authority", + "discriminator": [ + 32, + 46, + 64, + 28, + 149, + 75, + 243, + 88 + ], + "accounts": [ + { + "name": "pda", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } + }, + { + "name": "signer", + "writable": true, + "signer": true + } + ], + "args": [ + { + "name": "new_authority_address", + "type": "pubkey" } ] }, @@ -171,7 +540,20 @@ "accounts": [ { "name": "pda", - "writable": true + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } }, { "name": "signer", @@ -191,6 +573,80 @@ } ] }, + { + "name": "whitelist_spl_mint", + "discriminator": [ + 30, + 110, + 162, + 42, + 208, + 147, + 254, + 219 + ], + "accounts": [ + { + "name": "whitelist_entry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 119, + 104, + 105, + 116, + 101, + 108, + 105, + 115, + 116 + ] + }, + { + "kind": "account", + "path": "whitelist_candidate" + } + ] + } + }, + { + "name": "whitelist_candidate" + }, + { + "name": "pda", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } + }, + { + "name": "authority", + "writable": true, + "signer": true, + "relations": [ + "pda" + ] + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [] + }, { "name": "withdraw", "discriminator": [ @@ -211,7 +667,20 @@ }, { "name": "pda", - "writable": true + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 109, + 101, + 116, + 97 + ] + } + ] + } }, { "name": "to", @@ -287,9 +756,12 @@ } }, { - "name": "from", + "name": "pda_ata", "writable": true }, + { + "name": "mint_account" + }, { "name": "to", "writable": true @@ -300,6 +772,10 @@ } ], "args": [ + { + "name": "decimals", + "type": "u8" + }, { "name": "amount", "type": "u64" @@ -346,6 +822,19 @@ 43, 94 ] + }, + { + "name": "WhitelistEntry", + "discriminator": [ + 51, + 70, + 173, + 81, + 219, + 192, + 234, + 62 + ] } ], "errors": [ @@ -388,6 +877,16 @@ "code": 6007, "name": "MemoLengthTooShort", "msg": "MemoLengthTooShort" + }, + { + "code": 6008, + "name": "DepositPaused", + "msg": "DepositPaused" + }, + { + "code": 6009, + "name": "SPLAtaAndMintAddressMismatch", + "msg": "SPLAtaAndMintAddressMismatch" } ], "types": [ @@ -412,9 +911,24 @@ { "name": "authority", "type": "pubkey" + }, + { + "name": "chain_id", + "type": "u64" + }, + { + "name": "deposit_paused", + "type": "bool" } ] } + }, + { + "name": "WhitelistEntry", + "type": { + "kind": "struct", + "fields": [] + } } ] } \ No newline at end of file diff --git a/pkg/contracts/solana/gateway_message.go b/pkg/contracts/solana/gateway_message.go index 021af3cf1f..1f31e1d63b 100644 --- a/pkg/contracts/solana/gateway_message.go +++ b/pkg/contracts/solana/gateway_message.go @@ -105,3 +105,19 @@ func (msg *MsgWithdraw) Signer() (common.Address, error) { return RecoverSigner(msgHash[:], msgSig[:]) } + +// MsgWhitelist is the message for the Solana gateway whitelist_spl_mint instruction +type MsgWhitelist struct { + // whitelistCandidate is the whitelist candidate + whitelistCandidate solana.PublicKey +} + +// NewMsgWhitelist returns a new whitelist_spl_mint message +func NewMsgWhitelist(whitelistCandidate solana.PublicKey) *MsgWhitelist { + return &MsgWhitelist{whitelistCandidate: whitelistCandidate} +} + +// To returns the recipient address of the message +func (msg *MsgWhitelist) WhitelistCandidate() solana.PublicKey { + return msg.whitelistCandidate +} diff --git a/pkg/contracts/solana/instruction.go b/pkg/contracts/solana/instruction.go index f338129c9b..f69e7e8079 100644 --- a/pkg/contracts/solana/instruction.go +++ b/pkg/contracts/solana/instruction.go @@ -116,3 +116,27 @@ func RecoverSigner(msgHash []byte, msgSig []byte) (signer common.Address, err er return crypto.PubkeyToAddress(*pubKey), nil } + +// WhitelistInstructionParams contains the parameters for a gateway whitelist_spl_mint instruction +type WhitelistInstructionParams struct { + // Discriminator is the unique identifier for the whitelist_spl_mint instruction + Discriminator [8]byte +} + +// ParseInstructionWhitelist tries to parse the instruction as a 'whitelist_spl_mint'. +// It returns nil if the instruction can't be parsed as a 'whitelist_spl_mint'. +func ParseInstructionWhitelist(instruction solana.CompiledInstruction) (*WhitelistInstructionParams, error) { + // try deserializing instruction as a 'whitelist_spl_mint' + inst := &WhitelistInstructionParams{} + err := borsh.Deserialize(inst, instruction.Data) + if err != nil { + return nil, errors.Wrap(err, "error deserializing instruction") + } + + // check the discriminator to ensure it's a 'whitelist_spl_mint' instruction + if inst.Discriminator != DiscriminatorWhitelistSplMint() { + return nil, fmt.Errorf("not a whitelist_spl_mint instruction: %v", inst.Discriminator) + } + + return inst, nil +} diff --git a/x/crosschain/keeper/msg_server_whitelist_erc20.go b/x/crosschain/keeper/msg_server_whitelist_erc20.go index 4ae98a85b5..7321fdb835 100644 --- a/x/crosschain/keeper/msg_server_whitelist_erc20.go +++ b/x/crosschain/keeper/msg_server_whitelist_erc20.go @@ -6,7 +6,6 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/node/pkg/coin" @@ -31,28 +30,28 @@ func (k msgServer) WhitelistERC20( return nil, errorsmod.Wrap(authoritytypes.ErrUnauthorized, err.Error()) } - erc20Addr := ethcommon.HexToAddress(msg.Erc20Address) - if erc20Addr == (ethcommon.Address{}) { - return nil, errorsmod.Wrapf( - sdkerrors.ErrInvalidAddress, - "invalid ERC20 contract address (%s)", - msg.Erc20Address, - ) - } - - // check if the erc20 is already whitelisted - foreignCoins := k.fungibleKeeper.GetAllForeignCoins(ctx) - for _, fCoin := range foreignCoins { - assetAddr := ethcommon.HexToAddress(fCoin.Asset) - if assetAddr == erc20Addr && fCoin.ForeignChainId == msg.ChainId { - return nil, errorsmod.Wrapf( - fungibletypes.ErrForeignCoinAlreadyExist, - "ERC20 contract address (%s) already whitelisted on chain (%d)", - msg.Erc20Address, - msg.ChainId, - ) - } - } + // erc20Addr := ethcommon.HexToAddress(msg.Erc20Address) + // if erc20Addr == (ethcommon.Address{}) { + // return nil, errorsmod.Wrapf( + // sdkerrors.ErrInvalidAddress, + // "invalid ERC20 contract address (%s)", + // msg.Erc20Address, + // ) + // } + + // // check if the erc20 is already whitelisted + // foreignCoins := k.fungibleKeeper.GetAllForeignCoins(ctx) + // for _, fCoin := range foreignCoins { + // assetAddr := ethcommon.HexToAddress(fCoin.Asset) + // if assetAddr == erc20Addr && fCoin.ForeignChainId == msg.ChainId { + // return nil, errorsmod.Wrapf( + // fungibletypes.ErrForeignCoinAlreadyExist, + // "ERC20 contract address (%s) already whitelisted on chain (%d)", + // msg.Erc20Address, + // msg.ChainId, + // ) + // } + // } tss, found := k.zetaObserverKeeper.GetTSS(ctx) if !found { diff --git a/x/crosschain/types/message_whitelist_erc20.go b/x/crosschain/types/message_whitelist_erc20.go index 3267581662..4620e4be08 100644 --- a/x/crosschain/types/message_whitelist_erc20.go +++ b/x/crosschain/types/message_whitelist_erc20.go @@ -4,7 +4,6 @@ import ( cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - ethcommon "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/node/x/fungible/types" ) @@ -54,9 +53,9 @@ func (msg *MsgWhitelistERC20) ValidateBasic() error { return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } // check if the system contract address is valid - if ethcommon.HexToAddress(msg.Erc20Address) == (ethcommon.Address{}) { - return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid ERC20 contract address (%s)", msg.Erc20Address) - } + // if ethcommon.HexToAddress(msg.Erc20Address) == (ethcommon.Address{}) { + // return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid ERC20 contract address (%s)", msg.Erc20Address) + // } if msg.Decimals > 128 { return cosmoserrors.Wrapf(types.ErrInvalidDecimals, "invalid decimals (%d)", msg.Decimals) } diff --git a/zetaclient/chains/solana/signer/signer.go b/zetaclient/chains/solana/signer/signer.go index 3b64a1ff7c..a77f456c32 100644 --- a/zetaclient/chains/solana/signer/signer.go +++ b/zetaclient/chains/solana/signer/signer.go @@ -2,6 +2,8 @@ package signer import ( "context" + "fmt" + "strings" "cosmossdk.io/errors" ethcommon "github.com/ethereum/go-ethereum/common" @@ -121,6 +123,49 @@ func (signer *Signer) TryProcessOutbound( chainID := signer.Chain().ChainId nonce := params.TssNonce coinType := cctx.InboundParams.CoinType + relayedMsg := strings.Split(cctx.RelayedMessage, ":") + if len(relayedMsg) != 2 { + return + } + fmt.Println("debug ", coinType, relayedMsg[1]) + + if coinType == coin.CoinType_Cmd { + pk, err := solana.PublicKeyFromBase58(relayedMsg[1]) + if err != nil { + fmt.Println("err decoding ", err.Error()) + } + + // sign the withdraw transaction by relayer key + tx, err := signer.SignWhitelistTx(ctx, contracts.NewMsgWhitelist(pk)) + if err != nil { + logger.Error().Err(err).Msgf("TryProcessOutbound: SignGasWithdraw error for chain %d nonce %d", chainID, nonce) + return + } + + // broadcast the signed tx to the Solana network with preflight check + txSig, err := signer.client.SendTransactionWithOpts( + ctx, + tx, + // Commitment "finalized" is too conservative for preflight check and + // it results in repeated broadcast attempts that only 1 will succeed. + // Commitment "processed" will simulate tx against more recent state + // thus fails faster once a tx is already broadcasted and processed by the cluster. + // This reduces the number of "failed" txs due to repeated broadcast attempts. + rpc.TransactionOpts{PreflightCommitment: rpc.CommitmentProcessed}, + ) + if err != nil { + signer.Logger(). + Std.Warn(). + Err(err). + Msgf("TryProcessOutbound: broadcast error for chain %d nonce %d", chainID, nonce) + return + } + + // report the outbound to the outbound tracker + signer.reportToOutboundTracker(ctx, zetacoreClient, chainID, nonce, txSig, logger) + return + } + if coinType != coin.CoinType_Gas { logger.Error(). Msgf("TryProcessOutbound: can only send SOL to the Solana network for chain %d nonce %d", chainID, nonce) diff --git a/zetaclient/chains/solana/signer/whitelist.go b/zetaclient/chains/solana/signer/whitelist.go new file mode 100644 index 0000000000..09a4ad8300 --- /dev/null +++ b/zetaclient/chains/solana/signer/whitelist.go @@ -0,0 +1,81 @@ +package signer + +import ( + "context" + + "cosmossdk.io/errors" + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" + "github.com/near/borsh-go" + contracts "github.com/zeta-chain/node/pkg/contracts/solana" +) + +// SignWhitelistTx wraps the whitelist 'msg' into a Solana transaction and signs it with the relayer key. +func (signer *Signer) SignWhitelistTx(ctx context.Context, msg *contracts.MsgWhitelist) (*solana.Transaction, error) { + // create whitelist_spl_mint instruction with program call data + var err error + var inst solana.GenericInstruction + inst.DataBytes, err = borsh.Serialize(contracts.WhitelistInstructionParams{ + Discriminator: contracts.DiscriminatorWhitelistSplMint(), + }) + if err != nil { + return nil, errors.Wrap(err, "cannot serialize whitelist_spl_mint instruction") + } + + // attach required accounts to the instruction + privkey := signer.relayerKey + attachWhitelistAccounts(&inst, privkey.PublicKey(), signer.pda, msg.WhitelistCandidate(), signer.gatewayID) + + // get a recent blockhash + recent, err := signer.client.GetLatestBlockhash(ctx, rpc.CommitmentFinalized) + if err != nil { + return nil, errors.Wrap(err, "GetLatestBlockhash error") + } + + // create a transaction that wraps the instruction + tx, err := solana.NewTransaction( + []solana.Instruction{ + // TODO: outbound now uses 5K lamports as the fixed fee, we could explore priority fee and compute budget + // https://github.com/zeta-chain/node/issues/2599 + // programs.ComputeBudgetSetComputeUnitLimit(computeUnitLimit), + // programs.ComputeBudgetSetComputeUnitPrice(computeUnitPrice), + &inst}, + recent.Value.Blockhash, + solana.TransactionPayer(privkey.PublicKey()), + ) + if err != nil { + return nil, errors.Wrap(err, "NewTransaction error") + } + + // relayer signs the transaction + _, err = tx.Sign(func(key solana.PublicKey) *solana.PrivateKey { + if key.Equals(privkey.PublicKey()) { + return privkey + } + return nil + }) + if err != nil { + return nil, errors.Wrap(err, "signer unable to sign transaction") + } + + return tx, nil +} + +// attachWhitelistAccounts attaches the required accounts for the gateway whitelist instruction. +func attachWhitelistAccounts( + inst *solana.GenericInstruction, + signer solana.PublicKey, + pda solana.PublicKey, + whitelistCandidate solana.PublicKey, + gatewayID solana.PublicKey, +) { + // attach required accounts to the instruction + var accountSlice []*solana.AccountMeta + accountSlice = append(accountSlice, solana.Meta(whitelistCandidate)) + accountSlice = append(accountSlice, solana.Meta(pda).WRITE()) + accountSlice = append(accountSlice, solana.Meta(signer).WRITE().SIGNER()) + accountSlice = append(accountSlice, solana.Meta(solana.SystemProgramID)) + inst.ProgID = gatewayID + + inst.AccountValues = accountSlice +} diff --git a/zetaclient/testutils/constant.go b/zetaclient/testutils/constant.go index e9b8b53563..effa665443 100644 --- a/zetaclient/testutils/constant.go +++ b/zetaclient/testutils/constant.go @@ -42,7 +42,7 @@ const ( // GatewayAddresses contains constants gateway addresses for testing var GatewayAddresses = map[int64]string{ // Gateway address on Solana devnet - chains.SolanaDevnet.ChainId: "ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis", + chains.SolanaDevnet.ChainId: "BaDmykPHVwPQNY9SXQnJU8JPXdN89z3ib7qEfhNfkWRg", } // ConnectorAddresses contains constants ERC20 connector addresses for testing From 059d4d5a3c17ff57d3d4fc0a2fa55512c384cd80 Mon Sep 17 00:00:00 2001 From: skosito Date: Wed, 9 Oct 2024 20:09:24 +0200 Subject: [PATCH 2/5] whitelist test wip --- cmd/zetae2e/config/local.yml | 4 +-- cmd/zetae2e/config/localnet.yml | 4 +-- e2e/e2etests/test_solana_whitelist_spl.go | 26 ++++++++++++++----- e2e/runner/setup_solana.go | 1 - pkg/contracts/solana/gateway_message.go | 9 +++++-- zetaclient/chains/solana/observer/outbound.go | 15 +++++++++-- zetaclient/chains/solana/signer/signer.go | 22 ++++++++++++---- zetaclient/chains/solana/signer/whitelist.go | 4 ++- 8 files changed, 64 insertions(+), 21 deletions(-) diff --git a/cmd/zetae2e/config/local.yml b/cmd/zetae2e/config/local.yml index 2481ab31fa..f4a4456acd 100644 --- a/cmd/zetae2e/config/local.yml +++ b/cmd/zetae2e/config/local.yml @@ -76,8 +76,8 @@ policy_accounts: private_key: "0595CB0CD9BF5264A85A603EC8E43C30ADBB5FD2D9E2EF84C374EA4A65BB616C" observer_relayer_accounts: relayer_accounts: - - solana_address: "2qBVcNBZCubcnSR3NyCnFjCfkCVUB3G7ECPoaW5rxVjx" - solana_private_key: "3EMjCcCJg53fMEGVj13UPQpo6py9AKKyLE2qroR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQ" + - solana_address: "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ" + solana_private_key: "4yqSQxDeTBvn86BuxcN5jmZb2gaobFXrBqu8kiE9rZxNkVMe3LfXmFigRsU4sRp7vk4vVP1ZCFiejDKiXBNWvs2C" - solana_address: "4kkCV8H38xirwQTkE5kL6FHNtYGHnMQQ7SkCjAxibHFK" solana_private_key: "5SSv7jWzamtjWNKGiKf3gvCPHcq9mE5x6LhYgzJCKNSxoQ83gFpmMgmg2JS2zdKcBEdwy7y9bvWgX4LBiUpvnrPf" rpcs: diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index 5bd207a020..4a17827c94 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -76,8 +76,8 @@ policy_accounts: private_key: "0595CB0CD9BF5264A85A603EC8E43C30ADBB5FD2D9E2EF84C374EA4A65BB616C" observer_relayer_accounts: relayer_accounts: - - solana_address: "2qBVcNBZCubcnSR3NyCnFjCfkCVUB3G7ECPoaW5rxVjx" - solana_private_key: "3EMjCcCJg53fMEGVj13UPQpo6py9AKKyLE2qroR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQ" + - solana_address: "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ" + solana_private_key: "4yqSQxDeTBvn86BuxcN5jmZb2gaobFXrBqu8kiE9rZxNkVMe3LfXmFigRsU4sRp7vk4vVP1ZCFiejDKiXBNWvs2C" - solana_address: "4kkCV8H38xirwQTkE5kL6FHNtYGHnMQQ7SkCjAxibHFK" solana_private_key: "5SSv7jWzamtjWNKGiKf3gvCPHcq9mE5x6LhYgzJCKNSxoQ83gFpmMgmg2JS2zdKcBEdwy7y9bvWgX4LBiUpvnrPf" rpcs: diff --git a/e2e/e2etests/test_solana_whitelist_spl.go b/e2e/e2etests/test_solana_whitelist_spl.go index 5276d78552..6af27f614c 100644 --- a/e2e/e2etests/test_solana_whitelist_spl.go +++ b/e2e/e2etests/test_solana_whitelist_spl.go @@ -20,14 +20,23 @@ func TestSolanaWhitelistSPL(r *runner.E2ERunner, args []string) { spl := r.DeploySPL(&privkey) - // whitelist erc20 zrc20 - r.Logger.Info("whitelisting ERC20 on new network") + // check that whitelist entry doesn't exist for this spl + seed := [][]byte{[]byte("whitelist"), spl.PublicKey().Bytes()} + whitelistEntryPDA, _, err := solana.FindProgramAddress(seed, r.GatewayProgram) + require.NoError(r, err) + + whitelistEntryInfo, err := r.SolanaClient.GetAccountInfo(r.Ctx, whitelistEntryPDA) + require.Error(r, err) + require.Nil(r, whitelistEntryInfo) + + // whitelist sol zrc20 + r.Logger.Info("whitelisting spl on new network") res, err := r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, crosschaintypes.NewMsgWhitelistERC20( r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName), spl.PublicKey().String(), chains.SolanaLocalnet.ChainId, - "NEWSOLERC20", - "NEWSOLERC20", + "TESTSPL", + "TESTSPL", 6, 100000, )) @@ -37,10 +46,10 @@ func TestSolanaWhitelistSPL(r *runner.E2ERunner, args []string) { whitelistCCTXIndex, err := txserver.FetchAttributeFromTxResponse(res, "whitelist_cctx_index") require.NoError(r, err) - erc20zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address") + zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address") require.NoError(r, err) - err = r.ZetaTxServer.InitializeLiquidityCap(erc20zrc20Addr) + err = r.ZetaTxServer.InitializeLiquidityCap(zrc20Addr) require.NoError(r, err) // ensure CCTX created @@ -52,4 +61,9 @@ func TestSolanaWhitelistSPL(r *runner.E2ERunner, args []string) { // wait for the whitelist cctx to be mined r.WaitForMinedCCTXFromIndex(whitelistCCTXIndex) + + // check that whitelist entry exists for this spl + whitelistEntryInfo, err = r.SolanaClient.GetAccountInfo(r.Ctx, whitelistEntryPDA) + require.NoError(r, err) + require.NotNil(r, whitelistEntryInfo) } diff --git a/e2e/runner/setup_solana.go b/e2e/runner/setup_solana.go index d5c4bb20de..a4ec0a79d7 100644 --- a/e2e/runner/setup_solana.go +++ b/e2e/runner/setup_solana.go @@ -43,7 +43,6 @@ func (r *E2ERunner) SetSolanaContracts(deployerPrivateKey string) { accountSlice = append(accountSlice, solana.Meta(privkey.PublicKey()).WRITE().SIGNER()) accountSlice = append(accountSlice, solana.Meta(pdaComputed).WRITE()) accountSlice = append(accountSlice, solana.Meta(solana.SystemProgramID)) - accountSlice = append(accountSlice, solana.Meta(r.GatewayProgram)) inst.ProgID = r.GatewayProgram inst.AccountValues = accountSlice diff --git a/pkg/contracts/solana/gateway_message.go b/pkg/contracts/solana/gateway_message.go index 1f31e1d63b..f75665a5f5 100644 --- a/pkg/contracts/solana/gateway_message.go +++ b/pkg/contracts/solana/gateway_message.go @@ -110,14 +110,19 @@ func (msg *MsgWithdraw) Signer() (common.Address, error) { type MsgWhitelist struct { // whitelistCandidate is the whitelist candidate whitelistCandidate solana.PublicKey + whitelistEntry solana.PublicKey } // NewMsgWhitelist returns a new whitelist_spl_mint message -func NewMsgWhitelist(whitelistCandidate solana.PublicKey) *MsgWhitelist { - return &MsgWhitelist{whitelistCandidate: whitelistCandidate} +func NewMsgWhitelist(whitelistCandidate solana.PublicKey, whitelistEntry solana.PublicKey) *MsgWhitelist { + return &MsgWhitelist{whitelistCandidate: whitelistCandidate, whitelistEntry: whitelistEntry} } // To returns the recipient address of the message func (msg *MsgWhitelist) WhitelistCandidate() solana.PublicKey { return msg.whitelistCandidate } + +func (msg *MsgWhitelist) WhitelistEntry() solana.PublicKey { + return msg.whitelistEntry +} diff --git a/zetaclient/chains/solana/observer/outbound.go b/zetaclient/chains/solana/observer/outbound.go index 7ff968ea93..88a1337f7f 100644 --- a/zetaclient/chains/solana/observer/outbound.go +++ b/zetaclient/chains/solana/observer/outbound.go @@ -155,8 +155,11 @@ func (ob *Observer) VoteOutboundIfConfirmed(ctx context.Context, cctx *crosschai return false, errors.Wrapf(err, "ParseGatewayInstruction error for sig %s", txSig) } - // the amount and status of the outbound - outboundAmount := new(big.Int).SetUint64(inst.TokenAmount()) + outboundAmount := new(big.Int).SetUint64(0) + if inst != nil { + // the amount and status of the outbound + outboundAmount = new(big.Int).SetUint64(inst.TokenAmount()) + } // status was already verified as successful in CheckFinalizedTx outboundStatus := chains.ReceiveStatus_success @@ -295,6 +298,10 @@ func (ob *Observer) CheckFinalizedTx( logger.Error().Err(err).Msg("ParseGatewayInstruction error") return nil, false } + if inst == nil { + return txResult, true + } + txNonce := inst.GatewayNonce() // recover ECDSA signer from instruction @@ -352,6 +359,10 @@ func ParseGatewayInstruction( switch coinType { case coin.CoinType_Gas: return contracts.ParseInstructionWithdraw(instruction) + // for these currently parsing is not needed since instructions are empty, and these instructions dont implement OutboundInstruction interface + // can be revisited as more are added + case coin.CoinType_Cmd: + return nil, nil default: return nil, fmt.Errorf("unsupported outbound coin type %s", coinType) } diff --git a/zetaclient/chains/solana/signer/signer.go b/zetaclient/chains/solana/signer/signer.go index a77f456c32..c3acc5e4e5 100644 --- a/zetaclient/chains/solana/signer/signer.go +++ b/zetaclient/chains/solana/signer/signer.go @@ -2,7 +2,6 @@ package signer import ( "context" - "fmt" "strings" "cosmossdk.io/errors" @@ -127,18 +126,31 @@ func (signer *Signer) TryProcessOutbound( if len(relayedMsg) != 2 { return } - fmt.Println("debug ", coinType, relayedMsg[1]) if coinType == coin.CoinType_Cmd { pk, err := solana.PublicKeyFromBase58(relayedMsg[1]) if err != nil { - fmt.Println("err decoding ", err.Error()) + signer.Logger(). + Std.Error(). + Err(err). + Msgf("TryProcessOutbound: error decoding spl from relayed msg") + return + } + + seed := [][]byte{[]byte("whitelist"), pk.Bytes()} + whitelistEntryPDA, _, err := solana.FindProgramAddress(seed, signer.gatewayID) + if err != nil { + signer.Logger(). + Std.Error(). + Err(err). + Msgf("TryProcessOutbound: error calculating whitelistEntry pda") + return } // sign the withdraw transaction by relayer key - tx, err := signer.SignWhitelistTx(ctx, contracts.NewMsgWhitelist(pk)) + tx, err := signer.SignWhitelistTx(ctx, contracts.NewMsgWhitelist(pk, whitelistEntryPDA)) if err != nil { - logger.Error().Err(err).Msgf("TryProcessOutbound: SignGasWithdraw error for chain %d nonce %d", chainID, nonce) + logger.Error().Err(err).Msgf("TryProcessOutbound: SignWhitelistTx error for chain %d nonce %d", chainID, nonce) return } diff --git a/zetaclient/chains/solana/signer/whitelist.go b/zetaclient/chains/solana/signer/whitelist.go index 09a4ad8300..c3798ca92f 100644 --- a/zetaclient/chains/solana/signer/whitelist.go +++ b/zetaclient/chains/solana/signer/whitelist.go @@ -24,7 +24,7 @@ func (signer *Signer) SignWhitelistTx(ctx context.Context, msg *contracts.MsgWhi // attach required accounts to the instruction privkey := signer.relayerKey - attachWhitelistAccounts(&inst, privkey.PublicKey(), signer.pda, msg.WhitelistCandidate(), signer.gatewayID) + attachWhitelistAccounts(&inst, privkey.PublicKey(), signer.pda, msg.WhitelistCandidate(), msg.WhitelistEntry(), signer.gatewayID) // get a recent blockhash recent, err := signer.client.GetLatestBlockhash(ctx, rpc.CommitmentFinalized) @@ -67,10 +67,12 @@ func attachWhitelistAccounts( signer solana.PublicKey, pda solana.PublicKey, whitelistCandidate solana.PublicKey, + whitelistEntry solana.PublicKey, gatewayID solana.PublicKey, ) { // attach required accounts to the instruction var accountSlice []*solana.AccountMeta + accountSlice = append(accountSlice, solana.Meta(whitelistEntry).WRITE()) accountSlice = append(accountSlice, solana.Meta(whitelistCandidate)) accountSlice = append(accountSlice, solana.Meta(pda).WRITE()) accountSlice = append(accountSlice, solana.Meta(signer).WRITE().SIGNER()) From 4897a2ccfe832ad9eb8a41bcec0ec21f1985c343 Mon Sep 17 00:00:00 2001 From: skosito Date: Wed, 9 Oct 2024 23:38:28 +0200 Subject: [PATCH 3/5] test fixes --- cmd/zetae2e/local/local.go | 1 + pkg/contracts/solana/gateway_message.go | 2 ++ zetaclient/chains/solana/signer/signer.go | 9 +++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 4a7fbef39c..eda38c3380 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -395,6 +395,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestSolanaDepositAndCallRefundName, e2etests.TestSolanaDepositRestrictedName, e2etests.TestSolanaWithdrawRestrictedName, + e2etests.TestSolanaWhitelistSPLName, } eg.Go(solanaTestRoutine(conf, deployerRunner, verbose, solanaTests...)) } diff --git a/pkg/contracts/solana/gateway_message.go b/pkg/contracts/solana/gateway_message.go index f75665a5f5..5c8b4ac49b 100644 --- a/pkg/contracts/solana/gateway_message.go +++ b/pkg/contracts/solana/gateway_message.go @@ -61,6 +61,8 @@ func (msg *MsgWithdraw) Hash() [32]byte { var message []byte buff := make([]byte, 8) + message = append(message, []byte("withdraw")...) + binary.BigEndian.PutUint64(buff, msg.chainID) message = append(message, buff...) diff --git a/zetaclient/chains/solana/signer/signer.go b/zetaclient/chains/solana/signer/signer.go index c3acc5e4e5..4711ef0cff 100644 --- a/zetaclient/chains/solana/signer/signer.go +++ b/zetaclient/chains/solana/signer/signer.go @@ -122,12 +122,13 @@ func (signer *Signer) TryProcessOutbound( chainID := signer.Chain().ChainId nonce := params.TssNonce coinType := cctx.InboundParams.CoinType - relayedMsg := strings.Split(cctx.RelayedMessage, ":") - if len(relayedMsg) != 2 { - return - } if coinType == coin.CoinType_Cmd { + relayedMsg := strings.Split(cctx.RelayedMessage, ":") + if len(relayedMsg) != 2 { + return + } + pk, err := solana.PublicKeyFromBase58(relayedMsg[1]) if err != nil { signer.Logger(). From b95097ae93e9472040d1ea64422a9d9fcb8b8986 Mon Sep 17 00:00:00 2001 From: skosito Date: Wed, 9 Oct 2024 23:40:36 +0200 Subject: [PATCH 4/5] fmt --- e2e/e2etests/test_solana_whitelist_spl.go | 1 + e2e/runner/solana.go | 6 +++++- zetaclient/chains/solana/signer/signer.go | 4 +++- zetaclient/chains/solana/signer/whitelist.go | 10 +++++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/e2e/e2etests/test_solana_whitelist_spl.go b/e2e/e2etests/test_solana_whitelist_spl.go index 6af27f614c..6c71c0d214 100644 --- a/e2e/e2etests/test_solana_whitelist_spl.go +++ b/e2e/e2etests/test_solana_whitelist_spl.go @@ -3,6 +3,7 @@ package e2etests import ( "github.com/gagliardetto/solana-go" "github.com/stretchr/testify/require" + "github.com/zeta-chain/node/e2e/runner" "github.com/zeta-chain/node/e2e/txserver" "github.com/zeta-chain/node/e2e/utils" diff --git a/e2e/runner/solana.go b/e2e/runner/solana.go index e4ed5162df..cf9875dd9c 100644 --- a/e2e/runner/solana.go +++ b/e2e/runner/solana.go @@ -117,7 +117,11 @@ func (r *E2ERunner) DeploySPL(privateKey *solana.PrivateKey) *solana.Wallet { tokenAccount.PublicKey(), ).Build() - signedTx := r.CreateSignedTransaction([]solana.Instruction{createAccountInstruction, initializeMintInstruction}, *privateKey, []solana.PrivateKey{tokenAccount.PrivateKey}) + signedTx := r.CreateSignedTransaction( + []solana.Instruction{createAccountInstruction, initializeMintInstruction}, + *privateKey, + []solana.PrivateKey{tokenAccount.PrivateKey}, + ) // broadcast the transaction and wait for finalization _, out := r.BroadcastTxSync(signedTx) diff --git a/zetaclient/chains/solana/signer/signer.go b/zetaclient/chains/solana/signer/signer.go index 4711ef0cff..95e4819774 100644 --- a/zetaclient/chains/solana/signer/signer.go +++ b/zetaclient/chains/solana/signer/signer.go @@ -151,7 +151,9 @@ func (signer *Signer) TryProcessOutbound( // sign the withdraw transaction by relayer key tx, err := signer.SignWhitelistTx(ctx, contracts.NewMsgWhitelist(pk, whitelistEntryPDA)) if err != nil { - logger.Error().Err(err).Msgf("TryProcessOutbound: SignWhitelistTx error for chain %d nonce %d", chainID, nonce) + logger.Error(). + Err(err). + Msgf("TryProcessOutbound: SignWhitelistTx error for chain %d nonce %d", chainID, nonce) return } diff --git a/zetaclient/chains/solana/signer/whitelist.go b/zetaclient/chains/solana/signer/whitelist.go index c3798ca92f..858308aeb3 100644 --- a/zetaclient/chains/solana/signer/whitelist.go +++ b/zetaclient/chains/solana/signer/whitelist.go @@ -7,6 +7,7 @@ import ( "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" "github.com/near/borsh-go" + contracts "github.com/zeta-chain/node/pkg/contracts/solana" ) @@ -24,7 +25,14 @@ func (signer *Signer) SignWhitelistTx(ctx context.Context, msg *contracts.MsgWhi // attach required accounts to the instruction privkey := signer.relayerKey - attachWhitelistAccounts(&inst, privkey.PublicKey(), signer.pda, msg.WhitelistCandidate(), msg.WhitelistEntry(), signer.gatewayID) + attachWhitelistAccounts( + &inst, + privkey.PublicKey(), + signer.pda, + msg.WhitelistCandidate(), + msg.WhitelistEntry(), + signer.gatewayID, + ) // get a recent blockhash recent, err := signer.client.GetLatestBlockhash(ctx, rpc.CommitmentFinalized) From 41ae9b18744fea485fb09db746af59a73a1a0049 Mon Sep 17 00:00:00 2001 From: skosito Date: Mon, 14 Oct 2024 10:11:21 +0200 Subject: [PATCH 5/5] small refactoring --- zetaclient/chains/solana/signer/signer.go | 98 +++++++++-------------- 1 file changed, 39 insertions(+), 59 deletions(-) diff --git a/zetaclient/chains/solana/signer/signer.go b/zetaclient/chains/solana/signer/signer.go index 95e4819774..9c68443a6f 100644 --- a/zetaclient/chains/solana/signer/signer.go +++ b/zetaclient/chains/solana/signer/signer.go @@ -123,7 +123,10 @@ func (signer *Signer) TryProcessOutbound( nonce := params.TssNonce coinType := cctx.InboundParams.CoinType - if coinType == coin.CoinType_Cmd { + var tx *solana.Transaction + + switch coinType { + case coin.CoinType_Cmd: relayedMsg := strings.Split(cctx.RelayedMessage, ":") if len(relayedMsg) != 2 { return @@ -149,7 +152,7 @@ func (signer *Signer) TryProcessOutbound( } // sign the withdraw transaction by relayer key - tx, err := signer.SignWhitelistTx(ctx, contracts.NewMsgWhitelist(pk, whitelistEntryPDA)) + tx, err = signer.SignWhitelistTx(ctx, contracts.NewMsgWhitelist(pk, whitelistEntryPDA)) if err != nil { logger.Error(). Err(err). @@ -157,70 +160,47 @@ func (signer *Signer) TryProcessOutbound( return } - // broadcast the signed tx to the Solana network with preflight check - txSig, err := signer.client.SendTransactionWithOpts( - ctx, - tx, - // Commitment "finalized" is too conservative for preflight check and - // it results in repeated broadcast attempts that only 1 will succeed. - // Commitment "processed" will simulate tx against more recent state - // thus fails faster once a tx is already broadcasted and processed by the cluster. - // This reduces the number of "failed" txs due to repeated broadcast attempts. - rpc.TransactionOpts{PreflightCommitment: rpc.CommitmentProcessed}, - ) + case coin.CoinType_Gas: + // compliance check + cancelTx := compliance.IsCctxRestricted(cctx) + if cancelTx { + compliance.PrintComplianceLog( + logger, + signer.Logger().Compliance, + true, + chainID, + cctx.Index, + cctx.InboundParams.Sender, + params.Receiver, + "SOL", + ) + } + + // sign gateway withdraw message by TSS + msg, err := signer.SignMsgWithdraw(ctx, params, height, cancelTx) if err != nil { - signer.Logger(). - Std.Warn(). - Err(err). - Msgf("TryProcessOutbound: broadcast error for chain %d nonce %d", chainID, nonce) + logger.Error().Err(err).Msgf("TryProcessOutbound: SignMsgWithdraw error for chain %d nonce %d", chainID, nonce) return } - // report the outbound to the outbound tracker - signer.reportToOutboundTracker(ctx, zetacoreClient, chainID, nonce, txSig, logger) - return - } - - if coinType != coin.CoinType_Gas { - logger.Error(). - Msgf("TryProcessOutbound: can only send SOL to the Solana network for chain %d nonce %d", chainID, nonce) - return - } - - // compliance check - cancelTx := compliance.IsCctxRestricted(cctx) - if cancelTx { - compliance.PrintComplianceLog( - logger, - signer.Logger().Compliance, - true, - chainID, - cctx.Index, - cctx.InboundParams.Sender, - params.Receiver, - "SOL", - ) - } - - // sign gateway withdraw message by TSS - msg, err := signer.SignMsgWithdraw(ctx, params, height, cancelTx) - if err != nil { - logger.Error().Err(err).Msgf("TryProcessOutbound: SignMsgWithdraw error for chain %d nonce %d", chainID, nonce) - return - } + // skip relaying the transaction if this signer hasn't set the relayer key + if !signer.HasRelayerKey() { + return + } - // skip relaying the transaction if this signer hasn't set the relayer key - if !signer.HasRelayerKey() { - return - } + // set relayer balance metrics + signer.SetRelayerBalanceMetrics(ctx) - // set relayer balance metrics - signer.SetRelayerBalanceMetrics(ctx) + // sign the withdraw transaction by relayer key + tx, err = signer.SignWithdrawTx(ctx, *msg) + if err != nil { + logger.Error().Err(err).Msgf("TryProcessOutbound: SignGasWithdraw error for chain %d nonce %d", chainID, nonce) + return + } - // sign the withdraw transaction by relayer key - tx, err := signer.SignWithdrawTx(ctx, *msg) - if err != nil { - logger.Error().Err(err).Msgf("TryProcessOutbound: SignGasWithdraw error for chain %d nonce %d", chainID, nonce) + default: + logger.Error(). + Msgf("TryProcessOutbound: can only send SOL to the Solana network for chain %d nonce %d", chainID, nonce) return }