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

wait for n block confirmations for evm chains before processing events #284

Merged
merged 3 commits into from
Oct 19, 2022
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
3 changes: 3 additions & 0 deletions crates/relayer-config/src/evm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub struct EvmChainConfig {
/// Websocket Endpoint for long living connections
#[serde(skip_serializing)]
pub ws_endpoint: RpcUrl,
/// Block confirmations
#[serde(skip_serializing)]
pub block_confirmations: u32,
/// Block Explorer for this chain.
///
/// Optional, and only used for printing a clickable links
Expand Down
21 changes: 17 additions & 4 deletions src/events_watcher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use std::ops::Deref;
use std::sync::Arc;
use std::time::Duration;

use crate::context::RelayerContext;
use crate::metric;
use webb::substrate::subxt::client::OfflineClientT;
use webb::{
Expand All @@ -44,7 +45,6 @@ use webb::{
subxt::{self, client::OnlineClientT, ext::sp_runtime::traits::Header},
},
};

use webb_relayer_store::sled::SledQueueKey;
use webb_relayer_store::{
BridgeCommand, BridgeKey, EventHashStore, HistoryStore, ProposalStore,
Expand Down Expand Up @@ -123,18 +123,28 @@ pub trait EventWatcher {
store: Arc<Self::Store>,
contract: Self::Contract,
handlers: Vec<EventHandlerFor<Self>>,
metrics: Arc<metric::Metrics>,
ctx: &RelayerContext,
) -> crate::Result<()> {
let backoff = backoff::backoff::Constant::new(Duration::from_secs(1));
let task = || async {
let step = contract.max_blocks_per_step();
// saves the last time we printed sync progress.
let mut instant = std::time::Instant::now();
let metrics = &ctx.metrics;
let chain_id = client
.get_chainid()
.map_err(Into::into)
.map_err(backoff::Error::transient)
.await?;
let chain_config =
ctx.config.evm.get(&chain_id.to_string()).ok_or_else(|| {
crate::Error::ChainNotFound {
chain_id: chain_id.clone().to_string(),
}
})?;
// no of blocks confirmation required before processing it
let block_confirmations: U64 =
chain_config.block_confirmations.into();
// now we start polling for new events.
loop {
let block = store.get_last_block_number(
Expand All @@ -150,9 +160,12 @@ pub trait EventWatcher {
"Latest block number: #{}",
current_block_number
);
let dest_block = cmp::min(block + step, current_block_number);
// latest finalized block after n block_confirmations
let latest_finalized_block =
current_block_number.saturating_sub(block_confirmations);
let dest_block = cmp::min(block + step, latest_finalized_block);
// check if we are now on the latest block.
let should_cooldown = dest_block == current_block_number;
let should_cooldown = dest_block == latest_finalized_block;
tracing::trace!("Reading from #{} to #{}", block, dest_block);
// Only handle events from found blocks if they are new
if dest_block != block {
Expand Down
9 changes: 5 additions & 4 deletions src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ async fn start_evm_vanchor_events_watcher(
Box::new(leaves_handler),
Box::new(encrypted_output_handler),
],
my_ctx.metrics.clone(),
&my_ctx,
);
tokio::select! {
_ = vanchor_watcher_task => {
Expand Down Expand Up @@ -754,7 +754,7 @@ async fn start_evm_vanchor_events_watcher(
Box::new(leaves_handler),
Box::new(encrypted_output_handler),
],
my_ctx.metrics.clone(),
&my_ctx,
);
tokio::select! {
_ = vanchor_watcher_task => {
Expand Down Expand Up @@ -783,7 +783,7 @@ async fn start_evm_vanchor_events_watcher(
Box::new(leaves_handler),
Box::new(encrypted_output_handler),
],
my_ctx.metrics.clone(),
&my_ctx,
);
tokio::select! {
_ = vanchor_watcher_task => {
Expand Down Expand Up @@ -828,6 +828,7 @@ async fn start_signature_bridge_events_watcher(
let wrapper =
SignatureBridgeContractWrapper::new(config.clone(), client.clone());
let metrics = ctx.metrics.clone();
let my_ctx = ctx.clone();
let task = async move {
tracing::debug!(
"Signature Bridge watcher for ({}) Started.",
Expand All @@ -842,7 +843,7 @@ async fn start_signature_bridge_events_watcher(
store.clone(),
wrapper.clone(),
vec![Box::new(governance_transfer_handler)],
metrics.clone(),
&my_ctx,
);
let cmd_handler_task = BridgeWatcher::run(
&bridge_contract_watcher,
Expand Down
4 changes: 4 additions & 0 deletions tests/lib/localTestnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export type ExportedConfigOptions = {
withdrawConfig?: WithdrawConfig;
relayerWallet?: Wallet;
linkedAnchors?: LinkedAnchor[];
blockConfirmations?: number;
};

// Default Events watcher for the contracts.
Expand Down Expand Up @@ -364,6 +365,7 @@ export class LocalChain {
enabled: true,
httpEndpoint: this.endpoint,
wsEndpoint: this.endpoint.replace('http', 'ws'),
blockConfirmations: opts.blockConfirmations ?? 1,
chainId: this.underlyingChainId,
beneficiary: (wallet as ethers.Wallet).address,
privateKey: (wallet as ethers.Wallet).privateKey,
Expand All @@ -380,6 +382,7 @@ export class LocalChain {
enabled: true,
httpEndpoint: this.endpoint,
wsEndpoint: this.endpoint.replace('http', 'ws'),
blockConfirmations: opts.blockConfirmations ?? 1,
chainId: this.underlyingChainId,
beneficiary: '',
privateKey: '',
Expand Down Expand Up @@ -432,6 +435,7 @@ export class LocalChain {
'http-endpoint': config.httpEndpoint,
'ws-endpoint': config.wsEndpoint,
'chain-id': config.chainId,
'block-confirmations': config.blockConfirmations,
beneficiary: config.beneficiary,
salman01zp marked this conversation as resolved.
Show resolved Hide resolved
'private-key': config.privateKey,
contracts: config.contracts.map((contract) => ({
Expand Down
1 change: 1 addition & 0 deletions tests/lib/webbRelayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ export interface ChainInfo {
chainId: number;
beneficiary?: string;
contracts: Contract[];
blockConfirmations: number;
}

export interface Contract {
Expand Down
1 change: 1 addition & 0 deletions tests/test/evm/evmToSubstrateTransaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ describe('Cross chain transaction <<>> Mocked Backend', function () {
linkedAnchors: [
{ type: 'Raw', resourceId: substrateResourceId.toString() },
],
blockConfirmations: 15
});

// This are pre-requisites for creating substrate chain.
Expand Down