Skip to content

Commit

Permalink
Streamline Rust Agent Config Shapes (#2659)
Browse files Browse the repository at this point in the history
### Description
Continues the updates to the rust config shapes by updating deployment
and runtime expectations. This PR also attempts to rely on the new
single source of truth created by the schema in the SDK as much as
reasonably possible which helped delete more code but also give some
guarantees of consistency.

THIS IS A BREAKING CHANGE! It changes the config shapes the agents want
and we should not merge this until we are ready.

Fixes #2215

---------

Co-authored-by: Guillaume Bouvignies <guillaumebouvignies@gmail.com>
Co-authored-by: Yorke Rhodes <yorke@hyperlane.xyz>
Co-authored-by: Guillaume Bouvignies <guillaume.bouvignies@kurtosistech.com>
  • Loading branch information
4 people authored Oct 2, 2023
1 parent df6ee62 commit 040bdbf
Show file tree
Hide file tree
Showing 78 changed files with 833 additions and 2,314 deletions.
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
1 change: 1 addition & 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/agents/relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ version.workspace = true
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
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();
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
83 changes: 73 additions & 10 deletions rust/agents/relayer/src/settings/matching_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ use serde::{
/// - wildcard "*"
/// - single value in decimal or hex (must start with `0x`) format
/// - list of values in decimal or hex format
#[derive(Debug, Deserialize, Default, Clone)]
#[serde(transparent)]
#[derive(Debug, Default, Clone)]
pub struct MatchingList(Option<Vec<ListElement>>);

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -63,6 +62,55 @@ impl<T: Debug> Display for Filter<T> {
}
}

struct MatchingListVisitor;
impl<'de> Visitor<'de> for MatchingListVisitor {
type Value = MatchingList;

fn expecting(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "an optional list of matching rules")
}

fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: Error,
{
Ok(MatchingList(None))
}

fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let list: Vec<ListElement> = deserializer.deserialize_seq(MatchingListArrayVisitor)?;
Ok(if list.is_empty() {
// this allows for empty matching lists to be treated as if no matching list was set
MatchingList(None)
} else {
MatchingList(Some(list))
})
}
}

struct MatchingListArrayVisitor;
impl<'de> Visitor<'de> for MatchingListArrayVisitor {
type Value = Vec<ListElement>;

fn expecting(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "a list of matching rules")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut rules = seq.size_hint().map(Vec::with_capacity).unwrap_or_default();
while let Some(rule) = seq.next_element::<ListElement>()? {
rules.push(rule);
}
Ok(rules)
}
}

struct FilterVisitor<T>(PhantomData<T>);
impl<'de> Visitor<'de> for FilterVisitor<u32> {
type Value = Filter<u32>;
Expand Down Expand Up @@ -145,6 +193,15 @@ impl<'de> Visitor<'de> for FilterVisitor<H256> {
}
}

impl<'de> Deserialize<'de> for MatchingList {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
d.deserialize_option(MatchingListVisitor)
}
}

impl<'de> Deserialize<'de> for Filter<u32> {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
Expand All @@ -166,13 +223,13 @@ impl<'de> Deserialize<'de> for Filter<H256> {
#[derive(Debug, Deserialize, Clone)]
#[serde(tag = "type")]
struct ListElement {
#[serde(default, rename = "originDomain")]
#[serde(default, rename = "origindomain")]
origin_domain: Filter<u32>,
#[serde(default, rename = "senderAddress")]
#[serde(default, rename = "senderaddress")]
sender_address: Filter<H256>,
#[serde(default, rename = "destinationDomain")]
#[serde(default, rename = "destinationdomain")]
destination_domain: Filter<u32>,
#[serde(default, rename = "recipientAddress")]
#[serde(default, rename = "recipientaddress")]
recipient_address: Filter<H256>,
}

Expand Down Expand Up @@ -266,7 +323,7 @@ mod test {

#[test]
fn basic_config() {
let list: MatchingList = serde_json::from_str(r#"[{"originDomain": "*", "senderAddress": "*", "destinationDomain": "*", "recipientAddress": "*"}, {}]"#).unwrap();
let list: MatchingList = serde_json::from_str(r#"[{"origindomain": "*", "senderaddress": "*", "destinationdomain": "*", "recipientaddress": "*"}, {}]"#).unwrap();
assert!(list.0.is_some());
assert_eq!(list.0.as_ref().unwrap().len(), 2);
let elem = &list.0.as_ref().unwrap()[0];
Expand Down Expand Up @@ -307,7 +364,7 @@ mod test {

#[test]
fn config_with_address() {
let list: MatchingList = serde_json::from_str(r#"[{"senderAddress": "0x9d4454B023096f34B160D6B654540c56A1F81688", "recipientAddress": "0x9d4454B023096f34B160D6B654540c56A1F81688"}]"#).unwrap();
let list: MatchingList = serde_json::from_str(r#"[{"senderaddress": "0x9d4454B023096f34B160D6B654540c56A1F81688", "recipientaddress": "0x9d4454B023096f34B160D6B654540c56A1F81688"}]"#).unwrap();
assert!(list.0.is_some());
assert_eq!(list.0.as_ref().unwrap().len(), 1);
let elem = &list.0.as_ref().unwrap()[0];
Expand Down Expand Up @@ -361,7 +418,7 @@ mod test {
#[test]
fn config_with_multiple_domains() {
let whitelist: MatchingList =
serde_json::from_str(r#"[{"destinationDomain": ["13372", "13373"]}]"#).unwrap();
serde_json::from_str(r#"[{"destinationdomain": ["13372", "13373"]}]"#).unwrap();
assert!(whitelist.0.is_some());
assert_eq!(whitelist.0.as_ref().unwrap().len(), 1);
let elem = &whitelist.0.as_ref().unwrap()[0];
Expand All @@ -371,6 +428,12 @@ mod test {
assert_eq!(elem.sender_address, Wildcard);
}

#[test]
fn config_with_empty_list_is_none() {
let whitelist: MatchingList = serde_json::from_str(r#"[]"#).unwrap();
assert!(whitelist.0.is_none());
}

#[test]
fn matches_empty_list() {
let info = MatchInfo {
Expand All @@ -388,7 +451,7 @@ mod test {
#[test]
fn supports_base58() {
serde_json::from_str::<MatchingList>(
r#"[{"originDomain":1399811151,"senderAddress":"DdTMkk9nuqH5LnD56HLkPiKMV3yB3BNEYSQfgmJHa5i7","destinationDomain":11155111,"recipientAddress":"0x6AD4DEBA8A147d000C09de6465267a9047d1c217"}]"#,
r#"[{"origindomain":1399811151,"senderaddress":"DdTMkk9nuqH5LnD56HLkPiKMV3yB3BNEYSQfgmJHa5i7","destinationdomain":11155111,"recipientaddress":"0x6AD4DEBA8A147d000C09de6465267a9047d1c217"}]"#,
).unwrap();
}
}
Loading

0 comments on commit 040bdbf

Please sign in to comment.