1+ use namada_sdk:: governance:: utils:: { ProposalStatus , TallyResult } ;
12use namada_sdk:: rpc;
3+ use namada_sdk:: token:: Amount ;
24
35use crate :: sdk:: namada:: Sdk ;
6+ use crate :: state:: State ;
47
58use super :: DoCheck ;
69
10+ const PROPOSAL_DEPOSIT : u64 = 50 * namada_sdk:: token:: NATIVE_SCALE ;
11+
712#[ derive( Clone , Debug , Default ) ]
813pub struct InflationCheck ;
914
1015impl DoCheck for InflationCheck {
11- async fn check ( & self , sdk : & Sdk , state : & mut crate :: state :: State ) -> Result < ( ) , String > {
16+ async fn check ( & self , sdk : & Sdk , state : & mut State ) -> Result < ( ) , String > {
1217 let native_token = rpc:: query_native_token ( & sdk. namada . client )
1318 . await
1419 . map_err ( |e| e. to_string ( ) ) ?;
1520 let current_total_supply = rpc:: get_token_total_supply ( & sdk. namada . client , & native_token)
1621 . await
1722 . map_err ( |e| format ! ( "Failed to query total supply: {e}" ) ) ?;
1823
19- if state. last_total_supply <= current_total_supply {
24+ let rejected = count_rejected_proposals ( sdk, state) . await ?;
25+ let burned_amount = Amount :: from_u64 ( rejected * PROPOSAL_DEPOSIT ) ;
26+ let last_total_supply = state
27+ . last_total_supply
28+ . checked_sub ( burned_amount)
29+ . unwrap_or_default ( ) ;
30+
31+ if last_total_supply <= current_total_supply {
2032 state. last_total_supply = current_total_supply;
2133 tracing:: info!( "Total supply ok" ) ;
2234 Ok ( ( ) )
2335 } else {
2436 Err ( format ! (
2537 "Total supply decreases: before: {} -> after {}" ,
26- state . last_total_supply, current_total_supply
38+ last_total_supply, current_total_supply
2739 ) )
2840 }
2941 }
@@ -36,3 +48,37 @@ impl DoCheck for InflationCheck {
3648 "InflationCheck" . to_string ( )
3749 }
3850}
51+
52+ async fn count_rejected_proposals ( sdk : & Sdk , state : & mut State ) -> Result < u64 , String > {
53+ let client = & sdk. namada . client ;
54+ let epoch = rpc:: query_epoch ( client) . await . map_err ( |e| e. to_string ( ) ) ?;
55+
56+ let mut rejected = 0 ;
57+ let mut proposal_id = state. last_end_proposal_id . map_or ( 0 , |last_id| last_id + 1 ) ;
58+ loop {
59+ let proposal = rpc:: query_proposal_by_id ( client, proposal_id)
60+ . await
61+ . map_err ( |e| e. to_string ( ) ) ?;
62+ let Some ( proposal) = proposal else {
63+ return Ok ( 0 ) ;
64+ } ;
65+
66+ if matches ! ( proposal. get_status( epoch) , ProposalStatus :: Ended ) {
67+ state. last_end_proposal_id = Some ( proposal_id) ;
68+
69+ let result = rpc:: query_proposal_result ( client, proposal_id)
70+ . await
71+ . map_err ( |e| e. to_string ( ) ) ?
72+ . expect ( "Proposal should exist" ) ;
73+ if matches ! ( result. result, TallyResult :: Rejected ) {
74+ rejected += 1 ;
75+ }
76+ } else {
77+ break ;
78+ }
79+
80+ proposal_id += 1 ;
81+ }
82+
83+ Ok ( rejected)
84+ }
0 commit comments