Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: op consumer chain slashing (2/2) #98

Merged
merged 4 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion contracts/op-finality-gadget/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@ pub fn execute(
} => handle_finality_signature(
deps,
env,
info,
&fp_pubkey_hex,
height,
&pub_rand,
&proof,
&block_hash,
&signature,
),
ExecuteMsg::Slashing { evidence } => handle_slashing(&evidence),
ExecuteMsg::Slashing { sender, evidence } => handle_slashing(&sender, &evidence),
ExecuteMsg::SetEnabled { enabled } => set_enabled(deps, info, enabled),
ExecuteMsg::UpdateAdmin { admin } => ADMIN
.execute_update_admin(deps, info, Some(api.addr_validate(&admin)?))
Expand Down
31 changes: 24 additions & 7 deletions contracts/op-finality-gadget/src/exec/finality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use babylon_bindings::BabylonMsg;

use babylon_apis::finality_api::{Evidence, PubRandCommit};
use babylon_merkle::Proof;
use cosmwasm_std::{to_json_binary, Deps, DepsMut, Env, Event, Response, WasmMsg};
use cosmwasm_std::{
to_json_binary, Addr, Deps, DepsMut, Env, Event, MessageInfo, Response, WasmMsg,
};
use k256::ecdsa::signature::Verifier;
use k256::schnorr::{Signature, VerifyingKey};
use k256::sha2::{Digest, Sha256};
Expand Down Expand Up @@ -114,6 +116,7 @@ pub(crate) fn verify_commitment_signature(
pub fn handle_finality_signature(
deps: DepsMut,
env: Env,
info: MessageInfo,
fp_btc_pk_hex: &str,
height: u64,
pub_rand: &[u8],
Expand Down Expand Up @@ -211,7 +214,7 @@ pub fn handle_finality_signature(

// slash this finality provider, including setting its voting power to
// zero, extracting its BTC SK, and emit an event
let (msg, ev) = slash_finality_provider(&env, fp_btc_pk_hex, &evidence)?;
let (msg, ev) = slash_finality_provider(&env, &info, fp_btc_pk_hex, &evidence)?;
res = res.add_message(msg);
res = res.add_event(ev);
}
Expand Down Expand Up @@ -311,6 +314,7 @@ fn check_fp_exist(deps: Deps, fp_pubkey_hex: &str) -> Result<(), ContractError>
/// its voting power to zero, extracting its BTC SK, and emitting an event
fn slash_finality_provider(
env: &Env,
info: &MessageInfo,
fp_btc_pk_hex: &str,
evidence: &Evidence,
) -> Result<(WasmMsg, Event), ContractError> {
Expand All @@ -328,6 +332,7 @@ fn slash_finality_provider(
// Emit slashing event.
// Raises slashing event to babylon over IBC.
let msg = ExecuteMsg::Slashing {
sender: info.sender.clone(),
evidence: evidence.clone(),
};
let wasm_msg: WasmMsg = WasmMsg::Execute {
Expand Down Expand Up @@ -357,12 +362,22 @@ fn slash_finality_provider(
Ok((wasm_msg, ev))
}

pub(crate) fn handle_slashing(evidence: &Evidence) -> Result<Response<BabylonMsg>, ContractError> {
pub(crate) fn handle_slashing(
sender: &Addr,
evidence: &Evidence,
) -> Result<Response<BabylonMsg>, ContractError> {
let mut res = Response::new();
// Send msg to Babylon

let msg = BabylonMsg::EquivocationEvidence {
evidence: Some(evidence.clone()),
signer: sender.to_string(),
fp_btc_pk: evidence.fp_btc_pk.clone(),
block_height: evidence.block_height,
pub_rand: evidence.pub_rand.clone(),
canonical_app_hash: evidence.canonical_app_hash.clone(),
fork_app_hash: evidence.fork_app_hash.clone(),
canonical_finality_sig: evidence.canonical_finality_sig.clone(),
fork_finality_sig: evidence.fork_finality_sig.clone(),
};

// Convert to CosmosMsg
Expand All @@ -376,8 +391,9 @@ pub(crate) fn handle_slashing(evidence: &Evidence) -> Result<Response<BabylonMsg
#[cfg(test)]
pub(crate) mod tests {
use super::*;
use cosmwasm_std::from_json;
use cosmwasm_std::testing::mock_env;
use cosmwasm_std::Addr;
use cosmwasm_std::{from_json, testing::message_info};
use std::collections::HashMap;

use babylon_apis::finality_api::PubRandCommit;
Expand Down Expand Up @@ -471,9 +487,9 @@ pub(crate) mod tests {

// Create mock environment
let env = mock_env(); // You'll need to add this mock helper

let info = message_info(&Addr::unchecked("test"), &[]);
// Test slash_finality_provider
let (wasm_msg, event) = slash_finality_provider(&env, &pk_hex, &evidence).unwrap();
let (wasm_msg, event) = slash_finality_provider(&env, &info, &pk_hex, &evidence).unwrap();

// Verify the WasmMsg is correctly constructed
match wasm_msg {
Expand All @@ -487,6 +503,7 @@ pub(crate) mod tests {
let msg_evidence = from_json::<ExecuteMsg>(&msg).unwrap();
match msg_evidence {
ExecuteMsg::Slashing {
sender: _,
evidence: msg_evidence,
} => {
assert_eq!(evidence, msg_evidence);
Expand Down
3 changes: 2 additions & 1 deletion contracts/op-finality-gadget/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use {

use babylon_apis::finality_api::Evidence;
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::Binary;
use cosmwasm_std::{Addr, Binary};

use babylon_merkle::Proof;

Expand Down Expand Up @@ -80,6 +80,7 @@ pub enum ExecuteMsg {
///
/// This message can be called by the admin only.
Slashing {
sender: Addr,
evidence: Evidence,
},
/// Enable or disable finality gadget.
Expand Down
34 changes: 28 additions & 6 deletions packages/bindings/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
//! - ForkHeader: reporting a fork that has a valid quorum certificate
//! - FinalizedHeader: reporting a BTC-finalised header.

use babylon_apis::finality_api::Evidence;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Coin, CosmosMsg, Empty};

/// BabylonMsg is the message that the Babylon contract can send to the Cosmos zone.
/// The Cosmos zone has to integrate https://github.com/babylonlabs-io/wasmbinding for
/// handling these messages
Expand All @@ -21,17 +21,39 @@ pub enum BabylonMsg {
/// 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 {
amount: Coin,
recipient: String,
},
MintRewards { amount: Coin, recipient: String },
/// EquivocationEvidence is the message that the Babylon contract sends to Babylon
/// to notify it of consumer chain slashing.
EquivocationEvidence {
evidence: Option<Evidence>,
/// `signer` is the address submitting the evidence
signer: String,
/// `fp_btc_pk` is the BTC PK of the finality provider that casts this vote
fp_btc_pk: Bytes,
/// `block_height` is the height of the conflicting blocks
block_height: u64,
/// `pub_rand is` the public randomness the finality provider has committed to.
/// Deserializes to `SchnorrPubRand`
pub_rand: Bytes,
/// `canonical_app_hash` is the AppHash of the canonical block
canonical_app_hash: Bytes,
/// `fork_app_hash` is the AppHash of the fork block
fork_app_hash: Bytes,
/// `canonical_finality_sig` is the finality signature to the canonical block,
/// where finality signature is an EOTS signature, i.e.,
/// the `s` in a Schnorr signature `(r, s)`.
/// `r` is the public randomness already committed by the finality provider.
/// Deserializes to `SchnorrEOTSSig`
canonical_finality_sig: Bytes,
/// `fork_finality_sig` is the finality signature to the fork block,
/// where finality signature is an EOTS signature.
/// Deserializes to `SchnorrEOTSSig`
fork_finality_sig: Bytes,
},
}

pub type BabylonSudoMsg = Empty;
pub type BabylonQuery = Empty;
pub type Bytes = Vec<u8>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is necessary 😓

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i followed the same struct definition as in babylon node. do you mean we should remove the alias here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I was suggesting to remove it as there are many Bytes definitions in various libraries already. No strong objection though


// make BabylonMsg to implement CosmosMsg::CustomMsg
impl cosmwasm_std::CustomMsg for BabylonMsg {}
Expand Down
Loading