Allow configs to use number or strings for numerics (#1885)

* Allow strings or integers for configuration

* Update TS for new integer change

* Fixed finality blocks parsing
pull/1890/head
Mattie Conover 2 years ago committed by GitHub
parent 7a121a8d80
commit 6ad3b39114
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      rust/agents/relayer/src/settings/matching_list.rs
  2. 4
      rust/agents/scraper/src/agent.rs
  3. 5
      rust/agents/validator/src/settings.rs
  4. 10
      rust/agents/validator/src/validator.rs
  5. 54
      rust/config/mainnet2/mainnet2_config.json
  6. 18
      rust/config/test/test_config.json
  7. 48
      rust/config/testnet3/testnet3_config.json
  8. 4
      rust/hyperlane-base/src/contract_sync/mailbox.rs
  9. 33
      rust/hyperlane-base/src/settings/chains.rs
  10. 16
      rust/hyperlane-core/src/chain.rs
  11. 79
      rust/hyperlane-core/src/utils.rs
  12. 6
      typescript/infra/config/environments/mainnet2/agent.ts
  13. 4
      typescript/infra/config/environments/testnet3/agent.ts
  14. 12
      typescript/infra/src/config/agent.ts
  15. 8
      typescript/infra/src/core/deploy.ts

@ -1,12 +1,11 @@
use std::fmt; use std::fmt;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::num::ParseIntError;
use serde::de::{Error, SeqAccess, Visitor}; use serde::de::{Error, SeqAccess, Visitor};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use hyperlane_core::{HyperlaneMessage, H160, H256}; use hyperlane_core::{utils::StrOrInt, HyperlaneMessage, H160, H256};
/// Defines a set of patterns for determining if a message should or should not /// Defines a set of patterns for determining if a message should or should not
/// be relayed. This is useful for determine if a message matches a given set or /// be relayed. This is useful for determine if a message matches a given set or
@ -57,24 +56,6 @@ impl<T: Debug> Display for Filter<T> {
} }
} }
#[derive(Deserialize)]
#[serde(untagged)]
enum StrOrInt<'a> {
Str(&'a str),
Int(u32),
}
impl TryFrom<StrOrInt<'_>> for u32 {
type Error = ParseIntError;
fn try_from(v: StrOrInt) -> Result<Self, Self::Error> {
match v {
StrOrInt::Str(s) => s.parse(),
StrOrInt::Int(i) => Ok(i),
}
}
}
struct FilterVisitor<T>(PhantomData<T>); struct FilterVisitor<T>(PhantomData<T>);
impl<'de> Visitor<'de> for FilterVisitor<u32> { impl<'de> Visitor<'de> for FilterVisitor<u32> {
type Value = Filter<u32>; type Value = Filter<u32>;

@ -62,7 +62,9 @@ impl BaseAgent for Scraper {
contract_sync_metrics.clone(), contract_sync_metrics.clone(),
) )
.await?; .await?;
let domain = chain_setup.domain.parse().expect("invalid uint"); let domain = (&chain_setup.domain)
.try_into()
.context("Invalid domain id")?;
scrapers.insert(domain, scraper); scrapers.insert(domain, scraper);
} }
} }

