From 239096fd97e373fb9f1e01ef14d1517cbf1982ee Mon Sep 17 00:00:00 2001 From: Chris Czub Date: Fri, 5 Jan 2024 15:21:42 -0500 Subject: [PATCH] governance: add actions to freeze/thaw ibc clients (#3403) Co-authored-by: erwanor --- Cargo.lock | 21 +- .../src/gen/proto_descriptor.bin.no_lfs | Bin 81667 -> 98731 bytes .../app/src/action_handler/actions/submit.rs | 27 + crates/core/component/governance/Cargo.toml | 3 +- .../governance/src/component/view.rs | 23 +- .../core/component/governance/src/proposal.rs | 46 + crates/core/component/ibc/src/component.rs | 2 + .../ibc/src/component/rpc/connection_query.rs | 1 - ...mbra.core.component.governance.v1alpha1.rs | 36 + ...ore.component.governance.v1alpha1.serde.rs | 220 ++++ .../proto/src/gen/proto_descriptor.bin.no_lfs | Bin 337861 -> 355874 bytes .../governance/v1alpha1/governance.pb.go | 1014 ++++++++++------- .../governance/v1alpha1/governance.proto | 12 + 13 files changed, 964 insertions(+), 441 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5469628668..501ee450dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,13 +596,13 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4353121d5644cdf2beb5726ab752e79a8db1ebb52031770ec47db31d245526" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ "async-channel 2.1.1", "async-executor", - "async-io 2.2.1", + "async-io 2.2.2", "async-lock 3.2.0", "blocking", "futures-lite 2.1.0", @@ -648,9 +648,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6d3b15875ba253d1110c740755e246537483f152fa334f91abd7fe84c88b3ff" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" dependencies = [ "async-lock 3.2.0", "cfg-if", @@ -719,7 +719,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" dependencies = [ - "async-io 2.2.1", + "async-io 2.2.2", "async-lock 2.8.0", "atomic-waker", "cfg-if", @@ -2463,9 +2463,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.10" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbb8258be8305fb0237d7b295f47bb24ff1b136a535f473baf40e70468515aa" +checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" dependencies = [ "indenter", "once_cell", @@ -5336,6 +5336,7 @@ dependencies = [ "decaf377 0.5.0", "decaf377-rdsa", "futures", + "ibc-types", "im", "metrics", "once_cell", @@ -9318,9 +9319,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.26" +version = "0.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff" +checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" dependencies = [ "memchr", ] diff --git a/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs b/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs index ad8745ec01f5af5a5d47cdbc6c4512e6b2345e35..75fa7cbc0028917609475d5cde1553d9b863058e 100644 GIT binary patch delta 31020 zcmd^|d7M?nvH0gK_ndprEX>?tbAWIelubaz4crohQBh>bfLn||yv$r+;xI#I5%Fho z#5^}5CVEg5%~PKy{G!n$PBdzMDn`+`d`w(kj4=q&CsEwRV2nQV`&M_KbMBz#CHeQ~ zC(&Eg-PP6A)z#J2)n~r-iF?bpyiD-dOWh#)=%F!}jVroWWrF&s_`~{WlQ-n2{fF2G z&mh!6kgM;jnQn9zMyVNs$ z8huwz8}X^WkJ1$ulzLl|%K2qM)tRO4_9gADx=%+jK3)0@r=D0=vY@xvTRJ2-Vcv;N zEpv{V(=@wfK*NT0R!~{SV}5Ahb@nY^Tud1<&!Q4VfE z%mdEn1Gjh8iqdf5A{VwOAm0#V8CI$L%u?I%3yCuuL;UVR%=blWncCCZ}6r%Bj-2GT-Y?b)`7R0xigP! zn!Bi_>B}d~X#r>Vzn;sw)?@weSHIyL{4Y*HG}AjZnvtJpzwbmB=l>X<7>sKxt>`W> zAEmZM9i^qk)>VtX*3;FwXi0miqis=ZSLc$B_SW8>;gvGpBkkc0)I=QC+kPsw+8)h*MG@6VnR^WR$AP*bWwMyt=QT-yjIva zB(tR0(Nhwoq^L!e(61@#MOwjABGaM8k3<~IrH(9niRdC5_8<_hW2!H9Bf)5$QkK$vQoIqztC*`46= zO$!#xq`(ng%Ufbl=FYBlcSkqR3!9pcs?Eq4%BwfcJK^|RkJUePckCjh(sD|zzkAOM znp#er!@#o`rhIv$%L2rii#*4GGqqmhYCAe?*ddF{&6$|#e{hsN z`Q7bQ8^bQOuXdtyhTlBE7LWZWNMMWm z!#zH-!jE%7knWfHZ^NZFzgXs;QfF&P?P@jCCjOmWcB-<#^G$;zXIx}iS6S{=mh~T2 zbw1m4^8C4TX3beRe7mpUIma9LPr&<@S9sNLsaBoGr1DFGT#3zfk=iR|a%!TYS0APf zPi>-DtmKhnRj;1vwKDI`n%lgfX}0P!mv@`zH_aRVC%+{t)TDa;aw{0tUD6w<*>D(b zS6h4MQne}9Oxy2sM;w-Vr?!~3YUoX-<&on*HT0SDW*atOYW~bw#{t2}kht#w?ek{^ zgZg@xOkaeFY;V(kiYud@HmRJMP0MM2nRLN zQQC;EYnPXLdWuU+ixNSI6H+s6@AAH->u_pW-^c4li3kd1A{d+>G`DHq(F>1RG{2?k zs5vJqNwf?y{lrc3=LD5{-|y;PUhGxwP0h4%yZ4%Q8um_A`@X7vEd=PFCj{jhv~ zZqv~-XPvU>$fgAg7d0JqRC9~gy&#{NId^XJNizCCIy_1dX#8qWJwSoQ+A1?GTrX&v zH%sjgW_zd#vQ44UX!ZrbSfAMh>I25B`c7OYrxE)SE2&t0vFORBV~A!0rJ>LZ0;9QX zTqg!YK2yu`;n-kwOOy837HLl5vU&ELc}JIRl91B+rrBf}DqV!|te|F~#^9?CJ7M8b z(-)mMbMBnk%2g~Q1b3oBnmbXT@TgOuvLG0=+uY|z2E)z9$L{nghLm&$XagjxgWT+< zxpR)6Bfh8IcuWwaQ!88Bu?yH_nZn~|E=*VoEAqKO&m|Pt<~}{)we}6U+5KZkK9j??5l9 zB_Wre84Oz9-r2q!gJwLl;d*s{zTZ@18W@_2L@_*T01drL{~nE^YG7zITxbQu(}54< z_8;=;j@j*OH^8s_XSUG(RU`Jc?BCeY4@S1yuUkiUDDeG}> z4RU@<^TOt7wcC9bbb<^OcK_Nx`T4q_Dy}+h-)Z}!OrohVYQIGb#qc!Gn|lf@lod=X zE3osUf?;us8T@l_S>gBAdb<}-Uo<(T`tP4EpHbHQy0u=ka@6V}m;cNO{Cs9y#REAj zxOq@uRpp&={ncN%#SbS`3=gt_mCZYoDrN_{z|L0cpBlM$#bkxF@{at}$jKG^DI|^L zr$$bxI9MU~$~*E?Bd1o3QOG^>j{MZfeJVyPp{LYa=vq=ZqqA#eXQ8AOx@T&@KTf8?%7@NjnX2HBz|ANI zjvOw3WIGOS-xX#m+)s=KvZ7b-IBN{7PGRI>JU_G-Lw}9uk~q zE5ek`wud#mZx!@mw$QVxv$uFwp|R8!s_05j@EbnVwR_JIyqZAa{+IxE2J6n5`iV2Cm%EYT5_0+ta2CP&&H`t0c~^z^M*(XmQ3>6*5WivH{`wbbEM zL=+Sj7hBI*S?q4>DYSMiUx8DzxV@vjcU2-HONpV@h{!@jv+IY3GWp04sL38?%4}*j z*>O!(RzEcOv88G<-N!OZH&_L;%zGGDvA3Y)v$$01EOeJTN=1gQ1!6|u-l}J;r%>!J z@&Co`z1_v`RUuQ`78H7xb@g?$6*{|=+z39DI@^$4SEm*Wf?HKs*^W9DJ60A~^@wnL z+n1N7bakU4R1_Vd&sBjQdv`ltM>24S;T&t%n87&=_1L;0!8g=sLiBu|-O#Y2FuzRY zVm(!KdrLCWOAGPb;C^>?^vT>LGd_U*K+iiIA&6CK6osz7-k$chlFYi0lLeqPHFRNa zo;}2XF3imvu2v+IlF2*Gc7rL(P_a3wn4w~GQjz63-)=M&Ju1$(_lO}X&L26(OtYVN zzMNF_so3=8q^3{JFDEszJ}pVjEHzt_idibQP;sBYhI{wKinF3i#_v;eVs=C@1509w zB{?a2bo`;yPcjw+6k|E5Qms#^0KJoND8$wPp;9O9(GW~hjVU@gI&8w^=_eopc=#3snPWl4w`;y(paQ;YSLI#`&9fV-Lp;OQ%4tqFRR7? zr$sdr7fe4bY3$JWv`V!S=t~sov^phcfu#Ok2(FuvrFUC$Lf+ zPccOve6%G*JSj7Fn~D%=8?7xo5JcMco@|Jq7$tjZXsGy5DJ4{VsFW(l#AQ$^HBO8n zsFWs8F;q~RCH7QPl!eHWgh&=5ODadlWe{0Xh>2t&vP6h9D`~JtEwlCZV%a&UEK8{5 zpt7toR-7DEmJQR}5;dW+Y)oVDK6VO`1$n14dV23&M|38w16p@h#+nn*y0c-D;V7VW z=ai|z_jPNw>0bK_4ePDQoia0=TxirLw{f!AE7>^WeIp18bCwiNH;B^ zj9mm$`;<1~SgipqwGvh`!rp|(N_3$&QP)a%?9GS64U?5H**jtsd##KRH)Ew;Xiz&> z`Mx6CjAB>qEZWpab^2ME^izc_R#xT>;VSxBSs!a#72T{HH9DBU0=M&-|Ls&fn3WZ+3T)8L+OxuY7Z3UfMJ zJNkOs&nz+Dg92Zd(l^CbDIz0?>U@fT;Q3bl@Du?D=UXF2COuH$0?Qpi4^3x`?mkHcksyeaCesL_x-m?vK=dMO?4%R{ z(TgnBubu;#SYx3STC5oe0>*QIX$8a%m{Mr1u^J}EAe7cviDFRq63gC46^6EreHAz+ zg@FY`!!#)@EMQ?$3_|LXlqo;&UTWE~)?i}=j45Gc0TZU!n*kff7)m~rF17M|?iCO` z7S*uwUS!!#XT-@JQ;<%U{2c2^FH>4NgK3sH_M%DWJruSk_cZRa3R4n2?Ayu04ACmSiSqX-y_ zj4cJQa(KLI@lt^I7$4V$+w~UPkn{@AkfDRs6={f--Pi=ED7+l^qqx?&XNoud|~2uR1p5H(gv8cL4~) z*Tst;kcQV;qxV-`0Mf;E)22eV>(Q?1gaHu+L zmCoW`tOuvGpf5=aZK1l~#s6H{&PLR!PajFG?qcWC*j6ZNunIXnR|kZ?y2e&NduTVWZ_XHhfKS6w3K;)s(OI5ilj%jCaq4tnz^67?dzVQ3po_ zPG6i0)LDmZvRL2?xs$bLe3aF;YO5=-qQhuqHP zLsdmFICxZwU<4bj!k7TTYN29_e#Dw-_^zeKu=@}sKK}Q|aYCm)9v)u`dy5<-i&Le| z}Uii-=PY@o6*e-v7SwOyB? zv)fSxyZ&T6QV>72+|dp9TH?U;cK5+#duN+m+n3CdPDE|A2}ee}8o4r;*^rWS3Y9KR z*31?=SDBJflu^yD(m>V5P*X>_CB^m*IUUPsl@svP0++l0G1Z!fkK;#Y)%h`Wd zDk(#;#;OxLtQJL3>bfI@xk59N>R#DSU}2!hKBHNey237YlnqIo2e?UwWOJkdQ8pqu zfZb6(B8(FVMzm*$E5p=d_I_@;gBpjx*YYkke?8o^>l>LsZNgFuYw~lex+a!PPRz|f z1WQ99ek$hF5f!`FvX5%`536vLoW5Dm-JQh_IsA6_98#FwykB8n^TNUj3!0`DPLdOU zDOMbO(^f7s#1wRK&@c3K^>w$(T8~ElWO#^sT{^4O$^n}*cYCLy+KN5s>{}rxe-;R& zdJBYEfXrz-?!H6f9b&R!5aGdL0%CmcwKzMNQpNwU#u!9w_gZ_63)E&xV|JcDy&vc+j#Rv7Cl|m5nOTwkh;TQq8B0Y;5h-*j<_1 z2Q7biFiWhS3jMj8Eq8Fk{)L$yK^9asDlV)KRjb4%$Ez{cPiY4s8V=H0BM1bu*^+Rs zp-hE`E!UV}D#(Tp!swYGXz{RBmk%z{YQoEcJKVe{^a5mGxWkuQ<2n6Efy^js{%vuR5?u5 z6ISI&qc&ntp0Gw~-;v6SdwfT&V-8C6gf(?`4B`MjVa=Eod_}wlR`Rc{=%?47cmRP= z`CUC+*ORcQfZ7wG5DER-8ZtcCAJ@apd(T)Ezp$fC2kf`+Ggfw_@)ii+=DlYv`+egr z07K(h%dZR;FcCVs>pmBaIq-yq&&Bhlu+V-ko-aYr?04~eDOe-)d?^Giekb#_(hvrI zA$shL>&){vfQxgc1B!2+xVO9kg$_ zwVXJIQg>@Pab&s8a)%_u36}_>Hbu~4n^iwJVTWn_V|fel+(D!*JX-uQX%R94X743z zN)*yY-n zxA&H!n&~r!6qjHO3%ex%M)Rkyt|@T*OTw{}qwh{1N=#MT$3m&IxVQuTKC`{37Rc$w zxkzrGPmk@FS=cfeL{@~4blP)p`kGZ&Pv}9Ny^ zyKhDjUwKs)YtQ}Q(_pS2jARZxzR8m#6cuO*m;uh6;_w8~;t)>NtbT+DK z@wQcKH1G@tRg-t$vD{(FeAUndgmw>P)HO7D#~M5|>10seeYd>DAXP|gS)(zXcx686WN!GR4 z&s~;ZMX*%nfiqd&{Yy0T(8=LnQr!d#mA_a+;*qG6+K1^#fT05-)@Bg2_)uCrA)b&> z2JzoCY50Y9g}X~%?`s!ltfRQN)FE-Mu1;RY=&Z$wbWp zw(s#hZ1XF~J8bXO_ZrK%uMmfBpe}2bRbJmB9an2DB?_D9I6g5%mZ8M2%;U6JIuHZd)+-9VThKyCK{F)`=b=5z=Mt#fU{TBfp-4}s0G z)s>!B+qT{$fFK1Jlagb}YMZ#QZYwjf+O8WGgBZ%yc7uf0gefNByp$;wTS_U3-*BFx zG+ru0>O8wH=1OetdBW7Svb7R4Anw8y@L}IO;)0ZhY-ktQm4i(8vY}mI*A9+B)n?f6 z;OE?=L4uL2wfk2eKHWNeZAwGD(zU5@#3x;Alk1=dC?4rr`wOFkZz>Yhz08hw9T6UJ zSxOM%Kmsu?hmgB%o#z5c>DW!v%!?{qed0g#P{UvdD;fZiR<+G|0U@O7UJ|LWKjyVN{ z{N|WbK*(>7IrW6oM{E;61cDM^Oi4I>#I78xrY)pc)!tJ(fq;;D#5Ms$Pgd}wHrE-V z%0Q3;j7iA~e$+OH5=x=;sLhRrsSKq@ZLTzaEPC%rNa!ise%5vx{@pILNC2nM6^)y_ zXLR(j{~bPM2P0JIk9s1Br|r*-3#(F?pjaO(6$05jZJVI2Lcqw=wuuWX1gt!5o4Bwb zsPK%f;=(%e96fkkeioRNsMxt@%881cp0Q0NSkZv!Ga~exWkGpjpq`J0&;8M1&!-X+ z`}DkR9B!&W<9U0O4*3B}6MO1DL5Cv1xVBt=eCOd?()MDTwxrW8wrNXj6+8*$0isp= zp;dm~`=ed4J-X%ieZxQ6S-nVok>yLVRsqompq@ZL$iEbm2Za1fu~q>>{-s!}e39A9 z@wNa2CBT@Hi0kFp_JkCx+Gbw>gw)INzTk^iy<(HCA&LS7DZrSNXw@rrr8dBnLg^KI zq*g&dD7|8nv9Tv(&gQ+>?25N+t6?Z1s-D*F_QgbhiqZ4)>ciLUtlX`+ZdPQlBbEUW z-2v+E0O5Q`ECWEg+Y!qEknVQGGRO)quiGY~3j`&=n3All*X_!JURe~Y+GBJ?7Z6gf z+eCCVQ^?>=+r-neN(O*2DUrdOwuz@x3Z*w~6Hf<((wjEn^nH;*F7Lf-SNshbG!Br# zj^@!{dDkYeE8XQp2Jgi(0D^Ns-5nq@crTU#Al-V+(D7e&trGrOYJ`B#U# zQVKHvyHW}=^j$VL)iT4hfWj`>do(W${R5lpd0i;e4;b?z;lK}4O48d0k_TlfL+JyX zm?xCJ3}wI%ZF?_MD#u;Gn3Sx(5A8~QGNmr0KD77H^8={bj@>h8Qlp~j$I%mCKKd&k zrvzmAeH`yUIh8N)v0WPzkmdKW4FSy>+6cJUK{3c4{jt68frdPkK8cpM9DUj+DS7c5 zK1s=o-|$IFUi^knQt}zdf0B~VK>iaU|Kl2zAjo?+I2Bj9{dEhb_;oip*?N7E9LT(H zbfV_3{P~EDju8w7RDmM(fl&QyMbYcRI#>3zVAQ>D20_4hW4q zopIVs03v`por#Ai`2r$#R zP;45z*>Q8~2&m9Vb+c1d9UN`y(fK1zG<)$eV;^zMVN&YJ>F5!MqkUWt_*YK! zzj92}KKdTmk2+Iq|}4i6w*KjsYAYXOjPKjw^& zr%rVDv2^N0cOR3fdnwSOh1OI3=eD+4hd-6}ARh5kse*||{FGx%N}xRAr<~Daf@hHs z%tCTY|CrK=cDN-aAs+FTbaKQa-jeE z<*J7MTQU!G6ahjv??#!9;|_l}B~Sx_cT)lq&3V_!>pd~BYasBhLwc4vGX^%HoDcff zcGO#keUOqE1c?t)5)$6|AhqIyAn}1i++7Z?flX-Vqv#LI&pqO!lmHLO+>cTMPc@A!L{fY;} zH7SXDNUTXo)I(y8o9t`#kXYj)5xE5k?7UrM&>aFpZK*Q&) zuG!@QX?3extKDKi#&oNTTP*Vo$XdMBHCrSgYw=c>E%J4l_Dbnla@_qdf+ zx~39*3WhnEG6l;HR4KOp9=Aq^x`1{ARb5JTT?KJ}p*T_=`#o+7#--PLN~Xx?DVKD? z%RIUBY~uE_i(KZY>74KOKe*~lyGajAd~2%d)mo`;r=LniBCgd_ZmrHrqEyi&xnfVW zO$Pl;)bNdQlb=ZkD-Fs)cv9eK)8N^t;~QhbXVV7aS(Sq{P~aAEFe~K{vCXyTH$3SS zn$(?vioNRh;$(MswspvjESI+ORLETHtCWu90lCVDCip55;qF#az15GdQfC zuHLi>CuCoCa_?7cZSCqKSwuq4VUfJ~c1dXH($uDLLr;Q1sYCABAql%Cds~IG8S_z=_pr{&Dp_SHy!93e0`bO#)AsvS}HE5Z~on*Gw_!c z351gxFV&Z~FXaxmSF&WZ21-5wbDV%I%5A9zihgW!YxO3MKA?fy+!@*@0c25ba}R4) z&b@%D`0#mZFQ}CD{qkq*1th)yBUj?IhcyVqtci2{a=aH%3TrRNdjTMQzbt!!q+C_X zQGdHDDOX4G8#>!lI+CEbJ>Cr{h0gYPHvojrcG(T&Mppc(*Ic=gU05kMvaiKE0T9gq z^-ciD%6Uz80x{@SdG8Ik;#;0J=;9{5;bsR1m&>B6l5@vS*{{FlMDKp{)==qK`|=eX zrR8J@vkaIedD_v{-7AR`tgfJNYO7=n9X_kMW%g-GhYe!E!WJGLo>rJ3YG$svC!z~j zn$9V4LWf?L+|58pB`Y;9UPV4nqbOwWvgqewb+kDgUmX;>pwg|X^h9rmV?wypvWI76 zw$n8i6o3qAr)zE%0Fl{Fmsp0V6d-D`(;cBtgn-!Uo$ffD!CEB;viDtkb;i-P)wT5d zF4tG1Id4%c^4aCOgBqgmoI5Jym(FrhB?x(!OGe6-j;RYDpSW&y!}*Rf1v+15ptzP7 zSFvykdeJNC7C%EgDn9}l2L&UYsf9TtnUQ)@p8bTxX6?PVWN{;I61ieK0sWp{Wy7dZ zEX?8!3Kv?eMKaceG8Hj*olCKXk{CkO}D?+_j>Lf=(>Z=M}-R(=;CC7)i$xBM{-I`36 z?4`_2RvoMrg4z2-wjQ~!6$J3P8FNLiU|N9C7w!sS4;Kt)=V$cNp~A%(dql%SPXEEH zkF`R{bH_ZIY3CQagSj+B{6TWNm^>LOoF1==-5#DN7l`p4dHhg|ovgRJtAnM3ILfXN zMb&3lsc0oE#p^_zri(MiE2C5~T&r*209hv&XILj2#I>su0bH5sfBd{_?C{EzhS;tv zGsgR;5;U&N|~00NzvX`5PK#oi7ih*32QBi<&+sCyRBPteB#A` zag`)Pv;9@6Tpsv{=TBl=o6`9ce`-_4TzyhmG0oK{vLDaK|))b(;j4l-JCJEZ#1EY%^A*idUj=l-JCJePfF=vbB6Hb ztGWY7J)Viq|ITZtKAv_U@z2N84rH5rJY(GIDz!~Mo-uAUARRoOF>W;=9Xy`Ft^T4K z0E+lzCVKR{Ukaa0=}QFZ$&|iqpHHSDlI`=!%rNb;R@ol(pUgDqa|j^xpUmtvNe8{F zL|dQE*atLRM8c`Dw9FbW2W9GXUZ;916UK(tyarr>F_o>7H+0&X@yr2Br@jk>#Z=!G zz^0a_VsVwVOX-OkiNnS#RC1$xc^y$`#pI${?by^rFC-No){I_+wgkPNPDd?4uctG$ z@hX&{*V7r|W_sEr==F4_Q6G*Nr5fgxX~AYSZKNuB&t>cvGET$KRHCiChea=U|9+0% zW|VCUJGEZ3&vcRdBSTM|<;9raZt;cZb@A;iG2G&hlNl*as=Se&oVXJR2FYS3<$ubR zUP=ZpZY^GMTNmq0#Jj508)&}~2eX7x=RIpUVevlG4m#k#8T%hFea6ICNGhq}xs0z< zN~%aUz?}Rpm1tTU9Itxo7umZo!@JLbb0m`^NU*1A26o|Bi*q7(S@+KgDpK*20 zxzH2?2}0+QDTJ!QGL>Unl~~9v8Qv7>xsf0vV7%bv!N8UbkLpY*w6fKm>gUPH36bez3PxLP@UD@t={c2<4QGUqhUvt zSuh(JoBR^VW@VQ8I#G_vg%JJK8PC|crdb|q9fsFD9P?R^4TgP7WCzeKg>)xPa5*>e`VZ}#w*Y-9zf_6ECg(e zC;eX;vR$-_kawGR!&lM?2LT2|JmDZ{@=AsYkDCB*&$xRgod^vOqf>;c!6k3pf{Ff9 zIa|Uv2*Z|S;POZqOc`G&(yOWJI_e?|M69|XXz^;QxsDu&UMp`Qwi!g)f+xHnlI7uu zE3kv1>sL-99Wl3H(y>cY;*RpMV{Be8AF7xt5b>gPY##N3U<-)H&H{O(eC!fv2a!%m zHl)cL1K$)^N3TKZzmu_bXuC=ta0(c&LCI=)Cu8oW zDTUTM8FM!c$kc@IWQhAJpGGns-pkm3j(r+O&LZz+cmSt{qZ1u=X52BFH-YI5gw8^! z5(NG2%v2j03IY;4GeeA03W7d&X1H2y6z9jO2t|S3&$wS`%oi4tSFVB($>#>-<$%zY zn`#ie#Sh)P&E{p!Nzt;6FPc7Lr6!9iQ9u+8CwUrs<1c;L`;&m4-DVCGUomo z5MsMByjInwORf)gWv1+-4&POBJ@8@XUk$|4oW5yqrf8a7N#7r4OdytG`u;Fu0?Qa>5-Xl4&SD|UEz38mVM}@0B69lYMLBMj577CnUTAb(E zHN4|B&shi}$+rR7f7O2%buH#~KQBubwRJ6Ghg^ik4)lbHs-EYWAa9ilA0}W3Og{>i zpg?urJKw9g)C2|OZsUB9pn!zUtHml_=-FfcwZ{WAN6NI`2l~jvruklou`MlDiu|enO}u+7xBx zto6)vRjcU&)YAosP}X`TQc{!mzUx)oW`rX5HQ)8PW)#|(!Kv-Jmky!YOxLP$bwhdl%>$>e<*^rWuWw{|GA*0&h84sBzkl5fE z4;c{axWO|XG9c!4gNKJKA=Mg`?OHE-^NK=vZLDlHO4-Um#;d?zi3?F9=b)QBySd?R z`~R1is*Yv0sHaBS|J*&Esh(n_(aW;nrMRL4qL*dCOJs?UXuJ)Kte}ei{BhCNlKw}vuBnhAarhym!#Z=-l~>lbB&nL zTjMneL^D9WCIL~(TjMo3DDVBmt9Zz)Nx1<1iI*K7d>|`okSxkOyr^USU&1@$!GWZw zJ7T#5(&mnMMFGOp9r20+MDBOQD+-Vmb%(4dv4n$U%I^Ay#2&WF2Zaj*-%-&XaX~4Ke_92?QDb_&h(Z{A(0|8Y#vnj}B z`h!XX!$G2f55^h@L^D9Gfq;nq!B_)p^WMW=#S2CQj|)*zkXli|N4so6$FsZ9*x%}AftKI!?Af@0+6*L&u6{fzm=ia ziQHfH`cM4cbJn6)V}`)e%d7FQ0crGVyz&8I=+$`GfDHT9c-Vjp`&AkCJF@!f8I0&FEqKU}gn`)*(P< zTR@}=5R*) zm^0CrU9omk3TL}w?FNLiU83FSU6#H9Kh%oHZwP&u5>i>8vEoq*p$}ul15_=|qL=KI zkJX|-uuc~J$FcSS(F{;)A0UJMShVlk4i0i22idQ<+V9`?9~WDL&-cmUe_ULqyd3$y z?c107{olB0jun2}5A+Kz3Pdw5@!dvs*i$fUgV1L%g@Bt&d~*g<2za=}H!uDb0_HFA z$$pgsq#&rU)_2DyG-b9y7@DEffaqGEamdk6HBoIyib)UtV=10G}iff9TB54l-Bv=AVP@`r3rY2 zZ<5Y|7#LtoN}}mk_~zD-Qb=9l*XevNK-HF{bIlY@uk`J>P`n<%n36=zuS}T|ujfiX zG)YK#<@Q{eN}I~-eOsq}Auvb*#-t=ZzCLA2VleCdx_D~j8hO1agJz1Exym>BZ@iB@}*D%9X@suJZFb3QTQCUFDNd{(@+CecrptulUHf8a^U&D3|;4Wm*-7+`sq=~?^0Fk!PHOg9`c|Y`B{izS3AS(}qesix7(EOo4 zG?ch317#fEExvub?<%7M%$fnAH64(3aEotp{sAF(i*LTF14wtb_#~SR!e9aNfaDf` z^6f}XEUF;La{Q5RLUIDvBez?Tn~rNL3?y&!U2Q-GF_Dp@cb#{nQv=MWMqMyE{8}%!p-{ZTH{n-7K;ll{T#71K zBlMlNLeSz)-`r^n0{G{?d8DjhT7b|w3<{xYki#H?59{f|yW6+#Pb4p!4TxCs;#%At z?+w(3+}*Ny$=(2nw?H7`MFB$9P>Vt|9IhYs?I#jBi=*@~ zZ>nNJi>LIkZ{8VE9R?ou$4obZmVNGF|IovXpgB1~?eHfOLEEC@kEDXOm7sr>m*_;PbY$wRs5vy4>5vPcPYR2-GULczDoh2!}9g! zF6Gxg;V>;{b(iv+RH6ASo(LLDtkL=|Nw#^@*Z{h)w^EN-^nWPr9y!zYb@B2z3 zXjcUN$7IkX_lcliN(Bu9k}s!%CdG{!|K+=L8Ip*V*TaAE?bj2rimUY}->)+x<}Gl@ z0WcM#ek%+@pX(r?Eb^y>J1fA#H##-S>QF8K_U z`4)4`A5H%1SL^(fdZjObF}tD+fAxp#5&X!;B_Es*z17)@C~Gx*&&CrqUma^pK2NPu z?iBOlM4S9db-hnQA4wZ{*YS6rw9m}N5H7g-OCH?kq;`7}$McGgpptN=q@E~b+2OD}|#6xP1G@~XQQe@${V7MBYXpk8)ydcZPve>5( zST>gnv&K1AF!lz7_GARgyL+m9fqa8cG3E9A>Osel!T zl&1KV7iGh0ZE95&)n>T%CKLjq7iD>gD@WnM!seQ+y`Nh6KrjiYjUpiA)@0514*;RH zCcCHpNGBka)@1kDH#koMeS?L&OSAU)hTc$R?V7){5vM6Jv+=Y{;A{H&6SfoMJT9ca zl3W+G0Gao-vb0EjioYTg&zxEh>WhMs(WJhpm?&1vvN+lyY$Py4xRk%eUX(9>1k`$o!syjuP{d?;<3D#Q0PN*uv1~s)7D+K%1)~xwR zg+f4lYqnl%wL-wm)+`Q$tOSK1{JJ$ea_^uv$QlH5xivd#Qt-5VaZBnzWVt{9 zJF#IMA99u`4vOD@-CebwVnSw}(v%5_+O5x-FsF<`2C+UjSm!_~1Wc^Y5xEn?BM9KD za_*!=GUBL%NNGy=?y7Q{;;Ua3<_2rKqG%{0e0Mu03XQ9C?zDucIHe#`q7uowx}2yu zrdQ_%i^s2LNL6xXx_U%Cx1qzVXLJ+#Sq@&#zf*D+x;j)e z=*C=h{idE0zv=PDoLLZn=<1C*3x>I~GC%mYz1|qO%^jC{z%AZHz~!5R7hP&M2fpKw)FfD5OHrc~9&XN& z{U+bl69gUJmWwhEu9&AFDBf01QIzYp@==L$-Ig=of>BMNcw3Gj^$W3}K=kLL2On&8 z#Vv^@J+xd&Oq8s@oVF-ge>rVYvi_X;B#h9OBVm6I_xx*`TZzj3Jm=n*%QT!^Xpui- zDxcPus3%)-Y(GeQRPK;`Q%vWuc9BFYRrpA(Jg1OdTfq1MLr~CvK$pFp56|k;ExoId z-_LWoy5K16g+ho9+@13VH5?$eA19BM+1ZtJBPq7@qC2IC6iodQl~4>gl%+RNS58Fnw6k9hH8O^J*Fy61)5ftjZ5_D-W=~H#VW`Y yGU@l{jxrG-g;1C>rIpj_{kdu#i&Hfqdw-6bdNB(Mfg0SO8`IeT+lQu{{r>=3e+YO0 delta 14089 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 K^+c3aKK?&GYlF7{ diff --git a/crates/core/app/src/action_handler/actions/submit.rs b/crates/core/app/src/action_handler/actions/submit.rs index 167b13bc4a..4e020fb700 100644 --- a/crates/core/app/src/action_handler/actions/submit.rs +++ b/crates/core/app/src/action_handler/actions/submit.rs @@ -1,3 +1,4 @@ +use std::str::FromStr; use std::sync::Arc; use anyhow::{Context, Result}; @@ -6,10 +7,12 @@ use async_trait::async_trait; use cnidarium::{StateDelta, StateRead, StateWrite}; use decaf377::Fq; use decaf377_rdsa::{VerificationKey, VerificationKeyBytes}; +use ibc_types::core::client::ClientId; use once_cell::sync::Lazy; use penumbra_asset::STAKING_TOKEN_DENOM; use penumbra_chain::component::StateReadExt as _; use penumbra_community_pool::component::StateReadExt as _; +use penumbra_ibc::component::ClientStateReadExt; use penumbra_keys::keys::{FullViewingKey, NullifierKey}; use penumbra_proto::DomainType; use penumbra_sct::component::StateReadExt as _; @@ -133,6 +136,14 @@ impl ActionHandler for ProposalSubmit { } } UpgradePlan { .. } => {} + FreezeIbcClient { client_id } => { + let _ = &ClientId::from_str(client_id) + .context("can't decode client id from IBC proposal")?; + } + UnfreezeIbcClient { client_id } => { + let _ = &ClientId::from_str(client_id) + .context("can't decode client id from IBC proposal")?; + } } Ok(()) @@ -203,6 +214,22 @@ impl ActionHandler for ProposalSubmit { ProposalPayload::UpgradePlan { .. } => { // TODO(erwan): no stateful checks for upgrade plan. } + ProposalPayload::FreezeIbcClient { client_id } => { + // Check that the client ID is valid and that there is a corresponding + // client state. If the client state is already frozen, then freezing it + // is a no-op. + let client_id = &ClientId::from_str(client_id) + .map_err(|e| tonic::Status::aborted(format!("invalid client id: {e}")))?; + let _ = state.get_client_state(client_id).await?; + } + ProposalPayload::UnfreezeIbcClient { client_id } => { + // Check that the client ID is valid and that there is a corresponding + // client state. If the client state is not frozen, then unfreezing it + // is a no-op. + let client_id = &ClientId::from_str(client_id) + .map_err(|e| tonic::Status::aborted(format!("invalid client id: {e}")))?; + let _ = state.get_client_state(client_id).await?; + } } Ok(()) diff --git a/crates/core/component/governance/Cargo.toml b/crates/core/component/governance/Cargo.toml index 5175e25fbc..9d4b589ebf 100644 --- a/crates/core/component/governance/Cargo.toml +++ b/crates/core/component/governance/Cargo.toml @@ -18,7 +18,7 @@ component = [ ] # proving-keys = ["penumbra-proof-params/proving-keys"] default = ["std", "component"] -std = ["ark-ff/std"] +std = ["ark-ff/std", "ibc-types/std"] parallel = [ "penumbra-tct/parallel", "ark-ff/parallel", @@ -78,6 +78,7 @@ futures = "0.3" pbjson-types = "0.6" once_cell = "1.8" rand_chacha = "0.3" +ibc-types = { version = "0.11.0", default-features = false } # Component dependencies tokio = { version = "1.21.1", features = ["full", "tracing"], optional = true } diff --git a/crates/core/component/governance/src/component/view.rs b/crates/core/component/governance/src/component/view.rs index acbc6d0a8e..10a627ea29 100644 --- a/crates/core/component/governance/src/component/view.rs +++ b/crates/core/component/governance/src/component/view.rs @@ -7,8 +7,11 @@ use anyhow::{Context, Result}; use async_trait::async_trait; use cnidarium::{StateRead, StateWrite}; use futures::StreamExt; +use ibc_types::core::client::ClientId; use penumbra_asset::{asset, Value, STAKING_TOKEN_DENOM}; use penumbra_chain::component::{StateReadExt as _, StateWriteExt as _}; +use penumbra_ibc::component::ClientStateReadExt as _; +use penumbra_ibc::component::ClientStateWriteExt as _; use penumbra_num::Amount; use penumbra_proto::{StateReadProto, StateWriteProto}; use penumbra_sct::{component::StateReadExt as _, Nullifier}; @@ -558,7 +561,7 @@ pub trait StateReadExt: StateRead + penumbra_stake::StateReadExt { impl StateReadExt for T {} #[async_trait] -pub trait StateWriteExt: StateWrite { +pub trait StateWriteExt: StateWrite + penumbra_ibc::component::ConnectionStateWriteExt { /// Writes the provided governance parameters to the JMT. fn put_governance_params(&mut self, params: GovernanceParameters) { // Note that the governance params have been updated: @@ -875,8 +878,24 @@ pub trait StateWriteExt: StateWrite { tracing::info!(target_height = height, "upgrade plan proposal passed"); self.signal_upgrade(*height).await?; } - } + ProposalPayload::FreezeIbcClient { client_id } => { + let client_id = &ClientId::from_str(client_id) + .map_err(|e| tonic::Status::aborted(format!("invalid client id: {e}")))?; + let client_state = self.get_client_state(client_id).await?; + let client_height = client_state.latest_height(); + + let frozen_client = client_state.with_frozen_height(client_height); + self.put_client(client_id, frozen_client); + } + ProposalPayload::UnfreezeIbcClient { client_id } => { + let client_id = &ClientId::from_str(client_id) + .map_err(|e| tonic::Status::aborted(format!("invalid client id: {e}")))?; + let client_state = self.get_client_state(client_id).await?; + let unfrozen_client = client_state.unfrozen(); + self.put_client(client_id, unfrozen_client); + } + } Ok(Ok(())) } diff --git a/crates/core/component/governance/src/proposal.rs b/crates/core/component/governance/src/proposal.rs index 3ea6bdab34..e9566db75c 100644 --- a/crates/core/component/governance/src/proposal.rs +++ b/crates/core/component/governance/src/proposal.rs @@ -79,6 +79,16 @@ impl From for pb::Proposal { ProposalPayload::UpgradePlan { height } => { proposal.upgrade_plan = Some(pb::proposal::UpgradePlan { height }); } + ProposalPayload::FreezeIbcClient { client_id } => { + proposal.freeze_ibc_client = Some(pb::proposal::FreezeIbcClient { + client_id: client_id.into(), + }); + } + ProposalPayload::UnfreezeIbcClient { client_id } => { + proposal.unfreeze_ibc_client = Some(pb::proposal::UnfreezeIbcClient { + client_id: client_id.into(), + }); + } } proposal } @@ -202,6 +212,12 @@ pub enum ProposalKind { /// An upgrade proposal. #[cfg_attr(feature = "clap", clap(display_order = 500))] UpgradePlan, + /// A proposal to freeze an IBC client. + #[cfg_attr(feature = "clap", clap(display_order = 600))] + FreezeIbcClient, + /// A proposal to unfreeze an IBC client. + #[cfg_attr(feature = "clap", clap(display_order = 700))] + UnfreezeIbcClient, } impl FromStr for ProposalKind { @@ -228,6 +244,8 @@ impl Proposal { ProposalPayload::ParameterChange { .. } => ProposalKind::ParameterChange, ProposalPayload::CommunityPoolSpend { .. } => ProposalKind::CommunityPoolSpend, ProposalPayload::UpgradePlan { .. } => ProposalKind::UpgradePlan, + ProposalPayload::FreezeIbcClient { .. } => ProposalKind::FreezeIbcClient, + ProposalPayload::UnfreezeIbcClient { .. } => ProposalKind::UnfreezeIbcClient, } } } @@ -276,6 +294,16 @@ pub enum ProposalPayload { /// An upgrade plan proposal describes a planned upgrade to the chain. If ratified, the chain /// will halt at the specified height, trigger an epoch transition, and halt the chain. UpgradePlan { height: u64 }, + /// A proposal to freeze a specific IBC client. + FreezeIbcClient { + /// The identifier of the client to freeze. + client_id: String, + }, + /// A proposal to unfreeze a specific IBC client. + UnfreezeIbcClient { + /// The identifier of the client to unfreeze. + client_id: String, + }, } /// A TOML-serializable version of `ProposalPayload`, meant for human consumption. @@ -298,6 +326,12 @@ pub enum ProposalPayloadToml { UpgradePlan { height: u64, }, + FreezeIbcClient { + client_id: String, + }, + UnfreezeIbcClient { + client_id: String, + }, } impl TryFrom for ProposalPayload { @@ -325,6 +359,12 @@ impl TryFrom for ProposalPayload { } } ProposalPayloadToml::UpgradePlan { height } => ProposalPayload::UpgradePlan { height }, + ProposalPayloadToml::FreezeIbcClient { client_id } => { + ProposalPayload::FreezeIbcClient { client_id } + } + ProposalPayloadToml::UnfreezeIbcClient { client_id } => { + ProposalPayload::UnfreezeIbcClient { client_id } + } }) } } @@ -348,6 +388,12 @@ impl From for ProposalPayloadToml { } } ProposalPayload::UpgradePlan { height } => ProposalPayloadToml::UpgradePlan { height }, + ProposalPayload::FreezeIbcClient { client_id } => { + ProposalPayloadToml::FreezeIbcClient { client_id } + } + ProposalPayload::UnfreezeIbcClient { client_id } => { + ProposalPayloadToml::UnfreezeIbcClient { client_id } + } } } } diff --git a/crates/core/component/ibc/src/component.rs b/crates/core/component/ibc/src/component.rs index a681940504..4cd8ecd42c 100644 --- a/crates/core/component/ibc/src/component.rs +++ b/crates/core/component/ibc/src/component.rs @@ -24,7 +24,9 @@ use msg_handler::MsgHandler; pub use self::metrics::register_metrics; pub use channel::StateReadExt as ChannelStateReadExt; pub use client::StateReadExt as ClientStateReadExt; +pub use client::StateWriteExt as ClientStateWriteExt; pub use connection::StateReadExt as ConnectionStateReadExt; +pub use connection::StateWriteExt as ConnectionStateWriteExt; pub use view::{StateReadExt, StateWriteExt}; pub use ibc_component::IBCComponent; diff --git a/crates/core/component/ibc/src/component/rpc/connection_query.rs b/crates/core/component/ibc/src/component/rpc/connection_query.rs index 73fcb76d10..91999fa056 100644 --- a/crates/core/component/ibc/src/component/rpc/connection_query.rs +++ b/crates/core/component/ibc/src/component/rpc/connection_query.rs @@ -1,6 +1,5 @@ use async_trait::async_trait; -use ibc_proto::ibc::core::client; use ibc_proto::ibc::core::client::v1::{Height, IdentifiedClientState}; use ibc_proto::ibc::core::connection::v1::query_server::Query as ConnectionQuery; use ibc_proto::ibc::core::connection::v1::{ diff --git a/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.rs b/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.rs index 9142cc034f..9d7b0727e2 100644 --- a/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.rs +++ b/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.rs @@ -669,6 +669,10 @@ pub struct Proposal { pub community_pool_spend: ::core::option::Option, #[prost(message, optional, tag = "9")] pub upgrade_plan: ::core::option::Option, + #[prost(message, optional, tag = "10")] + pub freeze_ibc_client: ::core::option::Option, + #[prost(message, optional, tag = "11")] + pub unfreeze_ibc_client: ::core::option::Option, } /// Nested message and enum types in `Proposal`. pub mod proposal { @@ -776,6 +780,38 @@ pub mod proposal { ) } } + /// Freeze an existing IBC client. + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct FreezeIbcClient { + #[prost(string, tag = "1")] + pub client_id: ::prost::alloc::string::String, + } + impl ::prost::Name for FreezeIbcClient { + const NAME: &'static str = "FreezeIbcClient"; + const PACKAGE: &'static str = "penumbra.core.component.governance.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!( + "penumbra.core.component.governance.v1alpha1.Proposal.{}", Self::NAME + ) + } + } + /// Unfreeze an existing IBC client. + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct UnfreezeIbcClient { + #[prost(string, tag = "1")] + pub client_id: ::prost::alloc::string::String, + } + impl ::prost::Name for UnfreezeIbcClient { + const NAME: &'static str = "UnfreezeIbcClient"; + const PACKAGE: &'static str = "penumbra.core.component.governance.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!( + "penumbra.core.component.governance.v1alpha1.Proposal.{}", Self::NAME + ) + } + } } impl ::prost::Name for Proposal { const NAME: &'static str = "Proposal"; diff --git a/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.serde.rs b/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.serde.rs index 0f40a860f3..8051845ee9 100644 --- a/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.serde.rs +++ b/crates/proto/src/gen/penumbra.core.component.governance.v1alpha1.serde.rs @@ -2184,6 +2184,12 @@ impl serde::Serialize for Proposal { if self.upgrade_plan.is_some() { len += 1; } + if self.freeze_ibc_client.is_some() { + len += 1; + } + if self.unfreeze_ibc_client.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("penumbra.core.component.governance.v1alpha1.Proposal", len)?; if self.id != 0 { #[allow(clippy::needless_borrow)] @@ -2210,6 +2216,12 @@ impl serde::Serialize for Proposal { if let Some(v) = self.upgrade_plan.as_ref() { struct_ser.serialize_field("upgradePlan", v)?; } + if let Some(v) = self.freeze_ibc_client.as_ref() { + struct_ser.serialize_field("freezeIbcClient", v)?; + } + if let Some(v) = self.unfreeze_ibc_client.as_ref() { + struct_ser.serialize_field("unfreezeIbcClient", v)?; + } struct_ser.end() } } @@ -2231,6 +2243,10 @@ impl<'de> serde::Deserialize<'de> for Proposal { "communityPoolSpend", "upgrade_plan", "upgradePlan", + "freeze_ibc_client", + "freezeIbcClient", + "unfreeze_ibc_client", + "unfreezeIbcClient", ]; #[allow(clippy::enum_variant_names)] @@ -2243,6 +2259,8 @@ impl<'de> serde::Deserialize<'de> for Proposal { ParameterChange, CommunityPoolSpend, UpgradePlan, + FreezeIbcClient, + UnfreezeIbcClient, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -2272,6 +2290,8 @@ impl<'de> serde::Deserialize<'de> for Proposal { "parameterChange" | "parameter_change" => Ok(GeneratedField::ParameterChange), "communityPoolSpend" | "community_pool_spend" => Ok(GeneratedField::CommunityPoolSpend), "upgradePlan" | "upgrade_plan" => Ok(GeneratedField::UpgradePlan), + "freezeIbcClient" | "freeze_ibc_client" => Ok(GeneratedField::FreezeIbcClient), + "unfreezeIbcClient" | "unfreeze_ibc_client" => Ok(GeneratedField::UnfreezeIbcClient), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -2299,6 +2319,8 @@ impl<'de> serde::Deserialize<'de> for Proposal { let mut parameter_change__ = None; let mut community_pool_spend__ = None; let mut upgrade_plan__ = None; + let mut freeze_ibc_client__ = None; + let mut unfreeze_ibc_client__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Id => { @@ -2351,6 +2373,18 @@ impl<'de> serde::Deserialize<'de> for Proposal { } upgrade_plan__ = map_.next_value()?; } + GeneratedField::FreezeIbcClient => { + if freeze_ibc_client__.is_some() { + return Err(serde::de::Error::duplicate_field("freezeIbcClient")); + } + freeze_ibc_client__ = map_.next_value()?; + } + GeneratedField::UnfreezeIbcClient => { + if unfreeze_ibc_client__.is_some() { + return Err(serde::de::Error::duplicate_field("unfreezeIbcClient")); + } + unfreeze_ibc_client__ = map_.next_value()?; + } } } Ok(Proposal { @@ -2362,6 +2396,8 @@ impl<'de> serde::Deserialize<'de> for Proposal { parameter_change: parameter_change__, community_pool_spend: community_pool_spend__, upgrade_plan: upgrade_plan__, + freeze_ibc_client: freeze_ibc_client__, + unfreeze_ibc_client: unfreeze_ibc_client__, }) } } @@ -2552,6 +2588,98 @@ impl<'de> serde::Deserialize<'de> for proposal::Emergency { deserializer.deserialize_struct("penumbra.core.component.governance.v1alpha1.Proposal.Emergency", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for proposal::FreezeIbcClient { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.client_id.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("penumbra.core.component.governance.v1alpha1.Proposal.FreezeIbcClient", len)?; + if !self.client_id.is_empty() { + struct_ser.serialize_field("clientId", &self.client_id)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for proposal::FreezeIbcClient { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "client_id", + "clientId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + ClientId, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "clientId" | "client_id" => Ok(GeneratedField::ClientId), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = proposal::FreezeIbcClient; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct penumbra.core.component.governance.v1alpha1.Proposal.FreezeIbcClient") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut client_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::ClientId => { + if client_id__.is_some() { + return Err(serde::de::Error::duplicate_field("clientId")); + } + client_id__ = Some(map_.next_value()?); + } + } + } + Ok(proposal::FreezeIbcClient { + client_id: client_id__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("penumbra.core.component.governance.v1alpha1.Proposal.FreezeIbcClient", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for proposal::ParameterChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -2753,6 +2881,98 @@ impl<'de> serde::Deserialize<'de> for proposal::Signaling { deserializer.deserialize_struct("penumbra.core.component.governance.v1alpha1.Proposal.Signaling", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for proposal::UnfreezeIbcClient { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.client_id.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("penumbra.core.component.governance.v1alpha1.Proposal.UnfreezeIbcClient", len)?; + if !self.client_id.is_empty() { + struct_ser.serialize_field("clientId", &self.client_id)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for proposal::UnfreezeIbcClient { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "client_id", + "clientId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + ClientId, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "clientId" | "client_id" => Ok(GeneratedField::ClientId), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = proposal::UnfreezeIbcClient; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct penumbra.core.component.governance.v1alpha1.Proposal.UnfreezeIbcClient") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut client_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::ClientId => { + if client_id__.is_some() { + return Err(serde::de::Error::duplicate_field("clientId")); + } + client_id__ = Some(map_.next_value()?); + } + } + } + Ok(proposal::UnfreezeIbcClient { + client_id: client_id__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("penumbra.core.component.governance.v1alpha1.Proposal.UnfreezeIbcClient", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for proposal::UpgradePlan { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result diff --git a/crates/proto/src/gen/proto_descriptor.bin.no_lfs b/crates/proto/src/gen/proto_descriptor.bin.no_lfs index 82edd3d7da33da4ecd767d6ba2f43b837639459c..1932603254a430bb925aba7e3e3d1b8caa107b79 100644 GIT binary patch delta 37057 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 delta 19339 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 jtg6Y}WY!o-8`n28o?X{0 penumbra.core.component.governance.v1alpha1.Proposal - 55, // 1: penumbra.core.component.governance.v1alpha1.ProposalSubmit.deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount - 55, // 2: penumbra.core.component.governance.v1alpha1.ProposalDepositClaim.deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount + 57, // 1: penumbra.core.component.governance.v1alpha1.ProposalSubmit.deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount + 57, // 2: penumbra.core.component.governance.v1alpha1.ProposalDepositClaim.deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount 17, // 3: penumbra.core.component.governance.v1alpha1.ProposalDepositClaim.outcome:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome 7, // 4: penumbra.core.component.governance.v1alpha1.ValidatorVote.body:type_name -> penumbra.core.component.governance.v1alpha1.ValidatorVoteBody - 56, // 5: penumbra.core.component.governance.v1alpha1.ValidatorVote.auth_sig:type_name -> penumbra.crypto.decaf377_rdsa.v1alpha1.SpendAuthSignature + 58, // 5: penumbra.core.component.governance.v1alpha1.ValidatorVote.auth_sig:type_name -> penumbra.crypto.decaf377_rdsa.v1alpha1.SpendAuthSignature 15, // 6: penumbra.core.component.governance.v1alpha1.ValidatorVoteBody.vote:type_name -> penumbra.core.component.governance.v1alpha1.Vote - 57, // 7: penumbra.core.component.governance.v1alpha1.ValidatorVoteBody.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey - 58, // 8: penumbra.core.component.governance.v1alpha1.ValidatorVoteBody.governance_key:type_name -> penumbra.core.keys.v1alpha1.GovernanceKey + 59, // 7: penumbra.core.component.governance.v1alpha1.ValidatorVoteBody.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey + 60, // 8: penumbra.core.component.governance.v1alpha1.ValidatorVoteBody.governance_key:type_name -> penumbra.core.keys.v1alpha1.GovernanceKey 6, // 9: penumbra.core.component.governance.v1alpha1.ValidatorVoteBody.reason:type_name -> penumbra.core.component.governance.v1alpha1.ValidatorVoteReason 9, // 10: penumbra.core.component.governance.v1alpha1.DelegatorVote.body:type_name -> penumbra.core.component.governance.v1alpha1.DelegatorVoteBody - 56, // 11: penumbra.core.component.governance.v1alpha1.DelegatorVote.auth_sig:type_name -> penumbra.crypto.decaf377_rdsa.v1alpha1.SpendAuthSignature + 58, // 11: penumbra.core.component.governance.v1alpha1.DelegatorVote.auth_sig:type_name -> penumbra.crypto.decaf377_rdsa.v1alpha1.SpendAuthSignature 1, // 12: penumbra.core.component.governance.v1alpha1.DelegatorVote.proof:type_name -> penumbra.core.component.governance.v1alpha1.ZKDelegatorVoteProof 15, // 13: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.vote:type_name -> penumbra.core.component.governance.v1alpha1.Vote - 59, // 14: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.value:type_name -> penumbra.core.asset.v1alpha1.Value - 55, // 15: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.unbonded_amount:type_name -> penumbra.core.num.v1alpha1.Amount - 60, // 16: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.nullifier:type_name -> penumbra.core.component.sct.v1alpha1.Nullifier - 61, // 17: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.rk:type_name -> penumbra.crypto.decaf377_rdsa.v1alpha1.SpendVerificationKey + 61, // 14: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.value:type_name -> penumbra.core.asset.v1alpha1.Value + 57, // 15: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.unbonded_amount:type_name -> penumbra.core.num.v1alpha1.Amount + 62, // 16: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.nullifier:type_name -> penumbra.core.component.sct.v1alpha1.Nullifier + 63, // 17: penumbra.core.component.governance.v1alpha1.DelegatorVoteBody.rk:type_name -> penumbra.crypto.decaf377_rdsa.v1alpha1.SpendVerificationKey 40, // 18: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.visible:type_name -> penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Visible 41, // 19: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.opaque:type_name -> penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Opaque 15, // 20: penumbra.core.component.governance.v1alpha1.DelegatorVotePlan.vote:type_name -> penumbra.core.component.governance.v1alpha1.Vote - 62, // 21: penumbra.core.component.governance.v1alpha1.DelegatorVotePlan.staked_note:type_name -> penumbra.core.component.shielded_pool.v1alpha1.Note - 55, // 22: penumbra.core.component.governance.v1alpha1.DelegatorVotePlan.unbonded_amount:type_name -> penumbra.core.num.v1alpha1.Amount - 59, // 23: penumbra.core.component.governance.v1alpha1.CommunityPoolDeposit.value:type_name -> penumbra.core.asset.v1alpha1.Value - 59, // 24: penumbra.core.component.governance.v1alpha1.CommunityPoolSpend.value:type_name -> penumbra.core.asset.v1alpha1.Value - 59, // 25: penumbra.core.component.governance.v1alpha1.CommunityPoolOutput.value:type_name -> penumbra.core.asset.v1alpha1.Value - 63, // 26: penumbra.core.component.governance.v1alpha1.CommunityPoolOutput.address:type_name -> penumbra.core.keys.v1alpha1.Address + 64, // 21: penumbra.core.component.governance.v1alpha1.DelegatorVotePlan.staked_note:type_name -> penumbra.core.component.shielded_pool.v1alpha1.Note + 57, // 22: penumbra.core.component.governance.v1alpha1.DelegatorVotePlan.unbonded_amount:type_name -> penumbra.core.num.v1alpha1.Amount + 61, // 23: penumbra.core.component.governance.v1alpha1.CommunityPoolDeposit.value:type_name -> penumbra.core.asset.v1alpha1.Value + 61, // 24: penumbra.core.component.governance.v1alpha1.CommunityPoolSpend.value:type_name -> penumbra.core.asset.v1alpha1.Value + 61, // 25: penumbra.core.component.governance.v1alpha1.CommunityPoolOutput.value:type_name -> penumbra.core.asset.v1alpha1.Value + 65, // 26: penumbra.core.component.governance.v1alpha1.CommunityPoolOutput.address:type_name -> penumbra.core.keys.v1alpha1.Address 0, // 27: penumbra.core.component.governance.v1alpha1.Vote.vote:type_name -> penumbra.core.component.governance.v1alpha1.Vote.Vote 42, // 28: penumbra.core.component.governance.v1alpha1.ProposalState.voting:type_name -> penumbra.core.component.governance.v1alpha1.ProposalState.Voting 43, // 29: penumbra.core.component.governance.v1alpha1.ProposalState.withdrawn:type_name -> penumbra.core.component.governance.v1alpha1.ProposalState.Withdrawn @@ -4328,59 +4462,61 @@ var file_penumbra_core_component_governance_v1alpha1_governance_proto_depIdxs = 52, // 37: penumbra.core.component.governance.v1alpha1.Proposal.parameter_change:type_name -> penumbra.core.component.governance.v1alpha1.Proposal.ParameterChange 53, // 38: penumbra.core.component.governance.v1alpha1.Proposal.community_pool_spend:type_name -> penumbra.core.component.governance.v1alpha1.Proposal.CommunityPoolSpend 54, // 39: penumbra.core.component.governance.v1alpha1.Proposal.upgrade_plan:type_name -> penumbra.core.component.governance.v1alpha1.Proposal.UpgradePlan - 19, // 40: penumbra.core.component.governance.v1alpha1.ProposalDataResponse.proposal:type_name -> penumbra.core.component.governance.v1alpha1.Proposal - 16, // 41: penumbra.core.component.governance.v1alpha1.ProposalDataResponse.state:type_name -> penumbra.core.component.governance.v1alpha1.ProposalState - 55, // 42: penumbra.core.component.governance.v1alpha1.ProposalDataResponse.proposal_deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount - 64, // 43: penumbra.core.component.governance.v1alpha1.ProposalRateDataResponse.rate_data:type_name -> penumbra.core.component.stake.v1alpha1.RateData - 19, // 44: penumbra.core.component.governance.v1alpha1.ProposalListResponse.proposal:type_name -> penumbra.core.component.governance.v1alpha1.Proposal - 16, // 45: penumbra.core.component.governance.v1alpha1.ProposalListResponse.state:type_name -> penumbra.core.component.governance.v1alpha1.ProposalState - 15, // 46: penumbra.core.component.governance.v1alpha1.ValidatorVotesResponse.vote:type_name -> penumbra.core.component.governance.v1alpha1.Vote - 57, // 47: penumbra.core.component.governance.v1alpha1.ValidatorVotesResponse.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey - 55, // 48: penumbra.core.component.governance.v1alpha1.GovernanceParameters.proposal_deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount - 30, // 49: penumbra.core.component.governance.v1alpha1.GenesisContent.governance_params:type_name -> penumbra.core.component.governance.v1alpha1.GovernanceParameters - 65, // 50: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.chain_params:type_name -> penumbra.core.component.chain.v1alpha1.ChainParameters - 66, // 51: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.community_pool_params:type_name -> penumbra.core.component.community_pool.v1alpha1.CommunityPoolParameters - 30, // 52: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.governance_params:type_name -> penumbra.core.component.governance.v1alpha1.GovernanceParameters - 67, // 53: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.ibc_params:type_name -> penumbra.core.component.ibc.v1alpha1.IbcParameters - 68, // 54: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.stake_params:type_name -> penumbra.core.component.stake.v1alpha1.StakeParameters - 69, // 55: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.fee_params:type_name -> penumbra.core.component.fee.v1alpha1.FeeParameters - 70, // 56: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.distributions_params:type_name -> penumbra.core.component.distributions.v1alpha1.DistributionsParameters - 32, // 57: penumbra.core.component.governance.v1alpha1.ChangedAppParametersSet.old:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters - 32, // 58: penumbra.core.component.governance.v1alpha1.ChangedAppParametersSet.new:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters - 57, // 59: penumbra.core.component.governance.v1alpha1.VotingPowerAtProposalStartRequest.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey - 18, // 60: penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalResponse.tally:type_name -> penumbra.core.component.governance.v1alpha1.Tally - 57, // 61: penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalResponse.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey - 8, // 62: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Visible.delegator_vote:type_name -> penumbra.core.component.governance.v1alpha1.DelegatorVote - 71, // 63: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Visible.note:type_name -> penumbra.core.component.shielded_pool.v1alpha1.NoteView - 8, // 64: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Opaque.delegator_vote:type_name -> penumbra.core.component.governance.v1alpha1.DelegatorVote - 17, // 65: penumbra.core.component.governance.v1alpha1.ProposalState.Finished.outcome:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome - 17, // 66: penumbra.core.component.governance.v1alpha1.ProposalState.Claimed.outcome:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome - 46, // 67: penumbra.core.component.governance.v1alpha1.ProposalOutcome.Failed.withdrawn:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome.Withdrawn - 46, // 68: penumbra.core.component.governance.v1alpha1.ProposalOutcome.Slashed.withdrawn:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome.Withdrawn - 32, // 69: penumbra.core.component.governance.v1alpha1.Proposal.ParameterChange.old_parameters:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters - 32, // 70: penumbra.core.component.governance.v1alpha1.Proposal.ParameterChange.new_parameters:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters - 72, // 71: penumbra.core.component.governance.v1alpha1.Proposal.CommunityPoolSpend.transaction_plan:type_name -> google.protobuf.Any - 20, // 72: penumbra.core.component.governance.v1alpha1.QueryService.ProposalInfo:input_type -> penumbra.core.component.governance.v1alpha1.ProposalInfoRequest - 26, // 73: penumbra.core.component.governance.v1alpha1.QueryService.ProposalList:input_type -> penumbra.core.component.governance.v1alpha1.ProposalListRequest - 22, // 74: penumbra.core.component.governance.v1alpha1.QueryService.ProposalData:input_type -> penumbra.core.component.governance.v1alpha1.ProposalDataRequest - 38, // 75: penumbra.core.component.governance.v1alpha1.QueryService.NextProposalId:input_type -> penumbra.core.component.governance.v1alpha1.NextProposalIdRequest - 28, // 76: penumbra.core.component.governance.v1alpha1.QueryService.ValidatorVotes:input_type -> penumbra.core.component.governance.v1alpha1.ValidatorVotesRequest - 34, // 77: penumbra.core.component.governance.v1alpha1.QueryService.VotingPowerAtProposalStart:input_type -> penumbra.core.component.governance.v1alpha1.VotingPowerAtProposalStartRequest - 36, // 78: penumbra.core.component.governance.v1alpha1.QueryService.AllTalliedDelegatorVotesForProposal:input_type -> penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalRequest - 24, // 79: penumbra.core.component.governance.v1alpha1.QueryService.ProposalRateData:input_type -> penumbra.core.component.governance.v1alpha1.ProposalRateDataRequest - 21, // 80: penumbra.core.component.governance.v1alpha1.QueryService.ProposalInfo:output_type -> penumbra.core.component.governance.v1alpha1.ProposalInfoResponse - 27, // 81: penumbra.core.component.governance.v1alpha1.QueryService.ProposalList:output_type -> penumbra.core.component.governance.v1alpha1.ProposalListResponse - 23, // 82: penumbra.core.component.governance.v1alpha1.QueryService.ProposalData:output_type -> penumbra.core.component.governance.v1alpha1.ProposalDataResponse - 39, // 83: penumbra.core.component.governance.v1alpha1.QueryService.NextProposalId:output_type -> penumbra.core.component.governance.v1alpha1.NextProposalIdResponse - 29, // 84: penumbra.core.component.governance.v1alpha1.QueryService.ValidatorVotes:output_type -> penumbra.core.component.governance.v1alpha1.ValidatorVotesResponse - 35, // 85: penumbra.core.component.governance.v1alpha1.QueryService.VotingPowerAtProposalStart:output_type -> penumbra.core.component.governance.v1alpha1.VotingPowerAtProposalStartResponse - 37, // 86: penumbra.core.component.governance.v1alpha1.QueryService.AllTalliedDelegatorVotesForProposal:output_type -> penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalResponse - 25, // 87: penumbra.core.component.governance.v1alpha1.QueryService.ProposalRateData:output_type -> penumbra.core.component.governance.v1alpha1.ProposalRateDataResponse - 80, // [80:88] is the sub-list for method output_type - 72, // [72:80] is the sub-list for method input_type - 72, // [72:72] is the sub-list for extension type_name - 72, // [72:72] is the sub-list for extension extendee - 0, // [0:72] is the sub-list for field type_name + 55, // 40: penumbra.core.component.governance.v1alpha1.Proposal.freeze_ibc_client:type_name -> penumbra.core.component.governance.v1alpha1.Proposal.FreezeIbcClient + 56, // 41: penumbra.core.component.governance.v1alpha1.Proposal.unfreeze_ibc_client:type_name -> penumbra.core.component.governance.v1alpha1.Proposal.UnfreezeIbcClient + 19, // 42: penumbra.core.component.governance.v1alpha1.ProposalDataResponse.proposal:type_name -> penumbra.core.component.governance.v1alpha1.Proposal + 16, // 43: penumbra.core.component.governance.v1alpha1.ProposalDataResponse.state:type_name -> penumbra.core.component.governance.v1alpha1.ProposalState + 57, // 44: penumbra.core.component.governance.v1alpha1.ProposalDataResponse.proposal_deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount + 66, // 45: penumbra.core.component.governance.v1alpha1.ProposalRateDataResponse.rate_data:type_name -> penumbra.core.component.stake.v1alpha1.RateData + 19, // 46: penumbra.core.component.governance.v1alpha1.ProposalListResponse.proposal:type_name -> penumbra.core.component.governance.v1alpha1.Proposal + 16, // 47: penumbra.core.component.governance.v1alpha1.ProposalListResponse.state:type_name -> penumbra.core.component.governance.v1alpha1.ProposalState + 15, // 48: penumbra.core.component.governance.v1alpha1.ValidatorVotesResponse.vote:type_name -> penumbra.core.component.governance.v1alpha1.Vote + 59, // 49: penumbra.core.component.governance.v1alpha1.ValidatorVotesResponse.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey + 57, // 50: penumbra.core.component.governance.v1alpha1.GovernanceParameters.proposal_deposit_amount:type_name -> penumbra.core.num.v1alpha1.Amount + 30, // 51: penumbra.core.component.governance.v1alpha1.GenesisContent.governance_params:type_name -> penumbra.core.component.governance.v1alpha1.GovernanceParameters + 67, // 52: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.chain_params:type_name -> penumbra.core.component.chain.v1alpha1.ChainParameters + 68, // 53: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.community_pool_params:type_name -> penumbra.core.component.community_pool.v1alpha1.CommunityPoolParameters + 30, // 54: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.governance_params:type_name -> penumbra.core.component.governance.v1alpha1.GovernanceParameters + 69, // 55: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.ibc_params:type_name -> penumbra.core.component.ibc.v1alpha1.IbcParameters + 70, // 56: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.stake_params:type_name -> penumbra.core.component.stake.v1alpha1.StakeParameters + 71, // 57: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.fee_params:type_name -> penumbra.core.component.fee.v1alpha1.FeeParameters + 72, // 58: penumbra.core.component.governance.v1alpha1.ChangedAppParameters.distributions_params:type_name -> penumbra.core.component.distributions.v1alpha1.DistributionsParameters + 32, // 59: penumbra.core.component.governance.v1alpha1.ChangedAppParametersSet.old:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters + 32, // 60: penumbra.core.component.governance.v1alpha1.ChangedAppParametersSet.new:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters + 59, // 61: penumbra.core.component.governance.v1alpha1.VotingPowerAtProposalStartRequest.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey + 18, // 62: penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalResponse.tally:type_name -> penumbra.core.component.governance.v1alpha1.Tally + 59, // 63: penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalResponse.identity_key:type_name -> penumbra.core.keys.v1alpha1.IdentityKey + 8, // 64: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Visible.delegator_vote:type_name -> penumbra.core.component.governance.v1alpha1.DelegatorVote + 73, // 65: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Visible.note:type_name -> penumbra.core.component.shielded_pool.v1alpha1.NoteView + 8, // 66: penumbra.core.component.governance.v1alpha1.DelegatorVoteView.Opaque.delegator_vote:type_name -> penumbra.core.component.governance.v1alpha1.DelegatorVote + 17, // 67: penumbra.core.component.governance.v1alpha1.ProposalState.Finished.outcome:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome + 17, // 68: penumbra.core.component.governance.v1alpha1.ProposalState.Claimed.outcome:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome + 46, // 69: penumbra.core.component.governance.v1alpha1.ProposalOutcome.Failed.withdrawn:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome.Withdrawn + 46, // 70: penumbra.core.component.governance.v1alpha1.ProposalOutcome.Slashed.withdrawn:type_name -> penumbra.core.component.governance.v1alpha1.ProposalOutcome.Withdrawn + 32, // 71: penumbra.core.component.governance.v1alpha1.Proposal.ParameterChange.old_parameters:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters + 32, // 72: penumbra.core.component.governance.v1alpha1.Proposal.ParameterChange.new_parameters:type_name -> penumbra.core.component.governance.v1alpha1.ChangedAppParameters + 74, // 73: penumbra.core.component.governance.v1alpha1.Proposal.CommunityPoolSpend.transaction_plan:type_name -> google.protobuf.Any + 20, // 74: penumbra.core.component.governance.v1alpha1.QueryService.ProposalInfo:input_type -> penumbra.core.component.governance.v1alpha1.ProposalInfoRequest + 26, // 75: penumbra.core.component.governance.v1alpha1.QueryService.ProposalList:input_type -> penumbra.core.component.governance.v1alpha1.ProposalListRequest + 22, // 76: penumbra.core.component.governance.v1alpha1.QueryService.ProposalData:input_type -> penumbra.core.component.governance.v1alpha1.ProposalDataRequest + 38, // 77: penumbra.core.component.governance.v1alpha1.QueryService.NextProposalId:input_type -> penumbra.core.component.governance.v1alpha1.NextProposalIdRequest + 28, // 78: penumbra.core.component.governance.v1alpha1.QueryService.ValidatorVotes:input_type -> penumbra.core.component.governance.v1alpha1.ValidatorVotesRequest + 34, // 79: penumbra.core.component.governance.v1alpha1.QueryService.VotingPowerAtProposalStart:input_type -> penumbra.core.component.governance.v1alpha1.VotingPowerAtProposalStartRequest + 36, // 80: penumbra.core.component.governance.v1alpha1.QueryService.AllTalliedDelegatorVotesForProposal:input_type -> penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalRequest + 24, // 81: penumbra.core.component.governance.v1alpha1.QueryService.ProposalRateData:input_type -> penumbra.core.component.governance.v1alpha1.ProposalRateDataRequest + 21, // 82: penumbra.core.component.governance.v1alpha1.QueryService.ProposalInfo:output_type -> penumbra.core.component.governance.v1alpha1.ProposalInfoResponse + 27, // 83: penumbra.core.component.governance.v1alpha1.QueryService.ProposalList:output_type -> penumbra.core.component.governance.v1alpha1.ProposalListResponse + 23, // 84: penumbra.core.component.governance.v1alpha1.QueryService.ProposalData:output_type -> penumbra.core.component.governance.v1alpha1.ProposalDataResponse + 39, // 85: penumbra.core.component.governance.v1alpha1.QueryService.NextProposalId:output_type -> penumbra.core.component.governance.v1alpha1.NextProposalIdResponse + 29, // 86: penumbra.core.component.governance.v1alpha1.QueryService.ValidatorVotes:output_type -> penumbra.core.component.governance.v1alpha1.ValidatorVotesResponse + 35, // 87: penumbra.core.component.governance.v1alpha1.QueryService.VotingPowerAtProposalStart:output_type -> penumbra.core.component.governance.v1alpha1.VotingPowerAtProposalStartResponse + 37, // 88: penumbra.core.component.governance.v1alpha1.QueryService.AllTalliedDelegatorVotesForProposal:output_type -> penumbra.core.component.governance.v1alpha1.AllTalliedDelegatorVotesForProposalResponse + 25, // 89: penumbra.core.component.governance.v1alpha1.QueryService.ProposalRateData:output_type -> penumbra.core.component.governance.v1alpha1.ProposalRateDataResponse + 82, // [82:90] is the sub-list for method output_type + 74, // [74:82] is the sub-list for method input_type + 74, // [74:74] is the sub-list for extension type_name + 74, // [74:74] is the sub-list for extension extendee + 0, // [0:74] is the sub-list for field type_name } func init() { file_penumbra_core_component_governance_v1alpha1_governance_proto_init() } @@ -5037,6 +5173,30 @@ func file_penumbra_core_component_governance_v1alpha1_governance_proto_init() { return nil } } + file_penumbra_core_component_governance_v1alpha1_governance_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Proposal_FreezeIbcClient); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_penumbra_core_component_governance_v1alpha1_governance_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Proposal_UnfreezeIbcClient); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_penumbra_core_component_governance_v1alpha1_governance_proto_msgTypes[9].OneofWrappers = []interface{}{ (*DelegatorVoteView_Visible_)(nil), @@ -5059,7 +5219,7 @@ func file_penumbra_core_component_governance_v1alpha1_governance_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_penumbra_core_component_governance_v1alpha1_governance_proto_rawDesc, NumEnums: 1, - NumMessages: 54, + NumMessages: 56, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/penumbra/penumbra/core/component/governance/v1alpha1/governance.proto b/proto/penumbra/penumbra/core/component/governance/v1alpha1/governance.proto index 790c69e3d7..7980cc3b20 100644 --- a/proto/penumbra/penumbra/core/component/governance/v1alpha1/governance.proto +++ b/proto/penumbra/penumbra/core/component/governance/v1alpha1/governance.proto @@ -246,6 +246,8 @@ message Proposal { ParameterChange parameter_change = 7; CommunityPoolSpend community_pool_spend = 8; UpgradePlan upgrade_plan = 9; + FreezeIbcClient freeze_ibc_client = 10; + UnfreezeIbcClient unfreeze_ibc_client = 11; // A signaling proposal is meant to register a vote on-chain, but does not have an automatic // effect when passed. @@ -295,6 +297,16 @@ message Proposal { message UpgradePlan { uint64 height = 1; } + + // Freeze an existing IBC client. + message FreezeIbcClient { + string client_id = 1; + } + + // Unfreeze an existing IBC client. + message UnfreezeIbcClient { + string client_id = 1; + } } // Query operations for the governance component.