Skip to content

Commit

Permalink
refactor(core-run): split storage into a single file
Browse files Browse the repository at this point in the history
  • Loading branch information
yangby-cryptape committed Aug 29, 2023
1 parent 2503b82 commit 854557c
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 81 deletions.
1 change: 1 addition & 0 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 core/run/src/components/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub(crate) mod extensions;
pub(crate) mod network;
pub(crate) mod storage;
pub(crate) mod system;

#[cfg(all(
Expand Down
80 changes: 80 additions & 0 deletions core/run/src/components/storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use std::{path::Path, sync::Arc};

use common_config_parser::types::{spec::InitialAccount, ConfigRocksDB};
use core_db::{RocksAdapter, RocksDB};
use core_executor::{MPTTrie, RocksTrieDB};
use core_storage::ImplStorage;
use protocol::{
async_trait,
codec::ProtocolCodec,
traits::{Context, Storage},
trie::{self, Trie},
types::{Account, Block, ExecResp, HasherKeccak, RichBlock, NIL_DATA, RLP_NULL},
ProtocolResult,
};

pub(crate) async fn init_storage<P: AsRef<Path>>(
config: &ConfigRocksDB,
rocksdb_path: P,
triedb_cache_size: usize,
) -> ProtocolResult<(
Arc<ImplStorage<RocksAdapter>>,
Arc<RocksTrieDB>,
Arc<RocksDB>,
)> {
let adapter = Arc::new(RocksAdapter::new(rocksdb_path, config.clone())?);
let inner_db = adapter.inner_db();
let trie_db = Arc::new(RocksTrieDB::new_evm(adapter.inner_db(), triedb_cache_size));
let storage = Arc::new(ImplStorage::new(adapter, config.cache_size));
Ok((storage, trie_db, inner_db))
}

#[async_trait]
pub(crate) trait StorageExt: Storage {
async fn try_load_genesis(&self) -> ProtocolResult<Option<Block>> {
self.get_block(Context::new(), 0).await.or_else(|e| {
if e.to_string().contains("GetNone") {
Ok(None)
} else {
Err(e)
}
})
}

async fn save_block(&self, rich: &RichBlock, resp: &ExecResp) -> ProtocolResult<()> {
self.update_latest_proof(Context::new(), rich.block.header.proof.clone())
.await?;
self.insert_block(Context::new(), rich.block.clone())
.await?;
self.insert_transactions(Context::new(), rich.block.header.number, rich.txs.clone())
.await?;
let (receipts, _logs) = rich.generate_receipts_and_logs(resp);
self.insert_receipts(Context::new(), rich.block.header.number, receipts)
.await?;
Ok(())
}
}

impl StorageExt for ImplStorage<RocksAdapter> {}

pub(crate) trait TrieExt<D, H>: Trie<D, H> + Sized
where
D: trie::DB,
H: trie::Hasher,
{
fn insert_accounts(mut self, accounts: &[InitialAccount]) -> ProtocolResult<Self> {
for account in accounts {
let raw_account = Account {
nonce: 0u64.into(),
balance: account.balance,
storage_root: RLP_NULL,
code_hash: NIL_DATA,
}
.encode()?;
self.insert(account.address.as_bytes().to_vec(), raw_account.to_vec())?;
}
Ok(self)
}
}

impl<D> TrieExt<D, HasherKeccak> for MPTTrie<D> where D: trie::DB {}
95 changes: 15 additions & 80 deletions core/run/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
#![allow(clippy::uninlined_format_args, clippy::mutable_key_type)]

use std::{collections::HashMap, path::Path, sync::Arc, time::Duration};
use std::{collections::HashMap, sync::Arc, time::Duration};

use common_apm::metrics::mempool::{MEMPOOL_CO_QUEUE_LEN, MEMPOOL_LEN_GAUGE};
use common_config_parser::types::spec::{ChainSpec, InitialAccount};
use common_config_parser::types::{Config, ConfigRocksDB};
use common_config_parser::types::Config;
use common_crypto::{BlsPrivateKey, BlsPublicKey, Secp256k1, Secp256k1PrivateKey, ToPublicKey};

use protocol::codec::{hex_decode, ProtocolCodec};
use protocol::codec::hex_decode;
use protocol::tokio::{
self, runtime::Builder as RuntimeBuilder, sync::Mutex as AsyncMutex, time::sleep,
};
use protocol::traits::{
Context, Executor, Gossip, MemPool, Network, NodeInfo, PeerTrust, ReadOnlyStorage, Rpc, Storage,
};
use protocol::trie::Trie;
use protocol::types::{
Account, Block, ExecResp, MerkleRoot, Metadata, Proposal, RichBlock, SignedTransaction,
Validator, ValidatorExtend, H256, NIL_DATA, RLP_NULL,
Block, ExecResp, MerkleRoot, Metadata, Proposal, RichBlock, SignedTransaction, Validator,
ValidatorExtend, H256,
};
use protocol::{lazy::CHAIN_ID, trie::DB as TrieDB, ProtocolResult};

Expand Down Expand Up @@ -46,7 +45,11 @@ mod key_provider;
#[cfg(test)]
mod tests;

