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

Add RoutingIsm #1985

Merged
merged 28 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
356717b
Add RoutingIsm
asaj Mar 22, 2023
72936f5
Merge branch 'main' into asaj/routing
asaj Mar 22, 2023
1cff464
Comments and ICA ISM
asaj Mar 22, 2023
c00b1f5
Add ICA routing ISM
asaj Mar 22, 2023
6dca359
rm
asaj Mar 22, 2023
9b4d5ef
Merge branch 'main' into asaj/routing
asaj Mar 22, 2023
6d554fd
test use of mailbox default ISM
asaj Mar 22, 2023
c68c6e0
Remove duplicate test
asaj Mar 22, 2023
0651853
Merge branch 'main' into asaj/routing
asaj Mar 29, 2023
b734c66
Add tests
asaj Mar 29, 2023
454788f
Add DomainRoutingIsmFactory
asaj Apr 4, 2023
19fba46
Merge main
asaj Apr 4, 2023
696348e
cleanup
asaj Apr 4, 2023
7fb391c
Merge branch 'main' into asaj/routing
asaj Apr 4, 2023
fe1c223
Merge branch 'main' into asaj/routing
asaj Apr 4, 2023
13d9ace
more coverage
asaj Apr 4, 2023
7924193
Merge branch 'asaj/routing' of github.com:abacus-network/abacus-monor…
asaj Apr 4, 2023
8a28813
Test factory
asaj Apr 4, 2023
f27e08a
Merge branch 'main' into asaj/routing
asaj Apr 5, 2023
4e143c9
Merge branch 'main' into asaj/routing
asaj Apr 5, 2023
27c776f
Merge branch 'asaj/routing' of github.com:abacus-network/abacus-monor…
asaj Apr 6, 2023
edc1701
Merge branch 'main' into asaj/routing
asaj Apr 6, 2023
d896d66
Merge branch 'main' into asaj/routing
asaj Apr 12, 2023
fc5cf95
Merge branch 'asaj/routing' of github.com:abacus-network/abacus-monor…
asaj Apr 12, 2023
a0a8987
Comments
asaj Apr 12, 2023
b5d2579
Fix tests
asaj Apr 12, 2023
6e287c5
Merge branch 'main' into asaj/routing
asaj Apr 17, 2023
409faf9
Pragma
asaj Apr 17, 2023
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
Prev Previous commit
Next Next commit
Merge main
  • Loading branch information
asaj committed Apr 4, 2023
commit 19fba46531fbc8124ea42555dedd75a296f128dc
2 changes: 1 addition & 1 deletion .github/workflows/node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:
strategy:
matrix:
environment: [testnet3, mainnet2]
module: [core, igp]
module: [core, igp, ica, iqs]

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 2 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ eyre = "0.6"
futures = "0.3"
futures-util = "0.3"
itertools = "0.10"
num-derive = "0.3"
num-traits = "0.2"
paste = "1.0"
prometheus = "0.13"
reqwest = "0.11"
Expand Down
4 changes: 3 additions & 1 deletion rust/agents/relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ tracing.workspace = true
hyperlane-core = { path = "../../hyperlane-core" }
hyperlane-base = { path = "../../hyperlane-base" }
hyperlane-ethereum = { path = "../../chains/hyperlane-ethereum" }
num-derive.workspace = true
num-traits.workspace = true

[dev-dependencies]
tokio-test = "0.4"
Expand All @@ -37,4 +39,4 @@ hyperlane-test = { path = "../../hyperlane-test" }
[features]
default = ["color-eyre", "oneline-errors"]
oneline-errors = ["hyperlane-base/oneline-errors"]
color-eyre = ["hyperlane-base/color-eyre"]
color-eyre = ["hyperlane-base/color-eyre"]
116 changes: 82 additions & 34 deletions rust/agents/relayer/src/msg/metadata_builder.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,57 @@
use std::collections::HashMap;
use async_trait::async_trait;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use std::fmt::Debug;
use std::str::FromStr;
use std::sync::Arc;
use std::{collections::HashMap, ops::Deref};

use derive_new::new;
use eyre::Context;
use tokio::sync::RwLock;
use tracing::{debug, info, instrument, warn};

