Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into test/authority-rotati…
Browse files Browse the repository at this point in the history
…on-integration

* origin/main:
  Added CFE setting for logging span lifecycles (#3936)
  fix: only burn flip if non zero (#3932)
  Fix: Correct Select Median Implementation (#3934)
  fix: independent witnessing startup (#3913)
  🍒 cherry-pick: changes in release for CI and chainspec (#3933)
  refactor: Re-arrange Chains traits for better composability (#3912)
  fix: log error when we try to transfer *more* than we have fetched (#3930)
  chore: add checks and increase timeout (#3928)
  Add `bind_redeem_address` to CLI (#3908)
  🍒 cherry-pick: add missing prod dockerfiles (#3926)
  chore: skip localnet specific tests in devnet 🤫 (#3919)
  fix: broadcast success should be witnessable after a rotation (#3921)

# Conflicts:
#	state-chain/cf-integration-tests/src/network.rs
  • Loading branch information
syan095 committed Sep 5, 2023
2 parents 9733a90 + b195c43 commit a872d75
Show file tree
Hide file tree
Showing 121 changed files with 5,872 additions and 4,296 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/_02_retrieve-bins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
uses: dawidd6/action-download-artifact@v2
with:
workflow: release-sisyphos.yml
name: chainflip-backend-runtime-ubuntu-${{ matrix.ubuntu_version }}
name: chainflip-node-runtime-ubuntu-${{ matrix.ubuntu_version }}
branch: release/${{ env.MAJOR_MINOR }}
github_token: ${{ secrets.CF_GITHUB_BOT_TOKEN }}
search_artifacts: true
Expand All @@ -40,6 +40,7 @@ jobs:
- name: Check Downloaded Binaries Version Matches Tag 🕵️‍♂️
shell: bash
run: |
chmod +x ./chainflip-*
# TODO: Make this look nicer once we have --version flag in all binaries
./ci/scripts/check_binary_version.sh ./chainflip-node ${{ github.ref_name }}
./ci/scripts/check_binary_version.sh ./chainflip-engine ${{ github.ref_name }}
Expand All @@ -51,6 +52,7 @@ jobs:
name: chainflip-backend-bin-ubuntu-${{ matrix.ubuntu_version }}
path: |
chainflip-broker-api
chainflip-btc-deposit-tracker
chainflip-cli
chainflip-engine
chainflip-lp-api
Expand All @@ -62,4 +64,4 @@ jobs:
with:
name: chainflip-node-runtime-ubuntu-${{ matrix.ubuntu_version }}
path: |
./state_chain_runtime*.wasm
./state_chain_runtime*.wasm
2 changes: 1 addition & 1 deletion .github/workflows/release-sisyphos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ jobs:
with:
version: "sisyphos/"
environment: dev
secrets: inherit
secrets: inherit
92 changes: 71 additions & 21 deletions api/bin/chainflip-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![feature(absolute_path)]
use anyhow::{Context, Result};
use anyhow::{bail, Context, Result};
use clap::Parser;
use futures::FutureExt;
use serde::Serialize;
Expand All @@ -10,8 +10,8 @@ use crate::settings::{
LiquidityProviderSubcommands,
};
use api::{
lp::LpApi, primitives::RedemptionAmount, AccountId32, BrokerApi, GovernanceApi, KeyPair,
OperatorApi, StateChainApi, SwapDepositAddress,
lp::LpApi, primitives::RedemptionAmount, queries::QueryApi, AccountId32, BrokerApi,
GovernanceApi, KeyPair, OperatorApi, SignedExtrinsicApi, StateChainApi, SwapDepositAddress,
};
use cf_chains::eth::Address as EthereumAddress;
use chainflip_api as api;
Expand Down Expand Up @@ -91,7 +91,13 @@ async fn run_cli() -> Result<()> {
println!("Emergency Withdrawal Address registered. Tx hash: {tx_hash}");
},
Redeem { amount, eth_address, executor } => {
request_redemption(api.operator_api(), amount, &eth_address, executor).await?;
request_redemption(api, amount, eth_address, executor).await?;
},
BindRedeemAddress { eth_address } => {
bind_redeem_address(api.operator_api(), &eth_address).await?;
},
GetBoundRedeemAddress {} => {
get_bound_redeem_address(api.query_api()).await?;
},
RegisterAccountRole { role } => {
println!(
Expand Down Expand Up @@ -129,36 +135,51 @@ async fn run_cli() -> Result<()> {
}

async fn request_redemption(
api: Arc<impl OperatorApi + Sync>,
api: StateChainApi,
amount: Option<f64>,
eth_address: &str,
supplied_address: Option<String>,
executor: Option<cf_chains::eth::Address>,
) -> Result<()> {
// Sanitise data
let eth_address = EthereumAddress::from_slice(
clean_hex_address::<[u8; 20]>(eth_address)
.context("Invalid ETH address supplied")?
.as_slice(),
);
let supplied_address = if let Some(address) = supplied_address {
Some(EthereumAddress::from(
clean_hex_address::<[u8; 20]>(&address).context("Invalid ETH address supplied")?,
))
} else {
None
};

let account_id = api.state_chain_client.account_id();
let bound_address =
api.query_api().get_bound_redeem_address(None, Some(account_id.clone())).await?;

let redeem_address = match (supplied_address, bound_address) {
(Some(supplied_address), Some(bound_address)) =>
if supplied_address != bound_address {
bail!("Supplied ETH address `{supplied_address:?}` does not match bound address for this account `{bound_address:?}`.");
} else {
bound_address
},
(Some(supplied_address), None) => supplied_address,
(None, Some(bound_address)) => {
println!("Using bound redeem address.");
bound_address
},
(None, None) =>
bail!("No redeem address supplied and no bound redeem address found for your account {account_id}."),
};

let amount = match amount {
Some(amount_float) => {
let atomic_amount = (amount_float * 10_f64.powi(18)) as u128;

println!(
"Submitting redemption with amount `{}` FLIP (`{}` Flipperinos) to ETH address `0x{}`.",
amount_float,
atomic_amount,
hex::encode(eth_address)
"Submitting redemption with amount `{amount_float}` FLIP (`{atomic_amount}` Flipperinos) to ETH address `{redeem_address:?}`."
);

RedemptionAmount::Exact(atomic_amount)
},
None => {
println!(
"Submitting redemption with MAX amount to ETH address `0x{}`.",
hex::encode(eth_address)
);
println!("Submitting redemption with MAX amount to ETH address `{redeem_address:?}`.");

RedemptionAmount::Max
},
Expand All @@ -168,7 +189,7 @@ async fn request_redemption(
return Ok(())
}

let tx_hash = api.request_redemption(amount, eth_address, executor).await?;
let tx_hash = api.operator_api().request_redemption(amount, redeem_address, executor).await?;

println!(
"Your redemption request has transaction hash: `{tx_hash:#x}`. View your redemption's progress on the funding app."
Expand All @@ -177,6 +198,35 @@ async fn request_redemption(
Ok(())
}

async fn bind_redeem_address(api: Arc<impl OperatorApi + Sync>, eth_address: &str) -> Result<()> {
let eth_address = EthereumAddress::from(
clean_hex_address::<[u8; 20]>(eth_address).context("Invalid ETH address supplied")?,
);

println!(
"Binding your account to a redemption address is irreversible. You will only ever be able to redeem to this address: {eth_address:?}.",
);
if !confirm_submit() {
return Ok(())
}

let tx_hash = api.bind_redeem_address(eth_address).await?;

println!("Account bound to address {eth_address}, transaction hash: `{tx_hash:#x}`.");

Ok(())
}

async fn get_bound_redeem_address(api: QueryApi) -> Result<()> {
if let Some(bound_address) = api.get_bound_redeem_address(None, None).await? {
println!("Your account is bound to redeem address: {bound_address:?}");
} else {
println!("Your account is not bound to any redeem address.");
}

Ok(())
}

fn confirm_submit() -> bool {
use std::{io, io::*};

Expand Down
13 changes: 11 additions & 2 deletions api/bin/chainflip-cli/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,22 @@ pub enum CliCommand {
long = "exact"
)]
amount: Option<f64>,
#[clap(help = "The Ethereum address you wish to redeem your FLIP to")]
eth_address: String,
#[clap(
help = "The Ethereum address you wish to redeem your FLIP to. If not specified, the redeem address bound to your account will be used"
)]
eth_address: Option<String>,
#[clap(
help = "Optional executor. If specified, only this address will be able to execute the redemption."
)]
executor: Option<cf_chains::eth::Address>,
},
#[clap(about = "Restricts your account to only be able to redeem to the specified address")]
BindRedeemAddress {
#[clap(help = "The Ethereum address you wish to bind your account to")]
eth_address: String,
},
#[clap(about = "Shows the redeem address your account is bound to")]
GetBoundRedeemAddress,
#[clap(
about = "Submit an extrinsic to request generation of a redemption certificate (redeeming all available FLIP)"
)]
Expand Down
14 changes: 12 additions & 2 deletions api/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anyhow::{anyhow, bail, Context, Result};
use async_trait::async_trait;
use cf_chains::{
address::EncodedAddress,
eth::{to_ethereum_address, Address as EthereumAddress},
evm::{to_evm_address, Address as EthereumAddress},
CcmChannelMetadata, ForeignChain,
};
use cf_primitives::{AccountRole, Asset, BasisPoints, ChannelId};
Expand Down Expand Up @@ -164,6 +164,16 @@ pub trait OperatorApi: SignedExtrinsicApi + RotateSessionKeysApi + AuctionPhaseA
Ok(tx_hash)
}

async fn bind_redeem_address(&self, address: EthereumAddress) -> Result<H256> {
let (tx_hash, ..) = self
.submit_signed_extrinsic(pallet_cf_funding::Call::bind_redeem_address { address })
.await
.until_finalized()
.await?;

Ok(tx_hash)
}

async fn register_account_role(&self, role: AccountRole) -> Result<H256> {
let call = match role {
AccountRole::Validator =>
Expand Down Expand Up @@ -424,7 +434,7 @@ pub fn generate_ethereum_key(
secret_key: secret_key.serialize().to_vec(),
public_key: public_key.serialize_compressed().to_vec(),
},
to_ethereum_address(public_key),
to_evm_address(public_key),
))
}

Expand Down
18 changes: 18 additions & 0 deletions api/lib/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,24 @@ impl QueryApi {
})
.collect())
}

pub async fn get_bound_redeem_address(
&self,
block_hash: Option<state_chain_runtime::Hash>,
account_id: Option<state_chain_runtime::AccountId>,
) -> Result<Option<EthereumAddress>, anyhow::Error> {
let block_hash =
block_hash.unwrap_or_else(|| self.state_chain_client.latest_finalized_hash());
let account_id = account_id.unwrap_or_else(|| self.state_chain_client.account_id());

Ok(self
.state_chain_client
.storage_map_entry::<pallet_cf_funding::BoundAddress<state_chain_runtime::Runtime>>(
block_hash,
&account_id,
)
.await?)
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
2 changes: 2 additions & 0 deletions bouncer/commands/explorer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env -S pnpm tsx

// Set the node you want to query by setting the `CF_NODE_ENDPOINT` environment variable.
// e.g. CF_NODE_ENDPOINT=wss://perseverance.chainflip.xyz
// Call with a range of blocks to query, like:
// ./explorer.js 1234 1300
// Alternatively, the first argument can be the string "live" to query the latest blocks.
Expand Down
9 changes: 8 additions & 1 deletion bouncer/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,12 @@ set -e
./tests/all_concurrent_tests.ts
./tests/gaslimit_ccm.ts
./tests/rotates_through_btc_swap.ts
./tests/swap_after_temp_disconnecting_chains.ts

if [[ $LOCALNET == false ]]; then
echo "🤫 Skipping tests that require localnet"
else
echo "🚀 Running tests that require localnet"
./tests/swap_after_temp_disconnecting_chains.ts
fi

./tests/multiple_members_governance.ts
5 changes: 4 additions & 1 deletion bouncer/shared/contract_swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ export async function performSwapViaContract(
const receipt = await executeContractSwap(sourceAsset, destAsset, destAddress, messageMetadata);
await observeEvent('swapping:SwapScheduled', api, (event) => {
if ('Vault' in event.data.origin) {
return event.data.origin.Vault.txHash === receipt.transactionHash;
const sourceAssetMatches = sourceAsset === (event.data.sourceAsset.toUpperCase() as Asset);
const destAssetMatches = destAsset === (event.data.destinationAsset.toUpperCase() as Asset);
const txHashMatches = event.data.origin.Vault.txHash === receipt.transactionHash;
return sourceAssetMatches && destAssetMatches && txHashMatches;
}
// Otherwise it was a swap scheduled by requesting a deposit address
return false;
Expand Down
4 changes: 2 additions & 2 deletions bouncer/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ export async function observeBalanceIncrease(
address: string,
oldBalance: string,
): Promise<number> {
for (let i = 0; i < 120; i++) {
for (let i = 0; i < 1200; i++) {
const newBalance = Number(await getBalance(dstCcy as Asset, address));
if (newBalance > Number(oldBalance)) {
return newBalance;
Expand Down Expand Up @@ -338,7 +338,7 @@ export async function observeEVMEvent(
// Get the parameter names of the event
const parameterNames = eventAbi.inputs.map((input) => input.name);

for (let i = 0; i < 120; i++) {
for (let i = 0; i < 1200; i++) {
if (stopObserve()) return undefined;
const currentBlockNumber = await web3.eth.getBlockNumber();
if (currentBlockNumber >= initBlockNumber) {
Expand Down
24 changes: 24 additions & 0 deletions ci/docker/prod/chainflip-btc-deposit-tracker.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM debian:bullseye
ARG BUILD_DATETIME
ARG VCS_REF

LABEL org.opencontainers.image.authors="dev@chainflip.io"
LABEL org.opencontainers.image.vendor="Chainflip Labs GmbH"
LABEL org.opencontainers.image.title="chainflip/chainflip-btc-deposit-tracker"
LABEL org.opencontainers.image.source="https://github.com/chainflip-io/chainflip-backend/blob/${VCS_REF}/ci/docker/chainflip-binaries/prod/chainflip-btc-deposit-tracker.Dockerfile"
LABEL org.opencontainers.image.revision="${VCS_REF}"
LABEL org.opencontainers.image.created="${BUILD_DATETIME}"
LABEL org.opencontainers.image.environment="production"
LABEL org.opencontainers.image.documentation="https://github.com/chainflip-io/chainflip-backend"

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates && \
rm -rf /var/lib/apt/lists/*

COPY chainflip-btc-deposit-tracker /usr/local/bin/chainflip-btc-deposit-tracker

WORKDIR /etc/chainflip

RUN chmod +x /usr/local/bin/chainflip-btc-deposit-tracker

CMD ["/usr/local/bin/chainflip-btc-deposit-tracker"]
22 changes: 22 additions & 0 deletions ci/docker/prod/chainflip-engine-databases.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM debian:bullseye
ARG BUILD_DATETIME
ARG VCS_REF

LABEL org.opencontainers.image.authors="dev@chainflip.io"
LABEL org.opencontainers.image.vendor="Chainflip Labs GmbH"
LABEL org.opencontainers.image.title="chainflip/chainflip-engine"
LABEL org.opencontainers.image.source="https://github.com/chainflip-io/chainflip-backend/blob/${VCS_REF}/ci/docker/chainflip-binaries/prod/chainflip-engine-databases.Dockerfile"
LABEL org.opencontainers.image.revision="${VCS_REF}"
LABEL org.opencontainers.image.created="${BUILD_DATETIME}"
LABEL org.opencontainers.image.environment="production"
LABEL org.opencontainers.image.documentation="https://github.com/chainflip-io/chainflip-backend"

WORKDIR /databases/3-node
COPY ./localnet/init/keyshare/3-node/bashful.db bashful.db
COPY ./localnet/init/keyshare/3-node/doc.db doc.db
COPY ./localnet/init/keyshare/3-node/dopey.db dopey.db

WORKDIR /databases/1-node
COPY ./localnet/init/keyshare/1-node/bashful.db bashful.db

WORKDIR /databases/
2 changes: 1 addition & 1 deletion engine/multisig/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ pub trait ECPoint:
pub trait ChainSigning: 'static + Clone + Send + Sync + Debug + PartialEq {
type CryptoScheme: CryptoScheme;

type Chain: cf_chains::ChainCrypto;
type ChainCrypto: cf_chains::ChainCrypto;

/// Name of the Chain
const NAME: &'static str;
Expand Down
Loading

0 comments on commit a872d75

Please sign in to comment.