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

V3 agents rebase #2746

Merged
merged 65 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
d7dc8af
contract changes from v3-agents branch
daniel-savu Sep 21, 2023
c58d664
add mrh builder
aroralanuk Sep 18, 2023
3151149
store in rocksDB
aroralanuk Sep 18, 2023
80ab924
feat(relayer): merkle insertion indexer
daniel-savu Sep 19, 2023
4555704
wip(relayer): merkle builder task
daniel-savu Sep 20, 2023
423ad5f
first merkle tree task impl
daniel-savu Sep 20, 2023
b3a1f45
finish merkle tree processor implementation
daniel-savu Sep 20, 2023
9dc552e
fix: clippy
daniel-savu Sep 20, 2023
6b3a3bb
cleanup
daniel-savu Sep 20, 2023
240d6ee
review fixes
daniel-savu Sep 21, 2023
0bdb5e6
trigger e2e
daniel-savu Sep 21, 2023
9fd8f8d
hyperlane interceptor
aroralanuk Sep 21, 2023
bcf40b6
fix compilation
daniel-savu Sep 22, 2023
f8008cb
Hopefully fixed agent config artifact writing for e2e
tkporter Sep 25, 2023
4e16acc
Fix yarn kathy maybe
tkporter Sep 25, 2023
2e5f00c
fix: e2e tests don't crash (but don't pass)
daniel-savu Sep 25, 2023
6f5e404
fmt
daniel-savu Sep 25, 2023
852b29b
fix: out of gas v3 txs
daniel-savu Sep 25, 2023
f7911c1
fix?: yarn clean before e2e
daniel-savu Sep 26, 2023
e90d85e
fix: mailbox count
daniel-savu Sep 26, 2023
2813272
temporarily ignore build cache
daniel-savu Sep 26, 2023
233d93c
remove yarn clean now that cache is ignored
daniel-savu Sep 26, 2023
85f60b6
refactor: decouple merkle tree hook logic from mailbox logic
daniel-savu Sep 26, 2023
67adfd2
merkle interceptor
aroralanuk Sep 26, 2023
15d7a50
op stack with postDeploy
aroralanuk Sep 27, 2023
2719423
fix: use 0/2 aggregation ISM; do not crash validator if no `count()`
daniel-savu Sep 27, 2023
92ce7f1
add console
aroralanuk Sep 27, 2023
dfd41ef
Merge branch 'v3' into hyperlane-interceptor-deployer
aroralanuk Sep 27, 2023
77060cc
merkle standalone
aroralanuk Sep 28, 2023
8804d95
update validatorKey test fix
aroralanuk Sep 28, 2023
191da20
add to e2e
aroralanuk Sep 28, 2023
2ce86fa
Merge branch 'v3' into hyperlane-interceptor-deployer
aroralanuk Sep 28, 2023
05cd4e2
Merge remote-tracking branch 'origin/hyperlane-interceptor-deployer' …
aroralanuk Sep 28, 2023
19faea7
chainmap mailboxes
aroralanuk Sep 28, 2023
a078621
re-enable sealevel e2e
daniel-savu Sep 29, 2023
5455b14
fix core deploy errpr
aroralanuk Sep 29, 2023
23567f8
revert multisig changes
aroralanuk Sep 29, 2023
f516184
handleDeploy -> deployContract
aroralanuk Sep 29, 2023
10d647f
Merge branch 'hyperlane-interceptor-deployer' into v3-agents-rebase
daniel-savu Sep 29, 2023
df6ee62
fix e2e to include merkle tree hook interceptor
daniel-savu Sep 29, 2023
040bdbf
Streamline Rust Agent Config Shapes (#2659)
mattiekat Oct 2, 2023
108cfd2
cleanup hook->interceptor
aroralanuk Sep 29, 2023
0736222
messageId deployer as well
aroralanuk Oct 2, 2023
10c4fbc
only deployer merkleTreeHook
aroralanuk Oct 2, 2023
a1d753f
fix redundant return false
aroralanuk Oct 2, 2023
535b637
left out hyperlaneHookDeployert
aroralanuk Oct 2, 2023
72e65b4
spelling fixes
aroralanuk Oct 2, 2023
bb2ad2c
feat: use merkle tree hook artifact in agents
daniel-savu Oct 3, 2023
33417b4
revert to standard igp / merkle tree hook setup
daniel-savu Oct 3, 2023
2c16b37
chore: re-enable cache
daniel-savu Oct 3, 2023
291eb93
fix: validator announce
daniel-savu Oct 3, 2023
0ba2b9c
Merge branch 'v3' into v3-agents-rebase
yorhodes Oct 3, 2023
2907581
Try taking v3 solidity and typescript
yorhodes Oct 3, 2023
1a1eb88
Setup e2e tests with hook deployment
yorhodes Oct 3, 2023
4e0c472
Streamline Rust Agent Config Shapes (#2659)
mattiekat Oct 2, 2023
d4c587a
Fix kathy
yorhodes Oct 3, 2023
9f999a3
TEMP: try disabling sealevel e2e
yorhodes Oct 3, 2023
58e289f
wip: update metadata format in agents
daniel-savu Oct 4, 2023
a76a4c8
feat: v3 metadata
daniel-savu Oct 4, 2023
6f639e7
Revert "TEMP: try disabling sealevel e2e"
daniel-savu Oct 4, 2023
7bfe7cd
temp: disable sealevel e2e invariants
daniel-savu Oct 4, 2023
044b523
Merge branch 'v3' into v3-agents-rebase
daniel-savu Oct 4, 2023
9f88da0
fix clippy
daniel-savu Oct 4, 2023
9448b66
fix: yorke's review comments
daniel-savu Oct 4, 2023
863ecfd
fix: trevor's 1st round of comments
daniel-savu Oct 4, 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
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [main]
pull_request:
branches: [main]
branches: '*'
workflow_dispatch:

concurrency:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ yarn-error.log
**/*.ignore
.vscode

tsconfig.editor.json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added by @mattiecnvr afaik

16 changes: 16 additions & 0 deletions rust/Cargo.lock

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

1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Inflector = "0.11.4"
anyhow = "1.0"
async-trait = "0.1"
auto_impl = "1.0"
backoff = { version = "0.4.0", features = ["tokio"] }
backtrace = "0.3"
base64 = "0.21.2"
bincode = "1.3"
Expand Down
2 changes: 2 additions & 0 deletions rust/agents/relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ version.workspace = true

[dependencies]
async-trait.workspace = true
backoff.workspace = true
config.workspace = true
convert_case.workspace = true
derive-new.workspace = true
derive_more.workspace = true
enum_dispatch.workspace = true
Expand Down
3 changes: 2 additions & 1 deletion rust/agents/relayer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use hyperlane_base::agent_main;

use crate::relayer::Relayer;

mod merkle_tree_builder;
mod merkle_tree;
mod msg;
mod processor;
mod prover;
mod relayer;
mod settings;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::Display;

use eyre::Result;
use eyre::{Context, Result};
use tracing::{debug, error, instrument};

use hyperlane_base::db::{DbError, HyperlaneRocksDB};
Expand Down Expand Up @@ -50,12 +50,6 @@ pub enum MerkleTreeBuilderError {
/// Root of the incremental merkle tree
incremental_root: H256,
},
/// Nonce was not found in DB, despite batch providing messages after
#[error("Nonce was not found {nonce:?}")]
UnavailableNonce {
/// Root of prover's local merkle tree
nonce: u32,
},
Comment on lines -53 to -58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we dont need this anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't find any uses of it

/// MerkleTreeBuilder attempts Prover operation and receives ProverError
#[error(transparent)]
ProverError(#[from] ProverError),
Expand All @@ -65,6 +59,9 @@ pub enum MerkleTreeBuilderError {
/// DB Error
#[error("{0}")]
DbError(#[from] DbError),
/// Some other error occured.
#[error("Failed to build the merkle tree: {0}")]
Other(String),
}

impl MerkleTreeBuilder {
Expand All @@ -81,54 +78,38 @@ impl MerkleTreeBuilder {
#[instrument(err, skip(self), level="debug", fields(prover_latest_index=self.count()-1))]
pub fn get_proof(
&self,
leaf_index: u32,
message_nonce: u32,
root_index: u32,
) -> Result<Proof, MerkleTreeBuilderError> {
) -> Result<Option<Proof>, MerkleTreeBuilderError> {
let Some(leaf_index) = self
.db
.retrieve_message_id_by_nonce(&message_nonce)?
.and_then(|message_id| self.db.retrieve_merkle_leaf_index_by_message_id(&message_id).ok().flatten())
else {
return Ok(None);
};
self.prover
.prove_against_previous(leaf_index as usize, root_index as usize)
.map(Option::from)
.map_err(Into::into)
}

fn ingest_nonce(&mut self, nonce: u32) -> Result<(), MerkleTreeBuilderError> {
match self.db.retrieve_message_id_by_nonce(&nonce) {
Ok(Some(leaf)) => {
debug!(nonce, "Ingesting leaf");
self.prover.ingest(leaf).expect("!tree full");
self.incremental.ingest(leaf);
assert_eq!(self.prover.root(), self.incremental.root());
Ok(())
}
Ok(None) => {
error!("We should not arrive here");
Err(MerkleTreeBuilderError::UnavailableNonce { nonce })
}
Err(e) => Err(e.into()),
}
}

pub fn count(&self) -> u32 {
self.prover.count() as u32
}

#[instrument(err, skip(self), level = "debug")]
pub async fn update_to_index(&mut self, index: u32) -> Result<(), MerkleTreeBuilderError> {
if index >= self.count() {
let starting_index = self.prover.count() as u32;
for i in starting_index..=index {
self.db.wait_for_message_nonce(i).await?;
self.ingest_nonce(i)?;
}

let prover_root = self.prover.root();
let incremental_root = self.incremental.root();
if prover_root != incremental_root {
return Err(MerkleTreeBuilderError::MismatchedRoots {
prover_root,
incremental_root,
});
}
pub async fn ingest_message_id(&mut self, message_id: H256) -> Result<()> {
const CTX: &str = "When ingesting message id";
debug!(?message_id, "Ingesting leaf");
self.prover.ingest(message_id).expect("tree full");
self.incremental.ingest(message_id);
match self.prover.root().eq(&self.incremental.root()) {
true => Ok(()),
false => Err(MerkleTreeBuilderError::MismatchedRoots {
prover_root: self.prover.root(),
incremental_root: self.incremental.root(),
}),
}

Ok(())
.context(CTX)
}
}
2 changes: 2 additions & 0 deletions rust/agents/relayer/src/merkle_tree/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub(crate) mod builder;
pub(crate) mod processor;
101 changes: 101 additions & 0 deletions rust/agents/relayer/src/merkle_tree/processor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use std::{
fmt::{Debug, Formatter},
sync::Arc,
time::Duration,
};

use async_trait::async_trait;
use derive_new::new;
use eyre::Result;
use hyperlane_base::db::HyperlaneRocksDB;
use hyperlane_core::{HyperlaneDomain, MerkleTreeInsertion};
use prometheus::IntGauge;
use tokio::sync::RwLock;
use tracing::debug;

use crate::processor::ProcessorExt;

use super::builder::MerkleTreeBuilder;

/// Finds unprocessed merkle tree insertions and adds them to the prover sync
#[derive(new)]
pub struct MerkleTreeProcessor {
db: HyperlaneRocksDB,
metrics: MerkleTreeProcessorMetrics,
prover_sync: Arc<RwLock<MerkleTreeBuilder>>,
#[new(default)]
daniel-savu marked this conversation as resolved.
Show resolved Hide resolved
leaf_index: u32,
}

impl Debug for MerkleTreeProcessor {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"MerkleTreeProcessor {{ leaf_index: {:?} }}",
self.leaf_index
)
}
}

#[async_trait]
impl ProcessorExt for MerkleTreeProcessor {
/// The domain this processor is getting merkle tree hook insertions from.
fn domain(&self) -> &HyperlaneDomain {
self.db.domain()
}

/// One round of processing, extracted from infinite work loop for
/// testing purposes.
async fn tick(&mut self) -> Result<()> {
if let Some(insertion) = self.next_unprocessed_leaf()? {
// Feed the message to the prover sync
self.prover_sync
.write()
.await
.ingest_message_id(insertion.message_id())
.await?;

// Increase the leaf index to move on to the next leaf
self.leaf_index += 1;
} else {
tokio::time::sleep(Duration::from_secs(1)).await;
}
Ok(())
}
}

impl MerkleTreeProcessor {
fn next_unprocessed_leaf(&mut self) -> Result<Option<MerkleTreeInsertion>> {
let leaf = if let Some(insertion) = self
.db
.retrieve_merkle_tree_insertion_by_leaf_index(&self.leaf_index)?
{
// Update the metrics
self.metrics
.max_leaf_index_gauge
.set(insertion.index() as i64);
Some(insertion)
} else {
debug!(leaf_index=?self.leaf_index, "No message found in DB for leaf index");
None
};
Ok(leaf)
}
}

#[derive(Debug)]
pub struct MerkleTreeProcessorMetrics {
max_leaf_index_gauge: IntGauge,
}

impl MerkleTreeProcessorMetrics {
pub fn new() -> Self {
Self {
max_leaf_index_gauge: IntGauge::new(
"max_leaf_index_gauge",
"The max merkle tree leaf index",
)
.unwrap(),
}
}
}
21 changes: 10 additions & 11 deletions rust/agents/relayer/src/msg/gas_payment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ use std::fmt::Debug;

use async_trait::async_trait;
use eyre::Result;
use tracing::{debug, error, trace};

use hyperlane_base::db::HyperlaneRocksDB;
use hyperlane_core::{
GasPaymentKey, HyperlaneMessage, InterchainGasExpenditure, InterchainGasPayment,
TxCostEstimate, TxOutcome, U256,
};

use crate::msg::gas_payment::policies::GasPaymentPolicyOnChainFeeQuoting;
use crate::settings::{
matching_list::MatchingList, GasPaymentEnforcementConf, GasPaymentEnforcementPolicy,
};
use tracing::{debug, error, trace};

use self::policies::{GasPaymentPolicyMinimum, GasPaymentPolicyNone};
use crate::{
msg::gas_payment::policies::GasPaymentPolicyOnChainFeeQuoting,
settings::{
matching_list::MatchingList, GasPaymentEnforcementConf, GasPaymentEnforcementPolicy,
},
};

mod policies;

Expand Down Expand Up @@ -148,12 +148,11 @@ mod test {
H256, U256,
};

use super::GasPaymentEnforcer;
use crate::settings::{
matching_list::MatchingList, GasPaymentEnforcementConf, GasPaymentEnforcementPolicy,
};

use super::GasPaymentEnforcer;

#[tokio::test]
async fn test_empty_whitelist() {
test_utils::run_test_db(|db| async move {
Expand Down Expand Up @@ -195,7 +194,7 @@ mod test {
test_utils::run_test_db(|db| async move {
let hyperlane_db =
HyperlaneRocksDB::new(&HyperlaneDomain::new_test_domain("test_no_match"), db);
let matching_list = serde_json::from_str(r#"[{"originDomain": 234}]"#).unwrap();
let matching_list = serde_json::from_str(r#"[{"origindomain": 234}]"#).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this necessary? assuming this is from Mattie's config change but curious if this implies that originDomain doesn't work anymore

Copy link
Contributor Author

@daniel-savu daniel-savu Oct 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what this tests is whether the config is robust against casing inconsistencies and that originDomain will still work

let enforcer = GasPaymentEnforcer::new(
// Require a payment
vec![GasPaymentEnforcementConf {
Expand Down Expand Up @@ -339,7 +338,7 @@ mod test {
let recipient_address = "0xbb000000000000000000000000000000000000bb";

let matching_list = serde_json::from_str(
&format!(r#"[{{"senderAddress": "{sender_address}", "recipientAddress": "{recipient_address}"}}]"#)
&format!(r#"[{{"senderaddress": "{sender_address}", "recipientaddress": "{recipient_address}"}}]"#)
).unwrap();

let enforcer = GasPaymentEnforcer::new(
Expand Down
Loading