diff --git a/contracts/btc-finality/src/contract.rs b/contracts/btc-finality/src/contract.rs index edd3d5ba..fa6b57ae 100644 --- a/contracts/btc-finality/src/contract.rs +++ b/contracts/btc-finality/src/contract.rs @@ -212,7 +212,8 @@ fn handle_end_block( let ev = finality::index_block(deps, env.block.height, &hex::decode(app_hash_hex)?)?; res = res.add_event(ev); // Tally all non-finalised blocks - let events = finality::tally_blocks(deps, activated_height, env.block.height)?; + let (msgs, events) = finality::tally_blocks(deps, activated_height, env.block.height)?; + res = res.add_messages(msgs); res = res.add_events(events); } Ok(res) diff --git a/contracts/btc-finality/src/finality.rs b/contracts/btc-finality/src/finality.rs index 41a64fdd..980ed7db 100644 --- a/contracts/btc-finality/src/finality.rs +++ b/contracts/btc-finality/src/finality.rs @@ -422,7 +422,7 @@ pub fn tally_blocks( deps: &mut DepsMut, activated_height: u64, height: u64, -) -> Result, ContractError> { +) -> Result<(Vec, Vec), ContractError> { // Start finalising blocks since max(activated_height, next_height) let next_height = NEXT_HEIGHT.may_load(deps.storage)?.unwrap_or(0); let start_height = max(activated_height, next_height); @@ -436,6 +436,7 @@ pub fn tally_blocks( // - Does not have finality providers, finalised: Impossible, panic. // After this for loop, the blocks since the earliest activated height are either finalised or // non-finalisable + let mut msgs = vec![]; let mut events = vec![]; for h in start_height..=height { let mut indexed_block = BLOCKS.load(deps.storage, h)?; @@ -451,7 +452,9 @@ pub fn tally_blocks( .collect::>>()?; if tally(&fp_set, &voter_btc_pks) { // If this block gets >2/3 votes, finalise it - let ev = finalize_block(deps.storage, &mut indexed_block, &voter_btc_pks)?; + let (msg, ev) = + finalize_block(deps.storage, &mut indexed_block, &voter_btc_pks)?; + msgs.push(msg); events.push(ev); } else { // If not, then this block and all subsequent blocks should not be finalised. @@ -480,7 +483,7 @@ pub fn tally_blocks( } } } - Ok(events) + Ok((msgs, events)) } /// `tally` checks whether a block with the given finality provider set and votes reaches a quorum @@ -504,7 +507,7 @@ fn finalize_block( store: &mut dyn Storage, block: &mut IndexedBlock, _voters: &[String], -) -> Result { +) -> Result<(BabylonMsg, Event), ContractError> { // Set block to be finalised block.finalized = true; BLOCKS.save(store, block.height, block)?; @@ -512,13 +515,16 @@ fn finalize_block( // Set the next height to finalise as height+1 NEXT_HEIGHT.save(store, &(block.height + 1))?; + // Generate block rewards for BTC staking delegators + let msg = BabylonMsg::MintRewards {}; + // TODO: Distribute rewards to BTC staking delegators // Record the last finalized height metric let ev = Event::new("finalize_block") .add_attribute("module", "finality") .add_attribute("finalized_height", block.height.to_string()); - Ok(ev) + Ok((msg, ev)) } const QUERY_LIMIT: Option = Some(30); diff --git a/packages/bindings-test/src/multitest.rs b/packages/bindings-test/src/multitest.rs index 731cca46..a114c2ed 100644 --- a/packages/bindings-test/src/multitest.rs +++ b/packages/bindings-test/src/multitest.rs @@ -88,6 +88,10 @@ impl Module for BabylonModule { // FIXME? We don't do anything here Ok(AppResponse::default()) } + BabylonMsg::MintRewards {} => { + // FIXME? We don't do anything here + Ok(AppResponse::default()) + } } } diff --git a/packages/bindings/src/msg.rs b/packages/bindings/src/msg.rs index 10b0f3a9..27c52001 100644 --- a/packages/bindings/src/msg.rs +++ b/packages/bindings/src/msg.rs @@ -17,6 +17,11 @@ pub enum BabylonMsg { height: i64, time: i64, // NOTE: UNIX timestamp is in i64 }, + /// MintRewards mints the block rewards for the finality providers. + /// It can only be sent from the finality contract. + /// The rewards are minted to the staking contract address, so that they + /// can be distributed across the active finality provider set + MintRewards {}, } pub type BabylonSudoMsg = Empty;