Skip to content

Commit

Permalink
Hash & gather factory deps to snapshot (#42)
Browse files Browse the repository at this point in the history
Factory deps (smart contracts in zkSync) are stored separately in
snapshots, but they must be gathered together with storage log entries
when fetching the state from L1. This change will do preliminary work
required for writing out the separate factory dep snapshot file.
  • Loading branch information
tuommaki authored Nov 17, 2023
1 parent 48c7029 commit 39b5bf1
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 31 deletions.
98 changes: 70 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ tokio = { version = "1.33.0", features = ["macros"] }
tracing = "0.1.40"
tracing-subscriber = "0.3.17"
zksync_merkle_tree = { git = "https://github.com/matter-labs/zksync-era.git" }
zkevm_opcode_defs = { git = "https://github.com/matter-labs/era-zkevm_opcode_defs.git" }
26 changes: 26 additions & 0 deletions src/processor/snapshot/bytecode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use ethers::types::H256;

// These are copied from zkSync-era project to avoid pulling in full dependency.
pub fn bytes_to_chunks(bytes: &[u8]) -> Vec<[u8; 32]> {
assert!(
bytes.len() % 32 == 0,
"Bytes must be divisible by 32 to split into chunks"
);

bytes
.chunks(32)
.map(|el| {
let mut chunk = [0u8; 32];
chunk.copy_from_slice(el);
chunk
})
.collect()
}

pub fn hash_bytecode(code: &[u8]) -> H256 {
let chunked_code = bytes_to_chunks(code);
let hash =
zkevm_opcode_defs::utils::bytecode_to_code_hash(&chunked_code).expect("Invalid bytecode");

H256(hash)
}
13 changes: 10 additions & 3 deletions src/processor/snapshot/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{collections::HashMap, fmt, fs, path::PathBuf, str::FromStr};

mod bytecode;
mod types;

use async_trait::async_trait;
Expand All @@ -13,7 +14,7 @@ use state_reconstruct_fetcher::{
};
use tokio::sync::mpsc;

use self::types::{SnapshotStorageLog, StorageKey, StorageValue};
use self::types::{SnapshotFactoryDependency, SnapshotStorageLog, StorageKey, StorageValue};
use super::Processor;
use crate::processor::snapshot::types::MiniblockNumber;

Expand All @@ -22,6 +23,7 @@ const DEFAULT_EXPORT_PATH: &str = "snapshot_export";

pub struct SnapshotExporter {
storage_log_entries: HashMap<StorageKey, SnapshotStorageLog>,
factory_deps: Vec<SnapshotFactoryDependency>,
index_to_key_map: IndexSet<U256>,
path: PathBuf,
}
Expand All @@ -45,6 +47,7 @@ impl SnapshotExporter {

Self {
storage_log_entries,
factory_deps: vec![],
index_to_key_map,
path,
}
Expand Down Expand Up @@ -103,9 +106,13 @@ impl Processor for SnapshotExporter {
.and_modify(|log| log.value = value);
}

// TODO: We need to index these by hash.
// Factory dependencies.
// for dep in &block.factory_deps {}
for dep in block.factory_deps {
self.factory_deps.push(SnapshotFactoryDependency {
bytecode_hash: bytecode::hash_bytecode(&dep),
bytecode: dep,
});
}
}

fs::write(&self.path, self.to_string()).expect("failed to export snapshot");
Expand Down

0 comments on commit 39b5bf1

Please sign in to comment.