diff --git a/rust/main/config/mainnet_config.json b/rust/main/config/mainnet_config.json index dc66d22345..06d1e30497 100644 --- a/rust/main/config/mainnet_config.json +++ b/rust/main/config/mainnet_config.json @@ -785,7 +785,8 @@ "index": { "from": 1, "mode": "sequence", - "chunk": 100 + "chunk": 100, + "direction": "forward" }, "interchainGasPaymaster": "ABb3i11z7wKoGCfeRQNQbVYWjAm7jG7HzZnDLV4RKRbK", "mailbox": "EitxJuv2iBjsg2d7jVy2LDC1e2zBrx4GB5Y9h2Ko3A9Y", diff --git a/rust/main/hyperlane-base/src/contract_sync/cursors/sequence_aware/mod.rs b/rust/main/hyperlane-base/src/contract_sync/cursors/sequence_aware/mod.rs index 74e7ebe014..89a30ec1ea 100644 --- a/rust/main/hyperlane-base/src/contract_sync/cursors/sequence_aware/mod.rs +++ b/rust/main/hyperlane-base/src/contract_sync/cursors/sequence_aware/mod.rs @@ -1,12 +1,13 @@ -use std::{fmt::Debug, sync::Arc, time::Duration}; +use std::{fmt::Debug, ops::RangeInclusive, sync::Arc, time::Duration}; use async_trait::async_trait; use eyre::Result; + use hyperlane_core::{ ChainCommunicationError, ContractSyncCursor, CursorAction, - HyperlaneSequenceAwareIndexerStoreReader, IndexMode, Indexed, LogMeta, SequenceAwareIndexer, + HyperlaneSequenceAwareIndexerStoreReader, IndexDirection, IndexMode, Indexed, LogMeta, + SequenceAwareIndexer, }; -use std::ops::RangeInclusive; mod backward; mod forward; @@ -67,6 +68,7 @@ pub(crate) struct ForwardBackwardSequenceAwareSyncCursor { forward: ForwardSequenceAwareSyncCursor, backward: BackwardSequenceAwareSyncCursor, last_direction: SyncDirection, + index_direction: IndexDirection, } impl ForwardBackwardSequenceAwareSyncCursor { @@ -76,6 +78,7 @@ impl ForwardBackwardSequenceAwareSyncCursor { store: Arc>, chunk_size: u32, mode: IndexMode, + direction: IndexDirection, ) -> Result { let (sequence_count, tip) = latest_sequence_querier .latest_sequence_count_and_tip() @@ -97,6 +100,7 @@ impl ForwardBackwardSequenceAwareSyncCursor { forward: forward_cursor, backward: backward_cursor, last_direction: SyncDirection::Forward, + index_direction: direction, }) } } @@ -109,15 +113,20 @@ impl ContractSyncCursor // TODO: Proper ETA for backwards sync let eta = Duration::from_secs(0); // Prioritize forward syncing over backward syncing. - if let Some(forward_range) = self.forward.get_next_range().await? { - self.last_direction = SyncDirection::Forward; - return Ok((CursorAction::Query(forward_range), eta)); + if self.index_direction.can_forward() { + if let Some(forward_range) = self.forward.get_next_range().await? { + self.last_direction = SyncDirection::Forward; + return Ok((CursorAction::Query(forward_range), eta)); + } } - if let Some(backward_range) = self.backward.get_next_range().await? { - self.last_direction = SyncDirection::Backward; - return Ok((CursorAction::Query(backward_range), eta)); + if self.index_direction.can_backward() { + if let Some(backward_range) = self.backward.get_next_range().await? { + self.last_direction = SyncDirection::Backward; + return Ok((CursorAction::Query(backward_range), eta)); + } } + // TODO: Define the sleep time from interval flag return Ok((CursorAction::Sleep(Duration::from_secs(5)), eta)); } diff --git a/rust/main/hyperlane-base/src/contract_sync/mod.rs b/rust/main/hyperlane-base/src/contract_sync/mod.rs index df9563d8a7..340417aa31 100644 --- a/rust/main/hyperlane-base/src/contract_sync/mod.rs +++ b/rust/main/hyperlane-base/src/contract_sync/mod.rs @@ -356,6 +356,7 @@ where Arc::new(self.store.clone()), index_settings.chunk_size, index_settings.mode, + index_settings.direction, ) .await?, )) diff --git a/rust/main/hyperlane-base/src/settings/chains.rs b/rust/main/hyperlane-base/src/settings/chains.rs index 33600418bb..3be93792cf 100644 --- a/rust/main/hyperlane-base/src/settings/chains.rs +++ b/rust/main/hyperlane-base/src/settings/chains.rs @@ -8,8 +8,8 @@ use eyre::{eyre, Context, Result}; use ethers_prometheus::middleware::{ChainInfo, ContractInfo, PrometheusMiddlewareConf}; use hyperlane_core::{ config::OperationBatchConfig, AggregationIsm, CcipReadIsm, ContractLocator, HyperlaneAbi, - HyperlaneDomain, HyperlaneDomainProtocol, HyperlaneMessage, HyperlaneProvider, IndexMode, - InterchainGasPaymaster, InterchainGasPayment, InterchainSecurityModule, Mailbox, + HyperlaneDomain, HyperlaneDomainProtocol, HyperlaneMessage, HyperlaneProvider, IndexDirection, + IndexMode, InterchainGasPaymaster, InterchainGasPayment, InterchainSecurityModule, Mailbox, MerkleTreeHook, MerkleTreeInsertion, MultisigIsm, ReorgPeriod, RoutingIsm, SequenceAwareIndexer, ValidatorAnnounce, H256, }; @@ -183,6 +183,8 @@ pub struct IndexSettings { pub chunk_size: u32, /// The indexing mode. pub mode: IndexMode, + /// The indexing direction. + pub direction: IndexDirection, } impl ChainConf { diff --git a/rust/main/hyperlane-base/src/settings/parser/mod.rs b/rust/main/hyperlane-base/src/settings/parser/mod.rs index d176ad857b..a4b837c9f5 100644 --- a/rust/main/hyperlane-base/src/settings/parser/mod.rs +++ b/rust/main/hyperlane-base/src/settings/parser/mod.rs @@ -19,7 +19,7 @@ use url::Url; use h_cosmos::RawCosmosAmount; use hyperlane_core::{ cfg_unwrap_all, config::*, HyperlaneDomain, HyperlaneDomainProtocol, - HyperlaneDomainTechnicalStack, IndexMode, ReorgPeriod, + HyperlaneDomainTechnicalStack, IndexDirection, IndexMode, ReorgPeriod, }; use crate::settings::{ @@ -170,6 +170,12 @@ fn parse_chain( }) .unwrap_or_default() }); + let direction = chain + .chain(&mut err) + .get_opt_key("index") + .get_opt_key("direction") + .parse_value("Invalid index direction") + .unwrap_or(IndexDirection::Both); let mailbox = chain .chain(&mut err) @@ -234,6 +240,7 @@ fn parse_chain( from, chunk_size, mode, + direction, }, }) } diff --git a/rust/main/hyperlane-core/src/traits/indexer.rs b/rust/main/hyperlane-core/src/traits/indexer.rs index 1c05360ff5..070f2355ff 100644 --- a/rust/main/hyperlane-core/src/traits/indexer.rs +++ b/rust/main/hyperlane-core/src/traits/indexer.rs @@ -24,6 +24,35 @@ pub enum IndexMode { Sequence, } +/// Indexing direction. +#[derive(Copy, Debug, Default, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub enum IndexDirection { + /// Both directions: backward and forward + #[default] + Both, + /// Backward direction + Backward, + /// Forward direction + Forward, +} + +impl IndexDirection { + pub fn can_backward(&self) -> bool { + match self { + IndexDirection::Both | IndexDirection::Backward => true, + IndexDirection::Forward => false, + } + } + + pub fn can_forward(&self) -> bool { + match self { + IndexDirection::Both | IndexDirection::Forward => true, + IndexDirection::Backward => false, + } + } +} + /// Interface for an indexer. #[async_trait] #[auto_impl(&, Box, Arc,)]