diff --git a/Cargo.lock b/Cargo.lock index 1385de2c..bc7d2fab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,6 +224,7 @@ version = "0.11.0" dependencies = [ "babylon-bitcoin", "babylon-merkle", + "babylon-proto", "bech32 0.9.1", "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/babylon/src/ibc.rs b/contracts/babylon/src/ibc.rs index 7e785340..8e752753 100644 --- a/contracts/babylon/src/ibc.rs +++ b/contracts/babylon/src/ibc.rs @@ -217,103 +217,12 @@ pub(crate) mod ibc_packet { new_fp: btc_staking .new_fp .iter() - .map(|fp| { - Ok(NewFinalityProvider { - description: fp - .description - .as_ref() - .map(|d| FinalityProviderDescription { - moniker: d.moniker.clone(), - identity: d.identity.clone(), - website: d.website.clone(), - security_contact: d.security_contact.clone(), - details: d.details.clone(), - }), - commission: Decimal::from_str(&fp.commission)?, - addr: fp.addr.clone(), - btc_pk_hex: fp.btc_pk_hex.clone(), - pop: fp.pop.as_ref().map(|pop| ProofOfPossessionBtc { - btc_sig_type: pop.btc_sig_type, - btc_sig: pop.btc_sig.to_vec().into(), - }), - consumer_id: fp.consumer_id.clone(), - }) - }) + .map(|fp| NewFinalityProvider::try_from(fp).map_err(StdError::generic_err)) .collect::>()?, active_del: btc_staking .active_del .iter() - .map(|d| { - let delegator_unbonding_info = if let Some(info) = d - .undelegation_info - .clone() - .unwrap() - .delegator_unbonding_info - { - Some(DelegatorUnbondingInfo { - spend_stake_tx: Binary::new(info.spend_stake_tx.to_vec()), - }) - } else { - None - }; - - Ok(ActiveBtcDelegation { - staker_addr: d.staker_addr.clone(), - btc_pk_hex: d.btc_pk_hex.clone(), - fp_btc_pk_list: d.fp_btc_pk_list.clone(), - start_height: d.start_height, - end_height: d.end_height, - total_sat: d.total_sat, - staking_tx: d.staking_tx.to_vec().into(), - slashing_tx: d.slashing_tx.to_vec().into(), - delegator_slashing_sig: d.delegator_slashing_sig.to_vec().into(), - covenant_sigs: d - .covenant_sigs - .iter() - .map(|s| CovenantAdaptorSignatures { - cov_pk: s.cov_pk.to_vec().into(), - adaptor_sigs: s - .adaptor_sigs - .iter() - .map(|a| a.to_vec().into()) - .collect(), - }) - .collect(), - staking_output_idx: d.staking_output_idx, - unbonding_time: d.unbonding_time, - undelegation_info: d - .undelegation_info - .as_ref() - .map(|ui| BtcUndelegationInfo { - unbonding_tx: ui.unbonding_tx.to_vec().into(), - delegator_unbonding_info: delegator_unbonding_info, - covenant_unbonding_sig_list: ui - .covenant_unbonding_sig_list - .iter() - .map(|s| SignatureInfo { - pk: s.pk.to_vec().into(), - sig: s.sig.to_vec().into(), - }) - .collect(), - slashing_tx: ui.slashing_tx.to_vec().into(), - delegator_slashing_sig: ui.delegator_slashing_sig.to_vec().into(), - covenant_slashing_sigs: ui - .covenant_slashing_sigs - .iter() - .map(|s| CovenantAdaptorSignatures { - cov_pk: s.cov_pk.to_vec().into(), - adaptor_sigs: s - .adaptor_sigs - .iter() - .map(|a| a.to_vec().into()) - .collect(), - }) - .collect(), - }) - .ok_or(StdError::generic_err("undelegation info not set"))?, - params_version: d.params_version, - }) - }) + .map(|d| ActiveBtcDelegation::try_from(d).map_err(StdError::generic_err)) .collect::>()?, slashed_del: btc_staking .slashed_del diff --git a/go.work.sum b/go.work.sum index 806449c6..3b265e30 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1022,6 +1022,7 @@ github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20 github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= @@ -1225,6 +1226,7 @@ github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= diff --git a/packages/apis/Cargo.toml b/packages/apis/Cargo.toml index f6300a5b..fcb652be 100644 --- a/packages/apis/Cargo.toml +++ b/packages/apis/Cargo.toml @@ -12,3 +12,4 @@ cosmwasm-schema = { workspace = true } hex = { workspace = true } tendermint-proto = { workspace = true } thiserror = { workspace = true } +babylon-proto = { workspace = true } \ No newline at end of file diff --git a/packages/apis/src/btc_staking_api.rs b/packages/apis/src/btc_staking_api.rs index 03eb3d92..6e641e88 100644 --- a/packages/apis/src/btc_staking_api.rs +++ b/packages/apis/src/btc_staking_api.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + /// BTC staking messages / API /// The definitions here follow the same structure as the equivalent IBC protobuf message types, /// defined in `packages/proto/src/gen/babylon.btcstaking.v1.rs` @@ -43,6 +45,36 @@ pub struct NewFinalityProvider { pub consumer_id: String, } +impl TryFrom<&babylon_proto::babylon::btcstaking::v1::NewFinalityProvider> for NewFinalityProvider { + type Error = String; + + fn try_from( + fp: &babylon_proto::babylon::btcstaking::v1::NewFinalityProvider, + ) -> Result { + Ok(NewFinalityProvider { + description: fp + .description + .as_ref() + .map(|d| FinalityProviderDescription { + moniker: d.moniker.clone(), + identity: d.identity.clone(), + website: d.website.clone(), + security_contact: d.security_contact.clone(), + details: d.details.clone(), + }), + commission: Decimal::from_str(&fp.commission) + .map_err(|e| format!("Failed to parse commission: {}", e))?, + addr: fp.addr.clone(), + btc_pk_hex: fp.btc_pk_hex.clone(), + pop: fp.pop.as_ref().map(|pop| ProofOfPossessionBtc { + btc_sig_type: pop.btc_sig_type, + btc_sig: pop.btc_sig.to_vec().into(), + }), + consumer_id: fp.consumer_id.clone(), + }) + } +} + #[cw_serde] pub struct FinalityProvider { /// description defines the description terms for the finality provider @@ -201,6 +233,80 @@ pub struct ActiveBtcDelegation { pub params_version: u32, } +impl TryFrom<&babylon_proto::babylon::btcstaking::v1::ActiveBtcDelegation> for ActiveBtcDelegation { + type Error = String; + + fn try_from( + d: &babylon_proto::babylon::btcstaking::v1::ActiveBtcDelegation, + ) -> Result { + let delegator_unbonding_info = if let Some(info) = d + .undelegation_info + .clone() + .unwrap() + .delegator_unbonding_info + { + Some(DelegatorUnbondingInfo { + spend_stake_tx: Binary::new(info.spend_stake_tx.to_vec()), + }) + } else { + None + }; + + Ok(ActiveBtcDelegation { + staker_addr: d.staker_addr.clone(), + btc_pk_hex: d.btc_pk_hex.clone(), + fp_btc_pk_list: d.fp_btc_pk_list.clone(), + start_height: d.start_height, + end_height: d.end_height, + total_sat: d.total_sat, + staking_tx: d.staking_tx.to_vec().into(), + slashing_tx: d.slashing_tx.to_vec().into(), + delegator_slashing_sig: d.delegator_slashing_sig.to_vec().into(), + covenant_sigs: d + .covenant_sigs + .iter() + .map(|s| CovenantAdaptorSignatures { + cov_pk: s.cov_pk.to_vec().into(), + adaptor_sigs: s.adaptor_sigs.iter().map(|a| a.to_vec().into()).collect(), + }) + .collect(), + staking_output_idx: d.staking_output_idx, + unbonding_time: d.unbonding_time, + undelegation_info: d + .undelegation_info + .as_ref() + .map(|ui| BtcUndelegationInfo { + unbonding_tx: ui.unbonding_tx.to_vec().into(), + delegator_unbonding_info: delegator_unbonding_info, + covenant_unbonding_sig_list: ui + .covenant_unbonding_sig_list + .iter() + .map(|s| SignatureInfo { + pk: s.pk.to_vec().into(), + sig: s.sig.to_vec().into(), + }) + .collect(), + slashing_tx: ui.slashing_tx.to_vec().into(), + delegator_slashing_sig: ui.delegator_slashing_sig.to_vec().into(), + covenant_slashing_sigs: ui + .covenant_slashing_sigs + .iter() + .map(|s| CovenantAdaptorSignatures { + cov_pk: s.cov_pk.to_vec().into(), + adaptor_sigs: s + .adaptor_sigs + .iter() + .map(|a| a.to_vec().into()) + .collect(), + }) + .collect(), + }) + .ok_or("undelegation info not set")?, + params_version: d.params_version, + }) + } +} + /// CovenantAdaptorSignatures is a list adaptor signatures signed by the /// covenant with different finality provider's public keys as encryption keys #[cw_serde]