Skip to content

Commit

Permalink
feat: Add private channel address to account info rpc (#5489)
Browse files Browse the repository at this point in the history
* feature: Added channel address to cf-account-info

* refactor: derive address from channel id

* refactor: renamed channel_address to deposit_address

* chore: renamed deposit_address -> btc_vault_deposit_address

* chore: moved btc address derivation to own function

* chore: improved comment

* chore: refactored cf_broker_info
  • Loading branch information
Janislav authored Dec 12, 2024
1 parent 24cb41c commit 6890461
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 37 deletions.
25 changes: 16 additions & 9 deletions state-chain/custom-rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ pub enum RpcAccountInfo {
Broker {
flip_balance: NumberOrHex,
earned_fees: any::AssetMap<NumberOrHex>,
btc_vault_deposit_address: Option<String>,
},
LiquidityProvider {
balances: any::AssetMap<NumberOrHex>,
Expand Down Expand Up @@ -289,9 +290,10 @@ impl RpcAccountInfo {
Self::Unregistered { flip_balance: balance.into() }
}

fn broker(balance: u128, broker_info: BrokerInfo) -> Self {
fn broker(broker_info: BrokerInfo, balance: u128) -> Self {
Self::Broker {
flip_balance: balance.into(),
btc_vault_deposit_address: broker_info.btc_vault_deposit_address,
earned_fees: cf_chains::assets::any::AssetMap::from_iter_or_default(
broker_info
.earned_fees
Expand Down Expand Up @@ -1388,7 +1390,7 @@ where
AccountRole::Broker => {
let info = api.cf_broker_info(hash, account_id)?;

RpcAccountInfo::broker(balance, info)
RpcAccountInfo::broker(info, balance)
},
AccountRole::LiquidityProvider => {
let info = api.cf_liquidity_provider_info(hash, account_id)?;
Expand Down Expand Up @@ -2145,7 +2147,7 @@ mod test {
use std::collections::BTreeSet;

use super::*;
use cf_chains::assets::sol;
use cf_chains::{assets::sol, btc::ScriptPubkey};
use cf_primitives::{
chains::assets::{any, arb, btc, dot, eth},
FLIPPERINOS_PER_FLIP,
Expand All @@ -2170,8 +2172,8 @@ mod test {

#[test]
fn test_broker_serialization() {
insta::assert_snapshot!(serde_json::to_value(RpcAccountInfo::broker(
0,
use cf_chains::btc::BitcoinNetwork;
let broker = RpcAccountInfo::broker(
BrokerInfo {
earned_fees: vec![
(Asset::Eth, 0),
Expand All @@ -2184,10 +2186,15 @@ mod test {
(Asset::ArbUsdc, 0),
(Asset::Sol, 0),
(Asset::SolUsdc, 0),
]
}
))
.unwrap());
],
btc_vault_deposit_address: Some(
ScriptPubkey::Taproot([1u8; 32]).to_address(&BitcoinNetwork::Testnet),
),
},
0,
);

insta::assert_snapshot!(serde_json::to_value(broker).unwrap());
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: state-chain/custom-rpc/src/lib.rs
expression: "serde_json::to_value(RpcAccountInfo::broker(0,\n BrokerInfo {\n earned_fees: vec![(Asset::Eth, 0), (Asset::Btc, 0),\n (Asset::Flip, 1000000000000000000), (Asset::Usdc, 0),\n (Asset::Usdt, 0), (Asset::Dot, 0), (Asset::ArbEth, 0),\n (Asset::ArbUsdc, 0), (Asset::Sol, 0), (Asset::SolUsdc, 0),],\n })).unwrap()"
expression: "serde_json::to_value(broker).unwrap()"
snapshot_kind: text
---
{"earned_fees":{"Arbitrum":{"ETH":"0x0","USDC":"0x0"},"Bitcoin":{"BTC":"0x0"},"Ethereum":{"ETH":"0x0","FLIP":"0xde0b6b3a7640000","USDC":"0x0","USDT":"0x0"},"Polkadot":{"DOT":"0x0"},"Solana":{"SOL":"0x0","USDC":"0x0"}},"flip_balance":"0x0","role":"broker"}
{"btc_vault_deposit_address":"tb1pqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsn60vlk","earned_fees":{"Arbitrum":{"ETH":"0x0","USDC":"0x0"},"Bitcoin":{"BTC":"0x0"},"Ethereum":{"ETH":"0x0","FLIP":"0xde0b6b3a7640000","USDC":"0x0","USDT":"0x0"},"Polkadot":{"DOT":"0x0"},"Solana":{"SOL":"0x0","USDC":"0x0"}},"flip_balance":"0x0","role":"broker"}
18 changes: 17 additions & 1 deletion state-chain/runtime/src/chainflip/address_derivation/btc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::AddressDerivation;
use crate::BitcoinThresholdSigner;
use crate::{BitcoinThresholdSigner, Environment, EpochKey, String};
use cf_chains::{
address::{AddressDerivationApi, AddressDerivationError},
btc::deposit_address::DepositAddress,
Expand Down Expand Up @@ -44,6 +44,22 @@ impl AddressDerivationApi<Bitcoin> for AddressDerivation {
}
}

/// ONLY FOR USE IN RPC CALLS.
///
/// Derives the BTC vault deposit address from the private channel id.
/// Note: This function will **panic** if the private channel id is out of bounds or if there is
/// no active epoch key for Bitcoin.
pub(crate) fn derive_btc_vault_deposit_address(private_channel_id: u64) -> String {
let EpochKey { key, .. } = BitcoinThresholdSigner::active_epoch_key()
.expect("We should always have a key for the current epoch.");
DepositAddress::new(
key.current,
private_channel_id.try_into().expect("Private channel id out of bounds."),
)
.script_pubkey()
.to_address(&Environment::network_environment().into())
}

#[test]
fn test_address_generation() {
use crate::Runtime;
Expand Down
35 changes: 10 additions & 25 deletions state-chain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod test_runner;
mod weights;
use crate::{
chainflip::{
address_derivation::btc::derive_btc_vault_deposit_address,
calculate_account_apy,
solana_elections::{
SolanaChainTrackingProvider, SolanaEgressWitnessingTrigger, SolanaIngress,
Expand Down Expand Up @@ -79,7 +80,7 @@ use pallet_cf_pools::{
AskBidMap, AssetPair, HistoricalEarnedFees, OrderId, PoolLiquidity, PoolOrderbook, PoolPriceV1,
PoolPriceV2, UnidirectionalPoolDepth,
};
use pallet_cf_swapping::{BatchExecutionError, FeeType, Swap};
use pallet_cf_swapping::{BatchExecutionError, BrokerPrivateBtcChannels, FeeType, Swap};
use runtime_apis::ChainAccounts;

use crate::{chainflip::EvmLimit, runtime_apis::TransactionScreeningEvent};
Expand Down Expand Up @@ -1905,11 +1906,13 @@ impl_runtime_apis! {
fn cf_broker_info(
account_id: AccountId,
) -> BrokerInfo {
let earned_fees = Asset::all().map(|asset|
(asset, AssetBalances::get_balance(&account_id, asset))
).collect();

BrokerInfo { earned_fees }
BrokerInfo {
earned_fees: Asset::all().map(|asset|
(asset, AssetBalances::get_balance(&account_id, asset))
).collect(),
btc_vault_deposit_address: BrokerPrivateBtcChannels::<Runtime>::get(&account_id)
.map(derive_btc_vault_deposit_address),
}
}

fn cf_account_role(account_id: AccountId) -> Option<AccountRole> {
Expand Down Expand Up @@ -2177,8 +2180,6 @@ impl_runtime_apis! {
// Encode swap
match ForeignChain::from(source_asset) {
ForeignChain::Bitcoin => {
use cf_chains::btc::deposit_address::DepositAddress;

let private_channel_id =
pallet_cf_swapping::BrokerPrivateBtcChannels::<Runtime>::get(&broker_id)
.ok_or(
Expand Down Expand Up @@ -2221,25 +2222,9 @@ impl_runtime_apis! {
},
};

let EpochKey { key, .. } = BitcoinThresholdSigner::active_epoch_key()
.expect("We should always have a key for the current epoch.");
let deposit_address = DepositAddress::new(
key.current,
private_channel_id.try_into().map_err(
// TODO: Ensure this can't happen.
|_| {
DispatchErrorWithMessage::Other(
"Private channel id out of bounds.".into(),
)
},
)?,
)
.script_pubkey()
.to_address(&Environment::network_environment().into());

Ok(VaultSwapDetails::Bitcoin {
nulldata_payload: encode_swap_params_in_nulldata_payload(params),
deposit_address,
deposit_address: derive_btc_vault_deposit_address(private_channel_id),
})
},
_ => Err(pallet_cf_swapping::Error::<Runtime>::UnsupportedSourceAsset.into()),
Expand Down
1 change: 1 addition & 0 deletions state-chain/runtime/src/runtime_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ pub struct LiquidityProviderInfo {
#[derive(Encode, Decode, Eq, PartialEq, TypeInfo)]
pub struct BrokerInfo {
pub earned_fees: Vec<(Asset, AssetAmount)>,
pub btc_vault_deposit_address: Option<String>,
}

/// Struct that represents the estimated output of a Swap.
Expand Down

0 comments on commit 6890461

Please sign in to comment.