Skip to content

Commit 1a8d8b8

Browse files
committed
add legacy support
1 parent ac6476b commit 1a8d8b8

File tree

4 files changed

+166
-38
lines changed

4 files changed

+166
-38
lines changed

crates/bin/src/commands/run_rpc.rs

+35-16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::utils;
22
use alloy::providers::{Provider, ProviderBuilder};
33
use clap::Args;
44
use futures::future::OptionFuture;
5+
use sbv::primitives::types::LegacyStorageTrace;
56
use sbv::{
67
core::HardforkConfig,
78
primitives::{types::BlockTrace, Block},
@@ -19,6 +20,9 @@ pub struct RunRpcCommand {
1920
/// RPC URL
2021
#[arg(short, long, default_value = "http://localhost:8545")]
2122
url: Url,
23+
/// Legacy rpc
24+
#[arg(short, long)]
25+
legacy: bool,
2226
/// Start Block number
2327
#[arg(short, long, default_value = "latest")]
2428
start_block: StartBlockSpec,
@@ -49,7 +53,11 @@ pub enum StartBlockSpec {
4953

5054
impl RunRpcCommand {
5155
pub async fn run(self, fork_config: impl Fn(u64) -> HardforkConfig) -> anyhow::Result<()> {
52-
dev_info!("Running RPC command with url: {}", self.url);
56+
dev_info!(
57+
"Running RPC command with url: {}, legacy support: {}",
58+
self.url,
59+
self.legacy
60+
);
5361
let provider = ProviderBuilder::new().on_http(self.url);
5462

5563
let chain_id = provider.get_chain_id().await?;
@@ -75,21 +83,32 @@ impl RunRpcCommand {
7583
let rx = rx.clone();
7684
handles.spawn(async move {
7785
while let Ok(block_number) = rx.recv().await {
78-
let l2_trace = _provider
79-
.raw_request::<_, BlockTrace>(
80-
"scroll_getBlockTraceByNumberOrHash".into(),
81-
(
82-
format!("0x{:x}", block_number),
83-
serde_json::json!({
84-
"ExcludeExecutionResults": true,
85-
"ExcludeTxStorageTraces": true,
86-
"StorageProofFormat": "flatten",
87-
"FlattenProofsOnly": true
88-
}),
89-
),
90-
)
91-
.await
92-
.map_err(|e| (block_number, e.into()))?;
86+
let l2_trace: BlockTrace = if self.legacy {
87+
let trace = _provider
88+
.raw_request::<_, BlockTrace<LegacyStorageTrace>>(
89+
"scroll_getBlockTraceByNumberOrHash".into(),
90+
(format!("0x{:x}", block_number),),
91+
)
92+
.await
93+
.map_err(|e| (block_number, e.into()))?;
94+
trace.into()
95+
} else {
96+
_provider
97+
.raw_request::<_, BlockTrace>(
98+
"scroll_getBlockTraceByNumberOrHash".into(),
99+
(
100+
format!("0x{:x}", block_number),
101+
serde_json::json!({
102+
"ExcludeExecutionResults": true,
103+
"ExcludeTxStorageTraces": true,
104+
"StorageProofFormat": "flatten",
105+
"FlattenProofsOnly": true
106+
}),
107+
),
108+
)
109+
.await
110+
.map_err(|e| (block_number, e.into()))?
111+
};
93112

94113
dev_info!(
95114
"worker#{_idx}: load trace for block #{block_number}({})",

crates/core/src/error.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ use std::error::Error;
44
/// Error variants encountered during manipulation of a zkTrie.
55
#[derive(Debug, thiserror::Error)]
66
pub enum DatabaseError {
7+
/// Error encountered from code db.
78
#[error("error encountered from code db: {0}")]
89
CodeDb(Box<dyn Error + Send + Sync>),
10+
/// Error encountered from zkTrie.
911
#[error("error encountered from zkTrie: {0}")]
1012
ZkTrie(Box<dyn Error + Send + Sync>),
1113
}

crates/primitives/src/lib.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,17 @@ pub trait Block: Debug {
7676
fn start_l1_queue_index(&self) -> u64;
7777

7878
/// flatten proofs
79-
fn flatten_proofs(&self) -> impl Iterator<Item = (&B256, &[u8])>;
79+
fn flatten_proofs(&self) -> impl Iterator<Item = &[u8]>;
8080

8181
/// Update zktrie state from trace
8282
#[inline]
8383
fn build_zktrie_db<Db: KVDatabase>(&self, db: &mut Db) -> Result<(), Db::Error> {
84-
for (k, bytes) in self.flatten_proofs() {
84+
for bytes in self.flatten_proofs() {
8585
if bytes == MAGIC_NODE_BYTES {
8686
continue;
8787
}
8888
let node = Node::<Poseidon>::try_from(bytes).expect("invalid node");
8989
let node_hash = node.get_or_calculate_node_hash().expect("infallible");
90-
debug_assert_eq!(k.as_slice(), node_hash.as_slice());
9190
dev_trace!("put zktrie node: {:?}", node);
9291
db.put_owned(node_hash.as_slice(), node.canonical_value(false))?;
9392
}
@@ -334,7 +333,7 @@ impl<T: Block> Block for &T {
334333
(*self).start_l1_queue_index()
335334
}
336335

337-
fn flatten_proofs(&self) -> impl Iterator<Item = (&B256, &[u8])> {
336+
fn flatten_proofs(&self) -> impl Iterator<Item = &[u8]> {
338337
(*self).flatten_proofs()
339338
}
340339
}

crates/primitives/src/types/mod.rs

+126-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use crate::Block;
22
use alloy::primitives::{Address, Bytes, B256, U256};
3-
use serde::{Deserialize, Serialize};
3+
use rkyv::Archive;
4+
use serde::{Deserialize, Deserializer, Serialize};
45
use serde_with::{serde_as, Map};
6+
use std::collections::{BTreeSet, HashMap};
7+
use std::fmt::Debug;
8+
use std::hash::Hash;
59

610
mod tx;
711
pub use tx::{ArchivedTransactionTrace, TransactionTrace, TxL1Msg, TypedTransaction};
@@ -58,16 +62,15 @@ pub struct BytecodeTrace {
5862
}
5963

6064
/// storage trace
61-
#[serde_as]
6265
#[derive(
6366
rkyv::Archive,
6467
rkyv::Serialize,
6568
rkyv::Deserialize,
6669
Serialize,
67-
Deserialize,
6870
Default,
6971
Debug,
7072
Clone,
73+
Hash,
7174
Eq,
7275
PartialEq,
7376
)]
@@ -82,8 +85,44 @@ pub struct StorageTrace {
8285
pub root_after: B256,
8386
/// proofs
8487
#[serde(rename = "flattenProofs")]
88+
pub flatten_proofs: Vec<Bytes>,
89+
}
90+
91+
/// legacy storage trace
92+
#[serde_as]
93+
#[derive(
94+
rkyv::Archive,
95+
rkyv::Serialize,
96+
rkyv::Deserialize,
97+
Serialize,
98+
Deserialize,
99+
Default,
100+
Debug,
101+
Clone,
102+
Hash,
103+
Eq,
104+
PartialEq,
105+
)]
106+
#[archive(check_bytes)]
107+
#[archive_attr(derive(Debug, Hash, PartialEq, Eq))]
108+
pub struct LegacyStorageTrace {
109+
/// root before
110+
#[serde(rename = "rootBefore")]
111+
pub root_before: B256,
112+
/// root after
113+
#[serde(rename = "rootAfter")]
114+
pub root_after: B256,
115+
/// account proofs
116+
#[serde(default)]
85117
#[serde_as(as = "Map<_, _>")]
86-
pub flatten_proofs: Vec<(B256, Bytes)>,
118+
pub proofs: Vec<(Address, Vec<Bytes>)>,
119+
#[serde(rename = "storageProofs", default)]
120+
#[serde_as(as = "Map<_, Map<_, _>>")]
121+
/// storage proofs for each account
122+
pub storage_proofs: Vec<(Address, Vec<(B256, Vec<Bytes>)>)>,
123+
#[serde(rename = "deletionProofs", default)]
124+
/// additional deletion proofs
125+
pub deletion_proofs: Vec<Bytes>,
87126
}
88127

89128
/// Block trace format
@@ -94,7 +133,11 @@ pub struct StorageTrace {
94133
)]
95134
#[archive(check_bytes)]
96135
#[archive_attr(derive(Debug, Hash, PartialEq, Eq))]
97-
pub struct BlockTrace {
136+
pub struct BlockTrace<S = StorageTrace>
137+
where
138+
S: Archive,
139+
<S as Archive>::Archived: Debug + Hash + PartialEq + Eq,
140+
{
98141
/// chain id
99142
#[serde(rename = "chainID", default)]
100143
pub chain_id: u64,
@@ -108,14 +151,86 @@ pub struct BlockTrace {
108151
pub codes: Vec<BytecodeTrace>,
109152
/// storage trace BEFORE execution
110153
#[serde(rename = "storageTrace")]
111-
pub storage_trace: StorageTrace,
154+
pub storage_trace: S,
112155
/// l1 tx queue
113156
#[serde(rename = "startL1QueueIndex", default)]
114157
pub start_l1_queue_index: u64,
115158
/// Withdraw root
116159
pub withdraw_trie_root: B256,
117160
}
118161

162+
impl<'de> Deserialize<'de> for StorageTrace {
163+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
164+
where
165+
D: Deserializer<'de>,
166+
{
167+
#[derive(Deserialize)]
168+
#[serde(untagged)]
169+
enum FlattenProofs {
170+
Map(HashMap<B256, Bytes>),
171+
Vec(Vec<Bytes>),
172+
}
173+
#[derive(Deserialize)]
174+
struct StorageTraceDe {
175+
#[serde(rename = "rootBefore")]
176+
pub root_before: B256,
177+
#[serde(rename = "rootAfter")]
178+
pub root_after: B256,
179+
#[serde(rename = "flattenProofs")]
180+
pub flatten_proofs: FlattenProofs,
181+
}
182+
183+
let de = StorageTraceDe::deserialize(deserializer)?;
184+
let mut flatten_proofs = match de.flatten_proofs {
185+
FlattenProofs::Map(map) => map.into_iter().map(|(_, v)| v).collect(),
186+
FlattenProofs::Vec(vec) => vec,
187+
};
188+
flatten_proofs.sort();
189+
190+
Ok(StorageTrace {
191+
root_before: de.root_before,
192+
root_after: de.root_after,
193+
flatten_proofs,
194+
})
195+
}
196+
}
197+
198+
impl From<LegacyStorageTrace> for StorageTrace {
199+
fn from(trace: LegacyStorageTrace) -> Self {
200+
let mut flatten_proofs = BTreeSet::new();
201+
for (_, proofs) in trace.proofs {
202+
flatten_proofs.extend(proofs);
203+
}
204+
for (_, proofs) in trace.storage_proofs {
205+
for (_, proofs) in proofs {
206+
flatten_proofs.extend(proofs);
207+
}
208+
}
209+
flatten_proofs.extend(trace.deletion_proofs);
210+
211+
StorageTrace {
212+
root_before: trace.root_before,
213+
root_after: trace.root_after,
214+
flatten_proofs: flatten_proofs.into_iter().collect(),
215+
}
216+
}
217+
}
218+
219+
impl From<BlockTrace<LegacyStorageTrace>> for BlockTrace {
220+
fn from(trace: BlockTrace<LegacyStorageTrace>) -> Self {
221+
BlockTrace {
222+
chain_id: trace.chain_id,
223+
coinbase: trace.coinbase,
224+
header: trace.header,
225+
transactions: trace.transactions,
226+
codes: trace.codes,
227+
storage_trace: trace.storage_trace.into(),
228+
start_l1_queue_index: trace.start_l1_queue_index,
229+
withdraw_trie_root: trace.withdraw_trie_root,
230+
}
231+
}
232+
}
233+
119234
impl Block for BlockTrace {
120235
type Tx = TransactionTrace;
121236

@@ -179,11 +294,8 @@ impl Block for BlockTrace {
179294
self.start_l1_queue_index
180295
}
181296

182-
fn flatten_proofs(&self) -> impl Iterator<Item = (&B256, &[u8])> {
183-
self.storage_trace
184-
.flatten_proofs
185-
.iter()
186-
.map(|(k, v)| (k, v.as_ref()))
297+
fn flatten_proofs(&self) -> impl Iterator<Item = &[u8]> {
298+
self.storage_trace.flatten_proofs.iter().map(|v| v.as_ref())
187299
}
188300
}
189301

@@ -254,11 +366,8 @@ impl Block for ArchivedBlockTrace {
254366
self.start_l1_queue_index
255367
}
256368

257-
fn flatten_proofs(&self) -> impl Iterator<Item = (&B256, &[u8])> {
258-
self.storage_trace
259-
.flatten_proofs
260-
.iter()
261-
.map(|(k, v)| (k, v.as_ref()))
369+
fn flatten_proofs(&self) -> impl Iterator<Item = &[u8]> {
370+
self.storage_trace.flatten_proofs.iter().map(|v| v.as_ref())
262371
}
263372
}
264373

@@ -404,8 +513,7 @@ mod tests {
404513
.iter()
405514
.zip(archived_block.storage_trace.flatten_proofs.iter())
406515
{
407-
assert_eq!(proof.0, archived_proof.0);
408-
assert_eq!(proof.1.as_ref(), archived_proof.1.as_ref());
516+
assert_eq!(proof.as_ref(), archived_proof.as_ref());
409517
}
410518

411519
assert_eq!(

0 commit comments

Comments
 (0)