use components::{extensions::ExtensionConfig as _, network::NetworkServiceExt as _};
use components::{
extensions::ExtensionConfig as _,
network::NetworkServiceExt as _,
storage::{init_storage, StorageExt as _, TrieExt as _},
};
pub use error::MainError;
use key_provider::KeyP;

Expand Down Expand Up @@ -85,7 +88,7 @@ impl Axon {
self.config.executor.triedb_cache_size,
)
.await?;
if let Some(genesis) = self.try_load_genesis(&storage).await? {
if let Some(genesis) = storage.try_load_genesis().await? {
log::info!("The Genesis block has been initialized.");
self.apply_genesis_after_checks(&genesis).await?;
} else {
Expand All @@ -99,19 +102,6 @@ impl Axon {
Ok(())
}

async fn try_load_genesis(
&self,
storage: &Arc<ImplStorage<RocksAdapter>>,
) -> ProtocolResult<Option<Block>> {
storage.get_block(Context::new(), 0).await.or_else(|e| {
if e.to_string().contains("GetNone") {
Ok(None)
} else {
Err(e)
}
})
}

async fn create_genesis(
&mut self,
storage: &Arc<ImplStorage<RocksAdapter>>,
Expand All @@ -137,7 +127,7 @@ impl Axon {

log::info!("The genesis block is created {:?}", self.genesis.block);

save_block(storage, &self.genesis, &resp).await?;
storage.save_block(&self.genesis, &resp).await?;

Ok(())
}
Expand Down Expand Up @@ -542,39 +532,6 @@ impl Axon {
}
}

async fn init_storage<P: AsRef<Path>>(
config: &ConfigRocksDB,
rocksdb_path: P,
triedb_cache_size: usize,
) -> ProtocolResult<(
Arc<ImplStorage<RocksAdapter>>,
Arc<RocksTrieDB>,
Arc<RocksDB>,
)> {
let adapter = Arc::new(RocksAdapter::new(rocksdb_path, config.clone())?);
let inner_db = adapter.inner_db();
let trie_db = Arc::new(RocksTrieDB::new_evm(adapter.inner_db(), triedb_cache_size));
let storage = Arc::new(ImplStorage::new(adapter, config.cache_size));
Ok((storage, trie_db, inner_db))
}

fn insert_accounts<DB>(mpt: &mut MPTTrie<DB>, accounts: &[InitialAccount]) -> ProtocolResult<()>
where
DB: TrieDB,
{
for account in accounts {
let raw_account = Account {
nonce: 0u64.into(),
balance: account.balance,
storage_root: RLP_NULL,
code_hash: NIL_DATA,
}
.encode()?;
mpt.insert(account.address.as_bytes().to_vec(), raw_account.to_vec())?;
}
Ok(())
}

fn execute_transactions<S>(
rich: &RichBlock,
storage: &Arc<S>,
Expand All @@ -585,11 +542,9 @@ fn execute_transactions<S>(
where
S: Storage + 'static,
{
let state_root = {
let mut mpt = MPTTrie::new(Arc::clone(trie_db));
insert_accounts(&mut mpt, accounts).expect("insert accounts");
mpt.commit()?
};
let state_root = MPTTrie::new(Arc::clone(&trie_db))
.insert_accounts(accounts)?
.commit()?;
let executor = AxonExecutor::default();
let mut backend = AxonExecutorApplyAdapter::from_root(
state_root,
Expand All @@ -613,23 +568,3 @@ where

Ok(resp)
}

async fn save_block<S>(storage: &Arc<S>, rich: &RichBlock, resp: &ExecResp) -> ProtocolResult<()>
where
S: Storage + 'static,
{
storage
.update_latest_proof(Context::new(), rich.block.header.proof.clone())
.await?;
storage
.insert_block(Context::new(), rich.block.clone())
.await?;
storage
.insert_transactions(Context::new(), rich.block.header.number, rich.txs.clone())
.await?;
let (receipts, _logs) = rich.generate_receipts_and_logs(resp);
storage
.insert_receipts(Context::new(), rich.block.header.number, receipts)
.await?;
Ok(())
}
1 change: 1 addition & 0 deletions protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ethereum-types = { version = "0.14", features = ["arbitrary", "codec", "rlp", "s
ethers-core = "2.0"
evm = { version = "0.37", features = ["with-serde"] }
faster-hex = "0.8"
hasher = "0.1"
lazy_static = "1.4"
ophelia = "0.3"
overlord = "0.4"
Expand Down
1 change: 1 addition & 0 deletions protocol/src/types/executor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub use ethereum::{AccessList, AccessListItem, Account};
pub use evm::{backend::Log, Config, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed};
pub use hasher::HasherKeccak;

use rlp_derive::{RlpDecodable, RlpEncodable};

Expand Down
2 changes: 1 addition & 1 deletion protocol/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub use ckb_client::*;
pub use evm::{backend::*, ExitError, ExitRevert, ExitSucceed};
pub use executor::{
logs_bloom, AccessList, AccessListItem, Account, Config, ExecResp, ExecutorContext, ExitReason,
TxResp,
HasherKeccak, TxResp,
};
pub use interoperation::*;
pub use primitive::*;
Expand Down

0 comments on commit 854557c

Please sign in to comment.