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: Add block tag support in reorgPeriod parameter #4629

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
12 changes: 7 additions & 5 deletions rust/main/agents/validator/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use hyperlane_base::{
CheckpointSyncerConf, Settings, SignerConf,
},
};
use hyperlane_core::{cfg_unwrap_all, config::*, HyperlaneDomain, HyperlaneDomainProtocol};
use hyperlane_core::{
cfg_unwrap_all, config::*, HyperlaneDomain, HyperlaneDomainProtocol, ReorgPeriod,
};
use serde::Deserialize;
use serde_json::Value;

Expand All @@ -36,8 +38,8 @@ pub struct ValidatorSettings {
pub validator: SignerConf,
/// The checkpoint syncer configuration
pub checkpoint_syncer: CheckpointSyncerConf,
/// The reorg_period in blocks
pub reorg_period: u64,
/// The reorg configuration
pub reorg_period: ReorgPeriod,
/// How frequently to check for new checkpoints
pub interval: Duration,
}
Expand Down Expand Up @@ -122,8 +124,8 @@ impl FromRawConf<RawValidatorSettings> for ValidatorSettings {
.get_key(origin_chain_name)
.get_opt_key("blocks")
.get_opt_key("reorgPeriod")
.parse_u64()
.unwrap_or(1);
.parse_value("Invalid reorgPeriod")
.unwrap_or(ReorgPeriod::Blocks(1));

cfg_unwrap_all!(cwp, err: [base, origin_chain, validator, checkpoint_syncer]);

Expand Down
16 changes: 10 additions & 6 deletions rust/main/agents/validator/src/submit.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::num::NonZeroU64;
use std::sync::Arc;
use std::time::{Duration, Instant};
use std::vec;

use hyperlane_core::rpc_clients::call_and_retry_indefinitely;
use hyperlane_core::{ChainResult, MerkleTreeHook};
use hyperlane_core::{ChainResult, MerkleTreeHook, ReorgPeriod};
use prometheus::IntGauge;
use tokio::time::sleep;
use tracing::{debug, error, info};
Expand All @@ -19,7 +18,7 @@ use hyperlane_ethereum::SingletonSignerHandle;
#[derive(Clone)]
pub(crate) struct ValidatorSubmitter {
interval: Duration,
reorg_period: Option<NonZeroU64>,
reorg_period: Option<ReorgPeriod>,
signer: SingletonSignerHandle,
merkle_tree_hook: Arc<dyn MerkleTreeHook>,
checkpoint_syncer: Arc<dyn CheckpointSyncer>,
Expand All @@ -30,15 +29,15 @@ pub(crate) struct ValidatorSubmitter {
impl ValidatorSubmitter {
pub(crate) fn new(
interval: Duration,
reorg_period: u64,
reorg_period: ReorgPeriod,
merkle_tree_hook: Arc<dyn MerkleTreeHook>,
signer: SingletonSignerHandle,
checkpoint_syncer: Arc<dyn CheckpointSyncer>,
message_db: HyperlaneRocksDB,
metrics: ValidatorSubmitterMetrics,
) -> Self {
Self {
reorg_period: NonZeroU64::new(reorg_period),
reorg_period: Some(reorg_period),
interval,
merkle_tree_hook,
signer,
Expand Down Expand Up @@ -93,7 +92,12 @@ impl ValidatorSubmitter {
// Lag by reorg period because this is our correctness checkpoint.
let latest_checkpoint = call_and_retry_indefinitely(|| {
let merkle_tree_hook = self.merkle_tree_hook.clone();
Box::pin(async move { merkle_tree_hook.latest_checkpoint(self.reorg_period).await })
let reorg_period = self.reorg_period.clone();
Box::pin(async move {
merkle_tree_hook
.latest_checkpoint(reorg_period.as_ref())
.await
})
})
.await;

Expand Down
14 changes: 7 additions & 7 deletions rust/main/agents/validator/src/validator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{num::NonZeroU64, sync::Arc, time::Duration};
use std::{sync::Arc, time::Duration};

use crate::server as validator_server;
use async_trait::async_trait;
Expand All @@ -19,8 +19,8 @@ use hyperlane_base::{

use hyperlane_core::{
Announcement, ChainResult, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneSigner,
HyperlaneSignerExt, Mailbox, MerkleTreeHook, MerkleTreeInsertion, TxOutcome, ValidatorAnnounce,
H256, U256,
HyperlaneSignerExt, Mailbox, MerkleTreeHook, MerkleTreeInsertion, ReorgPeriod, TxOutcome,
ValidatorAnnounce, H256, U256,
};
use hyperlane_ethereum::{SingletonSigner, SingletonSignerHandle};

Expand All @@ -44,7 +44,7 @@ pub struct Validator {
signer: SingletonSignerHandle,
// temporary holder until `run` is called
signer_instance: Option<Box<SingletonSigner>>,
reorg_period: u64,
reorg_period: ReorgPeriod,
interval: Duration,
checkpoint_syncer: Arc<dyn CheckpointSyncer>,
core_metrics: Arc<CoreMetrics>,
Expand Down Expand Up @@ -180,7 +180,7 @@ impl BaseAgent for Validator {
// announce the validator after spawning the signer task
self.announce().await.expect("Failed to announce validator");

let reorg_period = NonZeroU64::new(self.reorg_period);
let reorg_period = Some(&self.reorg_period);

// Ensure that the merkle tree hook has count > 0 before we begin indexing
// messages or submitting checkpoints.
Expand Down Expand Up @@ -237,15 +237,15 @@ impl Validator {
async fn run_checkpoint_submitters(&self) -> Vec<Instrumented<JoinHandle<()>>> {
let submitter = ValidatorSubmitter::new(
self.interval,
self.reorg_period,
self.reorg_period.clone(),
self.merkle_tree_hook.clone(),
self.signer.clone(),
self.checkpoint_syncer.clone(),
self.db.clone(),
ValidatorSubmitterMetrics::new(&self.core.metrics, &self.origin_chain),
);

let reorg_period = NonZeroU64::new(self.reorg_period);
let reorg_period = Some(&self.reorg_period);
let tip_tree = self
.merkle_tree_hook
.tree(reorg_period)
Expand Down
4 changes: 2 additions & 2 deletions rust/main/chains/hyperlane-cosmos/src/mailbox/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use tracing::instrument;
use hyperlane_core::{
utils::bytes_to_hex, ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract,
HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Mailbox, RawHyperlaneMessage,
TxCostEstimate, TxOutcome, H256, U256,
ReorgPeriod, TxCostEstimate, TxOutcome, H256, U256,
};

use crate::address::CosmosAddress;
Expand Down Expand Up @@ -83,7 +83,7 @@ impl HyperlaneChain for CosmosMailbox {
impl Mailbox for CosmosMailbox {
#[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32> {
async fn count(&self, lag: Option<&ReorgPeriod>) -> ChainResult<u32> {
let block_height = get_block_height_for_lag(self.provider.grpc(), lag).await?;
self.nonce_at_block(block_height).await
}
Expand Down
8 changes: 4 additions & 4 deletions rust/main/chains/hyperlane-cosmos/src/merkle_tree_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use hyperlane_core::accumulator::incremental::IncrementalMerkle;
use hyperlane_core::{
ChainCommunicationError, ChainResult, Checkpoint, ContractLocator, HyperlaneChain,
HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer, LogMeta,
MerkleTreeHook, MerkleTreeInsertion, SequenceAwareIndexer, H256, H512,
MerkleTreeHook, MerkleTreeInsertion, ReorgPeriod, SequenceAwareIndexer, H256, H512,
};

use crate::grpc::WasmProvider;
Expand Down Expand Up @@ -76,7 +76,7 @@ impl MerkleTreeHook for CosmosMerkleTreeHook {
/// Return the incremental merkle tree in storage
#[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn tree(&self, lag: Option<NonZeroU64>) -> ChainResult<IncrementalMerkle> {
async fn tree(&self, lag: Option<&ReorgPeriod>) -> ChainResult<IncrementalMerkle> {
let payload = merkle_tree_hook::MerkleTreeRequest {
tree: general::EmptyStruct {},
};
Expand Down Expand Up @@ -110,7 +110,7 @@ impl MerkleTreeHook for CosmosMerkleTreeHook {
}

/// Gets the current leaf count of the merkle tree
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32> {
async fn count(&self, lag: Option<&ReorgPeriod>) -> ChainResult<u32> {
let payload = merkle_tree_hook::MerkleTreeCountRequest {
count: general::EmptyStruct {},
};
Expand All @@ -121,7 +121,7 @@ impl MerkleTreeHook for CosmosMerkleTreeHook {
}
#[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn latest_checkpoint(&self, lag: Option<NonZeroU64>) -> ChainResult<Checkpoint> {
async fn latest_checkpoint(&self, lag: Option<&ReorgPeriod>) -> ChainResult<Checkpoint> {
let payload = merkle_tree_hook::CheckPointRequest {
check_point: general::EmptyStruct {},
};
Expand Down
9 changes: 5 additions & 4 deletions rust/main/chains/hyperlane-cosmos/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tendermint::Hash;
use tokio::task::JoinHandle;
use tracing::warn;

use hyperlane_core::{ChainCommunicationError, ChainResult, Indexed, LogMeta, H256};
use hyperlane_core::{ChainCommunicationError, ChainResult, Indexed, LogMeta, ReorgPeriod, H256};

use crate::grpc::{WasmGrpcProvider, WasmProvider};
use crate::rpc::{CosmosWasmRpcProvider, ParsedEvent, WasmRpcProvider};
Expand All @@ -29,12 +29,13 @@ pub(crate) static CONTRACT_ADDRESS_ATTRIBUTE_KEY_BASE64: Lazy<String> =
/// tip directly can be used.
pub(crate) async fn get_block_height_for_lag(
provider: &WasmGrpcProvider,
lag: Option<NonZeroU64>,
lag: Option<&ReorgPeriod>,
) -> ChainResult<Option<u64>> {
let block_height = match lag {
Some(lag) => {
Some(reorg_period) => {
let lag = reorg_period.as_number()?;
let tip = provider.latest_block_height().await?;
let block_height = tip - lag.get();
let block_height = tip - lag as u64;
Some(block_height)
}
None => None,
Expand Down
34 changes: 33 additions & 1 deletion rust/main/chains/hyperlane-ethereum/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use hyperlane_core::{config::OperationBatchConfig, U256};
use ethers_core::types::{BlockId, BlockNumber};
use eyre::{eyre, Report};
use hyperlane_core::{config::OperationBatchConfig, ReorgPeriod, U256};
use url::Url;

/// Ethereum RPC connection configuration
Expand Down Expand Up @@ -52,3 +54,33 @@ pub struct TransactionOverrides {
/// Max priority fee per gas to use for EIP-1559 transactions.
pub max_priority_fee_per_gas: Option<U256>,
}

/// Ethereum reorg period
#[derive(Copy, Clone, Debug)]
pub enum EthereumReorgPeriod {
/// Number of blocks
Blocks(u32),
/// A block tag
Tag(BlockId),
}

impl TryFrom<&ReorgPeriod> for EthereumReorgPeriod {
type Error = Report;

fn try_from(value: &ReorgPeriod) -> Result<Self, Self::Error> {
match value {
ReorgPeriod::Blocks(blocks) => Ok(EthereumReorgPeriod::Blocks(*blocks)),
ReorgPeriod::Tag(tag) => {
let tag = match tag.as_str() {
"latest" => BlockNumber::Latest,
"finalized" => BlockNumber::Finalized,
"safe" => BlockNumber::Safe,
"earliest" => BlockNumber::Earliest,
"pending" => BlockNumber::Pending,
_ => return Err(eyre!("Invalid Ethereum reorg period")),
};
Ok(EthereumReorgPeriod::Tag(tag.into()))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ use async_trait::async_trait;
use ethers::prelude::Middleware;
use hyperlane_core::rpc_clients::call_and_retry_indefinitely;
use hyperlane_core::{
ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi, HyperlaneChain,
HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer,
InterchainGasPaymaster, InterchainGasPayment, LogMeta, SequenceAwareIndexer, H160, H256, H512,
ChainResult, ContractLocator, HyperlaneAbi, HyperlaneChain, HyperlaneContract, HyperlaneDomain,
HyperlaneProvider, Indexed, Indexer, InterchainGasPaymaster, InterchainGasPayment, LogMeta,
SequenceAwareIndexer, H160, H256, H512,
};
use tracing::instrument;

use super::utils::fetch_raw_logs_and_meta;
use super::utils::{fetch_raw_logs_and_meta, get_finalized_block_number};
use crate::interfaces::i_interchain_gas_paymaster::{
GasPaymentFilter, IInterchainGasPaymaster as EthereumInterchainGasPaymasterInternal,
IINTERCHAINGASPAYMASTER_ABI,
};
use crate::{BuildableWithProvider, ConnectionConf, EthereumProvider};
use crate::{BuildableWithProvider, ConnectionConf, EthereumProvider, EthereumReorgPeriod};

impl<M> Display for EthereumInterchainGasPaymasterInternal<M>
where
Expand All @@ -33,7 +33,7 @@ where

pub struct InterchainGasPaymasterIndexerBuilder {
pub mailbox_address: H160,
pub reorg_period: u32,
pub reorg_period: EthereumReorgPeriod,
}

#[async_trait]
Expand Down Expand Up @@ -63,15 +63,19 @@ where
{
contract: Arc<EthereumInterchainGasPaymasterInternal<M>>,
provider: Arc<M>,
reorg_period: u32,
reorg_period: EthereumReorgPeriod,
}

impl<M> EthereumInterchainGasPaymasterIndexer<M>
where
M: Middleware + 'static,
{
/// Create new EthereumInterchainGasPaymasterIndexer
pub fn new(provider: Arc<M>, locator: &ContractLocator, reorg_period: u32) -> Self {
pub fn new(
provider: Arc<M>,
locator: &ContractLocator,
reorg_period: EthereumReorgPeriod,
) -> Self {
Self {
contract: Arc::new(EthereumInterchainGasPaymasterInternal::new(
locator.address,
Expand Down Expand Up @@ -122,13 +126,7 @@ where
#[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn get_finalized_block_number(&self) -> ChainResult<u32> {
Ok(self
.provider
.get_block_number()
.await
.map_err(ChainCommunicationError::from_other)?
.as_u32()
.saturating_sub(self.reorg_period))
get_finalized_block_number(&self.provider, self.reorg_period).await
}

async fn fetch_logs_by_tx_hash(
Expand Down
Loading
Loading