1515// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
1717use std:: collections:: VecDeque ;
18- use std:: convert:: TryInto ;
18+ use std:: convert:: { TryFrom , TryInto } ;
1919use std:: time:: Duration ;
2020
2121use burnchains:: {
@@ -28,13 +28,18 @@ use chainstate::burn::{
2828 BlockHeaderHash , BlockSnapshot , ConsensusHash ,
2929} ;
3030use chainstate:: stacks:: {
31+ boot:: STACKS_BOOT_CODE_CONTRACT_ADDRESS ,
3132 db:: { ClarityTx , StacksChainState , StacksHeaderInfo } ,
3233 events:: StacksTransactionReceipt ,
3334 Error as ChainstateError , StacksAddress , StacksBlock , StacksBlockHeader , StacksBlockId ,
3435} ;
3536use monitoring:: increment_stx_blocks_processed_counter;
3637use util:: db:: Error as DBError ;
37- use vm:: { costs:: ExecutionCost , types:: PrincipalData } ;
38+ use vm:: {
39+ costs:: ExecutionCost ,
40+ types:: { PrincipalData , QualifiedContractIdentifier } ,
41+ Value ,
42+ } ;
3843
3944pub mod comm;
4045use chainstate:: stacks:: index:: MarfTrieId ;
@@ -177,10 +182,35 @@ impl RewardSetProvider for OnChainRewardSetProvider {
177182 sortdb : & SortitionDB ,
178183 block_id : & StacksBlockId ,
179184 ) -> Result < Vec < StacksAddress > , Error > {
180- let res =
185+ let registered_addrs =
181186 chainstate. get_reward_addresses ( burnchain, sortdb, current_burn_height, block_id) ?;
182- let addresses = res. iter ( ) . map ( |a| a. 0 ) . collect :: < Vec < StacksAddress > > ( ) ;
183- Ok ( addresses)
187+
188+ let liquid_ustx = StacksChainState :: get_stacks_block_header_info_by_index_block_hash (
189+ chainstate. headers_db ( ) ,
190+ block_id,
191+ ) ?
192+ . expect ( "CORRUPTION: Failed to look up block header info for PoX anchor block" )
193+ . total_liquid_ustx ;
194+
195+ let ( threshold, participation) = StacksChainState :: get_reward_threshold_and_participation (
196+ & burnchain. pox_constants ,
197+ & registered_addrs,
198+ liquid_ustx,
199+ ) ;
200+
201+ if !burnchain
202+ . pox_constants
203+ . enough_participation ( participation, liquid_ustx)
204+ {
205+ info ! ( "PoX reward cycle did not have enough participation. Defaulting to burn. participation={}, liquid_ustx={}, burn_height={}" ,
206+ participation, liquid_ustx, current_burn_height) ;
207+ return Ok ( vec ! [ ] ) ;
208+ }
209+
210+ Ok ( StacksChainState :: make_reward_set (
211+ threshold,
212+ registered_addrs,
213+ ) )
184214 }
185215}
186216
@@ -212,7 +242,32 @@ impl<'a, T: BlockEventDispatcher>
212242 stacks_chain_id,
213243 chain_state_path,
214244 initial_balances,
215- boot_block_exec,
245+ |clarity_tx| {
246+ let burnchain = burnchain. clone ( ) ;
247+ let contract = QualifiedContractIdentifier :: parse ( & format ! (
248+ "{}.pox" ,
249+ STACKS_BOOT_CODE_CONTRACT_ADDRESS
250+ ) )
251+ . expect ( "Failed to construct boot code contract address" ) ;
252+ let sender = PrincipalData :: from ( contract. clone ( ) ) ;
253+
254+ clarity_tx. connection ( ) . as_transaction ( |conn| {
255+ conn. run_contract_call (
256+ & sender,
257+ & contract,
258+ "set-burnchain-parameters" ,
259+ & [
260+ Value :: UInt ( burnchain. first_block_height as u128 ) ,
261+ Value :: UInt ( burnchain. pox_constants . prepare_length as u128 ) ,
262+ Value :: UInt ( burnchain. pox_constants . reward_cycle_length as u128 ) ,
263+ Value :: UInt ( burnchain. pox_constants . pox_rejection_fraction as u128 ) ,
264+ ] ,
265+ |_, _| false ,
266+ )
267+ . expect ( "Failed to set burnchain parameters in PoX contract" ) ;
268+ } ) ;
269+ boot_block_exec ( clarity_tx)
270+ } ,
216271 block_limit,
217272 )
218273 . unwrap ( ) ;
0 commit comments