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: ETH broker level screening support #5663

Draft
wants to merge 17 commits into
base: release/1.7
Choose a base branch
from
Draft
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: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/bin/chainflip-broker-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["Chainflip team <https://github.com/chainflip-io>"]
name = "chainflip-broker-api"
version = "1.7.9"
version = "1.7.10"
edition = "2021"

[package.metadata.deb]
Expand Down
13 changes: 13 additions & 0 deletions api/bin/chainflip-broker-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ pub trait Rpc {
query: GetOpenDepositChannelsQuery,
) -> RpcResult<ChainAccounts>;

#[method(name = "all_open_deposit_channels", aliases = ["broker_allOpenDepositChannels"])]
async fn all_open_deposit_channels(&self) -> RpcResult<Vec<(AccountId32, ChainAccounts)>>;

#[subscription(name = "subscribe_transaction_screening_events", item = BlockUpdate<TransactionScreeningEvents>)]
async fn subscribe_transaction_screening_events(&self) -> SubscriptionResult;
}
Expand Down Expand Up @@ -202,6 +205,16 @@ impl RpcServer for RpcServerImpl {
.map_err(BrokerApiError::ClientError)
}

async fn all_open_deposit_channels(&self) -> RpcResult<Vec<(AccountId32, ChainAccounts)>> {
self.api
.state_chain_client
.base_rpc_client
.raw_rpc_client
.cf_all_open_deposit_channels(None)
.await
.map_err(BrokerApiError::ClientError)
}

async fn subscribe_transaction_screening_events(
&self,
pending_sink: PendingSubscriptionSink,
Expand Down
2 changes: 1 addition & 1 deletion api/bin/chainflip-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ authors = ["Chainflip team <https://github.com/chainflip-io>"]
edition = "2021"
build = "build.rs"
name = "chainflip-cli"
version = "1.7.9"
version = "1.7.10"

[lints]
workspace = true
Expand Down
2 changes: 1 addition & 1 deletion api/bin/chainflip-lp-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["Chainflip team <https://github.com/chainflip-io>"]
name = "chainflip-lp-api"
version = "1.7.9"
version = "1.7.10"
edition = "2021"

[package.metadata.deb]
Expand Down
2 changes: 1 addition & 1 deletion api/lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "chainflip-api"
version = "1.7.9"
version = "1.7.10"
edition = "2021"

[lints]
Expand Down
8 changes: 8 additions & 0 deletions api/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ pub type TransactionInIdFor<C> = <<C as Chain>::ChainCrypto as ChainCrypto>::Tra
#[derive(Serialize, Deserialize)]
pub enum TransactionInId {
Bitcoin(TransactionInIdFor<cf_chains::Bitcoin>),
Ethereum(TransactionInIdFor<cf_chains::Ethereum>),
// other variants reserved for other chains.
}

Expand All @@ -576,6 +577,13 @@ pub trait DepositMonitorApi:
),
)
.await,
TransactionInId::Ethereum(tx_id) =>
self.simple_submission_with_dry_run(
state_chain_runtime::RuntimeCall::EthereumIngressEgress(
pallet_cf_ingress_egress::Call::mark_transaction_for_rejection { tx_id },
),
)
.await,
}
}
}
Expand Down
98 changes: 90 additions & 8 deletions bouncer/tests/broker_level_screening.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import {
sleep,
handleSubstrateError,
brokerMutex,
amountToFineAmount,
assetDecimals,
} from '../shared/utils';
import { getChainflipApi, observeEvent } from '../shared/utils/substrate';
import Keyring from '../polkadot/keyring';
import { requestNewSwap } from '../shared/perform_swap';
import { FillOrKillParamsX128 } from '../shared/new_swap';
import { getBtcBalance } from '../shared/get_btc_balance';
import { signAndSendTxEvm } from '../shared/send_evm';
import { getBalance } from '../shared/get_balance';

