Skip to content

Commit

Permalink
feat: Update consumer BTC light client (#112)
Browse files Browse the repository at this point in the history
1. updates proto definitions
2. new btc_header ibc packet handler to ingest the headers sent from
babylon
  • Loading branch information
gusin13 authored Feb 21, 2025
1 parent 457242b commit 75ce0bd
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 10 deletions.
28 changes: 27 additions & 1 deletion contracts/babylon/src/ibc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::error::ContractError;
use babylon_bindings::BabylonMsg;
use babylon_proto::babylon::zoneconcierge::v1::{
outbound_packet::Packet as OutboundPacketType, BtcTimestamp, OutboundPacket,
outbound_packet::Packet as OutboundPacketType, BtcTimestamp, OutboundPacket, BtcHeaders,
};

use crate::state::config::CONFIG;
Expand Down Expand Up @@ -138,6 +138,9 @@ pub fn ibc_packet_receive(
OutboundPacketType::BtcStaking(btc_staking) => {
ibc_packet::handle_btc_staking(deps, caller, &btc_staking)
}
OutboundPacketType::BtcHeaders(btc_headers) => {
ibc_packet::handle_btc_headers(deps, caller, &btc_headers)
}
}
})()
.or_else(|e| {
Expand Down Expand Up @@ -252,6 +255,29 @@ pub(crate) mod ibc_packet {
Ok(resp)
}

pub fn handle_btc_headers(
deps: DepsMut,
_caller: String,
btc_headers: &BtcHeaders,
) -> StdResult<IbcReceiveResponse<BabylonMsg>> {
let storage = deps.storage;
let cfg = CONFIG.load(storage)?;

let msg_option = crate::state::handle_btc_headers(storage, btc_headers)?;

let mut resp: IbcReceiveResponse<BabylonMsg> =
IbcReceiveResponse::new(StdAck::success(vec![])); // TODO: design response format
resp = resp.add_attribute("action", "receive_btc_headers");

if let Some(msg) = msg_option {
if cfg.notify_cosmos_zone {
resp = resp.add_message(msg);
}
}

Ok(resp)
}

pub fn slashing_msg(
env: &Env,
channel: &IbcChannel,
Expand Down
30 changes: 25 additions & 5 deletions contracts/babylon/src/state/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//! state is the module that manages smart contract's system state
use cosmwasm_std::{StdError, Storage};

use babylon_proto::babylon::zoneconcierge::v1::BtcTimestamp;

use babylon_proto::babylon::zoneconcierge::v1::{BtcTimestamp, BtcHeaders};
use crate::bindings::msg_btc_finalized_header;
use babylon_bindings::BabylonMsg;

Expand All @@ -21,13 +20,15 @@ pub fn handle_btc_timestamp(
btc_ts: &BtcTimestamp,
) -> Result<Option<BabylonMsg>, StdError> {
// extract and init/handle BTC headers
let btc_headers = &btc_ts.btc_headers;
let btc_headers = btc_ts.btc_headers.as_ref()
.ok_or_else(|| StdError::generic_err("btc_headers is None"))?;

if btc_light_client::is_initialized(storage) {
btc_light_client::handle_btc_headers_from_babylon(storage, btc_headers).map_err(|e| {
btc_light_client::handle_btc_headers_from_babylon(storage, &btc_headers.headers).map_err(|e| {
StdError::generic_err(format!("failed to handle BTC headers from Babylon: {e}"))
})?;
} else {
btc_light_client::init(storage, btc_headers)
btc_light_client::init(storage, &btc_headers.headers)
.map_err(|e| StdError::generic_err(format!("failed to initialize BTC headers: {e}")))?;
}

Expand Down Expand Up @@ -76,3 +77,22 @@ pub fn handle_btc_timestamp(

Ok(None)
}

pub fn handle_btc_headers(
storage: &mut dyn Storage,
btc_headers: &BtcHeaders,
) -> Result<Option<BabylonMsg>, StdError> {
if btc_light_client::is_initialized(storage) {
btc_light_client::handle_btc_headers_from_babylon(storage, &btc_headers.headers)
.map_err(|e| StdError::generic_err(format!("failed to handle BTC headers: {e}")))?;
} else {
// TODO: Two issues to fix:
// 1. Remove init logic once BSN base BTC header is set during contract instantiation
// 2. Babylon to send headers from BSN base to tip instead of last w+1 headers
// See: https://github.com/babylonlabs-io/babylon-contract/issues/114
btc_light_client::init(storage, &btc_headers.headers)
.map_err(|e| StdError::generic_err(format!("failed to initialize BTC headers: {e}")))?;
}

Ok(None)
}
2 changes: 1 addition & 1 deletion packages/proto/babylon
Submodule babylon updated 452 files
16 changes: 13 additions & 3 deletions packages/proto/src/gen/babylon.zoneconcierge.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub struct ProofFinalizedChainInfo {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct OutboundPacket {
/// packet is the actual message carried in the IBC packet
#[prost(oneof="outbound_packet::Packet", tags="1, 2")]
#[prost(oneof="outbound_packet::Packet", tags="1, 2, 3")]
pub packet: ::core::option::Option<outbound_packet::Packet>,
}
/// Nested message and enum types in `OutboundPacket`.
Expand All @@ -166,6 +166,8 @@ pub mod outbound_packet {
BtcTimestamp(super::BtcTimestamp),
#[prost(message, tag="2")]
BtcStaking(super::super::super::btcstaking::v1::BtcStakingIbcPacket),
#[prost(message, tag="3")]
BtcHeaders(super::BtcHeaders),
}
}
/// InboundPacket represents packets received by Babylon from other chains
Expand All @@ -186,6 +188,14 @@ pub mod inbound_packet {
ConsumerSlashing(super::ConsumerSlashingIbcPacket),
}
}
/// BTCHeaders contains BTC headers that have been verified and inserted into Babylon's BTC light client
/// These headers are forwarded to consumer chains to keep their light clients in sync with Babylon
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BtcHeaders {
#[prost(message, repeated, tag="1")]
pub headers: ::prost::alloc::vec::Vec<super::super::btclightclient::v1::BtcHeaderInfo>,
}
/// BTCTimestamp is a BTC timestamp that carries information of a BTC-finalised epoch
/// It includes a number of BTC headers, a raw checkpoint, an epoch metadata, and
/// a CZ header if there exists CZ headers checkpointed to this epoch.
Expand All @@ -204,8 +214,8 @@ pub struct BtcTimestamp {
/// - the block AFTER the common ancestor of BTC tip at epoch `lastFinalizedEpoch-1` and BTC tip at epoch `lastFinalizedEpoch`
/// - BTC tip at epoch `lastFinalizedEpoch`
/// where `lastFinalizedEpoch` is the last finalised epoch in Babylon
#[prost(message, repeated, tag="2")]
pub btc_headers: ::prost::alloc::vec::Vec<super::super::btclightclient::v1::BtcHeaderInfo>,
#[prost(message, optional, tag="2")]
pub btc_headers: ::core::option::Option<BtcHeaders>,
//
// Data for Babylon epoch chain

Expand Down

0 comments on commit 75ce0bd

Please sign in to comment.