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: Btc vault swap bouncer test can open a private channel #5410

Merged
merged 3 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 17 additions & 3 deletions api/bin/chainflip-broker-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use chainflip_api::{
DcaParameters,
},
settings::StateChain,
AccountId32, AddressString, BlockUpdate, BrokerApi, ChainApi, DepositMonitorApi, OperatorApi,
RefundParameters, SignedExtrinsicApi, StateChainApi, SwapDepositAddress, TransactionInId,
WithdrawFeesDetail,
AccountId32, AddressString, BlockUpdate, BrokerApi, ChainApi, ChannelId, DepositMonitorApi,
OperatorApi, RefundParameters, SignedExtrinsicApi, StateChainApi, SwapDepositAddress,
TransactionInId, WithdrawFeesDetail,
};
use clap::Parser;
use custom_rpc::CustomApiClient;
Expand Down Expand Up @@ -128,6 +128,12 @@ pub trait Rpc {

#[subscription(name = "subscribe_tainted_transaction_events", item = BlockUpdate<TaintedTransactionEvents>)]
async fn subscribe_tainted_transaction_events(&self) -> SubscriptionResult;

#[method(name = "open_private_btc_channel", aliases = ["broker_openPrivateBtcChannel"])]
async fn open_private_btc_channel(&self) -> RpcResult<ChannelId>;

#[method(name = "close_private_btc_channel", aliases = ["broker_closePrivateBtcChannel"])]
async fn close_private_btc_channel(&self) -> RpcResult<ChannelId>;
}

pub struct RpcServerImpl {
Expand Down Expand Up @@ -298,6 +304,14 @@ impl RpcServer for RpcServerImpl {
});
Ok(())
}

async fn open_private_btc_channel(&self) -> RpcResult<ChannelId> {
Ok(self.api.broker_api().open_private_btc_channel().await?)
}

async fn close_private_btc_channel(&self) -> RpcResult<ChannelId> {
Ok(self.api.broker_api().close_private_btc_channel().await?)
}
}

#[derive(Parser, Debug, Clone, Default)]
Expand Down
50 changes: 50 additions & 0 deletions api/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,56 @@ pub trait BrokerApi: SignedExtrinsicApi + StorageApi + Sized + Send + Sync + 'st
self.simple_submission_with_dry_run(pallet_cf_swapping::Call::deregister_as_broker {})
.await
}

async fn open_private_btc_channel(&self) -> Result<ChannelId> {
let (_, events, ..) = self
.submit_signed_extrinsic_with_dry_run(RuntimeCall::from(
pallet_cf_swapping::Call::open_private_btc_channel {},
))
.await?
.until_in_block()
.await?;

if let Some(state_chain_runtime::RuntimeEvent::Swapping(
pallet_cf_swapping::Event::PrivateBrokerChannelOpened { channel_id, .. },
)) = events.iter().find(|event| {
matches!(
event,
state_chain_runtime::RuntimeEvent::Swapping(
pallet_cf_swapping::Event::PrivateBrokerChannelOpened { .. }
)
)
Comment on lines +487 to +495
Copy link
Contributor

Choose a reason for hiding this comment

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

we use this pattern a lot here, seems like it should be a util

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can't see a good way to make it a util. Same problem we hit in the LP api.

Copy link
Contributor

Choose a reason for hiding this comment

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

}) {
Ok(*channel_id)
} else {
bail!("No PrivateBrokerChannelOpened event was found");
}
}

async fn close_private_btc_channel(&self) -> Result<ChannelId> {
let (_, events, ..) = self
.submit_signed_extrinsic_with_dry_run(RuntimeCall::from(
pallet_cf_swapping::Call::close_private_btc_channel {},
))
.await?
.until_in_block()
.await?;

if let Some(state_chain_runtime::RuntimeEvent::Swapping(
pallet_cf_swapping::Event::PrivateBrokerChannelClosed { channel_id, .. },
)) = events.iter().find(|event| {
matches!(
event,
state_chain_runtime::RuntimeEvent::Swapping(
pallet_cf_swapping::Event::PrivateBrokerChannelClosed { .. }
)
)
}) {
Ok(*channel_id)
} else {
bail!("No PrivateBrokerChannelClosed event was found");
}
}
}

#[async_trait]
Expand Down
2 changes: 2 additions & 0 deletions bouncer/tests/all_concurrent_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { testAllSwaps } from './all_swaps';
import { depositChannelCreation } from './request_swap_deposit_address_with_affiliates';
import { testDCASwaps } from './DCA_test';
import { testBrokerLevelScreening } from './broker_level_screening';
import { testBtcVaultSwap } from './btc_vault_swap';

