fix: Avoid Relayer to use GetBlock for Sealevel (#4883)

### Description

Avoid Relayer to use GetBlock for Sealevel.

It is a temporary solution until we migrate Sealevel integration to the
latest Solana libraries

### Related issues

- Contributes into
https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/4271

### Backward compatibility

Yes

### Testing

E2E Ethereum and Sealevel test

---------

Co-authored-by: Danil Nemirovsky <4614623+ameten@users.noreply.github.com>
pull/4888/head
Danil Nemirovsky 3 days ago committed by GitHub
parent 58425a2de3
commit 79e9d02f30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      rust/main/agents/relayer/src/relayer.rs
  2. 3
      rust/main/agents/scraper/src/agent.rs
  3. 1
      rust/main/agents/validator/src/validator.rs
  4. 46
      rust/main/chains/hyperlane-sealevel/src/interchain_gas.rs
  5. 82
      rust/main/chains/hyperlane-sealevel/src/mailbox.rs
  6. 15
      rust/main/hyperlane-base/src/settings/base.rs
  7. 72
      rust/main/hyperlane-base/src/settings/chains.rs

@ -152,6 +152,7 @@ impl BaseAgent for Relayer {
dbs.iter()
.map(|(d, db)| (d.clone(), Arc::new(db.clone())))
.collect(),
false,
)
.await?
.into_iter()
@ -166,6 +167,7 @@ impl BaseAgent for Relayer {
dbs.iter()
.map(|(d, db)| (d.clone(), Arc::new(db.clone())))
.collect(),
false,
)
.await?
.into_iter()
@ -180,6 +182,7 @@ impl BaseAgent for Relayer {
dbs.iter()
.map(|(d, db)| (d.clone(), Arc::new(db.clone())))
.collect(),
false,
)
.await?
.into_iter()

@ -198,6 +198,7 @@ impl Scraper {
&metrics.clone(),
&contract_sync_metrics.clone(),
store.into(),
true,
)
.await
.unwrap();
@ -229,6 +230,7 @@ impl Scraper {
&metrics.clone(),
&contract_sync_metrics.clone(),
Arc::new(store.clone()) as _,
true,
)
.await
.unwrap();
@ -261,6 +263,7 @@ impl Scraper {
&metrics.clone(),
&contract_sync_metrics.clone(),
Arc::new(store.clone()),
true,
)
.await
.unwrap();

@ -109,6 +109,7 @@ impl BaseAgent for Validator {
&metrics,
&contract_sync_metrics,
msg_db.clone().into(),
false,
)
.await?;

@ -91,7 +91,8 @@ impl InterchainGasPaymaster for SealevelInterchainGasPaymaster {}
pub struct SealevelInterchainGasPaymasterIndexer {
rpc_client: SealevelRpcClient,
igp: SealevelInterchainGasPaymaster,
_log_meta_composer: LogMetaComposer,
log_meta_composer: LogMetaComposer,
advanced_log_meta: bool,
}
/// IGP payment data on Sealevel
@ -107,6 +108,7 @@ impl SealevelInterchainGasPaymasterIndexer {
pub async fn new(
conf: &ConnectionConf,
igp_account_locator: ContractLocator<'_>,
advanced_log_meta: bool,
) -> ChainResult<Self> {
// Set the `processed` commitment at rpc level
let rpc_client = SealevelRpcClient::new(conf.url.to_string());
@ -122,7 +124,8 @@ impl SealevelInterchainGasPaymasterIndexer {
Ok(Self {
rpc_client,
igp,
_log_meta_composer: log_meta_composer,
log_meta_composer,
advanced_log_meta,
})
}
@ -168,23 +171,24 @@ impl SealevelInterchainGasPaymasterIndexer {
gas_amount: gas_payment_account.gas_amount.into(),
};
// let log_meta = self
// .interchain_payment_log_meta(
// U256::from(sequence_number),
// &valid_payment_pda_pubkey,
// &gas_payment_account.slot,
// )
// .await?;
let log_meta = LogMeta {
address: self.igp.program_id.to_bytes().into(),
block_number: gas_payment_account.slot,
// TODO: get these when building out scraper support.
// It's inconvenient to get these :|
block_hash: H256::zero(),
transaction_id: H512::zero(),
transaction_index: 0,
log_index: sequence_number.into(),
let log_meta = if self.advanced_log_meta {
self.interchain_payment_log_meta(
U256::from(sequence_number),
&valid_payment_pda_pubkey,
&gas_payment_account.slot,
)
.await?
} else {
LogMeta {
address: self.igp.program_id.to_bytes().into(),
block_number: gas_payment_account.slot,
// TODO: get these when building out scraper support.
// It's inconvenient to get these :|
block_hash: H256::zero(),
transaction_id: H512::zero(),
transaction_index: 0,
log_index: sequence_number.into(),
}
};
Ok(SealevelGasPayment::new(
@ -212,7 +216,7 @@ impl SealevelInterchainGasPaymasterIndexer {
Ok(expected_pubkey)
}
async fn _interchain_payment_log_meta(
async fn interchain_payment_log_meta(
&self,
log_index: U256,
payment_pda_pubkey: &Pubkey,
@ -220,7 +224,7 @@ impl SealevelInterchainGasPaymasterIndexer {
) -> ChainResult<LogMeta> {
let block = self.rpc_client.get_block(*payment_pda_slot).await?;
self._log_meta_composer
self.log_meta_composer
.log_meta(block, log_index, payment_pda_pubkey, payment_pda_slot)
.map_err(Into::<ChainCommunicationError>::into)
}

@ -648,10 +648,15 @@ pub struct SealevelMailboxIndexer {
program_id: Pubkey,
dispatch_message_log_meta_composer: LogMetaComposer,
delivery_message_log_meta_composer: LogMetaComposer,
advanced_log_meta: bool,
}
impl SealevelMailboxIndexer {
pub fn new(conf: &ConnectionConf, locator: ContractLocator) -> ChainResult<Self> {
pub fn new(
conf: &ConnectionConf,
locator: ContractLocator,
advanced_log_meta: bool,
) -> ChainResult<Self> {
let program_id = Pubkey::from(<[u8; 32]>::from(locator.address));
let mailbox = SealevelMailbox::new(conf, locator, None)?;
@ -672,6 +677,7 @@ impl SealevelMailboxIndexer {
mailbox,
dispatch_message_log_meta_composer,
delivery_message_log_meta_composer,
advanced_log_meta,
})
}
@ -712,23 +718,24 @@ impl SealevelMailboxIndexer {
let hyperlane_message =
HyperlaneMessage::read_from(&mut &dispatched_message_account.encoded_message[..])?;
// let log_meta = self
// .dispatch_message_log_meta(
// U256::from(nonce),
// &valid_message_storage_pda_pubkey,
// &dispatched_message_account.slot,
// )
// .await?;
let log_meta = LogMeta {
address: self.program_id.to_bytes().into(),
block_number: dispatched_message_account.slot,
// TODO: get these when building out scraper support.
// It's inconvenient to get these :|
block_hash: H256::zero(),
transaction_id: H512::zero(),
transaction_index: 0,
log_index: U256::zero(),
let log_meta = if self.advanced_log_meta {
self.dispatch_message_log_meta(
U256::from(nonce),
&valid_message_storage_pda_pubkey,
&dispatched_message_account.slot,
)
.await?
} else {
LogMeta {
address: self.program_id.to_bytes().into(),
block_number: dispatched_message_account.slot,
// TODO: get these when building out scraper support.
// It's inconvenient to get these :|
block_hash: H256::zero(),
transaction_id: H512::zero(),
transaction_index: 0,
log_index: U256::zero(),
}
};
Ok((hyperlane_message.into(), log_meta))
@ -748,7 +755,7 @@ impl SealevelMailboxIndexer {
Ok(expected_pubkey)
}
async fn _dispatch_message_log_meta(
async fn dispatch_message_log_meta(
&self,
log_index: U256,
message_storage_pda_pubkey: &Pubkey,
@ -805,23 +812,24 @@ impl SealevelMailboxIndexer {
.into_inner();
let message_id = delivered_message_account.message_id;
// let log_meta = self
// .delivered_message_log_meta(
// U256::from(nonce),
// &valid_message_storage_pda_pubkey,
// &delivered_message_account.slot,
// )
// .await?;
let log_meta = LogMeta {
address: self.program_id.to_bytes().into(),
block_number: delivered_message_account.slot,
// TODO: get these when building out scraper support.
// It's inconvenient to get these :|
block_hash: H256::zero(),
transaction_id: H512::zero(),
transaction_index: 0,
log_index: U256::zero(),
let log_meta = if self.advanced_log_meta {
self.delivered_message_log_meta(
U256::from(nonce),
&valid_message_storage_pda_pubkey,
&delivered_message_account.slot,
)
.await?
} else {
LogMeta {
address: self.program_id.to_bytes().into(),
block_number: delivered_message_account.slot,
// TODO: get these when building out scraper support.
// It's inconvenient to get these :|
block_hash: H256::zero(),
transaction_id: H512::zero(),
transaction_index: 0,
log_index: U256::zero(),
}
};
Ok((message_id.into(), log_meta))
@ -839,7 +847,7 @@ impl SealevelMailboxIndexer {
Ok(expected_pubkey)
}
async fn _delivered_message_log_meta(
async fn delivered_message_log_meta(
&self,
log_index: U256,
message_storage_pda_pubkey: &Pubkey,

@ -151,13 +151,14 @@ impl Settings {
build_contract_fns!(build_validator_announce, build_validator_announces -> dyn ValidatorAnnounce);
build_contract_fns!(build_provider, build_providers -> dyn HyperlaneProvider);
/// Build a contract sync for type `T` using log store `D`
/// Build a contract sync for type `T` using log store `S`
pub async fn sequenced_contract_sync<T, S>(
&self,
domain: &HyperlaneDomain,
metrics: &CoreMetrics,
sync_metrics: &ContractSyncMetrics,
store: Arc<S>,
advanced_log_meta: bool,
) -> eyre::Result<Arc<SequencedDataContractSync<T>>>
where
T: Indexable + Debug,
@ -166,7 +167,8 @@ impl Settings {
{
let setup = self.chain_setup(domain)?;
// Currently, all indexers are of the `SequenceIndexer` type
let indexer = SequenceIndexer::<T>::try_from_with_metrics(setup, metrics).await?;
let indexer =
SequenceIndexer::<T>::try_from_with_metrics(setup, metrics, advanced_log_meta).await?;
Ok(Arc::new(ContractSync::new(
domain.clone(),
store.clone() as SequenceAwareLogStore<_>,
@ -175,13 +177,14 @@ impl Settings {
)))
}
/// Build a contract sync for type `T` using log store `D`
/// Build a contract sync for type `T` using log store `S`
pub async fn watermark_contract_sync<T, S>(
&self,
domain: &HyperlaneDomain,
metrics: &CoreMetrics,
sync_metrics: &ContractSyncMetrics,
store: Arc<S>,
advanced_log_meta: bool,
) -> eyre::Result<Arc<WatermarkContractSync<T>>>
where
T: Indexable + Debug,
@ -190,7 +193,8 @@ impl Settings {
{
let setup = self.chain_setup(domain)?;
// Currently, all indexers are of the `SequenceIndexer` type
let indexer = SequenceIndexer::<T>::try_from_with_metrics(setup, metrics).await?;
let indexer =
SequenceIndexer::<T>::try_from_with_metrics(setup, metrics, advanced_log_meta).await?;
Ok(Arc::new(ContractSync::new(
domain.clone(),
store.clone() as WatermarkLogStore<_>,
@ -208,6 +212,7 @@ impl Settings {
metrics: &CoreMetrics,
sync_metrics: &ContractSyncMetrics,
stores: HashMap<HyperlaneDomain, Arc<S>>,
advanced_log_meta: bool,
) -> Result<HashMap<HyperlaneDomain, Arc<dyn ContractSyncer<T>>>>
where
T: Indexable + Debug + Send + Sync + Clone + Eq + Hash + 'static,
@ -227,6 +232,7 @@ impl Settings {
metrics,
sync_metrics,
stores.get(domain).unwrap().clone(),
advanced_log_meta,
)
.await
.map(|r| r as Arc<dyn ContractSyncer<T>>)?,
@ -236,6 +242,7 @@ impl Settings {
metrics,
sync_metrics,
stores.get(domain).unwrap().clone(),
advanced_log_meta,
)
.await
.map(|r| r as Arc<dyn ContractSyncer<T>>)?,

@ -33,7 +33,11 @@ use super::ChainSigner;
#[async_trait]
pub trait TryFromWithMetrics<T>: Sized {
/// Try to convert the chain configuration into the type
async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result<Self>;
async fn try_from_with_metrics(
conf: &ChainConf,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Self>;
}
/// A chain setup is a domain ID, an address on that chain (where the mailbox is
@ -72,22 +76,38 @@ pub type MerkleTreeHookIndexer = Arc<dyn SequenceAwareIndexer<MerkleTreeInsertio
#[async_trait]
impl TryFromWithMetrics<ChainConf> for MessageIndexer {
async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result<Self> {
conf.build_message_indexer(metrics).await.map(Into::into)
async fn try_from_with_metrics(
conf: &ChainConf,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Self> {
conf.build_message_indexer(metrics, advanced_log_meta)
.await
.map(Into::into)
}
}
#[async_trait]
impl TryFromWithMetrics<ChainConf> for DeliveryIndexer {
async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result<Self> {
conf.build_delivery_indexer(metrics).await.map(Into::into)
async fn try_from_with_metrics(
conf: &ChainConf,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Self> {
conf.build_delivery_indexer(metrics, advanced_log_meta)
.await
.map(Into::into)
}
}
#[async_trait]
impl TryFromWithMetrics<ChainConf> for IgpIndexer {
async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result<Self> {
conf.build_interchain_gas_payment_indexer(metrics)
async fn try_from_with_metrics(
conf: &ChainConf,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Self> {
conf.build_interchain_gas_payment_indexer(metrics, advanced_log_meta)
.await
.map(Into::into)
}
@ -95,8 +115,12 @@ impl TryFromWithMetrics<ChainConf> for IgpIndexer {
#[async_trait]
impl TryFromWithMetrics<ChainConf> for MerkleTreeHookIndexer {
async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result<Self> {
conf.build_merkle_tree_hook_indexer(metrics)
async fn try_from_with_metrics(
conf: &ChainConf,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Self> {
conf.build_merkle_tree_hook_indexer(metrics, advanced_log_meta)
.await
.map(Into::into)
}
@ -266,6 +290,7 @@ impl ChainConf {
pub async fn build_message_indexer(
&self,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Box<dyn SequenceAwareIndexer<HyperlaneMessage>>> {
let ctx = "Building delivery indexer";
let locator = self.locator(self.addresses.mailbox);
@ -284,7 +309,11 @@ impl ChainConf {
}
ChainConnectionConf::Fuel(_) => todo!(),
ChainConnectionConf::Sealevel(conf) => {
let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?);
let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(
conf,
locator,
advanced_log_meta,
)?);
Ok(indexer as Box<dyn SequenceAwareIndexer<HyperlaneMessage>>)
}
ChainConnectionConf::Cosmos(conf) => {
@ -306,6 +335,7 @@ impl ChainConf {
pub async fn build_delivery_indexer(
&self,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Box<dyn SequenceAwareIndexer<H256>>> {
let ctx = "Building delivery indexer";
let locator = self.locator(self.addresses.mailbox);
@ -324,7 +354,11 @@ impl ChainConf {
}
ChainConnectionConf::Fuel(_) => todo!(),
ChainConnectionConf::Sealevel(conf) => {
let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?);
let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(
conf,
locator,
advanced_log_meta,
)?);
Ok(indexer as Box<dyn SequenceAwareIndexer<H256>>)
}
ChainConnectionConf::Cosmos(conf) => {
@ -385,6 +419,7 @@ impl ChainConf {
pub async fn build_interchain_gas_payment_indexer(
&self,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Box<dyn SequenceAwareIndexer<InterchainGasPayment>>> {
let ctx = "Building IGP indexer";
let locator = self.locator(self.addresses.interchain_gas_paymaster);
@ -407,7 +442,12 @@ impl ChainConf {
ChainConnectionConf::Fuel(_) => todo!(),
ChainConnectionConf::Sealevel(conf) => {
let indexer = Box::new(
h_sealevel::SealevelInterchainGasPaymasterIndexer::new(conf, locator).await?,
h_sealevel::SealevelInterchainGasPaymasterIndexer::new(
conf,
locator,
advanced_log_meta,
)
.await?,
);
Ok(indexer as Box<dyn SequenceAwareIndexer<InterchainGasPayment>>)
}
@ -428,6 +468,7 @@ impl ChainConf {
pub async fn build_merkle_tree_hook_indexer(
&self,
metrics: &CoreMetrics,
advanced_log_meta: bool,
) -> Result<Box<dyn SequenceAwareIndexer<MerkleTreeInsertion>>> {
let ctx = "Building merkle tree hook indexer";
let locator = self.locator(self.addresses.merkle_tree_hook);
@ -446,8 +487,11 @@ impl ChainConf {
}
ChainConnectionConf::Fuel(_) => todo!(),
ChainConnectionConf::Sealevel(conf) => {
let mailbox_indexer =
Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?);
let mailbox_indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(
conf,
locator,
advanced_log_meta,
)?);
let indexer = Box::new(h_sealevel::SealevelMerkleTreeHookIndexer::new(
*mailbox_indexer,
));

Loading…
Cancel
Save