Skip to content

Commit f4560a0

Browse files
committed
recover KMS address test
1 parent 97a8b0a commit f4560a0

7 files changed

Lines changed: 239 additions & 37 deletions

File tree

rust/main/Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/main/chains/hyperlane-dango/tests/localdango.rs

Lines changed: 99 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
use {
2-
crate::utils::{try_for, DangoBuilder},
2+
crate::utils::{try_for, DangoBuilder, SingleSignerExt},
33
dango_client::{Secp256k1, Secret, SingleSigner},
44
dango_genesis::{GatewayOption, GenesisOption, HyperlaneOption},
5-
dango_hyperlane_types::isms::multisig::ValidatorSet,
5+
dango_hyperlane_types::{
6+
domain_hash, eip191_hash,
7+
isms::{multisig::ValidatorSet, HYPERLANE_DOMAIN_KEY},
8+
mailbox, multisig_hash, Addr32,
9+
},
610
dango_testing::{constants::user5, Preset},
711
dango_types::{
812
config::AppConfig,
913
constants::dango,
1014
gateway::{self, Origin, Remote},
1115
},
1216
grug::{
13-
BroadcastClientExt, Coins, GasOption, QueryClientExt, ResultExt, SearchTxClient,
14-
__private::hex_literal::hex, addr, btree_map, btree_set,
17+
addr, btree_map, btree_set, Addr, Api, BroadcastClientExt, CheckedContractEvent, Coins,
18+
EventName, FlatCommitmentStatus, GasOption, Hash256, Inner, JsonDeExt, MockApi,
19+
QueryClientExt, ResultExt, SearchEvent, SearchTxClient, __private::hex_literal::hex,
1520
},
1621
grug_indexer_client::HttpClient,
22+
manual_relay::get_checkpoint_from_s3,
1723
std::time::Duration,
1824
tracing::Level,
1925
};
2026

27+
pub mod manual_relay;
2128
pub mod utils;
2229