use hyperlane_base::{
CachingMailbox, ChainSetup, CheckpointSyncer, CheckpointSyncerConf, CoreMetrics,
MultisigCheckpointSyncer,
};
use hyperlane_core::{
HyperlaneChain, HyperlaneMessage, Mailbox, MultisigIsm, ValidatorAnnounce, H160, H256,
ChainSetup, CheckpointSyncer, CheckpointSyncerConf, CoreMetrics, MultisigCheckpointSyncer,
};
use hyperlane_core::{HyperlaneMessage, MultisigIsm, ValidatorAnnounce, H160, H256};

use crate::merkle_tree_builder::MerkleTreeBuilder;

#[derive(Debug, thiserror::Error)]
pub enum MetadataBuilderError {
#[error("Unknown or invalid module type ({0})")]
UnsupportedModuleType(u8),
}

#[derive(FromPrimitive)]
pub enum SupportedIsmTypes {
// Routing = 1,
// Aggregation = 2,
LegacyMultisig = 3,
// Multisig = 4,
}

#[async_trait]
pub trait MetadataBuilder {
#[allow(clippy::async_yields_async)]
async fn build(
&self,
ism_address: H256,
message: &HyperlaneMessage,
) -> eyre::Result<Option<Vec<u8>>>;
}

#[derive(Clone, new)]
pub struct MetadataBuilder {
pub struct BaseMetadataBuilder {
chain_setup: ChainSetup,
prover_sync: Arc<RwLock<MerkleTreeBuilder>>,
validator_announce: Arc<dyn ValidatorAnnounce>,
allow_local_checkpoint_syncers: bool,
metrics: Arc<CoreMetrics>,
}

impl Debug for MetadataBuilder {
impl Debug for BaseMetadataBuilder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
Expand All @@ -37,39 +61,61 @@ impl Debug for MetadataBuilder {
}
}

impl MetadataBuilder {
#[instrument(err, skip(mailbox))]
pub async fn fetch_metadata(
#[async_trait]
impl MetadataBuilder for BaseMetadataBuilder {
#[instrument(err)]
async fn build(
&self,
ism_address: H256,
message: &HyperlaneMessage,
mailbox: CachingMailbox,
) -> eyre::Result<Option<Vec<u8>>> {
const CTX: &str = "When fetching metadata";

// The Mailbox's `recipientIsm` function will revert if
// the recipient is not a contract. This can pose issues with
// our use of the RetryingProvider, which will continuously retry
// the eth_call to the `recipientIsm` function.
// As a workaround, we avoid the call entirely if the recipient is
// not a contract.
let provider = mailbox.provider();
if !provider
.is_contract(&message.recipient)
const CTX: &str = "When fetching module type";
let ism = self
.chain_setup
.build_ism(ism_address, &self.metrics)
.await
.context(CTX)?
{
info!(
recipient=?message.recipient,
"Could not fetch metadata: Recipient is not a contract"
);
return Ok(None);
}
.context(CTX)?;
let module_type = ism.module_type().await.context(CTX)?;
let supported_type = SupportedIsmTypes::from_u8(module_type)
.ok_or(MetadataBuilderError::UnsupportedModuleType(module_type))
.context(CTX)?;

let ism_address = mailbox
.recipient_ism(message.recipient)
let metadata_builder = match supported_type {
SupportedIsmTypes::LegacyMultisig => {
LegacyMultisigIsmMetadataBuilder::new(self.clone())
}
};
metadata_builder
.build(ism_address, message)
.await
.context(CTX)?;
.context(CTX)
}
}

#[derive(Clone, Debug, new)]
pub struct LegacyMultisigIsmMetadataBuilder {
base: BaseMetadataBuilder,
}

impl Deref for LegacyMultisigIsmMetadataBuilder {
type Target = BaseMetadataBuilder;

fn deref(&self) -> &Self::Target {
&self.base
}
}

#[async_trait]
impl MetadataBuilder for LegacyMultisigIsmMetadataBuilder {
#[instrument(err)]
async fn build(
&self,
ism_address: H256,
message: &HyperlaneMessage,
) -> eyre::Result<Option<Vec<u8>>> {
const CTX: &str = "When fetching LegacyMultisigIsm metadata";
let multisig_ism = self
.base
.chain_setup
.build_multisig_ism(ism_address, &self.metrics)
.await
Expand Down Expand Up @@ -132,7 +178,9 @@ impl MetadataBuilder {
Ok(None)
}
}
}

impl LegacyMultisigIsmMetadataBuilder {
async fn build_checkpoint_syncer(
&self,
validators: &[H256],
Expand Down
37 changes: 33 additions & 4 deletions rust/agents/relayer/src/msg/serial_submitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::sync::Arc;
use std::time::{Duration, Instant};

use derive_new::new;
use eyre::{bail, Result};
use eyre::{bail, Context, Result};
use prometheus::{IntCounter, IntGauge};
use tokio::sync::mpsc::{self, error::TryRecvError};
use tokio::task::JoinHandle;
Expand All @@ -15,7 +15,10 @@ use crate::msg::PendingMessage;
use hyperlane_base::{CachingMailbox, CoreMetrics};
use hyperlane_core::{db::HyperlaneDB, HyperlaneChain, HyperlaneDomain, Mailbox, U256};

use super::{gas_payment::GasPaymentEnforcer, metadata_builder::MetadataBuilder};
use super::{
gas_payment::GasPaymentEnforcer, metadata_builder::BaseMetadataBuilder,
metadata_builder::MetadataBuilder,
};

/// SerialSubmitter accepts undelivered messages over a channel from a
/// MessageProcessor. It is responsible for executing the right strategy to
Expand Down Expand Up @@ -80,7 +83,7 @@ pub(crate) struct SerialSubmitter {
/// Mailbox on the destination chain.
mailbox: CachingMailbox,
/// Used to construct the ISM metadata needed to verify a message.
metadata_builder: MetadataBuilder,
metadata_builder: BaseMetadataBuilder,
/// Interface to agent rocks DB for e.g. writing delivery status upon
/// completion.
db: HyperlaneDB,
Expand Down Expand Up @@ -199,8 +202,34 @@ impl SerialSubmitter {
return Ok(true);
}

// The Mailbox's `recipientIsm` function will revert if
// the recipient is not a contract. This can pose issues with
// our use of the RetryingProvider, which will continuously retry
// the eth_call to the `recipientIsm` function.
// As a workaround, we avoid the call entirely if the recipient is
// not a contract.
const CTX: &str = "When fetching ISM";
let provider = self.mailbox.provider();
if !provider
.is_contract(&msg.message.recipient)
.await
.context(CTX)?
{
info!(
recipient=?msg.message.recipient,
"Could not fetch metadata: Recipient is not a contract"
);
return Ok(false);
}

let ism_address = self
.mailbox
.recipient_ism(msg.message.recipient)
.await
.context(CTX)?;

let Some(metadata) = self.metadata_builder
.fetch_metadata(&msg.message, self.mailbox.clone())
.build(ism_address, &msg.message)
.await?
else {
info!("Could not fetch metadata");
Expand Down
6 changes: 3 additions & 3 deletions rust/agents/relayer/src/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
merkle_tree_builder::MerkleTreeBuilder,
msg::{
gas_payment::GasPaymentEnforcer,
metadata_builder::MetadataBuilder,
metadata_builder::BaseMetadataBuilder,
processor::{MessageProcessor, MessageProcessorMetrics},
serial_submitter::{SerialSubmitter, SerialSubmitterMetrics},
PendingMessage,
Expand Down Expand Up @@ -182,7 +182,7 @@ impl BaseAgent for Relayer {
.clone();

let txsubmission = chain_setup.txsubmission;
let metadata_builder = MetadataBuilder::new(
let metadata_builder = BaseMetadataBuilder::new(
chain_setup,
prover_sync.clone(),
self.validator_announce.clone(),
Expand Down Expand Up @@ -269,7 +269,7 @@ impl Relayer {
fn run_destination_mailbox(
&self,
destination_mailbox: CachingMailbox,
metadata_builder: MetadataBuilder,
metadata_builder: BaseMetadataBuilder,
tx_submission: TransactionSubmissionType,
gas_payment_enforcer: Arc<GasPaymentEnforcer>,
msg_receive: UnboundedReceiver<PendingMessage>,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "messageId",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "gasAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "payment",
"type": "uint256"
}
],
"name": "GasPayment",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_messageId",
"type": "bytes32"
},
{
"internalType": "uint32",
"name": "_destinationDomain",
"type": "uint32"
},
{
"internalType": "uint256",
"name": "_gasAmount",
"type": "uint256"
},
{
"internalType": "address",
"name": "_refundAddress",
"type": "address"
}
],
"name": "payForGas",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_destinationDomain",
"type": "uint32"
},
{
"internalType": "uint256",
"name": "_gasAmount",
"type": "uint256"
}
],
"name": "quoteGasPayment",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.