From e07fe68b76891dc83314e415b78980725fb2e336 Mon Sep 17 00:00:00 2001 From: Jon C Date: Fri, 1 Nov 2024 17:38:32 +0100 Subject: [PATCH] transfer-hook-interface: Remove solana-program dependency (#7442) * transfer-hook-interface: Remove solana-program dependency #### Problem The transfer-hook-interface pulls in solana-program, but it doesn't need to. #### Summary of changes Use the component crates. The only breaking change is the re-exports. It still uses a dev-dependency on solana-program since the system program id isn't available yet outside of solana-program. * Add missing solana-pubkey feature * Add all test programs * Run cargo fmt * Fixup imports --- Cargo.lock | 62 +++++ Cargo.toml | 5 + token/program-2022-test/README.md | 26 ++ .../tests/fixtures/spl_instruction_padding.so | Bin 0 -> 24464 bytes .../fixtures/spl_transfer_hook_example.so | Bin 0 -> 111920 bytes .../spl_transfer_hook_example_downgrade.so | Bin 0 -> 19320 bytes .../spl_transfer_hook_example_fail.so | Bin 0 -> 18768 bytes .../spl_transfer_hook_example_success.so | Bin 0 -> 17696 bytes .../spl_transfer_hook_example_swap.so | Bin 0 -> 69920 bytes ...spl_transfer_hook_example_swap_with_fee.so | Bin 0 -> 72712 bytes .../program-2022-test/tests/transfer_hook.rs | 232 ++---------------- .../downgrade/Cargo.toml | 21 ++ .../downgrade/src/lib.rs | 42 ++++ .../fail/Cargo.toml | 21 ++ .../fail/src/lib.rs | 16 ++ .../success/Cargo.toml | 21 ++ .../success/src/lib.rs | 14 ++ .../swap-with-fee/Cargo.toml | 22 ++ .../swap-with-fee/src/lib.rs | 59 +++++ .../swap/Cargo.toml | 22 ++ .../swap/src/lib.rs | 57 +++++ token/transfer-hook/interface/Cargo.toml | 14 +- token/transfer-hook/interface/src/error.rs | 49 +++- .../interface/src/instruction.rs | 18 +- token/transfer-hook/interface/src/lib.rs | 7 +- token/transfer-hook/interface/src/offchain.rs | 8 +- token/transfer-hook/interface/src/onchain.rs | 12 +- 27 files changed, 484 insertions(+), 244 deletions(-) create mode 100644 token/program-2022-test/README.md create mode 100755 token/program-2022-test/tests/fixtures/spl_instruction_padding.so create mode 100755 token/program-2022-test/tests/fixtures/spl_transfer_hook_example.so create mode 100755 token/program-2022-test/tests/fixtures/spl_transfer_hook_example_downgrade.so create mode 100755 token/program-2022-test/tests/fixtures/spl_transfer_hook_example_fail.so create mode 100755 token/program-2022-test/tests/fixtures/spl_transfer_hook_example_success.so create mode 100755 token/program-2022-test/tests/fixtures/spl_transfer_hook_example_swap.so create mode 100755 token/program-2022-test/tests/fixtures/spl_transfer_hook_example_swap_with_fee.so create mode 100644 token/program-2022-test/transfer-hook-test-programs/downgrade/Cargo.toml create mode 100644 token/program-2022-test/transfer-hook-test-programs/downgrade/src/lib.rs create mode 100644 token/program-2022-test/transfer-hook-test-programs/fail/Cargo.toml create mode 100644 token/program-2022-test/transfer-hook-test-programs/fail/src/lib.rs create mode 100644 token/program-2022-test/transfer-hook-test-programs/success/Cargo.toml create mode 100644 token/program-2022-test/transfer-hook-test-programs/success/src/lib.rs create mode 100644 token/program-2022-test/transfer-hook-test-programs/swap-with-fee/Cargo.toml create mode 100644 token/program-2022-test/transfer-hook-test-programs/swap-with-fee/src/lib.rs create mode 100644 token/program-2022-test/transfer-hook-test-programs/swap/Cargo.toml create mode 100644 token/program-2022-test/transfer-hook-test-programs/swap/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 515f2a1d419..11025d53a99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8967,6 +8967,58 @@ dependencies = [ "spl-type-length-value 0.7.0", ] +[[package]] +name = "spl-transfer-hook-example-downgrade" +version = "1.0.0" +dependencies = [ + "solana-account-info", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "spl-transfer-hook-example-fail" +version = "1.0.0" +dependencies = [ + "solana-account-info", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "spl-transfer-hook-example-success" +version = "1.0.0" +dependencies = [ + "solana-account-info", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "spl-transfer-hook-example-swap" +version = "1.0.0" +dependencies = [ + "solana-account-info", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", + "spl-token-2022 5.0.2", +] + +[[package]] +name = "spl-transfer-hook-example-swap-with-fee" +version = "1.0.0" +dependencies = [ + "solana-account-info", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", + "spl-token-2022 5.0.2", +] + [[package]] name = "spl-transfer-hook-interface" version = "0.7.0" @@ -8989,12 +9041,22 @@ version = "0.8.2" dependencies = [ "arrayref", "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", "solana-program", + "solana-program-error", + "solana-pubkey", "spl-discriminator 0.4.0", "spl-pod 0.5.0", "spl-program-error 0.6.0", "spl-tlv-account-resolution 0.9.0", "spl-type-length-value 0.7.0", + "thiserror", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index a2ca9427310..3aa974f74d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,6 +69,11 @@ members = [ "token/program", "token/program-2022", "token/program-2022-test", + "token/program-2022-test/transfer-hook-test-programs/downgrade", + "token/program-2022-test/transfer-hook-test-programs/fail", + "token/program-2022-test/transfer-hook-test-programs/success", + "token/program-2022-test/transfer-hook-test-programs/swap", + "token/program-2022-test/transfer-hook-test-programs/swap-with-fee", "token/transfer-hook/cli", "token/transfer-hook/example", "token/transfer-hook/interface", diff --git a/token/program-2022-test/README.md b/token/program-2022-test/README.md new file mode 100644 index 00000000000..11d5768709b --- /dev/null +++ b/token/program-2022-test/README.md @@ -0,0 +1,26 @@ +## SPL Token 2022 Program Tests + +All of the end-to-end tests for spl-token-2022 exist in this directory. + +### Requirements + +These tests require other built on-chain programs, including: + +* spl-instruction-padding +* spl-transfer-hook-example +* spl-transfer-hook-example-downgrade +* spl-transfer-hook-example-fail +* spl-transfer-hook-example-success +* spl-transfer-hook-example-swap +* spl-transfer-hook-example-swap-with-fee + +Built versions of these programs exist in `tests/fixtures`, and may be +regenerated from the following places in this repo: + +* instruction-padding/program +* token/transfer-hook/example +* token/program-2022-test/transfer-hook-test-programs/downgrade +* token/program-2022-test/transfer-hook-test-programs/fail +* token/program-2022-test/transfer-hook-test-programs/success +* token/program-2022-test/transfer-hook-test-programs/swap +* token/program-2022-test/transfer-hook-test-programs/swap-with-fee diff --git a/token/program-2022-test/tests/fixtures/spl_instruction_padding.so b/token/program-2022-test/tests/fixtures/spl_instruction_padding.so new file mode 100755 index 0000000000000000000000000000000000000000..16a50fee6e7efb4cfe0da100c7272600b03d1678 GIT binary patch literal 24464 zcmd6PYm8mTkzR9VE?;(h$srF#jhD+ilBgNY>Pqu|FzYoXS(Z#Y5cRkkS_@`)H5?5` zd<^Fyk?oU(hmx#E76C-dUK0v7;E834ub@-62pNK7+LQANC^Ll0tX3` z?8aQLy-a=eRh>C=NlMzy21rYsI$d2|U0q#O{WyK@S0DV+=bKin2%eh5PXluAuOw!N z73|t$4+3_C;m{&~*M!wdTM}HwSTw@-9%DU+VIA`zM-v}B&U_<$x0!f{#dn?59^6{fqZ*MPVnN`xM(R-PdvX_dfhl12soTwqe#B)SiwzKsN{ z^8)=ju|7a{l}T@YpBvD$6znf=sSn9qz3{M{zN zzq;WNst0XXpMqLKYVEC({;m;x+P0VddTKxWYxWMk{X__=Q*59V{SWd-Xowuo zQZMC=#K-##ZrrR7>CSV?H*OS$lG2^0EKh0EohO+$J5JkP*F5@-IMD z^x0#IPgeG7$!4pE4D=8`r|6*4Ebv+N@A}(8TwEld>IwEYyOsFt8wT$u>=3=(CXX4E zCu!?lg!y=ht${;z4f$MvQ%kC?G`=U8hdj&1Yu$D&fSr1RoM|g_7YrFsQ{NarH0^qE zc~^;C?ShYY{vq|cpB3XITZk7n_#WZfiwff+?Zo3ty7Ro^v(uCt@*+;S{lqh`vff#aKkWW}=|Cy`9oDO}UiNiD z_|vY2_)?ZJc00{%J^`N}iY+=G`5#C=v+*p(t#?HplwX!6;@j*`e8>A^dN^(U?P9!6 z+Zf*)`DAaIymJQk5rY3`q#d^-#HnIDjHln#{%&cNfs_;%O|SX5QJ$r7BfXDXQH~F+ zKOcy$la)3Ph+&8bqE}IZq*apd1{B>1`8D?skH>LF$wHjH%JDJ#TqXJkecH?NTC*S| z#oKA$OXX(orf-b9)@!$VO=h31RxdASz7&3R+D=gs0q2Bk}Ky*kXc z5%2bR(|HT=Yk{=dPoK9qod=%}w%$jYyq_|@=t;HC{#=keQXUU6VN1%4&nq0pFgB>@ z0C|@6vrfBglryc9zWRjmdysjTD=W-r>xD(Om*uX9wC$9Rv+LjE4%*rE1ZnZt*BkE7 zz8*>2=$A$NzXJQTbqn}ZD4H_!I9Q}VrSy!4Mf^Fz7vt7N$-|GoAVVG(8Q0uzftTWI z-Y?|;f#}rp*%14Zbs99iC#%;gBHl-BCoAYM@qQXkt%>EyD$W;~`DOM3`JkP@FYP9_ zkS&Eo3vzvKB45{ADR80S>xAq@lV^U3-|s3vPMoFi2`xxgkFQa=>3PbX zzTDU@9nI}9TVQ)R{mLbJl%%GgTz{62`&iHY8}SCi>-}~A_ITj_Ju1zEu2%YGWsp5Y zK9lYzLo^Z}C#*+-LHzlhZ-4vSpcc?nogBs)Wqqe}`ncC7-mg z|FO<~b_g->=}yL1kK^bEC_K&=?eTrlb9Pn=C9RVB9_Rmw;N#-^>PN{6v@Z5}+UBiA z`UmXfCsGtGpFXc-qG!tEdiM2S+GX?LZKSI;HQ1G{AJQ(igSet{Kl=gai!-cW9%ub% z@id;MpT)DUD_wdA?IoUOz4Q*sn4B9s^#S9p?etePU$*$3_R~MS9~a0bWF4&E zA>#vmBOb^&=Hr=mG5%Cr|Cth^9;&*XW1NwP{_at~_^#5WYptJWSwG#mTn}!KK8|iL z7dSjJ4}V(uWbF!qujex>_kQ{MZEi!C5_;U3+i;iV-&H-%ZRoW8Me21!Mf2(7)JysX z^_Wwy#WnZTiIdw+5RU={hjMO?gm%s$1Q|4SucPN?Z~iRi(jUG;t7_26u;E=C(fr7{8-}`ii?-E{+`zFDJ;f;%OY>uMSoA9I;rL8$FHLwZ!sTF zvpkx8##6M{QuvP2d;OW?)PFADaT#z)KHtt9hnA3kSL?y9E0Qnz#Si`h@t=G=exV$6 zkZVkea(`GyJtHswhjbmsF(o==#|0?~`hQqpx|VuO*O^{k+ok2>C&f4PD#`_V$n_;Da)0u30GA8vD9D%V&-97$M)Gx5Ji~GGc_)2}`C2pe==PUx zxA8q=dNg}ZM@=6-KRJIdUrYM*7Sog2Z&6P$?erGvC;e6h;)U{WDG1qXgxDW~1Ez8G zAAUO~52FIF!ftH8QLdBT&rRGemh6#=z0MvBcDVLK?65K3xm{i#_t@{HxJUhY+?#tG zy;vH*)Z^WYriVG|)#GQnK{_reeM5o7seSaT)1u9r<=cf=Qfl+Fug~M#q~CIKmzL-D zCSqv&H1Cj2YH>)Key04LZ=8n|BFBR)-}3m9KR{oluvQD=1MF8!2=@$dK8g>Ro)W@6 z16P&5`&0a!#e;-!&x3!W<(RL~U*F%>n*XcfGtmRm%=&hPwG~?w7VQ}8siGbHQ=y29 zY}eN(n5T;S_AR~W4f->vFmm}GAcwHKma@6gVmBVf^0mfZ0R7 zj-p?re!gexr_}brB^@oXmqis%<7#6+zavF?JGKtHc|U1z#ePBqAE%%H>L&d}{k;9W zpTDEyRti5>=y5u2qd&$)`b~ZgWBwQysgK-m&iFh?|A2oZg1NuOGgrv}Y=a*AX^+1C zEQLQ)x^(9P;r3&MZLhNaqvp?cP8uKebE5sE>w2AZ=KmO9)tjw9)3%dZo~-B;=_LLz z%*r~R`0P$ahYqph+vE}J*nc4jSOLw|*1dQXJz6`PDL?q29p8_8yU@drej)a`_7vL< zyR|;%KO}E=%cf1tpCMhoE`3SSvVS?petnJY#Rc=*SLl~BueB>-wvY5PFIV(oZk#at zJn?gHkS?8Ly|kHp(#MVOS+wcs|`*{wGJm_wux8D=J`T29QhK?3blaI%p?1Zul**GEe{Xb;v(r0Oh z>9g;voavkIQQk$4v#+~+y|r{+d!BSNMchJ8ndXBd4N}43_DjoGzr2D4Oxj*~9EqhwYwcSrj8$N#(@oNN+IL8wX zrC*4*QJ>NFrJJSOvYgbu2>5FC2{9l^+3gAfmY2{t_T#XZ)Xr_v9$*EJHh^y@-^RG= z^RCPPQS#JUZrncJ*I=Cf`rBte{{PX(a(Vt=>%-@{;(IL_&IKR;fAj!Gnd?RPg`YoH z2Vf0?mvQ-&zzG?*Pbw^{Crz~6q3?r}mcI$Iuvub*Covg0FRH6O74c$fQkU-mCt5xk zu+*4nsf4o94~M^@@G)(#SPvR2g;Dtn`cLS(Hfgz2SAt2)cAXE4^sul}c+}|E>WN~~ za(lp%F=-jn6T~7tW{6VwqS0^Am0i*@pzk+}bnvrMV8EYfX${!QBrSab^^0`ymr}S- z{-V615e0H0Vif71vQqd}kO|!{s~;vU!(qMTi*%5?6ox=1be-z&#d7Ga6#A^ZL;bZ_ zj&Usoo`)3in4(MJZmn0u_a%ki*lKPN7>iQ=M&BM(Epox zaVBY=QMqt#4gW8N9r9Q7BN^l^EtJA<=;MT}kJSI0@23AZKSlpL0ZFpJIGyzK`*txu)>}^=V%nN{9B5 zwElH6rx`DrJ2YOP9__E9<*3J%nr5XQ^)=Dl#`w{EyT%XHqkVFJf_lhXl6p_- zW70g#c+&ic#uL<|-ErfFdbCU>mwJy_y?(}*<}a#epdM=Eb}#kF!RtM2^;$LFfS!J0 zb}#hETatF}*T+Q01Mx2rJ3&vd9w?**UoVW?dcxx$HQoL{7)9;618~$Hj09s-p9e;7o$Jt z3v&7UV$dP^dmGx_X3g=Cb<6?my^zj|3UUIk6*}nLBNFj1Gyq9!6#&MSWeCzwJ zT%R)d&`4tU%X}R$YWP}-QOw`-eq24?RDaE;zq;vfyXnvFQ$a4soI9!R9(7v!1%dz?||jGUZt+;brs{U@3V{NNq_gx#qVdd8JX)jyLtR| zK0dClmy*p+@jljbd&}mThaJ7Sj4z~skCVUOA8>xo-{)m-_kz@+{D=;s2a~fX|Ln4M zc%GbY5&^X=XV; zoI8Lra+(k2hgm;Ak1#*aULwBc=kv3i-IJ#ET7Y#llItD*0?}PB)vr-f-D5eU-OzI* z#9_=s|E4&9iN3HC#d*V}!hC{rsH=rM`uho~o1ZhjK)%5LzVLNFce|Su+KP}IHHh(E zkbHFm?E!hD@$Em)<30?mx}jb1AI1kGSKT0tC6&S*%jic1{aL|anpzMz*Y+2jN61#? zfhVKI&n+!dD*CA_2!8Jh`Wb|N zOkaKgd%{T+g@-3Avo(OPM*X6J$c6X z`g@I9_;sa=C(Qq)K2q9sQT+@2){PQJJm3FZ5WKJ!x^qhB@2`vFtM8lbJ+|L(#X0y! zt;e_t{+*8%`P;gwi*dAA4;uG-W~g^=Sv_0#*nQ9J40&Q6JOw**dz~d7aEUF!EZQ9dbjrNDcR@mtD1#1q0;QnYwqT!+36J(+&cPhqciqV)DY5&AiH z-`i>tGoSv=@9t@5zoWgkLiwRRKll%*bN8;FjBja&_88L|bfmiuQu|J%A8^X`tKecSgA7X%N<5BNUl2KS3EiN2ucTO^L;esJAA z=J)AG!ffxdcFrpv?T89wU+^yd$iA;CjtkZ!{ywmXhh6)A0{z%k^oLw-^P@%TLAHef z_nB|B?!kM&;=1&YLDzNCC>-pywk5Re#T+cl6u=Y-nG@- zH^o85+hpZFE%*1HakB^@3H}cgo)oi3yp9%E{Qj1oPx*Q?+IL>@>x`ei?p%sj`@uHE z<5vEnW5I(~K^M1Fo-#(ATO-io!)1->T5AIXau1jW*)N?$JQqhyxi|Wa~pDDL0 zI>dH^_Fc-&`};X1EcO@j;og+@`#tn`4Nkj6?r{ZjK5KEw*8TZ7Jbklq7}ARML(yXWmtP<@Yu0 zK1;0y+FIJ*`MvCta#_OX-&fdr0PzYbzR0+eH2?4#M2IiYFA}-$2ojH2N$WA%kwXl&g;cqmY2dmSA1?Kb{<%rp&-6*#QBZ#U!u!$vOVPSUZS77-u?TAX!qUR{`{UI^ass0zK4X}{EGaG z@6g_s?CKBbM^c8AtP#hM&f?3 zTlPzbBz@d|U_AgmCiWf;dFaFUAueZi^Q+6+D}|RepFOF~1%FTD=TYvTm?tYja@1hb zBm*XEpZF56qF-AFI(;55PH1uPdv-og)tZEnB+fHppV$CM^7$)zJepN>eoxW)mV({q zw)@vn`~@k)WFzU3CkT@k&Tsj-s`;P4FG@{iTClESui@2dr}}g>H7vJTGnzL3-zEm?`QRX8EE7S zeB^P>_GWS+d&)Qs%Qy7_~ ze82S(`fcpjl76eo2kS>zvj0AS%Xd`NqWzVA0s6d>zPWt;QQzFHeBvgvuUjjchgzX0 z|9&`*6W{pW0`iDTga4ii#s%%wRxt4S_jPff>CfWc&FtoSJ`7-a9I@{le4Vhx-n)I2 zeD2rzJYfCvdC28<`>(d57fW$?RGxv!w2{{08x^r`qZ@+TVEA;)(SuX-bqZ+eLclMf+j$m(9Li4!^H6Gf(=) zIPT|*{(f*m-v4K!7xyop50aJqU5Tar1iu$3?tTi~@i&WObeoX9!us$#kh~*<1v#*O z6I6KQ7|X}@6Z(7KXy5(#`Xa9{{n7dYwZ7?ZY@gMCi7u0`f`q?bX;>il(y@m%pOu+3k+rfHC69d27YkZsSCrz*d@l$E!=K`@$g4{UoxG1oC zqFw$c+;6Z9MY;P|(o{jQ z^!rb>o$||?)p;IIqoNnEm^6s<;iBKgy`U2L>89$Z>NkQ@yBDZ-Z*gXfW**8FDUgJ? zfbqxvM&pmz6;fiqA5{uG*F?KT`|*S%DR3s;P8^?@cGYpA5DED~WA^p(&E+r3J_YxM*6YyqvNa*%Sk$<<@A<991 z>k*@WhY<1mk3@mxhnSy~dKfnx`#e=64uAc<=+w)^9hkgbA1385=tt!r-uUA__p*AD zN1EEJARJh=O&<_{@qTz)>BrZuUH;P&@*PsLO+xLsz>?jvbv=xVp0r;AwO`hM)X{!H z2uU~>Re9u($|JaC@~l%bJqN+}KE?M3s)zenK1C1?fSIJs;uFSet>mi-&u6_o+}l{z zj*TDs^`Y&Ujt>}r|85ucVAuXTQ~3QqmG40nNAFQ|%j2B2bF+T3> z#!QXnb59V0ANU;FzEN5`I@7#IHa$}`imhwAh5(zVL`Y<+6JGIi+4!HGi?hv(VQ z?8N+Yvxg`4RqBT;6OiV5cF!D|XHTXM@0&R0B0W9*+~Iw5+bi??C!mzd)Ldozk^14O z@dIEsUs+puT4YBltD(Ho-QC^O-P_&Q-QPXXJ=i_eJ={Ig)7{h4)7#V6)88}DGuSiK zGu$)M+uhsK+uPgM+uu9TJJ>taJKQ_c*WK6C*W1_E*WWkLH`q7SH{3VU-`(HS-`n5U z-`_vbKiEIiKioeu&^^#I&^ypK&_6IRFgP$YFg!3a*ge=Y*gM!a*grThI5;>oI6OEq z)IHQQ)H~ES)IT&ZG&nRgG(0pi+&$bg+&kPi+&?@pJUBcwJUl!yA|j4R^CQA~M5>Jl zYH2h#i4Dp$nkW2bE8m*QZ)OSBpSKF#-A2_eaH~D<6+FEugx?cGv5*q>ckT+U`odT`xc-A#HQuP-uN{MN)U9}hr(t8Zo>VQ%{1 z*um+^u~2_{dY0L#!_QA2m>8Rznv~!%HY*jCN+Q|#kvK-VE}Pt|nGM}GfS$*1t8WvT}^b@%g=!F_Kr2=Uv0>rGu!t1 zR~z!X&EUNJ^@jWh4f)}Lvk>Y_i#i0 zQbT^nqs!_2H{u{}j_un-2y#E%K=lxEy=TAPlod2nY{JDm_f9vA){aY2!`(0zt zUumfCcaOciGP=C|?uPu1hWze^{N9HAk%s*14f!j!j)EJ&l{zgjA&<~@xlpcob9R)= z(k@&rlp`NH@rUz`=52xiJ!0IY$5G01bvlmyo2>-Wq~9K2_CIw+I^ zmc~O0>xZVs!##8Rg?hgJw9rhW3Yq?2{6*jK&*O9j8A%S`vwc0WOYy|>JLCaXe12*C zUG?ogu~-EkZ_DZ$81-#B$$vZC?c1&cIC<`0j=*U%WcT`~Y@8jQH$v~9w{OE4wn;gL z-oZ#MiYfoR+7`#k2*=P@H!UHLO0%miy3ukZ7$!;982pC`S2mw!;| Wdf(+SPpkLv@!=f92OHiT`+ookrdK8a literal 0 HcmV?d00001 diff --git a/token/program-2022-test/tests/fixtures/spl_transfer_hook_example.so b/token/program-2022-test/tests/fixtures/spl_transfer_hook_example.so new file mode 100755 index 0000000000000000000000000000000000000000..c3ad4a44acc942d1af07a7f893f303d187626616 GIT binary patch literal 111920 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 Rj}u?xIn`SO;kTUs{{`FP&Y%DQ literal 0 HcmV?d00001 diff --git a/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_downgrade.so b/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_downgrade.so new file mode 100755 index 0000000000000000000000000000000000000000..fdda8fb327b988206e18bb1f4e0e5b925b382d5d GIT binary patch literal 19320 zcmbtceT-GtaX;+tWq~Aqu*)^eCS>0l@NPDK`0e*w8rLkC;JB%RKVFt3qRV4Scsgx?NqEslVDw;nklz-|fRg2Q3aor@_ z`OU|D_uVx%Nl(n1J9FmDnKLtI&d0r*FYf;2$Lm(Ca8~Nw&mFLml6GiC=@Z7`+zwZA z4fMO(tzzDQs`AR8g>T(2?F_oLf`fe}{c9N(JPX&>3*BJ4T?18Je?aQ9umzP=3|hN7 zqM^S|ZI^|wq7fB?s|0m^ojiPr^u9?teO2jklRU(W0vl;SuPrStfv=gKTj<{!^ zzjAd6sK4|E!}y?7hK)PDz@q#=td_j%VmG z?h!m}9B?pYND9I<0b^9J{X_m$rgzhCE&V3pVdFMxQ%i@B!^V%YJ$(gSG_H_=^WzG4 z2;8(6qjK&F387{rORVBUv9RAEaR1)_75jv1ncwdaxPR|kOh>ThSNo;I%j@XyV2v8~(zrMn#^9My=zgcj^5BMXEpK`tE={L)`tMzIRod<{` zZr3hy%60$Adiy4Am(&X$xF3t(L_9abqgQ|M{5>hMKo9Fh|F}vDi7H5TB z!f$bNMNn4`RE~tZdsf`-M%zVB3*n-n#8aV390|G==o8ue7q=&NHT%X}h1>E3;?oL` zQ}ap-lF~`3;c;p%j_(v&ToKqdEHD`-`4u7y6%l-eaFi>MN5%YYa-M~7Dx(7ep-;^? zE33I8t7lXZ{=#F@PrO@j(<^>daOAx~(jh(|xY;3UJ;#1F`$w%e#P1}|az0u_t&$(X zhn}KV$&*p*b>>gU|4qba>$OBqUR2|bqgILMH2*o~m-&>YUnY8do|`$&gM?!oGvsT( z_$tfy=U-z8I#n;(xPX6$`ZYWr6ghFHLiJy`O7q>YSUX%Hf#Y|Q04n7=sSg_^Kg6@z z{waaz=MSmhP#3bmgzvo`OR;ljzC>uUieUtvQ^hjj0>4ylIWO9 z@jPms>mZ~^Fl>e|O#1PfPyKlrm%pg}*!p;0+C{dGs{YXy)pLC(KfvGIPhXz#oaXnaPv(b> z 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 literal 0 HcmV?d00001 diff --git a/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_fail.so b/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_fail.so new file mode 100755 index 0000000000000000000000000000000000000000..6e46894064dcf4d211ca07817de69180011bc561 GIT binary patch literal 18768 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 M+G7<88`SCk4+nw{g#Z8m literal 0 HcmV?d00001 diff --git a/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_success.so b/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_success.so new file mode 100755 index 0000000000000000000000000000000000000000..258c11432a29edd85528c2d37da9336fc00c0c48 GIT binary patch literal 17696 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 literal 0 HcmV?d00001 diff --git a/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_swap_with_fee.so b/token/program-2022-test/tests/fixtures/spl_transfer_hook_example_swap_with_fee.so new file mode 100755 index 0000000000000000000000000000000000000000..b8184a8aa7f6ee2214e06481c8eb154a5adadab0 GIT binary patch literal 72712 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 literal 0 HcmV?d00001 diff --git a/token/program-2022-test/tests/transfer_hook.rs b/token/program-2022-test/tests/transfer_hook.rs index 584b88e133d..32f929857a4 100644 --- a/token/program-2022-test/tests/transfer_hook.rs +++ b/token/program-2022-test/tests/transfer_hook.rs @@ -6,13 +6,10 @@ use { program_test::{ ConfidentialTokenAccountBalances, ConfidentialTokenAccountMeta, TestContext, TokenContext, }, - solana_program_test::{processor, tokio, ProgramTest}, + solana_program_test::{tokio, ProgramTest}, solana_sdk::{ account::Account, - account_info::{next_account_info, AccountInfo}, - entrypoint::ProgramResult, instruction::{AccountMeta, Instruction, InstructionError}, - program_error::ProgramError, program_option::COption, pubkey::Pubkey, signature::Signer, @@ -28,8 +25,7 @@ use { transfer_hook::{TransferHook, TransferHookAccount}, BaseStateWithExtensions, }, - instruction, offchain, onchain, - processor::Processor, + instruction, offchain, }, spl_token_client::token::{ExtensionInitializationParams, TokenError as TokenClientError}, spl_transfer_hook_interface::{ @@ -41,161 +37,6 @@ use { const TEST_MAXIMUM_FEE: u64 = 10_000_000; const TEST_FEE_BASIS_POINTS: u16 = 100; -/// Test program to fail transfer hook, conforms to transfer-hook-interface -pub fn process_instruction_fail( - _program_id: &Pubkey, - _accounts: &[AccountInfo], - _input: &[u8], -) -> ProgramResult { - Err(ProgramError::InvalidInstructionData) -} - -/// Test program to succeed transfer hook, conforms to transfer-hook-interface -pub fn process_instruction_success( - _program_id: &Pubkey, - _accounts: &[AccountInfo], - _input: &[u8], -) -> ProgramResult { - Ok(()) -} - -/// Test program to check signer / write downgrade for repeated accounts, -/// conforms to transfer-hook-interface -pub fn process_instruction_downgrade( - _program_id: &Pubkey, - accounts: &[AccountInfo], - _input: &[u8], -) -> ProgramResult { - let account_info_iter = &mut accounts.iter(); - - let source_account_info = next_account_info(account_info_iter)?; - let _mint_info = next_account_info(account_info_iter)?; - let _destination_account_info = next_account_info(account_info_iter)?; - let authority_info = next_account_info(account_info_iter)?; - let _extra_account_metas_info = next_account_info(account_info_iter)?; - - let source_account_info_again = next_account_info(account_info_iter)?; - let authority_info_again = next_account_info(account_info_iter)?; - - if source_account_info.key != source_account_info_again.key { - return Err(ProgramError::InvalidAccountData); - } - - if source_account_info_again.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - if authority_info.key != authority_info_again.key { - return Err(ProgramError::InvalidAccountData); - } - - if authority_info.is_signer { - return Err(ProgramError::InvalidAccountData); - } - Ok(()) -} - -/// Test program to transfer two types of tokens with transfer hooks at once -pub fn process_instruction_swap( - _program_id: &Pubkey, - accounts: &[AccountInfo], - _input: &[u8], -) -> ProgramResult { - let account_info_iter = &mut accounts.iter(); - - let source_a_account_info = next_account_info(account_info_iter)?; - let mint_a_info = next_account_info(account_info_iter)?; - let destination_a_account_info = next_account_info(account_info_iter)?; - let authority_a_info = next_account_info(account_info_iter)?; - let token_program_a_info = next_account_info(account_info_iter)?; - - let source_b_account_info = next_account_info(account_info_iter)?; - let mint_b_info = next_account_info(account_info_iter)?; - let destination_b_account_info = next_account_info(account_info_iter)?; - let authority_b_info = next_account_info(account_info_iter)?; - let token_program_b_info = next_account_info(account_info_iter)?; - - let remaining_accounts = account_info_iter.as_slice(); - - onchain::invoke_transfer_checked( - token_program_a_info.key, - source_a_account_info.clone(), - mint_a_info.clone(), - destination_a_account_info.clone(), - authority_a_info.clone(), - remaining_accounts, - 1, - 9, - &[], - )?; - - onchain::invoke_transfer_checked( - token_program_b_info.key, - source_b_account_info.clone(), - mint_b_info.clone(), - destination_b_account_info.clone(), - authority_b_info.clone(), - remaining_accounts, - 1, - 9, - &[], - )?; - - Ok(()) -} - -// Test program to transfer two types of tokens with transfer hooks at once with -// fees -pub fn process_instruction_swap_with_fee( - _program_id: &Pubkey, - accounts: &[AccountInfo], - _input: &[u8], -) -> ProgramResult { - let account_info_iter = &mut accounts.iter(); - - let source_a_account_info = next_account_info(account_info_iter)?; - let mint_a_info = next_account_info(account_info_iter)?; - let destination_a_account_info = next_account_info(account_info_iter)?; - let authority_a_info = next_account_info(account_info_iter)?; - let token_program_a_info = next_account_info(account_info_iter)?; - - let source_b_account_info = next_account_info(account_info_iter)?; - let mint_b_info = next_account_info(account_info_iter)?; - let destination_b_account_info = next_account_info(account_info_iter)?; - let authority_b_info = next_account_info(account_info_iter)?; - let token_program_b_info = next_account_info(account_info_iter)?; - - let remaining_accounts = account_info_iter.as_slice(); - - onchain::invoke_transfer_checked_with_fee( - token_program_a_info.key, - source_a_account_info.clone(), - mint_a_info.clone(), - destination_a_account_info.clone(), - authority_a_info.clone(), - remaining_accounts, - 1_000_000_000, - 9, - 10_000_000, - &[], - )?; - - onchain::invoke_transfer_checked_with_fee( - token_program_b_info.key, - source_b_account_info.clone(), - mint_b_info.clone(), - destination_b_account_info.clone(), - authority_b_info.clone(), - remaining_accounts, - 1_000_000_000, - 9, - 10_000_000, - &[], - )?; - - Ok(()) -} - async fn setup_accounts( token_context: &TokenContext, alice_account: Keypair, @@ -231,17 +72,8 @@ async fn setup_accounts( fn setup_program_test(program_id: &Pubkey) -> ProgramTest { let mut program_test = ProgramTest::default(); - program_test.prefer_bpf(false); - program_test.add_program( - "spl_token_2022", - spl_token_2022::id(), - processor!(Processor::process), - ); - program_test.add_program( - "my_transfer_hook", - *program_id, - processor!(spl_transfer_hook_example::processor::process), - ); + program_test.add_program("spl_token_2022", spl_token_2022::id(), None); + program_test.add_program("spl_transfer_hook_example", *program_id, None); program_test } @@ -413,12 +245,7 @@ async fn success_init() { #[tokio::test] async fn fail_init_all_none() { let mut program_test = ProgramTest::default(); - program_test.prefer_bpf(false); - program_test.add_program( - "spl_token_2022", - spl_token_2022::id(), - processor!(Processor::process), - ); + program_test.add_program("spl_token_2022", spl_token_2022::id(), None); let context = program_test.start_with_context().await; let context = Arc::new(tokio::sync::Mutex::new(context)); let mut context = TestContext { @@ -743,17 +570,8 @@ async fn fail_transfer_hook_program() { let program_id = Pubkey::new_unique(); let mint = Keypair::new(); let mut program_test = ProgramTest::default(); - program_test.prefer_bpf(false); - program_test.add_program( - "spl_token_2022", - spl_token_2022::id(), - processor!(Processor::process), - ); - program_test.add_program( - "my_transfer_hook", - program_id, - processor!(process_instruction_fail), - ); + program_test.add_program("spl_token_2022", spl_token_2022::id(), None); + program_test.add_program("spl_transfer_hook_example_fail", program_id, None); let validation_address = get_extra_account_metas_address(&mint.pubkey(), &program_id); program_test.add_account( validation_address, @@ -812,17 +630,8 @@ async fn success_downgrade_writable_and_signer_accounts() { let program_id = Pubkey::new_unique(); let mint = Keypair::new(); let mut program_test = ProgramTest::default(); - program_test.prefer_bpf(false); - program_test.add_program( - "spl_token_2022", - spl_token_2022::id(), - processor!(Processor::process), - ); - program_test.add_program( - "my_transfer_hook", - program_id, - processor!(process_instruction_downgrade), - ); + program_test.add_program("spl_token_2022", spl_token_2022::id(), None); + program_test.add_program("spl_transfer_hook_example_downgrade", program_id, None); let alice = Keypair::new(); let alice_account = Keypair::new(); let validation_address = get_extra_account_metas_address(&mint.pubkey(), &program_id); @@ -898,11 +707,7 @@ async fn success_transfers_using_onchain_helper() { let swap_program_id = Pubkey::new_unique(); let mut program_test = setup_program_test(&program_id); - program_test.add_program( - "my_swap", - swap_program_id, - processor!(process_instruction_swap), - ); + program_test.add_program("spl_transfer_hook_example_swap", swap_program_id, None); add_validation_account(&mut program_test, &mint_a, &program_id); add_validation_account(&mut program_test, &mint_b, &program_id); @@ -1027,9 +832,9 @@ async fn success_transfers_with_fee_using_onchain_helper() { let swap_program_id = Pubkey::new_unique(); let mut program_test = setup_program_test(&program_id); program_test.add_program( - "my_swap", + "spl_transfer_hook_example_swap_with_fee", swap_program_id, - processor!(process_instruction_swap_with_fee), + None, ); add_validation_account(&mut program_test, &mint_a, &program_id); add_validation_account(&mut program_test, &mint_b, &program_id); @@ -1263,17 +1068,8 @@ async fn success_without_validation_account() { let program_id = Pubkey::new_unique(); let mint = Keypair::new(); let mut program_test = ProgramTest::default(); - program_test.prefer_bpf(false); - program_test.add_program( - "spl_token_2022", - spl_token_2022::id(), - processor!(Processor::process), - ); - program_test.add_program( - "my_transfer_hook", - program_id, - processor!(process_instruction_success), - ); + program_test.add_program("spl_token_2022", spl_token_2022::id(), None); + program_test.add_program("spl_transfer_hook_example_success", program_id, None); let context = program_test.start_with_context().await; let context = Arc::new(tokio::sync::Mutex::new(context)); let mut context = TestContext { diff --git a/token/program-2022-test/transfer-hook-test-programs/downgrade/Cargo.toml b/token/program-2022-test/transfer-hook-test-programs/downgrade/Cargo.toml new file mode 100644 index 00000000000..8434af65498 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/downgrade/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "spl-transfer-hook-example-downgrade" +version = "1.0.0" +description = "Solana Program Library Transfer Hook Example: Downgrade" +authors = ["Solana Labs Maintainers "] +repository = "https://github.com/solana-labs/solana-program-library" +license = "Apache-2.0" +edition = "2021" +publish = false + +[dependencies] +solana-account-info = "2.1.0" +solana-program-entrypoint = "2.1.0" +solana-program-error = "2.1.0" +solana-pubkey = "2.1.0" + +[lib] +crate-type = ["cdylib", "lib"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/token/program-2022-test/transfer-hook-test-programs/downgrade/src/lib.rs b/token/program-2022-test/transfer-hook-test-programs/downgrade/src/lib.rs new file mode 100644 index 00000000000..9b2ab4e156a --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/downgrade/src/lib.rs @@ -0,0 +1,42 @@ +//! Program implementation + +use { + solana_account_info::{next_account_info, AccountInfo}, + solana_program_error::{ProgramError, ProgramResult}, + solana_pubkey::Pubkey, +}; + +solana_program_entrypoint::entrypoint!(process_instruction); +fn process_instruction( + _program_id: &Pubkey, + accounts: &[AccountInfo], + _instruction_data: &[u8], +) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + + let source_account_info = next_account_info(account_info_iter)?; + let _mint_info = next_account_info(account_info_iter)?; + let _destination_account_info = next_account_info(account_info_iter)?; + let authority_info = next_account_info(account_info_iter)?; + let _extra_account_metas_info = next_account_info(account_info_iter)?; + + let source_account_info_again = next_account_info(account_info_iter)?; + let authority_info_again = next_account_info(account_info_iter)?; + + if source_account_info.key != source_account_info_again.key { + return Err(ProgramError::InvalidAccountData); + } + + if source_account_info_again.is_writable { + return Err(ProgramError::InvalidAccountData); + } + + if authority_info.key != authority_info_again.key { + return Err(ProgramError::InvalidAccountData); + } + + if authority_info.is_signer { + return Err(ProgramError::InvalidAccountData); + } + Ok(()) +} diff --git a/token/program-2022-test/transfer-hook-test-programs/fail/Cargo.toml b/token/program-2022-test/transfer-hook-test-programs/fail/Cargo.toml new file mode 100644 index 00000000000..b8e6d4bfe68 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/fail/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "spl-transfer-hook-example-fail" +version = "1.0.0" +description = "Solana Program Library Transfer Hook Example: Fail" +authors = ["Solana Labs Maintainers "] +repository = "https://github.com/solana-labs/solana-program-library" +license = "Apache-2.0" +edition = "2021" +publish = false + +[dependencies] +solana-account-info = "2.1.0" +solana-program-entrypoint = "2.1.0" +solana-program-error = "2.1.0" +solana-pubkey = "2.1.0" + +[lib] +crate-type = ["cdylib", "lib"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/token/program-2022-test/transfer-hook-test-programs/fail/src/lib.rs b/token/program-2022-test/transfer-hook-test-programs/fail/src/lib.rs new file mode 100644 index 00000000000..e82ab842ae6 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/fail/src/lib.rs @@ -0,0 +1,16 @@ +//! Program implementation + +use { + solana_account_info::AccountInfo, + solana_program_error::{ProgramError, ProgramResult}, + solana_pubkey::Pubkey, +}; + +solana_program_entrypoint::entrypoint!(process_instruction); +fn process_instruction( + _program_id: &Pubkey, + _accounts: &[AccountInfo], + _instruction_data: &[u8], +) -> ProgramResult { + Err(ProgramError::InvalidInstructionData) +} diff --git a/token/program-2022-test/transfer-hook-test-programs/success/Cargo.toml b/token/program-2022-test/transfer-hook-test-programs/success/Cargo.toml new file mode 100644 index 00000000000..26c7a507aa5 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/success/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "spl-transfer-hook-example-success" +version = "1.0.0" +description = "Solana Program Library Transfer Hook Example: Success" +authors = ["Solana Labs Maintainers "] +repository = "https://github.com/solana-labs/solana-program-library" +license = "Apache-2.0" +edition = "2021" +publish = false + +[dependencies] +solana-account-info = "2.1.0" +solana-program-entrypoint = "2.1.0" +solana-program-error = "2.1.0" +solana-pubkey = "2.1.0" + +[lib] +crate-type = ["cdylib", "lib"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/token/program-2022-test/transfer-hook-test-programs/success/src/lib.rs b/token/program-2022-test/transfer-hook-test-programs/success/src/lib.rs new file mode 100644 index 00000000000..5baa0db1f18 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/success/src/lib.rs @@ -0,0 +1,14 @@ +//! Program implementation + +use { + solana_account_info::AccountInfo, solana_program_error::ProgramResult, solana_pubkey::Pubkey, +}; + +solana_program_entrypoint::entrypoint!(process_instruction); +fn process_instruction( + _program_id: &Pubkey, + _accounts: &[AccountInfo], + _instruction_data: &[u8], +) -> ProgramResult { + Ok(()) +} diff --git a/token/program-2022-test/transfer-hook-test-programs/swap-with-fee/Cargo.toml b/token/program-2022-test/transfer-hook-test-programs/swap-with-fee/Cargo.toml new file mode 100644 index 00000000000..6a263434801 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/swap-with-fee/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "spl-transfer-hook-example-swap-with-fee" +version = "1.0.0" +description = "Solana Program Library Transfer Hook Example: Swap with Fee" +authors = ["Solana Labs Maintainers "] +repository = "https://github.com/solana-labs/solana-program-library" +license = "Apache-2.0" +edition = "2021" +publish = false + +[dependencies] +solana-account-info = "2.1.0" +solana-program-entrypoint = "2.1.0" +solana-program-error = "2.1.0" +solana-pubkey = "2.1.0" +spl-token-2022 = { path = "../../../program-2022", features = ["no-entrypoint"] } + +[lib] +crate-type = ["cdylib", "lib"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/token/program-2022-test/transfer-hook-test-programs/swap-with-fee/src/lib.rs b/token/program-2022-test/transfer-hook-test-programs/swap-with-fee/src/lib.rs new file mode 100644 index 00000000000..5d21fb88440 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/swap-with-fee/src/lib.rs @@ -0,0 +1,59 @@ +//! Program implementation + +use { + solana_account_info::{next_account_info, AccountInfo}, + solana_program_error::ProgramResult, + solana_pubkey::Pubkey, + spl_token_2022::onchain, +}; + +solana_program_entrypoint::entrypoint!(process_instruction); +fn process_instruction( + _program_id: &Pubkey, + accounts: &[AccountInfo], + _instruction_data: &[u8], +) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + + let source_a_account_info = next_account_info(account_info_iter)?; + let mint_a_info = next_account_info(account_info_iter)?; + let destination_a_account_info = next_account_info(account_info_iter)?; + let authority_a_info = next_account_info(account_info_iter)?; + let token_program_a_info = next_account_info(account_info_iter)?; + + let source_b_account_info = next_account_info(account_info_iter)?; + let mint_b_info = next_account_info(account_info_iter)?; + let destination_b_account_info = next_account_info(account_info_iter)?; + let authority_b_info = next_account_info(account_info_iter)?; + let token_program_b_info = next_account_info(account_info_iter)?; + + let remaining_accounts = account_info_iter.as_slice(); + + onchain::invoke_transfer_checked_with_fee( + token_program_a_info.key, + source_a_account_info.clone(), + mint_a_info.clone(), + destination_a_account_info.clone(), + authority_a_info.clone(), + remaining_accounts, + 1_000_000_000, + 9, + 10_000_000, + &[], + )?; + + onchain::invoke_transfer_checked_with_fee( + token_program_b_info.key, + source_b_account_info.clone(), + mint_b_info.clone(), + destination_b_account_info.clone(), + authority_b_info.clone(), + remaining_accounts, + 1_000_000_000, + 9, + 10_000_000, + &[], + )?; + + Ok(()) +} diff --git a/token/program-2022-test/transfer-hook-test-programs/swap/Cargo.toml b/token/program-2022-test/transfer-hook-test-programs/swap/Cargo.toml new file mode 100644 index 00000000000..05d4d40d4a7 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/swap/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "spl-transfer-hook-example-swap" +version = "1.0.0" +description = "Solana Program Library Transfer Hook Example: Swap" +authors = ["Solana Labs Maintainers "] +repository = "https://github.com/solana-labs/solana-program-library" +license = "Apache-2.0" +edition = "2021" +publish = false + +[dependencies] +solana-account-info = "2.1.0" +solana-program-entrypoint = "2.1.0" +solana-program-error = "2.1.0" +solana-pubkey = "2.1.0" +spl-token-2022 = { path = "../../../program-2022", features = ["no-entrypoint"] } + +[lib] +crate-type = ["cdylib", "lib"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/token/program-2022-test/transfer-hook-test-programs/swap/src/lib.rs b/token/program-2022-test/transfer-hook-test-programs/swap/src/lib.rs new file mode 100644 index 00000000000..c299f6217b0 --- /dev/null +++ b/token/program-2022-test/transfer-hook-test-programs/swap/src/lib.rs @@ -0,0 +1,57 @@ +//! Program implementation + +use { + solana_account_info::{next_account_info, AccountInfo}, + solana_program_error::ProgramResult, + solana_pubkey::Pubkey, + spl_token_2022::onchain, +}; + +solana_program_entrypoint::entrypoint!(process_instruction); +fn process_instruction( + _program_id: &Pubkey, + accounts: &[AccountInfo], + _instruction_data: &[u8], +) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + + let source_a_account_info = next_account_info(account_info_iter)?; + let mint_a_info = next_account_info(account_info_iter)?; + let destination_a_account_info = next_account_info(account_info_iter)?; + let authority_a_info = next_account_info(account_info_iter)?; + let token_program_a_info = next_account_info(account_info_iter)?; + + let source_b_account_info = next_account_info(account_info_iter)?; + let mint_b_info = next_account_info(account_info_iter)?; + let destination_b_account_info = next_account_info(account_info_iter)?; + let authority_b_info = next_account_info(account_info_iter)?; + let token_program_b_info = next_account_info(account_info_iter)?; + + let remaining_accounts = account_info_iter.as_slice(); + + onchain::invoke_transfer_checked( + token_program_a_info.key, + source_a_account_info.clone(), + mint_a_info.clone(), + destination_a_account_info.clone(), + authority_a_info.clone(), + remaining_accounts, + 1, + 9, + &[], + )?; + + onchain::invoke_transfer_checked( + token_program_b_info.key, + source_b_account_info.clone(), + mint_b_info.clone(), + destination_b_account_info.clone(), + authority_b_info.clone(), + remaining_accounts, + 1, + 9, + &[], + )?; + + Ok(()) +} diff --git a/token/transfer-hook/interface/Cargo.toml b/token/transfer-hook/interface/Cargo.toml index 634ce42c2ed..fa40b4b9444 100644 --- a/token/transfer-hook/interface/Cargo.toml +++ b/token/transfer-hook/interface/Cargo.toml @@ -10,17 +10,27 @@ edition = "2021" [dependencies] arrayref = "0.3.9" bytemuck = { version = "1.19.0", features = ["derive"] } -solana-program = "2.1.0" -spl-discriminator = { version = "0.4.0", path = "../../../libraries/discriminator" } +num-derive = "0.4" +num-traits = "0.2" +solana-account-info = "2.1.0" +solana-cpi = "2.1.0" +solana-decode-error = "2.1.0" +solana-instruction = { version = "2.1.0", features = ["std"] } +solana-msg = "2.1.0" +solana-program-error = "2.1.0" +solana-pubkey = { version = "2.1.0", features = ["curve25519"] } +spl-discriminator = { version = "0.4.0" , path = "../../../libraries/discriminator" } spl-program-error = { version = "0.6.0", path = "../../../libraries/program-error" } spl-tlv-account-resolution = { version = "0.9.0", path = "../../../libraries/tlv-account-resolution" } spl-type-length-value = { version = "0.7.0", path = "../../../libraries/type-length-value" } spl-pod = { version = "0.5.0", path = "../../../libraries/pod" } +thiserror = "1.0" [lib] crate-type = ["cdylib", "lib"] [dev-dependencies] +solana-program = "2.1.0" tokio = { version = "1.41.0", features = ["full"] } [package.metadata.docs.rs] diff --git a/token/transfer-hook/interface/src/error.rs b/token/transfer-hook/interface/src/error.rs index aaf25e19627..de50ec827c7 100644 --- a/token/transfer-hook/interface/src/error.rs +++ b/token/transfer-hook/interface/src/error.rs @@ -1,13 +1,18 @@ //! Error types -use spl_program_error::*; +use { + solana_decode_error::DecodeError, + solana_msg::msg, + solana_program_error::{PrintProgramError, ProgramError}, +}; /// Errors that may be returned by the interface. -#[spl_program_error(hash_error_code_start = 2_110_272_652)] +#[repr(u32)] +#[derive(Clone, Debug, Eq, thiserror::Error, num_derive::FromPrimitive, PartialEq)] pub enum TransferHookError { /// Incorrect account provided #[error("Incorrect account provided")] - IncorrectAccount, + IncorrectAccount = 2_110_272_652, /// Mint has no mint authority #[error("Mint has no mint authority")] MintHasNoMintAuthority, @@ -18,3 +23,41 @@ pub enum TransferHookError { #[error("Program called outside of a token transfer")] ProgramCalledOutsideOfTransfer, } + +impl From for ProgramError { + fn from(e: TransferHookError) -> Self { + ProgramError::Custom(e as u32) + } +} + +impl DecodeError for TransferHookError { + fn type_of() -> &'static str { + "TransferHookError" + } +} + +impl PrintProgramError for TransferHookError { + fn print(&self) + where + E: 'static + + std::error::Error + + DecodeError + + PrintProgramError + + num_traits::FromPrimitive, + { + match self { + TransferHookError::IncorrectAccount => { + msg!("Incorrect account provided") + } + TransferHookError::MintHasNoMintAuthority => { + msg!("Mint has no mint authority") + } + TransferHookError::IncorrectMintAuthority => { + msg!("Incorrect mint authority has signed the instruction") + } + TransferHookError::ProgramCalledOutsideOfTransfer => { + msg!("Program called outside of a token transfer") + } + } + } +} diff --git a/token/transfer-hook/interface/src/instruction.rs b/token/transfer-hook/interface/src/instruction.rs index d6d71323450..52419b6fc5d 100644 --- a/token/transfer-hook/interface/src/instruction.rs +++ b/token/transfer-hook/interface/src/instruction.rs @@ -1,18 +1,17 @@ //! Instruction types use { - solana_program::{ - instruction::{AccountMeta, Instruction}, - program_error::ProgramError, - pubkey::Pubkey, - system_program, - }, + solana_instruction::{AccountMeta, Instruction}, + solana_program_error::ProgramError, + solana_pubkey::Pubkey, spl_discriminator::{ArrayDiscriminator, SplDiscriminate}, spl_pod::{bytemuck::pod_slice_to_bytes, slice::PodSlice}, spl_tlv_account_resolution::account::ExtraAccountMeta, std::convert::TryInto, }; +const SYSTEM_PROGRAM_ID: Pubkey = Pubkey::from_str_const("11111111111111111111111111111111"); + /// Instructions supported by the transfer hook interface. #[repr(C)] #[derive(Clone, Debug, PartialEq)] @@ -215,7 +214,7 @@ pub fn initialize_extra_account_meta_list( AccountMeta::new(*extra_account_metas_pubkey, false), AccountMeta::new_readonly(*mint_pubkey, false), AccountMeta::new_readonly(*authority_pubkey, true), - AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(SYSTEM_PROGRAM_ID, false), ]; Instruction { @@ -255,6 +254,11 @@ pub fn update_extra_account_meta_list( mod test { use {super::*, crate::NAMESPACE, solana_program::hash, spl_pod::bytemuck::pod_from_bytes}; + #[test] + fn system_program_id() { + assert_eq!(solana_program::system_program::id(), SYSTEM_PROGRAM_ID); + } + #[test] fn validate_packing() { let amount = 111_111_111; diff --git a/token/transfer-hook/interface/src/lib.rs b/token/transfer-hook/interface/src/lib.rs index d22b7f89f18..0e4f382ebc5 100644 --- a/token/transfer-hook/interface/src/lib.rs +++ b/token/transfer-hook/interface/src/lib.rs @@ -14,8 +14,11 @@ pub mod onchain; // Export current sdk types for downstream users building with a different sdk // version -pub use solana_program; -use solana_program::pubkey::Pubkey; +use solana_pubkey::Pubkey; +pub use { + solana_account_info, solana_cpi, solana_decode_error, solana_instruction, solana_msg, + solana_program_error, solana_pubkey, +}; /// Namespace for all programs implementing transfer-hook pub const NAMESPACE: &str = "spl-transfer-hook-interface"; diff --git a/token/transfer-hook/interface/src/offchain.rs b/token/transfer-hook/interface/src/offchain.rs index 50c8c57e4b7..46e078e38f8 100644 --- a/token/transfer-hook/interface/src/offchain.rs +++ b/token/transfer-hook/interface/src/offchain.rs @@ -7,11 +7,9 @@ use { get_extra_account_metas_address, instruction::{execute, ExecuteInstruction}, }, - solana_program::{ - instruction::{AccountMeta, Instruction}, - program_error::ProgramError, - pubkey::Pubkey, - }, + solana_instruction::{AccountMeta, Instruction}, + solana_program_error::ProgramError, + solana_pubkey::Pubkey, spl_tlv_account_resolution::state::ExtraAccountMetaList, std::future::Future, }; diff --git a/token/transfer-hook/interface/src/onchain.rs b/token/transfer-hook/interface/src/onchain.rs index 1e332579e80..7bd8eff3925 100644 --- a/token/transfer-hook/interface/src/onchain.rs +++ b/token/transfer-hook/interface/src/onchain.rs @@ -3,13 +3,11 @@ use { crate::{error::TransferHookError, get_extra_account_metas_address, instruction}, - solana_program::{ - account_info::AccountInfo, - entrypoint::ProgramResult, - instruction::{AccountMeta, Instruction}, - program::invoke, - pubkey::Pubkey, - }, + solana_account_info::AccountInfo, + solana_cpi::invoke, + solana_instruction::{AccountMeta, Instruction}, + solana_program_error::ProgramResult, + solana_pubkey::Pubkey, spl_tlv_account_resolution::state::ExtraAccountMetaList, }; /// Helper to CPI into a transfer-hook program on-chain, looking through the