2330
const PORT: u16 = 8080;
@@ -27,6 +34,8 @@ const PORT: u16 = 8080;
2734
async fn run_dango() -> anyhow::Result<()> {
2835
// --- SETTINGS ---
2936

37+
let local_domain = 88888867;
38+
3039
let routes = [(
3140
Origin::Local(dango::DENOM.clone()),
3241
Remote::Warp {
@@ -61,7 +70,7 @@ async fn run_dango() -> anyhow::Result<()> {
6170
let mut ism_valset = HyperlaneOption::preset_test().ism_validator_sets;
6271
ism_valset.extend(ism_validator_sets);
6372

64-
DangoBuilder::new("localdango", 88888888)
73+
DangoBuilder::new("localdango", local_domain)
6574
.with_block_creation(grug::BlockCreation::Timed)
6675
.with_block_time(grug::Duration::from_seconds(1))
6776
.with_port(PORT)
@@ -71,6 +80,7 @@ async fn run_dango() -> anyhow::Result<()> {
7180
..Preset::preset_test()
7281
},
7382
hyperlane: HyperlaneOption {
83+
local_domain,
7484
ism_validator_sets: ism_valset,
7585
..Preset::preset_test()
7686
},
@@ -87,6 +97,10 @@ async fn run_dango() -> anyhow::Result<()> {
8797
async fn transfer_remote() -> anyhow::Result<()> {
8898
// --- SETTINGS ---
8999

100+
let run_recover_address = true;
101+
let location = "s3://hyperlane-testnet-val1/eu-north-1";
102+
let recover_address_should_be = addr!("6603760598E4aAc3E9D47569cc3A7024cDa7003a");
103+
90104
let url = format!("http://localhost:{}", PORT);
91105
let denom = dango::DENOM.clone();
92106
let amount = 55;
@@ -96,18 +110,20 @@ async fn transfer_remote() -> anyhow::Result<()> {
96110
};
97111
let recipient = addr!("f63130398dE6467a539020ac2B6d876B7A850C5F");
98112

113+
// --- SETTINGS ---
114+
99115
let dango_client = HttpClient::new(url)?;
100116

101117
let cfg: AppConfig = dango_client.query_app_config(None).await?;
102118
let chain_id = dango_client.query_status(None).await?.chain_id;
103119

104-
let mut user5 = SingleSigner::new(
105-
addr!("a20a0e1a71b82d50fc046bc6e3178ad0154fd184"),
120+
let mut user5 = SingleSigner::new_first_account(
121+
&dango_client,
106122
Secp256k1::from_bytes(user5::PRIVATE_KEY)?,
123+
Some(&cfg),
107124
)
108-
.with_query_nonce(&dango_client)
109125
.await?
110-
.with_query_user_index(&dango_client)
126+
.with_query_nonce(&dango_client)
111127
.await?;
112128

113129
let res = dango_client
@@ -129,11 +145,82 @@ async fn transfer_remote() -> anyhow::Result<()> {
129145
Duration::from_millis(100),
130146
|| async { dango_client.search_tx(res.tx_hash).await },
131147
)
132-
.await?;
148+
.await?
149+
.outcome
150+
.should_succeed();
151+
152+
if !run_recover_address {
153+
return Ok(());
154+
}
155+
156+
let dispatch = outcome
157+
.events
158+
.clone()
159+
.search_event::<CheckedContractEvent>()
160+
.with_commitment_status(FlatCommitmentStatus::Committed)
161+
.with_predicate(move |e| {
162+
&e.contract == &cfg.addresses.hyperlane.mailbox && e.ty == mailbox::Dispatch::EVENT_NAME
163+
})
164+
.take()
165+
.one()
166+
.event
167+
.data
168+
.deserialize_json::<mailbox::Dispatch>()?
169+
.0;
170+
171+
let insertion = outcome
172+
.events
173+
.search_event::<CheckedContractEvent>()
174+
.with_commitment_status(FlatCommitmentStatus::Committed)
175+
.with_predicate(move |e| {
176+
&e.contract == &cfg.addresses.hyperlane.mailbox
177+
&& e.ty == mailbox::InsertedIntoTree::EVENT_NAME
178+
})
179+
.take()
180+
.one()
181+
.event
182+
.data
183+
.deserialize_json::<mailbox::InsertedIntoTree>()?;
133184

134-
outcome.outcome.should_succeed();
185+
let checkpoint = try_for(
186+
Duration::from_secs(10),
187+
Duration::from_millis(100),
188+
|| async { get_checkpoint_from_s3(location, &insertion.index.to_string()).await },
189+
)
190+
.await?;
135191

136-
println!("found at height: {}", outcome.height);
192+
let api = MockApi;
193+
194+
let raw_message = dispatch.encode();
195+
let message_id = Hash256::from_inner(api.keccak256(&raw_message));
196+
197+
assert_eq!(message_id.inner(), checkpoint.message_id.inner());
198+
199+
let merkle_tree_hook_address =
200+
Addr32::from_inner(checkpoint.merkle_tree_hook_address.into_inner());
201+
let merkle_root = Hash256::from_inner(checkpoint.root.into_inner());
202+
203+
let multisig_hash = eip191_hash(multisig_hash(
204+
domain_hash(
205+
dispatch.origin_domain,
206+
merkle_tree_hook_address,
207+
HYPERLANE_DOMAIN_KEY,
208+
),
209+
merkle_root,
210+
checkpoint.index,
211+
Hash256::from_inner(checkpoint.message_id.into_inner()),
212+
));
213+
214+
let pk = api.secp256k1_pubkey_recover(
215+
&multisig_hash,
216+
&checkpoint.serialized_signature[..64],
217+
checkpoint.serialized_signature[64] - 27, // Ethereum uses recovery IDs 27, 28 instead of 0, 1.
218+
false, // We need the _uncompressed_ public key for deriving address!
219+
)?;
220+
let pk_hash = api.keccak256(&pk[1..]);
221+
let address: [u8; 20] = pk_hash[12..].try_into().unwrap();
222+
223+
assert_eq!(Addr::from_inner(address), recover_address_should_be);
137224

138225
Ok(())
139226
}

rust/main/chains/hyperlane-dango/tests/manual_relay.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ use {
3030
type AddrEncoded<const N: usize> = EncodedBytes<[u8; N], AddrEncoder>;
3131

3232
#[derive(Debug, Serialize, Deserialize)]
33-
struct CheckpointResponse {
34-
merkle_tree_hook_address: AddrEncoded<32>,
35-
mailbox_domain: u32,
36-
root: AddrEncoded<32>,
37-
index: u32,
38-
message_id: AddrEncoded<32>,
39-
serialized_signature: AddrEncoded<65>,
33+
pub struct CheckpointResponse {
34+
pub merkle_tree_hook_address: AddrEncoded<32>,
35+
pub mailbox_domain: u32,
36+
pub root: AddrEncoded<32>,
37+
pub index: u32,
38+
pub message_id: AddrEncoded<32>,
39+
pub serialized_signature: AddrEncoded<65>,
4040
}
4141

4242
abigen!(
@@ -237,7 +237,7 @@ async fn get_validator_locations<I: IntoIterator<Item = H160>>(
237237
.collect::<Result<Vec<String>, anyhow::Error>>()
238238
}
239239

240-
async fn get_checkpoint_from_s3(s3: &str, index_msg: &str) -> anyhow::Result<CheckpointResponse> {
240+
pub async fn get_checkpoint_from_s3(s3: &str, index_msg: &str) -> anyhow::Result<CheckpointResponse> {
241241
let without_scheme = s3
242242
.strip_prefix("s3://")
243243
.ok_or(anyhow::anyhow!("Invalid S3 URL"))?;

rust/main/chains/hyperlane-dango/tests/run_agents.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use {
22
crate::utils::{
33
build_agents, workspace, Agent, CheckpointSyncer, DangoSettings, EvmSettings, Location,
4-
LogLevel, Relayer, Validator,
4+
LogLevel, Relayer, SingleSignerExt, Validator, ValidatorSigner,
55
},
6-
dango_hyperlane_testing::constants::MOCK_HYPERLANE_VALIDATOR_SIGNING_KEYS,
6+
dango_client::{Secp256k1, Secret, SingleSigner},
77
dango_testing::constants::{user4, user6},
88
dango_types::config::AppConfig,
9-
grug::{addr, HexByteArray, QueryClientExt},
9+
grug::{HexByteArray, QueryClientExt},
1010
grug_indexer_client::HttpClient,
1111
hyperlane_base::settings::SignerConf,
1212
hyperlane_core::H256,
@@ -35,6 +35,14 @@ async fn run_relayer() -> anyhow::Result<()> {
3535
let dango_client = HttpClient::new(HTTPD_URL)?;
3636
let app_cfg: AppConfig = dango_client.query_app_config(None).await?;
3737

38+
let dango_chain_signer_address = SingleSigner::new_first_account(
39+
&dango_client,
40+
Secp256k1::from_bytes(user4::PRIVATE_KEY)?,
41+
Some(&app_cfg),
42+
)
43+
.await?
44+
.address;
45+
3846
Agent::new(Relayer::default().with_allow_local_checkpoint_syncer(true))
3947
.with_chain(
4048
EvmSettings::new("sepolia")
@@ -45,7 +53,7 @@ async fn run_relayer() -> anyhow::Result<()> {
4553
DangoSettings::new("dangolocal2")
4654
.with_chain_signer(SignerConf::Dango {
4755
key: HexByteArray::from_inner(user4::PRIVATE_KEY),
48-
address: addr!("5a7213b5a8f12e826e88d67c083be371a442689c"),
56+
address: dango_chain_signer_address,
4957
})
5058
.with_index(1, Some(20))
5159
.with_chain_settings(|dango| {
@@ -67,31 +75,41 @@ async fn run_relayer() -> anyhow::Result<()> {
6775
async fn run_dango_validator() -> anyhow::Result<()> {
6876
load_env();
6977

78+
let validator_chain = "localdango1";
79+
7080
build_agents();
7181

7282
let dango_client = HttpClient::new(HTTPD_URL)?;
7383
let chain_id = dango_client.query_status(None).await?.chain_id;
74-
let app_cfg = dango_client.query_app_config(None).await?;
84+
let app_cfg: AppConfig = dango_client.query_app_config(None).await?;
7585
let path = workspace().join("val-1");
7686

87+
let dango_chain_signer_address = SingleSigner::new_first_account(
88+
&dango_client,
89+
Secp256k1::from_bytes(user6::PRIVATE_KEY)?,
90+
Some(&app_cfg),
91+
)
92+
.await?
93+
.address;
94+
7795
Agent::new(
7896
Validator::default()
79-
.with_origin_chain_name("dangolocal2")
97+
.with_origin_chain_name(validator_chain)
8098
.with_checkpoint_syncer(CheckpointSyncer::s3(
81-
"hyperlane-test",
99+
"hyperlane-testnet-val1",
82100
"eu-north-1",
83101
None::<String>,
84102
))
85-
// .with_checkpoint_syncer(CheckpointSyncer::LocalStorage(Location::Temp))
86-
.with_validator_signer(utils::ValidatorSigner::Hex(H256::from(
87-
MOCK_HYPERLANE_VALIDATOR_SIGNING_KEYS[0],
88-
))),
103+
.with_validator_signer(ValidatorSigner::kms(
104+
"alias/hyperlane-testnet-val1-singer-key",
105+
"eu-north-1",
106+
)),
89107
)
90108
.with_chain(
91-
DangoSettings::new("dangolocal2")
109+
DangoSettings::new(validator_chain)
92110
.with_chain_signer(SignerConf::Dango {
93111
key: HexByteArray::from_inner(user6::PRIVATE_KEY),
94-
address: addr!("365a389d8571b681d087ee8f7eecf1ff710f59c8"),
112+
address: dango_chain_signer_address,
95113
})
96114
.with_index(1, Some(20))
97115
.with_chain_settings(|dango| {

rust/main/chains/hyperlane-dango/tests/utils/agents/validator.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ impl Args for OriginChainName {
115115

116116
pub enum ValidatorSigner {
117117
Hex(H256),
118+
KMS { alias: String, region: String },
119+
}
120+
121+
impl ValidatorSigner {
122+
pub fn kms(alias: impl Into<String>, region: impl Into<String>) -> Self {
123+
Self::KMS {
124+
alias: alias.into(),
125+
region: region.into(),
126+
}
127+
}
118128
}
119129

120130
impl Args for ValidatorSigner {
@@ -124,6 +134,11 @@ impl Args for ValidatorSigner {
124134
"validator.type".to_string() => "hexKey".to_string(),
125135
"validator.key".to_string() => format!("{:?}", key),
126136
},
137+
ValidatorSigner::KMS { alias, region } => btree_map! {
138+
"validator.type".to_string() => "aws".to_string(),
139+
"validator.id".to_string() => alias,
140+
"validator.region".to_string() => region,
141+
},
127142
}
128143
}
129144
}

0 commit comments

Comments
 (0)