Skip to content

Commit 9760421

Browse files
Merge remote-tracking branch 'origin/feat/integrate-zksync-on-sdk' into feat/integrate-zksync-on-cli
2 parents 3a0c303 + 05a1338 commit 9760421

File tree

66 files changed

+2118
-1182
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2118
-1182
lines changed

.changeset/late-fishes-end.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hyperlane-xyz/sdk': patch
3+
---
4+
5+
Fix contract address filtering to remove undefined factory addresses from the addresses map

.changeset/red-games-agree.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@hyperlane-xyz/sdk': patch
3+
'@hyperlane-xyz/core': patch
4+
---
5+
6+
Added ESLint configuration and dependency to enforce Node.js module restrictions

eslint.config.mjs

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@ export default [
8282
name: 'console',
8383
message: 'Please use a logger and/or the utils package assert',
8484
},
85-
{
86-
name: 'fs',
87-
message: 'Avoid use of node-specific libraries',
88-
},
8985
],
9086

9187
'@typescript-eslint/ban-ts-comment': ['off'],
@@ -112,4 +108,98 @@ export default [
112108
'jest/valid-expect': 'error',
113109
},
114110
},
111+
112+
{
113+
files: ['**/*.ts', '**/*.js', '**/*.mjs'],
114+
ignores: ['**/aws/**/*', '**/test/**/*', '**/*.test.ts'],
115+
rules: {
116+
'no-restricted-imports': [
117+
'error',
118+
{
119+
paths: [
120+
{
121+
name: 'fs',
122+
message:
123+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
124+
},
125+
{
126+
name: 'path',
127+
message:
128+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
129+
},
130+
{
131+
name: 'child_process',
132+
message:
133+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
134+
},
135+
{
136+
name: 'os',
137+
message:
138+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
139+
},
140+
{
141+
name: 'process',
142+
message:
143+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
144+
},
145+
{
146+
name: 'http',
147+
message:
148+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
149+
},
150+
{
151+
name: 'https',
152+
message:
153+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
154+
},
155+
{
156+
name: 'net',
157+
message:
158+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
159+
},
160+
{
161+
name: 'dgram',
162+
message:
163+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
164+
},
165+
{
166+
name: 'dns',
167+
message:
168+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
169+
},
170+
{
171+
name: 'crypto',
172+
message:
173+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
174+
},
175+
{
176+
name: 'tls',
177+
message:
178+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
179+
},
180+
{
181+
name: 'cluster',
182+
message:
183+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
184+
},
185+
{
186+
name: 'stream',
187+
message:
188+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
189+
},
190+
{
191+
name: 'vm',
192+
message:
193+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
194+
},
195+
{
196+
name: 'readline',
197+
message:
198+
'Avoid Node.js built-in modules in cross-platform code. Use environment-agnostic alternatives.',
199+
},
200+
],
201+
},
202+
],
203+
},
204+
},
115205
];

rust/main/agents/relayer/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
pub mod msg;
2+
13
mod merkle_tree;
2-
mod msg;
34
mod processor;
45
mod prover;
56
mod relayer;

rust/main/agents/relayer/src/merkle_tree/builder.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ impl Display for MerkleTreeBuilder {
3838
}
3939
}
4040

41+
impl Default for MerkleTreeBuilder {
42+
fn default() -> Self {
43+
Self::new()
44+
}
45+
}
46+
4147
/// MerkleTreeBuilder errors
4248
#[derive(Debug, thiserror::Error)]
4349
pub enum MerkleTreeBuilderError {

rust/main/agents/relayer/src/msg/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ pub(crate) mod gas_payment;
3232
pub(crate) mod metadata;
3333
pub(crate) mod op_queue;
3434
pub(crate) mod op_submitter;
35-
pub(crate) mod pending_message;
3635
pub(crate) mod processor;
3736

37+
pub mod pending_message;
38+
3839
pub use gas_payment::GAS_EXPENDITURE_LOG_MESSAGE;

rust/main/agents/relayer/src/msg/op_submitter.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,8 @@ async fn receive_task(
230230
// make sure things are getting wired up correctly; if this works in testing it
231231
// should also be valid in production.
232232
debug_assert_eq!(*op.destination_domain(), domain);
233-
let status = op.retrieve_status_from_db().unwrap_or_else(|| {
234-
trace!(
235-
?op,
236-
"No status found for message, defaulting to FirstPrepareAttempt"
237-
);
238-
PendingOperationStatus::FirstPrepareAttempt
239-
});
240-
prepare_queue.push(op, Some(status)).await;
233+
let op_status = op.status();
234+
prepare_queue.push(op, Some(op_status)).await;
241235
}
242236
}
243237