@ -1,6 +1,7 @@
//! Configuration //! Configuration
use hyperlane_base::decl_settings; use hyperlane_base::decl_settings;
use hyperlane_core::utils::StrOrInt;
decl_settings!(Validator { decl_settings!(Validator {
// The name of the origin chain // The name of the origin chain
@ -10,7 +11,7 @@ decl_settings!(Validator {
/// The checkpoint syncer configuration /// The checkpoint syncer configuration
checkpointsyncer: hyperlane_base::CheckpointSyncerConf, checkpointsyncer: hyperlane_base::CheckpointSyncerConf,
/// The reorg_period in blocks /// The reorg_period in blocks
reorgperiod: String, reorgperiod: StrOrInt,
/// How frequently to check for new checkpoints /// How frequently to check for new checkpoints
interval: String, interval: StrOrInt,
}); });

@ -47,8 +47,14 @@ impl BaseAgent for Validator {
.build::<hyperlane_ethereum::Signers>() .build::<hyperlane_ethereum::Signers>()
.await .await
.map(|validator| Arc::new(validator) as Arc<dyn HyperlaneSigner>)?; .map(|validator| Arc::new(validator) as Arc<dyn HyperlaneSigner>)?;
let reorg_period = settings.reorgperiod.parse().expect("invalid uint"); let reorg_period = (&settings.reorgperiod)
let interval = Duration::from_secs(settings.interval.parse().expect("invalid uint")); .try_into()
.expect("invalid reorg period");
let interval = Duration::from_secs(
(&settings.interval)
.try_into()
.expect("invalid validator interval"),
);
let core = settings.build_hyperlane_core(metrics.clone()); let core = settings.build_hyperlane_core(metrics.clone());
let checkpoint_syncer = settings.checkpointsyncer.build(None)?.into(); let checkpoint_syncer = settings.checkpointsyncer.build(None)?.into();

@ -3,7 +3,7 @@
"chains": { "chains": {
"celo": { "celo": {
"name": "celo", "name": "celo",
"domain": "42220", "domain": 42220,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -11,18 +11,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "0", "finalityBlocks": 0,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "16884144" "from": 16884144
} }
}, },
"ethereum": { "ethereum": {
"name": "ethereum", "name": "ethereum",
"domain": "1", "domain": 1,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -30,18 +30,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "14", "finalityBlocks": 14,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "16271503" "from": 16271503
} }
}, },
"avalanche": { "avalanche": {
"name": "avalanche", "name": "avalanche",
"domain": "43114", "domain": 43114,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -49,18 +49,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "3", "finalityBlocks": 3,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "24145479" "from": 24145479
} }
}, },
"polygon": { "polygon": {
"name": "polygon", "name": "polygon",
"domain": "137", "domain": 137,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -68,18 +68,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "256", "finalityBlocks": 256,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "37313389" "from": 37313389
} }
}, },
"bsc": { "bsc": {
"name": "bsc", "name": "bsc",
"domain": "56", "domain": 56,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -87,18 +87,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "15", "finalityBlocks": 15,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "25063295" "from": 25063295
} }
}, },
"arbitrum": { "arbitrum": {
"name": "arbitrum", "name": "arbitrum",
"domain": "42161", "domain": 42161,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -106,18 +106,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "0", "finalityBlocks": 0,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "49073182" "from": 49073182
} }
}, },
"optimism": { "optimism": {
"name": "optimism", "name": "optimism",
"domain": "10", "domain": 10,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -125,18 +125,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "0", "finalityBlocks": 0,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "55698988" "from": 55698988
} }
}, },
"moonbeam": { "moonbeam": {
"name": "moonbeam", "name": "moonbeam",
"domain": "1284", "domain": 1284,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -144,18 +144,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "1", "finalityBlocks": 1,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "2595747" "from": 2595747
} }
}, },
"gnosis": { "gnosis": {
"name": "gnosis", "name": "gnosis",
"domain": "100", "domain": 100,
"addresses": { "addresses": {
"mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70", "mailbox": "0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70",
"interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918", "interchainGasPaymaster": "0x6cA0B6D22da47f091B7613223cD4BB03a2d77918",
@ -163,13 +163,13 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "14", "finalityBlocks": 14,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "25900000" "from": 25900000
} }
} }
}, },

@ -3,7 +3,7 @@
"chains": { "chains": {
"test1": { "test1": {
"name": "test1", "name": "test1",
"domain": "13371", "domain": 13371,
"addresses": { "addresses": {
"mailbox": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", "mailbox": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
"interchainGasPaymaster": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", "interchainGasPaymaster": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
@ -11,18 +11,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "0", "finalityBlocks": 0,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "4" "from": 4
} }
}, },
"test2": { "test2": {
"name": "test2", "name": "test2",
"domain": "13372", "domain": 13372,
"addresses": { "addresses": {
"mailbox": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1", "mailbox": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
"interchainGasPaymaster": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE", "interchainGasPaymaster": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
@ -30,18 +30,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "1", "finalityBlocks": 1,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "16" "from": 16
} }
}, },
"test3": { "test3": {
"name": "test3", "name": "test3",
"domain": "13373", "domain": 13373,
"addresses": { "addresses": {
"mailbox": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9", "mailbox": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",
"interchainGasPaymaster": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", "interchainGasPaymaster": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
@ -49,13 +49,13 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "2", "finalityBlocks": 2,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "29" "from": 29
} }
} }
}, },

