Skip to content

Commit 5acd5c4

Browse files
authored
feat(tron): isms (#7830)
1 parent 6b373bb commit 5acd5c4

7 files changed

Lines changed: 315 additions & 5 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub use {aggregation_ism::*, interchain_security_module::*, multisig_ism::*, routing_ism::*};
2+
3+
mod aggregation_ism;
4+
mod interchain_security_module;
5+
mod multisig_ism;
6+
mod routing_ism;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#![allow(clippy::enum_variant_names)]
2+
#![allow(missing_docs)]
3+
4+
use std::sync::Arc;
5+
6+
use async_trait::async_trait;
7+
use tracing::instrument;
8+
9+
use hyperlane_core::{
10+
AggregationIsm, ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract,
11+
HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, RawHyperlaneMessage, H256,
12+
};
13+
14+
use crate::{
15+
interfaces::i_aggregation_ism::IAggregationIsm as TronAggregationIsmInternal, TronProvider,
16+
};
17+
18+
/// A reference to an AggregationIsm contract on some Tron chain
19+
#[derive(Debug)]
20+
pub struct TronAggregationIsm {
21+
contract: Arc<TronAggregationIsmInternal<TronProvider>>,
22+
domain: HyperlaneDomain,
23+
}
24+
25+
impl TronAggregationIsm {
26+
/// Creates a new TronAggregationIsm instance
27+
pub fn new(provider: TronProvider, locator: &ContractLocator) -> Self {
28+
let provider = Arc::new(provider);
29+
Self {
30+
contract: Arc::new(TronAggregationIsmInternal::new(locator.address, provider)),
31+
domain: locator.domain.clone(),
32+
}
33+
}
34+
}
35+
36+
impl HyperlaneChain for TronAggregationIsm {
37+
fn domain(&self) -> &HyperlaneDomain {
38+
&self.domain
39+
}
40+
41+
fn provider(&self) -> Box<dyn HyperlaneProvider> {
42+
Box::new(self.contract.client().clone())
43+
}
44+
}
45+
46+
impl HyperlaneContract for TronAggregationIsm {
47+
fn address(&self) -> H256 {
48+
self.contract.address().into()
49+
}
50+
}
51+
52+
#[async_trait]
53+
impl AggregationIsm for TronAggregationIsm {
54+
#[instrument(err, skip(self, message))]
55+
async fn modules_and_threshold(
56+
&self,
57+
message: &HyperlaneMessage,
58+
) -> ChainResult<(Vec<H256>, u8)> {
59+
let (isms, threshold) = self
60+
.contract
61+
.modules_and_threshold(RawHyperlaneMessage::from(message).to_vec().into())
62+
.call()
63+
.await?;
64+
let isms_h256 = isms.iter().map(|address| (*address).into()).collect();
65+
Ok((isms_h256, threshold))
66+
}
67+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#![allow(clippy::enum_variant_names)]
2+
#![allow(missing_docs)]
3+
4+
use std::sync::Arc;
5+
6+
use async_trait::async_trait;
7+
use tracing::{instrument, warn};
8+
9+
use futures_util::future::try_join;
10+
use hyperlane_core::{
11+
ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain,
12+
HyperlaneMessage, HyperlaneProvider, InterchainSecurityModule, Metadata, ModuleType,
13+
RawHyperlaneMessage, H256, U256,
14+
};
15+
use num_traits::cast::FromPrimitive;
16+
17+
use crate::interfaces::i_interchain_security_module::IInterchainSecurityModule as TronInterchainSecurityModuleInternal;
18+
use crate::TronProvider;
19+
20+
/// A reference to an InterchainSecurityModule contract on some Tron chain
21+
#[derive(Debug)]
22+
pub struct TronInterchainSecurityModule {
23+
contract: Arc<TronInterchainSecurityModuleInternal<TronProvider>>,
24+
domain: HyperlaneDomain,
25+
}
26+
27+
impl TronInterchainSecurityModule {
28+
/// Creates a new TronInterchainSecurityModule instance
29+
pub fn new(provider: TronProvider, locator: &ContractLocator) -> Self {
30+
Self {
31+
contract: Arc::new(TronInterchainSecurityModuleInternal::new(
32+
locator.address,
33+
Arc::new(provider),
34+
)),
35+
domain: locator.domain.clone(),
36+
}
37+
}
38+
}
39+
40+
impl HyperlaneChain for TronInterchainSecurityModule {
41+
fn domain(&self) -> &HyperlaneDomain {
42+
&self.domain
43+
}
44+
45+
fn provider(&self) -> Box<dyn HyperlaneProvider> {
46+
Box::new(self.contract.client().clone())
47+
}
48+
}
49+
50+
impl HyperlaneContract for TronInterchainSecurityModule {
51+
fn address(&self) -> H256 {
52+
self.contract.address().into()
53+
}
54+
}
55+
56+
#[async_trait]
57+
impl InterchainSecurityModule for TronInterchainSecurityModule {
58+
#[instrument]
59+
async fn module_type(&self) -> ChainResult<ModuleType> {
60+
let module = self.contract.module_type().call().await?;
61+
if let Some(module_type) = ModuleType::from_u8(module) {
62+
Ok(module_type)
63+
} else {
64+
warn!(%module, "Unknown module type");
65+
Ok(ModuleType::Unused)
66+
}
67+
}
68+
69+
#[instrument]
70+
async fn dry_run_verify(
71+
&self,
72+
message: &HyperlaneMessage,
73+
metadata: &Metadata,
74+
) -> ChainResult<Option<U256>> {
75+
let tx = self.contract.verify(
76+
metadata.to_owned().into(),
77+
RawHyperlaneMessage::from(message).to_vec().into(),
78+
);
79+
let (verifies, gas_estimate) = try_join(tx.call(), tx.estimate_gas()).await?;
80+
if verifies {
81+
Ok(Some(gas_estimate.into()))
82+
} else {
83+
Ok(None)
84+
}
85+
}
86+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#![allow(clippy::enum_variant_names)]
2+
#![allow(missing_docs)]
3+
4+
use std::sync::Arc;
5+
6+
use async_trait::async_trait;
7+
use tracing::instrument;
8+
9+
use hyperlane_core::{
10+
ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain,
11+
HyperlaneMessage, HyperlaneProvider, MultisigIsm, RawHyperlaneMessage, H256,
12+
};
13+
14+
use crate::interfaces::i_multisig_ism::IMultisigIsm as TronMultisigIsmInternal;
15+
use crate::TronProvider;
16+
17+
/// A reference to an MultisigIsm contract on some Tron chain
18+
#[derive(Debug)]
19+
pub struct TronMultisigIsm {
20+
contract: Arc<TronMultisigIsmInternal<TronProvider>>,
21+
domain: HyperlaneDomain,
22+
}
23+
24+
impl TronMultisigIsm {
25+
/// Creates a new TronMultisigIsm instance
26+
pub fn new(provider: TronProvider, locator: &ContractLocator) -> Self {
27+
Self {
28+
contract: Arc::new(TronMultisigIsmInternal::new(
29+
locator.address,
30+
Arc::new(provider),
31+
)),
32+
domain: locator.domain.clone(),
33+
}
34+
}
35+
}
36+
37+
impl HyperlaneChain for TronMultisigIsm {
38+
fn domain(&self) -> &HyperlaneDomain {
39+
&self.domain
40+
}
41+
42+
fn provider(&self) -> Box<dyn HyperlaneProvider> {
43+
Box::new(self.contract.client().clone())
44+
}
45+
}
46+
47+
impl HyperlaneContract for TronMultisigIsm {
48+
fn address(&self) -> H256 {
49+
self.contract.address().into()
50+
}
51+
}
52+
53+
#[async_trait]
54+
impl MultisigIsm for TronMultisigIsm {
55+
#[instrument(err, skip(self, message))]
56+
async fn validators_and_threshold(
57+
&self,
58+
message: &HyperlaneMessage,
59+
) -> ChainResult<(Vec<H256>, u8)> {
60+
let (validator_addresses, threshold) = self
61+
.contract
62+
.validators_and_threshold(RawHyperlaneMessage::from(message).to_vec().into())
63+
.call()
64+
.await?;
65+
let validators: Vec<H256> = validator_addresses.iter().map(|&x| H256::from(x)).collect();
66+
Ok((validators, threshold))
67+
}
68+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#![allow(clippy::enum_variant_names)]
2+
#![allow(missing_docs)]
3+
4+
use std::sync::Arc;
5+
6+
use async_trait::async_trait;
7+
use tracing::instrument;
8+
9+
use hyperlane_core::{
10+
ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain,
11+
HyperlaneMessage, HyperlaneProvider, RawHyperlaneMessage, RoutingIsm, H256,
12+
};
13+
14+
use crate::interfaces::i_routing_ism::IRoutingIsm as TronRoutingIsmInternal;
15+
use crate::TronProvider;
16+
17+
/// A reference to an RoutingIsm contract on some Tron chain
18+
#[derive(Debug)]
19+
pub struct TronRoutingIsm {
20+
contract: Arc<TronRoutingIsmInternal<TronProvider>>,
21+
domain: HyperlaneDomain,
22+
}
23+
24+
impl TronRoutingIsm {
25+
/// Creates a new TronRoutingIsm instance
26+
pub fn new(provider: TronProvider, locator: &ContractLocator) -> Self {
27+
Self {
28+
contract: Arc::new(TronRoutingIsmInternal::new(
29+
locator.address,
30+
Arc::new(provider),
31+
)),
32+
domain: locator.domain.clone(),
33+
}
34+
}
35+
}
36+
37+
impl HyperlaneChain for TronRoutingIsm {
38+
fn domain(&self) -> &HyperlaneDomain {
39+
&self.domain
40+
}
41+
42+
fn provider(&self) -> Box<dyn HyperlaneProvider> {
43+
Box::new(self.contract.client().clone())
44+
}
45+
}
46+
47+
impl HyperlaneContract for TronRoutingIsm {
48+
fn address(&self) -> H256 {
49+
self.contract.address().into()
50+
}
51+
}
52+
53+
#[async_trait]
54+
impl RoutingIsm for TronRoutingIsm {
55+
#[instrument(err, skip(self, message))]
56+
async fn route(&self, message: &HyperlaneMessage) -> ChainResult<H256> {
57+
let ism = self
58+
.contract
59+
.route(RawHyperlaneMessage::from(message).to_vec().into())
60+
.call()
61+
.await?;
62+
Ok(ism.into())
63+
}
64+
}

rust/main/chains/hyperlane-tron/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ use ethers_signers::LocalWallet;
99

1010
pub use {
1111
config::ConnectionConf, contracts::TronInterchainGasPaymaster, contracts::TronMailboxIndexer,
12-
contracts::TronMerkleTreeHookIndexer, provider::TronProvider,
12+
contracts::TronMerkleTreeHookIndexer, ism::TronAggregationIsm,
13+
ism::TronInterchainSecurityModule, ism::TronMultisigIsm, ism::TronRoutingIsm,
14+
provider::TronProvider,
1315
};
1416

1517
mod config;
1618
mod contracts;
1719
mod error;
20+
mod ism;
1821
mod provider;
1922
mod utils;
2023

rust/main/hyperlane-base/src/settings/chains.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,11 @@ impl ChainConf {
10511051
let ism = h_radix::RadixIsm::new(provider, &locator, conf)?;
10521052
Ok(Box::new(ism) as Box<dyn InterchainSecurityModule>)
10531053
}
1054-
ChainConnectionConf::Tron(_) => todo!(),
1054+
ChainConnectionConf::Tron(conf) => {
1055+
let provider = build_tron_provider(self, conf, metrics, &locator, None)?;
1056+
let ism = h_tron::TronInterchainSecurityModule::new(provider, &locator);
1057+
Ok(Box::new(ism) as Box<dyn InterchainSecurityModule>)
1058+
}
10551059
#[cfg(feature = "aleo")]
10561060
ChainConnectionConf::Aleo(conf) => {
10571061
let provider = build_aleo_provider(self, conf, metrics, &locator, None)?;
@@ -1112,7 +1116,11 @@ impl ChainConf {
11121116
let ism = h_radix::RadixIsm::new(provider, &locator, conf)?;
11131117
Ok(Box::new(ism) as Box<dyn MultisigIsm>)
11141118
}
1115-
ChainConnectionConf::Tron(_) => todo!(),
1119+
ChainConnectionConf::Tron(conf) => {
1120+
let provider = build_tron_provider(self, conf, metrics, &locator, None)?;
1121+
let ism = h_tron::TronMultisigIsm::new(provider, &locator);
1122+
Ok(Box::new(ism) as Box<dyn MultisigIsm>)
1123+
}
11161124
#[cfg(feature = "aleo")]
11171125
ChainConnectionConf::Aleo(conf) => {
11181126
let provider = build_aleo_provider(self, conf, metrics, &locator, None)?;
@@ -1168,7 +1176,11 @@ impl ChainConf {
11681176
let ism = h_radix::RadixIsm::new(provider, &locator, conf)?;
11691177
Ok(Box::new(ism) as Box<dyn RoutingIsm>)
11701178
}
1171-
ChainConnectionConf::Tron(_) => todo!(),
1179+
ChainConnectionConf::Tron(conf) => {
1180+
let provider = build_tron_provider(self, conf, metrics, &locator, None)?;
1181+
let ism = h_tron::TronRoutingIsm::new(provider, &locator);
1182+
Ok(Box::new(ism) as Box<dyn RoutingIsm>)
1183+
}
11721184
#[cfg(feature = "aleo")]
11731185
ChainConnectionConf::Aleo(conf) => {
11741186
let provider = build_aleo_provider(self, conf, metrics, &locator, None)?;
@@ -1224,7 +1236,11 @@ impl ChainConf {
12241236
ChainConnectionConf::Radix(_) => {
12251237
todo!("Radix aggregation ISM not yet implemented")
12261238
}
1227-
ChainConnectionConf::Tron(_) => todo!(),
1239+
ChainConnectionConf::Tron(conf) => {
1240+
let provider = build_tron_provider(self, conf, metrics, &locator, None)?;
1241+
let ism = h_tron::TronAggregationIsm::new(provider, &locator);
1242+
Ok(Box::new(ism) as Box<dyn AggregationIsm>)
1243+
}
12281244
#[cfg(feature = "aleo")]
12291245
ChainConnectionConf::Aleo(_) => Err(eyre!("Aleo support missing")).context(ctx),
12301246
}

0 commit comments

Comments
 (0)