Skip to content

Commit

Permalink
feat: exporting snapshot using CommitBlockInfoV2 (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeapoz authored Feb 8, 2024
1 parent 5b7dc9d commit 41c8406
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 37 deletions.
43 changes: 36 additions & 7 deletions src/processor/snapshot/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use std::{
path::PathBuf,
};

use ethers::types::H256;
use ethers::types::{H256, U256};
use eyre::Result;
use rocksdb::{Options, DB};
use state_reconstruct_fetcher::types::v2::PackingType;
use thiserror::Error;

use super::types::{SnapshotFactoryDependency, SnapshotStorageLog};
Expand Down Expand Up @@ -50,6 +51,31 @@ impl SnapshotDB {
Ok(Self(db))
}

pub fn process_value(&self, key: U256, value: PackingType) -> H256 {
let processed_value = match value {
PackingType::NoCompression(v) | PackingType::Transform(v) => v,
PackingType::Add(_) | PackingType::Sub(_) => {
let mut buffer = [0; 32];
key.to_little_endian(&mut buffer);
if let Ok(Some(log)) = self.get_storage_log(&buffer) {
let existing_value = U256::from(log.value.to_fixed_bytes());
// NOTE: We're explicitly allowing over-/underflow as per the spec.
match value {
PackingType::Add(v) => existing_value.overflowing_add(v).0,
PackingType::Sub(v) => existing_value.overflowing_sub(v).0,
_ => unreachable!(),
}
} else {
panic!("no key found for version")
}
}
};

let mut buffer = [0; 32];
processed_value.to_big_endian(&mut buffer);
H256::from(buffer)
}

pub fn new_read_only(db_path: PathBuf) -> Result<Self> {
let mut db_opts = Options::default();
db_opts.create_missing_column_families(true);
Expand Down Expand Up @@ -127,16 +153,19 @@ impl SnapshotDB {
.map_err(Into::into)
}

pub fn get_key_from_index(&self, key_idx: u64) -> Result<Vec<u8>> {
let index_to_key_map = self.cf_handle(INDEX_TO_KEY_MAP).unwrap();
match self.get_cf(index_to_key_map, key_idx.to_be_bytes())? {
Some(k) => Ok(k),
None => Err(DatabaseError::NoSuchKey.into()),
}
}

pub fn update_storage_log_value(&self, key_idx: u64, value: &[u8]) -> Result<()> {
// Unwrapping column family handle here is safe because presence of
// those CFs is ensured in construction of this DB.
let index_to_key_map = self.cf_handle(INDEX_TO_KEY_MAP).unwrap();
let storage_logs = self.cf_handle(STORAGE_LOGS).unwrap();

let key: Vec<u8> = match self.get_cf(index_to_key_map, key_idx.to_be_bytes())? {
Some(k) => k,
None => return Err(DatabaseError::NoSuchKey.into()),
};
let key = self.get_key_from_index(key_idx)?;

// XXX: These should really be inside a transaction...
let entry_bs = self.get_cf(storage_logs, &key)?.unwrap();
Expand Down
38 changes: 8 additions & 30 deletions src/processor/snapshot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use eyre::Result;
use prost::Message;
use state_reconstruct_fetcher::{
constants::{ethereum, storage},
types::{v2::PackingType, CommitBlock},
types::CommitBlock,
};
use tokio::sync::mpsc;

Expand Down Expand Up @@ -71,20 +71,7 @@ impl Processor for SnapshotBuilder {
self.database
.insert_storage_log(&mut SnapshotStorageLog {
key: U256::from_little_endian(key),
value: {
// TODO: procure value depending on packing type. requires reading from
// existing database.
let processed_value = match value {
PackingType::Add(v)
| PackingType::Sub(v)
| PackingType::Transform(v)
| PackingType::NoCompression(v) => v,
};

let mut buffer = [0; 32];
processed_value.to_big_endian(&mut buffer);
H256::from(buffer)
},
value: self.database.process_value(U256::from(key), *value),
miniblock_number_of_initial_write: U64::from(0),
l1_batch_number_of_initial_write: U64::from(
block.l1_block_number.unwrap_or(0),
Expand All @@ -97,24 +84,15 @@ impl Processor for SnapshotBuilder {
// Repeated calldata.
for (index, value) in &block.repeated_storage_changes {
let index = usize::try_from(*index).expect("truncation failed");
let value = {
// TODO: procure value depending on packing type. requires reading from
// existing database.
let processed_value = match value {
PackingType::Add(v)
| PackingType::Sub(v)
| PackingType::Transform(v)
| PackingType::NoCompression(v) => v,
};

let mut buffer = [0; 32];
processed_value.to_big_endian(&mut buffer);
buffer
};
let key = self
.database
.get_key_from_index(index as u64)
.expect("missing key");
let value = self.database.process_value(U256::from(&key[0..32]), *value);

if self
.database
.update_storage_log_value(index as u64, &value)
.update_storage_log_value(index as u64, &value.to_fixed_bytes())
.is_err()
{
let max_idx = self
Expand Down

0 comments on commit 41c8406

Please sign in to comment.