Skip to content

Commit

Permalink
fix(state-bridge): storage trie changes weren't being gossiped (#1393)
Browse files Browse the repository at this point in the history
  • Loading branch information
KolbyML authored Aug 21, 2024
1 parent 7802037 commit 8523913
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion ethportal-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const_format = {version = "0.2.0", features = ["rust_1_64"]}
c-kzg = "1.0.0"
discv5 = { version = "0.4.1", features = ["serde"] }
ethereum_hashing = "0.6.0"
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7e57d3dfadee126cc9fda2696fb039bf7b6ed688" }
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7947a83091192a7988f359b750b05121d5d7ba8c" }
ethereum_serde_utils = "0.5.2"
ethereum_ssz = "0.5.3"
ethereum_ssz_derive = "0.5.3"
Expand Down
2 changes: 1 addition & 1 deletion portal-bridge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ clap = { version = "4.2.1", features = ["derive"] }
discv5 = { version = "0.4.1", features = ["serde"] }
ethereum_ssz = "0.5.3"
ethportal-api = { path = "../ethportal-api" }
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7e57d3dfadee126cc9fda2696fb039bf7b6ed688" }
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7947a83091192a7988f359b750b05121d5d7ba8c" }
e2store = { path = "../e2store" }
futures = "0.3.21"
jsonrpsee = { version = "0.20.0", features = [
Expand Down
29 changes: 14 additions & 15 deletions portal-bridge/src/bridge/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,6 @@ impl StateBridge {
};
let account: AccountStateInfo = Decodable::decode(&mut leaf.value.as_slice())?;

// if the code_hash is empty then it isn't a contract so we can skip it
if account.code_hash == keccak256([]) {
continue;
}

// reconstruct the address hash from the path so that we can fetch the
// address from the database
let mut partial_key_path = leaf.key.get_data().to_vec();
Expand All @@ -181,16 +176,19 @@ impl StateBridge {
[&account_proof.path.clone(), partial_key_path.as_slice()].concat();
let address_hash = full_nibble_path_to_address_hash(&full_key_path);

// gossip contract bytecode
let code = state.database.code_by_hash_ref(account.code_hash)?;
self.gossip_contract_bytecode(
address_hash,
&account_proof,
block_tuple.header.header.hash(),
account.code_hash,
code,
)
.await?;
// if the code_hash is empty then then don't try to gossip the contract bytecode
if account.code_hash != keccak256([]) {
// gossip contract bytecode
let code = state.database.code_by_hash_ref(account.code_hash)?;
self.gossip_contract_bytecode(
address_hash,
&account_proof,
block_tuple.header.header.hash(),
account.code_hash,
code,
)
.await?;
}

// gossip contract storage
let storage_changed_nodes = state.database.get_storage_trie_diff(address_hash);
Expand All @@ -209,6 +207,7 @@ impl StateBridge {
.await?;
}
}

// flush the database cache
// This is used for gossiping storage trie diffs
state.database.storage_cache.clear();
Expand Down
2 changes: 1 addition & 1 deletion trin-execution/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ clap = { version = "4.2.1", features = ["derive"] }
directories = "3.0"
ethportal-api = { path = "../ethportal-api" }
e2store = { path = "../e2store" }
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7e57d3dfadee126cc9fda2696fb039bf7b6ed688" }
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7947a83091192a7988f359b750b05121d5d7ba8c" }
hashbrown = "0.14.0"
lazy_static = "1.4.0"
parking_lot = "0.11.2"
Expand Down
2 changes: 1 addition & 1 deletion trin-execution/src/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn create_contract_content_value(
Ok(StateContentValue::ContractBytecodeWithProof(
ContractBytecodeWithProof {
block_hash,
code: code.bytecode.to_vec().into(),
code: code.original_bytes().to_vec().into(),
account_proof: account_proof.into(),
},
))
Expand Down
13 changes: 5 additions & 8 deletions trin-execution/src/storage/account_db.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use alloy_primitives::{keccak256, Address, B256};
use alloy_primitives::{keccak256, B256};
use eth_trie::DB;
use rocksdb::DB as RocksDB;

Expand All @@ -16,11 +16,8 @@ pub struct AccountDB {
}

impl AccountDB {
pub fn new(address: Address, db: Arc<RocksDB>) -> Self {
Self {
address_hash: keccak256(address),
db,
}
pub fn new(address_hash: B256, db: Arc<RocksDB>) -> Self {
Self { address_hash, db }
}

fn get_db_key(&self, key: &[u8]) -> Vec<u8> {
Expand Down Expand Up @@ -72,7 +69,7 @@ mod test_account_db {
#[test]
fn test_account_db_get() {
let rocksdb = setup_rocksdb(setup_temp_dir().unwrap().into_path()).unwrap();
let accdb = AccountDB::new(Address::ZERO, Arc::new(rocksdb));
let accdb = AccountDB::new(B256::ZERO, Arc::new(rocksdb));
accdb
.insert(keccak256(b"test-key").as_slice(), b"test-value".to_vec())
.unwrap();
Expand All @@ -86,7 +83,7 @@ mod test_account_db {
#[test]
fn test_account_db_remove() {
let rocksdb = setup_rocksdb(setup_temp_dir().unwrap().into_path()).unwrap();
let accdb = AccountDB::new(Address::ZERO, Arc::new(rocksdb));
let accdb = AccountDB::new(B256::ZERO, Arc::new(rocksdb));
accdb
.insert(keccak256(b"test").as_slice(), b"test".to_vec())
.unwrap();
Expand Down
16 changes: 11 additions & 5 deletions trin-execution/src/storage/evm_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,14 @@ impl EvmDB {
.get(&address_hash)
.unwrap_or(&HashSet::new())
{
// storage trie keys are prefixed with the address hash in the database
let value = self
.db
.get(key)
.get(
[address_hash.as_slice(), key.as_slice()]
.concat()
.as_slice(),
)
.expect("Getting storage value should never fail");

if let Some(raw_value) = value {
Expand Down Expand Up @@ -125,7 +130,7 @@ impl DatabaseCommit for EvmDB {
None => RocksAccount::default(),
};
if rocks_account.storage_root != keccak256([EMPTY_STRING_CODE]) {
let account_db = AccountDB::new(address, self.db.clone());
let account_db = AccountDB::new(address_hash, self.db.clone());
let mut trie = EthTrie::from(Arc::new(account_db), rocks_account.storage_root)
.expect("Creating trie should never fail");
trie.clear_trie_from_db()
Expand Down Expand Up @@ -167,7 +172,7 @@ impl DatabaseCommit for EvmDB {
rocks_account.nonce = account.info.nonce;
rocks_account.code_hash = account.info.code_hash;

let account_db = AccountDB::new(address, self.db.clone());
let account_db = AccountDB::new(address_hash, self.db.clone());

let mut trie = if rocks_account.storage_root == keccak256([EMPTY_STRING_CODE]) {
EthTrie::new(Arc::new(account_db))
Expand Down Expand Up @@ -268,11 +273,12 @@ impl DatabaseRef for EvmDB {
}

fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> {
let account: RocksAccount = match self.db.get(keccak256(address))? {
let address_hash = keccak256(address);
let account: RocksAccount = match self.db.get(address_hash)? {
Some(raw_account) => Decodable::decode(&mut raw_account.as_slice())?,
None => return Err(Self::Error::NotFound),
};
let account_db = AccountDB::new(address, self.db.clone());
let account_db = AccountDB::new(address_hash, self.db.clone());
let trie = if account.storage_root == keccak256([EMPTY_STRING_CODE]) {
EthTrie::new(Arc::new(account_db))
} else {
Expand Down
6 changes: 4 additions & 2 deletions trin-execution/src/trie_walker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ pub struct TrieWalker {
impl TrieWalker {
pub fn new(root_hash: B256, nodes: BrownHashMap<B256, Vec<u8>>) -> Self {
// if the storage root is empty then there is no storage to gossip
if root_hash == keccak256([EMPTY_STRING_CODE]) && !nodes.is_empty() {
panic!("Root hash is empty but there are nodes to gossip. This should never happen.");
if root_hash == keccak256([EMPTY_STRING_CODE]) {
return Self {
nodes: BrownHashMap::new(),
};
}

if nodes.is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion trin-state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ alloy-primitives = { version = "0.7.0", features = ["getrandom"] }
alloy-rlp = "0.3.4"
anyhow = "1.0.68"
discv5 = { version = "0.4.1", features = ["serde"] }
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7e57d3dfadee126cc9fda2696fb039bf7b6ed688" }
eth_trie = { git = "https://github.com/kolbyml/eth-trie.rs.git", rev = "7947a83091192a7988f359b750b05121d5d7ba8c" }
ethportal-api = { path = "../ethportal-api" }
keccak-hash = "0.10.0"
parking_lot = "0.11.2"
Expand Down

0 comments on commit 8523913

Please sign in to comment.