rust/main/agents/relayer/src/msg/pending_message.rs

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use hyperlane_core::{
2121
};
2222
use prometheus::{IntCounter, IntGauge};
2323
use serde::Serialize;
24-
use tracing::{debug, error, info, info_span, instrument, trace, warn, Instrument};
24+
use tracing::{debug, error, info, info_span, instrument, trace, warn, Instrument, Level};
2525

2626
use super::{
2727
gas_payment::{GasPaymentEnforcer, GasPolicyStatus},
@@ -36,6 +36,8 @@ pub const CONFIRM_DELAY: Duration = if cfg!(any(test, feature = "test-utils")) {
3636
Duration::from_secs(60 * 10)
3737
};
3838

39+
pub const RETRIEVED_MESSAGE_LOG: &str = "Message status retrieved from db";
40+
3941
/// The message context contains the links needed to submit a message. Each
4042
/// instance is for a unique origin -> destination pairing.
4143
pub struct MessageContext {
@@ -510,27 +512,53 @@ impl PendingMessage {
510512
ctx: Arc<MessageContext>,
511513
app_context: Option<String>,
512514
) -> Self {
513-
let mut pm = Self::new(
514-
message,
515-
ctx,
516-
// Since we don't persist the message status for now, assume it's the first attempt
517-
PendingOperationStatus::FirstPrepareAttempt,
518-
app_context,
519-
);
520-
match pm
521-
.ctx
515+
// Attempt to fetch status about message from database
516+
let message_status = match ctx.origin_db.retrieve_status_by_message_id(&message.id()) {
517+
Ok(Some(status)) => {
518+
// This event is used for E2E tests to ensure message statuses
519+
// are being properly loaded from the db
520+
tracing::event!(
521+
if cfg!(feature = "test-utils") {
522+
Level::DEBUG
523+
} else {
524+
Level::TRACE
525+
},
526+
?status,
527+
id=?message.id(),
528+
RETRIEVED_MESSAGE_LOG,
529+
);
530+
status
531+
}
532+
_ => {
533+
tracing::event!(
534+
if cfg!(feature = "test-utils") {
535+
Level::DEBUG
536+
} else {
537+
Level::TRACE
538+
},
539+
"Message status not found in db"
540+
);
541+
PendingOperationStatus::FirstPrepareAttempt
542+
}
543+
};
544+
545+
let num_retries = match ctx
522546
.origin_db
523-
.retrieve_pending_message_retry_count_by_message_id(&pm.message.id())
547+
.retrieve_pending_message_retry_count_by_message_id(&message.id())
524548
{
525-
Ok(Some(num_retries)) => {
526-
let next_attempt_after = PendingMessage::calculate_msg_backoff(num_retries)
527-
.map(|dur| Instant::now() + dur);
528-
pm.num_retries = num_retries;
529-
pm.next_attempt_after = next_attempt_after;
530-
}
549+
Ok(Some(num_retries)) => num_retries,
531550
r => {
532-
trace!(message_id = ?pm.message.id(), result = ?r, "Failed to read retry count from HyperlaneDB for message.")
551+
trace!(message_id = ?message.id(), result = ?r, "Failed to read retry count from HyperlaneDB for message.");
552+
0
533553
}
554+
};
555+
556+
let mut pm = Self::new(message, ctx, message_status, app_context);
557+
if num_retries > 0 {
558+
let next_attempt_after =
559+
PendingMessage::calculate_msg_backoff(num_retries).map(|dur| Instant::now() + dur);
560+
pm.num_retries = num_retries;
561+
pm.next_attempt_after = next_attempt_after;
534562
}
535563
pm
536564
}

rust/main/utils/run-locally/src/invariants/termination_invariants.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,52 +90,70 @@ pub fn termination_invariants_met(
9090
const TX_ID_INDEXING_LOG_MESSAGE: &str = "Found log(s) for tx id";
9191

9292
let relayer_logfile = File::open(log_file_path)?;
93-
let invariant_logs = &[
94-
STORING_NEW_MESSAGE_LOG_MESSAGE,
95-
LOOKING_FOR_EVENTS_LOG_MESSAGE,
96-
GAS_EXPENDITURE_LOG_MESSAGE,
97-
HYPER_INCOMING_BODY_LOG_MESSAGE,
98-
TX_ID_INDEXING_LOG_MESSAGE,
93+
94+
let storing_new_msg_line_filter = vec![STORING_NEW_MESSAGE_LOG_MESSAGE];
95+
let looking_for_events_line_filter = vec![LOOKING_FOR_EVENTS_LOG_MESSAGE];
96+
let gas_expenditure_line_filter = vec![GAS_EXPENDITURE_LOG_MESSAGE];
97+
let hyper_incoming_body_line_filter = vec![HYPER_INCOMING_BODY_LOG_MESSAGE];
98+
let tx_id_indexing_line_filter = vec![TX_ID_INDEXING_LOG_MESSAGE];
99+
let invariant_logs = vec![
100+
storing_new_msg_line_filter.clone(),
101+
looking_for_events_line_filter.clone(),
102+
gas_expenditure_line_filter.clone(),
103+
hyper_incoming_body_line_filter.clone(),
104+
tx_id_indexing_line_filter.clone(),
99105
];
100106
let log_counts = get_matching_lines(&relayer_logfile, invariant_logs);
107+
101108
// Zero insertion messages don't reach `submit` stage where gas is spent, so we only expect these logs for the other messages.
102109
// TODO: Sometimes we find more logs than expected. This may either mean that gas is deducted twice for the same message due to a bug,
103110
// or that submitting the message transaction fails for some messages. Figure out which is the case and convert this check to
104111
// strict equality.
105112
// EDIT: Having had a quick look, it seems like there are some legitimate reverts happening in the confirm step
106113
// (`Transaction attempting to process message either reverted or was reorged`)
107114
// in which case more gas expenditure logs than messages are expected.
108-
let gas_expenditure_log_count = log_counts.get(GAS_EXPENDITURE_LOG_MESSAGE).unwrap();
115+
let gas_expenditure_log_count = *log_counts
116+
.get(&gas_expenditure_line_filter)
117+
.expect("Failed to get gas expenditure log count");
109118
assert!(
110-
gas_expenditure_log_count >= &total_messages_expected,
119+
gas_expenditure_log_count >= total_messages_expected,
111120
"Didn't record gas payment for all delivered messages. Got {} gas payment logs, expected at least {}",
112121
gas_expenditure_log_count,
113122
total_messages_expected
114123
);
115124
// These tests check that we fixed https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/3915, where some logs would not show up
125+
126+
let storing_new_msg_log_count = *log_counts
127+
.get(&storing_new_msg_line_filter)
128+
.expect("Failed to get storing new msg log count");
116129
assert!(
117-
log_counts.get(STORING_NEW_MESSAGE_LOG_MESSAGE).unwrap() > &0,
130+
storing_new_msg_log_count > 0,
118131
"Didn't find any logs about storing messages in db"
119132
);
133+
let looking_for_events_log_count = *log_counts
134+
.get(&looking_for_events_line_filter)
135+
.expect("Failed to get looking for events log count");
120136
assert!(
121-
log_counts.get(LOOKING_FOR_EVENTS_LOG_MESSAGE).unwrap() > &0,
137+
looking_for_events_log_count > 0,
122138
"Didn't find any logs about looking for events in index range"
123139
);
124-
let total_tx_id_log_count = log_counts.get(TX_ID_INDEXING_LOG_MESSAGE).unwrap();
140+
let total_tx_id_log_count = *log_counts
141+
.get(&tx_id_indexing_line_filter)
142+
.expect("Failed to get tx id indexing log count");
125143
assert!(
126144
// there are 3 txid-indexed events:
127145
// - relayer: merkle insertion and gas payment
128146
// - scraper: gas payment
129147
// some logs are emitted for multiple events, so requiring there to be at least
130148
// `config.kathy_messages` logs is a reasonable approximation, since all three of these events
131149
// are expected to be logged for each message.
132-
*total_tx_id_log_count as u64 >= config.kathy_messages,
150+
total_tx_id_log_count as u64 >= config.kathy_messages,
133151
"Didn't find as many tx id logs as expected. Found {} and expected {}",
134152
total_tx_id_log_count,
135153
config.kathy_messages
136154
);
137155
assert!(
138-
log_counts.get(HYPER_INCOMING_BODY_LOG_MESSAGE).is_none(),
156+
log_counts.get(&hyper_incoming_body_line_filter).is_none(),
139157
"Verbose logs not expected at the log level set in e2e"
140158
);
141159

0 commit comments

Comments
 (0)