@ -3,7 +3,7 @@
"chains": { "chains": {
"alfajores": { "alfajores": {
"name": "alfajores", "name": "alfajores",
"domain": "44787", "domain": 44787,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -11,18 +11,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "0", "finalityBlocks": 0,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "14863532" "from": 14863532
} }
}, },
"fuji": { "fuji": {
"name": "fuji", "name": "fuji",
"domain": "43113", "domain": 43113,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -30,18 +30,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "3", "finalityBlocks": 3,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "16330615" "from": 16330615
} }
}, },
"mumbai": { "mumbai": {
"name": "mumbai", "name": "mumbai",
"domain": "80001", "domain": 80001,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -49,18 +49,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "32", "finalityBlocks": 32,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "29390033" "from": 29390033
} }
}, },
"bsctestnet": { "bsctestnet": {
"name": "bsctestnet", "name": "bsctestnet",
"domain": "97", "domain": 97,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -68,18 +68,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "9", "finalityBlocks": 9,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "25001629" "from": 25001629
} }
}, },
"goerli": { "goerli": {
"name": "goerli", "name": "goerli",
"domain": "5", "domain": 5,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -87,18 +87,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "2", "finalityBlocks": 2,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "8039005" "from": 8039005
} }
}, },
"moonbasealpha": { "moonbasealpha": {
"name": "moonbasealpha", "name": "moonbasealpha",
"domain": "1287", "domain": 1287,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -106,18 +106,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "1", "finalityBlocks": 1,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "3310405" "from": 3310405
} }
}, },
"optimismgoerli": { "optimismgoerli": {
"name": "optimismgoerli", "name": "optimismgoerli",
"domain": "420", "domain": 420,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -125,18 +125,18 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "1", "finalityBlocks": 1,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "3055263" "from": 3055263
} }
}, },
"arbitrumgoerli": { "arbitrumgoerli": {
"name": "arbitrumgoerli", "name": "arbitrumgoerli",
"domain": "421613", "domain": 421613,
"addresses": { "addresses": {
"mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685",
"interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a",
@ -144,13 +144,13 @@
}, },
"signer": null, "signer": null,
"protocol": "ethereum", "protocol": "ethereum",
"finalityBlocks": "1", "finalityBlocks": 1,
"connection": { "connection": {
"type": "http", "type": "http",
"url": "" "url": ""
}, },
"index": { "index": {
"from": "1941997" "from": 1941997
} }
} }
}, },

@ -410,8 +410,8 @@ mod test {
hyperlane_db.clone(), hyperlane_db.clone(),
indexer, indexer,
IndexSettings { IndexSettings {
from: Some("0".to_string()), from: Some(0.into()),
chunk: Some("19".to_string()), chunk: Some(19.into()),
}, },
sync_metrics, sync_metrics,
); );

