Skip to content

Commit f516bc0

Browse files
prestwichdylanlott
authored andcommitted
feat: simrevert type
1 parent 1fc9892 commit f516bc0

File tree

2 files changed

+134
-38
lines changed

2 files changed

+134
-38
lines changed

src/tasks/block/sim.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ impl Simulator {
8282
block: BlockEnv,
8383
) -> eyre::Result<BuiltBlock> {
8484
let db = self.create_db().await.unwrap();
85-
8685
let block_build: BlockBuild<_, NoOpInspector> = BlockBuild::new(
8786
db,
8887
constants,

src/tasks/submit.rs

Lines changed: 134 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use alloy::{
77
consensus::{SimpleCoder, constants::GWEI_TO_WEI},
88
eips::BlockNumberOrTag,
99
network::{TransactionBuilder, TransactionBuilder4844},
10-
primitives::{FixedBytes, TxHash, U256},
10+
primitives::{Bytes, FixedBytes, TxHash, U256},
1111
providers::{Provider as _, SendableTx, WalletProvider},
12-
rpc::types::eth::TransactionRequest,
12+
rpc::{json_rpc::ErrorPayload, types::eth::TransactionRequest},
1313
sol_types::{SolCall, SolError},
1414
transports::TransportError,
1515
};
@@ -48,6 +48,133 @@ macro_rules! spawn_provider_send {
4848
};
4949
}
5050

51+
/// Represents the kind of revert that can occur during simulation.
52+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53+
pub enum SimRevertKind {
54+
/// Incorrect host block error
55+
IncorrectHostBlock,
56+
/// Bad signature error
57+
BadSignature,
58+
/// One rollup block per host block error
59+
OneRollupBlockPerHostBlock,
60+
/// Unknown error
61+
Unknown,
62+
}
63+
64+
impl From<Option<Bytes>> for SimRevertKind {
65+
fn from(data: Option<Bytes>) -> Self {
66+
let Some(data) = data else {
67+
return Self::Unknown;
68+
};
69+
70+
if data.starts_with(&IncorrectHostBlock::SELECTOR) {
71+
Self::IncorrectHostBlock
72+
} else if data.starts_with(&Zenith::BadSignature::SELECTOR) {
73+
Self::BadSignature
74+
} else if data.starts_with(&Zenith::OneRollupBlockPerHostBlock::SELECTOR) {
75+
Self::OneRollupBlockPerHostBlock
76+
} else {
77+
Self::Unknown
78+
}
79+
}
80+
}
81+
82+
#[derive(Debug, Clone)]
83+
/// Represents an error that occurs during simulation of a transaction.
84+
pub struct SimErrorResp {
85+
/// The error payload containing the error code and message.
86+
pub err: ErrorPayload,
87+
/// The kind of revert that occurred (or unknown if not recognized).
88+
kind: SimRevertKind,
89+
}
90+
91+
impl core::fmt::Display for SimErrorResp {
92+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93+
write!(
94+
f,
95+
"SimErrorResp {{ code: {}, message: {}, kind: {:?} }}",
96+
self.code(),
97+
self.message(),
98+
self.kind
99+
)
100+
}
101+
}
102+
103+
impl From<ErrorPayload> for SimErrorResp {
104+
fn from(err: ErrorPayload) -> Self {
105+
Self::new(err)
106+
}
107+
}
108+
109+
impl SimErrorResp {
110+
/// Creates a new `SimRevertError` with the specified kind and error
111+
/// payload.
112+
pub fn new(err: ErrorPayload) -> Self {
113+
let kind = err.as_revert_data().into();
114+
Self { err, kind }
115+
}
116+
117+
/// True if the error is an incorrect host block.
118+
pub fn is_incorrect_host_block(&self) -> bool {
119+
self.as_revert_data()
120+
.map(|b| b.starts_with(&IncorrectHostBlock::SELECTOR))
121+
.unwrap_or_default()
122+
}
123+
124+
/// Attempts to decode the error payload as an [`IncorrectHostBlock`].
125+
pub fn as_incorrect_host_block(&self) -> Option<IncorrectHostBlock> {
126+
self.as_revert_data().and_then(|data| IncorrectHostBlock::abi_decode(&data, true).ok())
127+
}
128+
129+
/// True if the error is a [`Zenith::BadSignature`].
130+
pub fn is_bad_signature(&self) -> bool {
131+
self.as_revert_data()
132+
.map(|b| b.starts_with(&Zenith::BadSignature::SELECTOR))
133+
.unwrap_or_default()
134+
}
135+
136+
/// Attempts to decode the error payload as a [`Zenith::BadSignature`].
137+
pub fn as_bad_signature(&self) -> Option<Zenith::BadSignature> {
138+
self.as_revert_data().and_then(|data| Zenith::BadSignature::abi_decode(&data, true).ok())
139+
}
140+
141+
/// True if the error is a [`Zenith::OneRollupBlockPerHostBlock`].
142+
pub fn is_one_rollup_block_per_host_block(&self) -> bool {
143+
self.as_revert_data()
144+
.map(|b| b.starts_with(&Zenith::OneRollupBlockPerHostBlock::SELECTOR))
145+
.unwrap_or_default()
146+
}
147+
148+
/// Attempts to decode the error payload as a
149+
/// [`Zenith::OneRollupBlockPerHostBlock`].
150+
pub fn as_one_rollup_block_per_host_block(&self) -> Option<Zenith::OneRollupBlockPerHostBlock> {
151+
self.as_revert_data()
152+
.and_then(|data| Zenith::OneRollupBlockPerHostBlock::abi_decode(&data, true).ok())
153+
}
154+
155+
/// True if the error is an unknown revert.
156+
pub fn is_unknown(&self) -> bool {
157+
!self.is_incorrect_host_block()
158+
&& !self.is_bad_signature()
159+
&& !self.is_one_rollup_block_per_host_block()
160+
}
161+
162+
/// Returns the revert data if available.
163+
pub fn as_revert_data(&self) -> Option<Bytes> {
164+
self.err.as_revert_data()
165+
}
166+
167+
/// Returns the JSON-RPC error code.
168+
pub const fn code(&self) -> i64 {
169+
self.err.code
170+
}
171+
172+
/// Returns the error message.
173+
pub fn message(&self) -> &str {
174+
&self.err.message
175+
}
176+
}
177+
51178
/// Control flow for transaction submission.
52179
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
53180
pub enum ControlFlow {
@@ -145,44 +272,14 @@ impl SubmitTask {
145272

146273
/// Simulates the transaction with a call to the host provider to check for reverts.
147274
async fn sim_with_call(&self, tx: &TransactionRequest) -> eyre::Result<()> {
148-
if let Err(TransportError::ErrorResp(e)) =
149-
self.provider().call(tx.clone()).block(BlockNumberOrTag::Pending.into()).await
150-
{
151-
// NB: These errors are all handled the same way but are logged for debugging purposes
152-
if e.as_revert_data()
153-
.map(|data| data.starts_with(&IncorrectHostBlock::SELECTOR))
154-
.unwrap_or_default()
155-
{
156-
debug!(%e, "incorrect host block");
157-
bail!(e)
158-
}
159-
160-
if e.as_revert_data()
161-
.map(|data| data.starts_with(&Zenith::BadSignature::SELECTOR))
162-
.unwrap_or_default()
163-
{
164-
debug!(%e, "bad signature");
275+
match self.provider().call(tx.clone()).block(BlockNumberOrTag::Pending.into()).await {
276+
Err(TransportError::ErrorResp(e)) => {
277+
let e = SimErrorResp::from(e);
165278
bail!(e)
166279
}
167-
168-
if e.as_revert_data()
169-
.map(|data| data.starts_with(&Zenith::OneRollupBlockPerHostBlock::SELECTOR))
170-
.unwrap_or_default()
171-
{
172-
debug!(%e, "one rollup block per host block");
173-
bail!(e)
174-
}
175-
176-
error!(
177-
code = e.code,
178-
message = %e.message,
179-
data = ?e.data,
180-
"unknown error in host transaction simulation call"
181-
);
182-
bail!(e)
280+
Err(e) => bail!(e),
281+
_ => Ok(()),
183282
}
184-
185-
Ok(())
186283
}
187284

188285
/// Creates a transaction request for the blob with the given header and signature values.

0 commit comments

Comments
 (0)