Skip to content

Commit

Permalink
Add send rewards distribution over FPs
Browse files Browse the repository at this point in the history
  • Loading branch information
Mauro Lacy committed Dec 11, 2024
1 parent 934aabc commit cfaf8a0
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 5 deletions.
3 changes: 3 additions & 0 deletions contracts/babylon/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ pub fn execute(
// TODO: Add events
Ok(res)
}
ExecuteMsg::SendRewards { .. } => {
todo!()
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions contracts/babylon/src/msg/contract.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::Uint128;
use cosmwasm_std::{Binary, StdError, StdResult};

use babylon_apis::finality_api::Evidence;
Expand Down Expand Up @@ -108,6 +109,17 @@ pub enum ExecuteMsg {
/// This will be forwarded over IBC to the Babylon side for propagation to other Consumers, and
/// Babylon itself
Slashing { evidence: Evidence },
/// `SendRewards` is a message sent by the finality contract, to send rewards to Babylon
SendRewards {
/// `fp_distribution` is the list of finality providers and their rewards
fp_distribution: Vec<RewardsDistribution>,
},
}

#[cw_serde]
pub struct RewardsDistribution {
pub fp_pubkey_hex: String,
pub reward: Uint128,
}

#[cw_serde]
Expand Down
1 change: 1 addition & 0 deletions contracts/babylon/src/state/btc_light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ pub(crate) mod tests {
match resp {
ExecuteMsg::BtcHeaders { headers } => headers,
ExecuteMsg::Slashing { .. } => unreachable!("unexpected slashing message"),
ExecuteMsg::SendRewards { .. } => unreachable!("unexpected send rewards message"),
}
}

Expand Down
1 change: 1 addition & 0 deletions contracts/babylon/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ fn get_fork_msg_test_headers() -> Vec<BtcHeader> {
match resp {
ExecuteMsg::BtcHeaders { headers } => headers,
ExecuteMsg::Slashing { .. } => unreachable!("unexpected slashing message"),
ExecuteMsg::SendRewards { .. } => unreachable!("unexpected send rewards message"),
}
}

Expand Down
1 change: 0 additions & 1 deletion contracts/btc-finality/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ full-validation = [ "btc-staking/full-validation" ]
babylon-apis = { path = "../../packages/apis" }
babylon-bindings = { path = "../../packages/bindings" }
babylon-merkle = { path = "../../packages/merkle" }
babylon-proto = { path = "../../packages/proto" }
babylon-btcstaking = { path = "../../packages/btcstaking" }
babylon-bitcoin = { path = "../../packages/bitcoin" }
eots = { path = "../../packages/eots" }
Expand Down
60 changes: 56 additions & 4 deletions contracts/btc-finality/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
use babylon_apis::finality_api::SudoMsg;
use babylon_bindings::BabylonMsg;
use btc_staking::msg::ActivatedHeightResponse;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
attr, to_json_binary, Addr, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo,
QuerierWrapper, QueryRequest, QueryResponse, Reply, Response, StdResult, WasmQuery,
attr, coins, to_json_binary, Addr, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo, Order,
QuerierWrapper, QueryRequest, QueryResponse, Reply, Response, StdResult, Uint128, WasmMsg,
WasmQuery,
};
use cw2::set_contract_version;
use cw_utils::{maybe_addr, nonpayable};

use btc_staking::msg::ActivatedHeightResponse;

use crate::error::ContractError;
use crate::finality::{
compute_active_finality_providers, distribute_rewards, handle_finality_signature,
handle_public_randomness_commit,
};
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::state::config::{Config, ADMIN, CONFIG, PARAMS};
use crate::state::finality::{REWARDS, TOTAL_REWARDS};
use crate::{finality, queries, state};

pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
Expand Down Expand Up @@ -256,9 +257,60 @@ fn handle_end_block(
}
res = res.add_events(events);
}

// On an epoch boundary, send rewards to Babylon through the babylon contract
let params = PARAMS.load(deps.storage)?;
if env.block.height > 0 && env.block.height % params.epoch_length == 0 {
let rewards = TOTAL_REWARDS.load(deps.storage)?;
if rewards.u128() > 0 {
let wasm_msg = send_rewards_msg(deps, rewards.u128(), &cfg)?;
res = res.add_message(wasm_msg);
// Zero out total rewards
TOTAL_REWARDS.save(deps.storage, &Uint128::zero())?;
}
}
Ok(res)
}

fn send_rewards_msg(
deps: &mut DepsMut,
rewards: u128,
cfg: &Config,
) -> Result<WasmMsg, ContractError> {
// Get the pending rewards distribution
let fp_rewards = REWARDS
.range(deps.storage, None, None, Order::Ascending)
.filter(|item| {
if let Ok((_, reward)) = item {
reward.u128() > 0
} else {
true // don't filter errors
}
})
.map(|item| {
let (fp_pubkey_hex, reward) = item?;
Ok(babylon_contract::msg::contract::RewardsDistribution {
fp_pubkey_hex,
reward,
})
})
.collect::<StdResult<Vec<_>>>()?;
let msg = babylon_contract::ExecuteMsg::SendRewards {
fp_distribution: fp_rewards.clone(),
};
let wasm_msg = WasmMsg::Execute {
contract_addr: cfg.babylon.to_string(),
msg: to_json_binary(&msg)?,
funds: coins(rewards, cfg.denom.as_str()),
};
// Zero out individual rewards
for reward in fp_rewards {
REWARDS.remove(deps.storage, &reward.fp_pubkey_hex);
}

Ok(wasm_msg)
}

pub fn get_activated_height(staking_addr: &Addr, querier: &QuerierWrapper) -> StdResult<u64> {
// TODO: Use a raw query
let query = encode_smart_query(
Expand Down
3 changes: 3 additions & 0 deletions contracts/btc-finality/src/state/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,7 @@ pub struct Params {
/// `finality_inflation_rate` is the inflation rate for finality providers' block rewards
#[derivative(Default(value = "Decimal::permille(35)"))] // 3.5 % by default
pub finality_inflation_rate: Decimal,
/// `epoch_length` is the number of blocks that defines an epoch
#[derivative(Default(value = "50"))] // 50 * ~6.5s = ~5min
pub epoch_length: u64,
}

0 comments on commit cfaf8a0

Please sign in to comment.