@ -8,17 +8,16 @@ use ethers_prometheus::middleware::{
ChainInfo, ContractInfo, PrometheusMiddlewareConf, WalletInfo, ChainInfo, ContractInfo, PrometheusMiddlewareConf, WalletInfo,
}; };
use hyperlane_core::{ use hyperlane_core::{
ContractLocator, HyperlaneAbi, HyperlaneDomain, HyperlaneDomainProtocol, HyperlaneProvider, utils::StrOrInt, ContractLocator, HyperlaneAbi, HyperlaneDomain, HyperlaneDomainProtocol,
HyperlaneSigner, InterchainGasPaymaster, InterchainGasPaymasterIndexer, Mailbox, HyperlaneProvider, HyperlaneSigner, InterchainGasPaymaster, InterchainGasPaymasterIndexer,
MailboxIndexer, MultisigIsm, ValidatorAnnounce, H256, Mailbox, MailboxIndexer, MultisigIsm, ValidatorAnnounce, H256,
}; };
use hyperlane_ethereum::{ use hyperlane_ethereum::{
self as h_eth, BuildableWithProvider, EthereumInterchainGasPaymasterAbi, EthereumMailboxAbi, self as h_eth, BuildableWithProvider, EthereumInterchainGasPaymasterAbi, EthereumMailboxAbi,
}; };
use hyperlane_fuel::{self as h_fuel, prelude::*}; use hyperlane_fuel::{self as h_fuel, prelude::*};
use crate::settings::signers::BuildableWithSignerConf; use crate::{settings::signers::BuildableWithSignerConf, CoreMetrics, SignerConf};
use crate::{CoreMetrics, SignerConf};
/// A connection to _some_ blockchain. /// A connection to _some_ blockchain.
/// ///
@ -84,10 +83,10 @@ pub struct CoreContractAddresses {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct IndexSettings { pub struct IndexSettings {
/// The height at which to start indexing the Outbox contract /// The height at which to start indexing the Outbox contract
pub from: Option<String>, pub from: Option<StrOrInt>,
/// The number of blocks to query at once at which to start indexing the /// The number of blocks to query at once at which to start indexing the
/// Mailbox contract /// Mailbox contract
pub chunk: Option<String>, pub chunk: Option<StrOrInt>,
} }
impl IndexSettings { impl IndexSettings {
@ -95,7 +94,7 @@ impl IndexSettings {
pub fn from(&self) -> u32 { pub fn from(&self) -> u32 {
self.from self.from
.as_ref() .as_ref()
.and_then(|s| s.parse::<u32>().ok()) .and_then(|s| s.try_into().ok())
.unwrap_or_default() .unwrap_or_default()
} }
@ -103,24 +102,24 @@ impl IndexSettings {
pub fn chunk_size(&self) -> u32 { pub fn chunk_size(&self) -> u32 {
self.chunk self.chunk
.as_ref() .as_ref()
.and_then(|s| s.parse::<u32>().ok()) .and_then(|s| s.try_into().ok())
.unwrap_or(1999) .unwrap_or(1999)
} }
} }
/// A chain setup is a domain ID, an address on that chain (where the mailbox is /// A chain setup is a domain ID, an address on that chain (where the mailbox is
/// deployed) and details for connecting to the chain API. /// deployed) and details for connecting to the chain API.
#[derive(Clone, Debug, Deserialize, Default)] #[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChainSetup { pub struct ChainSetup {
/// Chain name /// Chain name
pub name: String, pub name: String,
/// Chain domain identifier /// Chain domain identifier
pub domain: String, pub domain: StrOrInt,
/// Signer configuration for this chain /// Signer configuration for this chain
pub signer: Option<SignerConf>, pub signer: Option<SignerConf>,
/// Number of blocks until finality /// Number of blocks until finality
pub finality_blocks: String, pub finality_blocks: StrOrInt,
/// Addresses of contracts on the chain /// Addresses of contracts on the chain
pub addresses: CoreContractAddresses, pub addresses: CoreContractAddresses,
/// The chain connection details /// The chain connection details
@ -313,14 +312,18 @@ impl ChainSetup {
/// Get the domain for this chain setup /// Get the domain for this chain setup
pub fn domain(&self) -> Result<HyperlaneDomain> { pub fn domain(&self) -> Result<HyperlaneDomain> {
HyperlaneDomain::from_config_strs(&self.domain, &self.name, self.chain.protocol()) HyperlaneDomain::from_config(
(&self.domain).try_into().context("Invalid domain id")?,
&self.name,
self.chain.protocol(),
)
.map_err(|e| eyre!("{e}")) .map_err(|e| eyre!("{e}"))
} }
/// Get the number of blocks until finality /// Get the number of blocks until finality
fn finality_blocks(&self) -> u32 { fn finality_blocks(&self) -> u32 {
self.finality_blocks (&self.finality_blocks)
.parse::<u32>() .try_into()
.expect("could not parse finality_blocks") .expect("could not parse finality_blocks")
} }

@ -284,20 +284,6 @@ impl HyperlaneDomain {
} }
} }
pub fn from_config_strs(
domain_id: &str,
name: &str,
protocol: HyperlaneDomainProtocol,
) -> Result<Self, &'static str> {
HyperlaneDomain::from_config(
domain_id
.parse::<u32>()
.map_err(|_| "Domain id is an invalid uint")?,
name,
protocol,
)
}
/// The chain name /// The chain name
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match self { match self {
@ -425,7 +411,7 @@ mod tests {
.flat_map(|x: &Settings| { .flat_map(|x: &Settings| {
x.chains.iter().map(|(_, v)| ChainCoordinate { x.chains.iter().map(|(_, v)| ChainCoordinate {
name: v.name.clone(), name: v.name.clone(),
domain: v.domain.parse().unwrap(), domain: (&v.domain).try_into().expect("Invalid domain id"),
}) })
}) })
.collect() .collect()

@ -1,5 +1,8 @@
use std::fmt::{Debug, Formatter};
use std::num::{ParseIntError, TryFromIntError};
use std::str::FromStr; use std::str::FromStr;
use serde::Deserialize;
use sha3::{digest::Update, Digest, Keccak256}; use sha3::{digest::Update, Digest, Keccak256};
use thiserror::Error; use thiserror::Error;
@ -128,6 +131,82 @@ pub fn fmt_domain(domain: u32) -> String {
.unwrap_or_else(|_| domain.to_string()) .unwrap_or_else(|_| domain.to_string())
} }
/// An error when parsing a StrOrInt type as an integer value.
#[derive(Error, Debug)]
pub enum StrOrIntParseError {
/// The string is not a valid integer
#[error("Invalid integer provided as a string: {0}")]
StrParse(#[from] ParseIntError),
/// The provided integer does not match the type requirements.
#[error("Provided number is an invalid integer: {0}")]
InvalidInt(#[from] TryFromIntError),
}
/// A type which can be used for parsing configs that may be provided as a
/// string or an integer but will ultimately be read as an integer. E.g. where
/// `"domain": "42"` and `"domain": 42` should both be considered valid.
#[derive(Clone, Deserialize)]
#[serde(untagged)]
pub enum StrOrInt {
/// The parsed type is a string
Str(String),
/// The parsed type is an integer
Int(i64),
}
impl Debug for StrOrInt {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
StrOrInt::Str(v) => write!(f, "\"{v}\""),
StrOrInt::Int(v) => write!(f, "{}", *v),
}
}
}
impl From<i64> for StrOrInt {
fn from(value: i64) -> Self {
StrOrInt::Int(value)
}
}
impl From<String> for StrOrInt {
fn from(value: String) -> Self {
StrOrInt::Str(value)
}
}
impl From<&str> for StrOrInt {
fn from(value: &str) -> Self {
StrOrInt::Str(value.to_owned())
}
}
macro_rules! convert_to {
($t:ty) => {
impl TryFrom<StrOrInt> for $t {
type Error = StrOrIntParseError;
fn try_from(v: StrOrInt) -> Result<Self, Self::Error> {
(&v).try_into()
}
}
impl TryFrom<&StrOrInt> for $t {
type Error = StrOrIntParseError;
fn try_from(v: &StrOrInt) -> Result<Self, Self::Error> {
Ok(match v {
StrOrInt::Str(s) => s.parse()?,
StrOrInt::Int(i) => (*i).try_into()?,
})
}
}
};
}
convert_to!(u32);
convert_to!(u64);
/// Shortcut for many-to-one match statements that get very redundant. Flips the /// Shortcut for many-to-one match statements that get very redundant. Flips the
/// order such that the thing which is mapped to is listed first. /// order such that the thing which is mapped to is listed first.
/// ///

@ -47,14 +47,14 @@ export const hyperlane: AgentConfig = {
blacklist: [ blacklist: [
...releaseCandidateHelloworldMatchingList, ...releaseCandidateHelloworldMatchingList,
{ {
originDomain: '137', originDomain: 137,
recipientAddress: '0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE', recipientAddress: '0xBC3cFeca7Df5A45d61BC60E7898E63670e1654aE',
}, },
], ],
gasPaymentEnforcement: { gasPaymentEnforcement: {
policy: { policy: {
type: GasPaymentEnforcementPolicyType.Minimum, type: GasPaymentEnforcementPolicyType.Minimum,
payment: 1, payment: BigInt(1),
}, },
// To continue relaying interchain query callbacks, we whitelist // To continue relaying interchain query callbacks, we whitelist
// all messages between interchain query routers. // all messages between interchain query routers.
@ -91,7 +91,7 @@ export const releaseCandidate: AgentConfig = {
gasPaymentEnforcement: { gasPaymentEnforcement: {
policy: { policy: {
type: GasPaymentEnforcementPolicyType.Minimum, type: GasPaymentEnforcementPolicyType.Minimum,
payment: 1, payment: BigInt(1),
}, },
whitelist: interchainQueriesMatchingList, whitelist: interchainQueriesMatchingList,
}, },

@ -51,7 +51,7 @@ export const hyperlane: AgentConfig = {
gasPaymentEnforcement: { gasPaymentEnforcement: {
policy: { policy: {
type: GasPaymentEnforcementPolicyType.Minimum, type: GasPaymentEnforcementPolicyType.Minimum,
payment: 1, payment: BigInt(1),
}, },
// To continue relaying interchain query callbacks, we whitelist // To continue relaying interchain query callbacks, we whitelist
// all messages between interchain query routers. // all messages between interchain query routers.
@ -88,7 +88,7 @@ export const releaseCandidate: AgentConfig = {
gasPaymentEnforcement: { gasPaymentEnforcement: {
policy: { policy: {
type: GasPaymentEnforcementPolicyType.Minimum, type: GasPaymentEnforcementPolicyType.Minimum,
payment: 1, // require 1 wei payment: BigInt(1), // require 1 wei
}, },
whitelist: interchainQueriesMatchingList, whitelist: interchainQueriesMatchingList,
}, },

@ -36,9 +36,9 @@ export function getChainOverriddenConfig<T>(
export type MatchingList = MatchingListElement[]; export type MatchingList = MatchingListElement[];
interface MatchingListElement { interface MatchingListElement {
originDomain?: '*' | string | string[] | number | number[]; originDomain?: '*' | number | number[];
senderAddress?: '*' | string | string[]; senderAddress?: '*' | string | string[];
destinationDomain?: '*' | string | string[] | number | number[]; destinationDomain?: '*' | number | number[];
recipientAddress?: '*' | string | string[]; recipientAddress?: '*' | string | string[];
} }
@ -54,7 +54,7 @@ export type GasPaymentEnforcementPolicy =
} }
| { | {
type: GasPaymentEnforcementPolicyType.Minimum; type: GasPaymentEnforcementPolicyType.Minimum;
payment: string | number; payment: bigint;
} }
| { | {
type: GasPaymentEnforcementPolicyType.MeetsEstimatedCost; type: GasPaymentEnforcementPolicyType.MeetsEstimatedCost;
@ -252,13 +252,13 @@ export type RustCoreAddresses = {
export type RustChainSetup = { export type RustChainSetup = {
name: ChainName; name: ChainName;
domain: string; domain: number;
signer?: RustSigner | null; signer?: RustSigner | null;
finalityBlocks: string; finalityBlocks: number;
addresses: RustCoreAddresses; addresses: RustCoreAddresses;
protocol: 'ethereum' | 'fuel'; protocol: 'ethereum' | 'fuel';
connection: RustConnection; connection: RustConnection;
index?: { from: string }; index?: { from: number };
}; };
export type RustConfig = { export type RustConfig = {

@ -125,7 +125,7 @@ export class HyperlaneCoreInfraDeployer extends HyperlaneCoreDeployer {
const chainConfig: RustChainSetup = { const chainConfig: RustChainSetup = {
name: chain, name: chain,
domain: metadata.chainId.toString(), domain: metadata.chainId,
addresses: { addresses: {
mailbox: contracts.mailbox.contract.address, mailbox: contracts.mailbox.contract.address,
interchainGasPaymaster: contracts.interchainGasPaymaster.address, interchainGasPaymaster: contracts.interchainGasPaymaster.address,
@ -133,7 +133,7 @@ export class HyperlaneCoreInfraDeployer extends HyperlaneCoreDeployer {
}, },
signer: null, signer: null,
protocol: 'ethereum', protocol: 'ethereum',
finalityBlocks: metadata.blocks!.reorgPeriod!.toString(), finalityBlocks: metadata.blocks!.reorgPeriod!,
connection: { connection: {
type: ConnectionType.Http, type: ConnectionType.Http,
url: '', url: '',
@ -141,10 +141,10 @@ export class HyperlaneCoreInfraDeployer extends HyperlaneCoreDeployer {
}; };
const startingBlockNumber = this.startingBlockNumbers[chain]; const startingBlockNumber = this.startingBlockNumbers[chain];
if (startingBlockNumber) { if (startingBlockNumber) {
chainConfig.index = { from: startingBlockNumber.toString() }; chainConfig.index = { from: startingBlockNumber };
} }
rustConfig.chains[chain] = chainConfig; rustConfig.chains[chain] = chainConfig;
}); });
writeJSON(directory, `${this.environment}_config.json`, rustConfig); writeJSON(directory, `${this.environment}_config.json`, rustConfig);

Loading…
Cancel
Save