const keyring = new Keyring({ type: 'sr25519' });
const broker = keyring.createFromUri('//BROKER_1');
Expand Down Expand Up @@ -59,13 +63,24 @@ async function newAssetAddress(asset: InternalAsset, seed = null): Promise<strin
* @param txId - The txId as a byte array in 'unreversed' order - which
* is reverse of how it's normally displayed in bitcoin block explorers.
*/
async function markTxForRejection(txId: number[]) {
async function markTxForRejection(txId: number[], chain: string) {
await using chainflip = await getChainflipApi();
return brokerMutex.runExclusive(async () =>
chainflip.tx.bitcoinIngressEgress
.markTransactionForRejection(txId)
.signAndSend(broker, { nonce: -1 }, handleSubstrateError(chainflip)),
);
switch (chain) {
case 'Bitcoin':
return brokerMutex.runExclusive(async () =>
chainflip.tx.bitcoinIngressEgress
.markTransactionForRejection(txId)
.signAndSend(broker, { nonce: -1 }, handleSubstrateError(chainflip)),
);
case 'Ethereum':
return brokerMutex.runExclusive(async () =>
chainflip.tx.ethereumIngressEgress
.markTransactionForRejection(txId)
.signAndSend(broker, { nonce: -1 }, handleSubstrateError(chainflip)),
);
default:
throw new Error(`Unsupported chain: ${chain}`);
}
}

/**
Expand Down Expand Up @@ -130,22 +145,84 @@ async function brokerLevelScreeningTestScenario(
// Note: The bitcoin core js lib returns the txId in reverse order.
// On chain we expect the txId to be in the correct order (like the Bitcoin internal representation).
// Because of this we need to reverse the txId before marking it for rejection.
await markTxForRejection(hexStringToBytesArray(txId).reverse());
await markTxForRejection(hexStringToBytesArray(txId).reverse(), 'Bitcoin');
await sleep(stopBlockProductionFor);
if (stopBlockProductionFor > 0) {
pauseBtcBlockProduction(false);
}
return Promise.resolve(swapParams.channelId.toString());
}

async function testBrokerLevelScreeningEthereum() {
testBrokerLevelScreening.log('Testing broker level screening with ethereum...');
const MAX_RETRIES = 30;

const destinationAddressForBtc = await newAssetAddress('Btc');
const ethereumRefundAddress = await newAssetAddress('Eth');

const refundParameters: FillOrKillParamsX128 = {
retryDurationBlocks: 0,
refundAddress: ethereumRefundAddress,
minPriceX128: '0',
};

const swapParams = await requestNewSwap(
'Eth',
'Btc',
destinationAddressForBtc,
'brokerLevelScreeningTestEth',
undefined,
0,
true,
0,
refundParameters,
);

const weiAmount = amountToFineAmount('0.002', assetDecimals('Eth'));

const receipt = await signAndSendTxEvm(
'Ethereum',
swapParams.depositAddress,
weiAmount,
undefined,
undefined,
true,
);

const txId = hexStringToBytesArray(receipt.transactionHash);

await markTxForRejection(txId, 'Ethereum');

await observeEvent('ethereumIngressEgress:TransactionRejectedByBroker').event;

let receivedRefund = false;

for (let i = 0; i < MAX_RETRIES; i++) {
const refundBalance = await getBalance('Eth', ethereumRefundAddress);
if (refundBalance !== '0') {
receivedRefund = true;
break;
}
await sleep(1000);
}

if (!receivedRefund) {
throw new Error(
`Didn't receive funds refund to address ${ethereumRefundAddress} within timeout!`,
);
}

testBrokerLevelScreening.log(`Marked transaction was rejected and refunded 👍.`);
}

// -- Test suite for broker level screening --
//
// In this tests we are interested in the following scenarios:
//
// 1. No boost and early tx report -> tx is reported early and the swap is refunded.
// 2. Boost and early tx report -> tx is reported early and the swap is refunded.
// 3. Boost and late tx report -> tx is reported late and the swap is not refunded.
async function main() {
async function testBrokerLevelScreeningBitcoin() {
const MILLI_SECS_PER_BLOCK = 6000;
const BLOCKS_TO_WAIT = 2;

Expand Down Expand Up @@ -205,3 +282,8 @@ async function main() {

testBrokerLevelScreening.log(`Swap was executed and transaction was not refunded 👍.`);
}

async function main() {
await testBrokerLevelScreeningBitcoin();
await testBrokerLevelScreeningEthereum();
}
4 changes: 2 additions & 2 deletions engine-dylib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ authors = ["Chainflip team <https://github.com/chainflip-io>"]
build = "build.rs"
edition = "2021"
name = "cf-engine-dylib"
version = "1.7.9"
version = "1.7.10"

[lib]
crate-type = ["cdylib"]
name = "chainflip_engine_v1_7_9"
name = "chainflip_engine_v1_7_10"
path = "src/lib.rs"

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion engine-proc-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
name = "engine-proc-macros"
# The version here is the version that will be used for the generated code, and therefore will be the
# suffix of the generated engine entrypoint. TODO: Fix this.
version = "1.7.9"
version = "1.7.10"

[lib]
proc-macro = true
Expand Down
6 changes: 3 additions & 3 deletions engine-runner-bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "engine-runner"
description = "The central runner for the chainflip engine, it requires two shared library versions to run."
# NB: When updating this version, you must update the debian assets appropriately too.
version = "1.7.9"
version = "1.7.10"
authors = ["Chainflip team <https://github.com/chainflip-io>"]
build = "build.rs"
edition = "2021"
Expand All @@ -22,10 +22,10 @@ assets = [
# to specify this. We do this in the `chainflip-engine.service` files, so the user does not need to set it
# manually.
[
"target/release/libchainflip_engine_v1_7_9.so",
"target/release/libchainflip_engine_v1_7_10.so",
# This is the path where the engine dylib is searched for on linux.
# As set in the build.rs file.
"usr/lib/chainflip-engine/libchainflip_engine_v1_7_9.so",
"usr/lib/chainflip-engine/libchainflip_engine_v1_7_10.so",
"755",
],
# The old version gets put into target/release by the package github actions workflow.
Expand Down
2 changes: 1 addition & 1 deletion engine-runner-bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod old {
}

mod new {
#[engine_proc_macros::link_engine_library_version("1.7.9")]
#[engine_proc_macros::link_engine_library_version("1.7.10")]
extern "C" {
fn cfe_entrypoint(
c_args: engine_upgrade_utils::CStrArray,
Expand Down
2 changes: 1 addition & 1 deletion engine-upgrade-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub mod build_helpers;
// relevant crates.
// Should also check that the compatibility function below `args_compatible_with_old` is correct.
pub const OLD_VERSION: &str = "1.6.8";
pub const NEW_VERSION: &str = "1.7.9";
pub const NEW_VERSION: &str = "1.7.10";

pub const ENGINE_LIB_PREFIX: &str = "chainflip_engine_v";
pub const ENGINE_ENTRYPOINT_PREFIX: &str = "cfe_entrypoint_v";
Expand Down
2 changes: 1 addition & 1 deletion engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ authors = ["Chainflip team <https://github.com/chainflip-io>"]
build = "build.rs"
edition = "2021"
name = "chainflip-engine"
version = "1.7.9"
version = "1.7.10"

[lib]
crate-type = ["lib"]
Expand Down
Loading
Loading