async function runAllConcurrentTests() {
// Specify the number of nodes via providing an argument to this script.
Expand Down Expand Up @@ -46,6 +47,7 @@ async function runAllConcurrentTests() {
testDCASwaps.run(),
testCancelOrdersBatch.run(),
depositChannelCreation.run(),
testBtcVaultSwap.run(),
];

// Tests that only work if there is more than one node
Expand Down
21 changes: 20 additions & 1 deletion bouncer/tests/btc_vault_swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from '../shared/utils';
import { getChainflipApi, observeEvent } from '../shared/utils/substrate';
import { getBalance } from '../shared/get_balance';
import { jsonRpc } from '../shared/json_rpc';

/* eslint-disable @typescript-eslint/no-use-before-define */
export const testBtcVaultSwap = new ExecutableTest('Btc-Vault-Swap', main, 100);
Expand Down Expand Up @@ -51,6 +52,7 @@ async function buildAndSendBtcVaultSwap(

assert.strictEqual(vaultSwapDetails.chain, 'Bitcoin');
testBtcVaultSwap.debugLog('nulldata_utxo:', vaultSwapDetails.nulldata_utxo);
testBtcVaultSwap.debugLog('deposit_address:', vaultSwapDetails.deposit_address);

// The `createRawTransaction` function will add the op codes, so we have to remove them here.
const nullDataWithoutOpCodes = vaultSwapDetails.nulldata_utxo.replace('0x', '').substring(4);
Expand Down Expand Up @@ -112,8 +114,25 @@ async function testVaultSwap(depositAmountBtc: number, brokerUri: string, destin
testBtcVaultSwap.log(`Balance increased, Vault Swap Complete`);
}

async function openPrivateBtcChannel(brokerUri: string) {
// TODO: Use chainflip SDK instead so we can support any broker uri
assert.strictEqual(brokerUri, '//BROKER_1', 'Support for other brokers is not implemented');

// TODO: use chainflip SDK to check if the channel is already open
try {
await jsonRpc('broker_open_private_btc_channel', [], 'http://127.0.0.1:10997');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does the jsonRpc util not have a constant (or similar) to avoid having to explicitly pass the api url/port??

Copy link
Contributor Author

@j4m1ef0rd j4m1ef0rd Nov 13, 2024

Choose a reason for hiding this comment

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

Didn't seem worth adding a broker constant when the code will be replaced later by the chainflip SDK.
Could add a brokerRPC function, just like the LP does. Would be useful in the future.

testBtcVaultSwap.log('Private Btc channel opened');
} catch (error) {
// We expect this to fail if the channel already exists from a previous run
testBtcVaultSwap.debugLog('Failed to open private Btc channel', error);
kylezs marked this conversation as resolved.
Show resolved Hide resolved
}
}

async function main() {
const btcDepositAmount = 0.1;
const brokerUri = '//BROKER_1';

await openPrivateBtcChannel(brokerUri);

await testVaultSwap(btcDepositAmount, '//BROKER_1', 'Flip');
await testVaultSwap(btcDepositAmount, brokerUri, 'Flip');
}
33 changes: 0 additions & 33 deletions engine/src/state_chain_observer/client/base_rpc_api.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use async_trait::async_trait;
use cf_primitives::BlockNumber;
use jsonrpsee::core::client::{ClientT, Subscription, SubscriptionClientT};
use sc_transaction_pool_api::TransactionStatus;
use sp_core::{
Expand Down Expand Up @@ -168,19 +167,6 @@ pub trait BaseRpcApi {
params: Option<Box<RawValue>>,
unsub: &str,
) -> RpcResult<Subscription<Box<RawValue>>>;

async fn validate_refund_params(
&self,
retry_duration: BlockNumber,
block_hash: Option<state_chain_runtime::Hash>,
) -> RpcResult<()>;

async fn validate_dca_params(
&self,
number_of_chunks: u32,
chunk_interval: u32,
block_hash: Option<state_chain_runtime::Hash>,
) -> RpcResult<()>;
}

pub struct BaseRpcClient<RawRpcClient> {
Expand Down Expand Up @@ -318,25 +304,6 @@ impl<RawRpcClient: RawRpcApi + Send + Sync> BaseRpcApi for BaseRpcClient<RawRpcC
) -> RpcResult<Subscription<Box<RawValue>>> {
self.raw_rpc_client.subscribe(sub, Params(params), unsub).await
}

async fn validate_refund_params(
&self,
retry_duration: BlockNumber,
block_hash: Option<state_chain_runtime::Hash>,
) -> RpcResult<()> {
self.raw_rpc_client.cf_validate_refund_params(retry_duration, block_hash).await
}

async fn validate_dca_params(
&self,
number_of_chunks: u32,
chunk_interval: u32,
block_hash: Option<state_chain_runtime::Hash>,
) -> RpcResult<()> {
self.raw_rpc_client
.cf_validate_dca_params(number_of_chunks, chunk_interval, block_hash)
.await
}
}

struct Params(Option<Box<RawValue>>);
Expand Down
3 changes: 1 addition & 2 deletions state-chain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2132,8 +2132,7 @@ impl_runtime_apis! {
Ok(())
}
})
.map_err(|()| pallet_cf_swapping::Error::<Runtime>::InvalidDestinationAddress)?;

.map_err(|_| pallet_cf_swapping::Error::<Runtime>::InvalidDestinationAddress)?;

// Encode swap
match ForeignChain::from(source_asset) {
Expand Down
Loading