Skip to content

Commit

Permalink
feat: hardfork storage
Browse files Browse the repository at this point in the history
  • Loading branch information
driftluo committed Aug 30, 2023
1 parent 14f5b3a commit 827c369
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 16 deletions.
8 changes: 6 additions & 2 deletions core/api/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use protocol::traits::{
};
use protocol::trie::Trie as _;
use protocol::types::{
Account, BigEndianHash, Block, BlockNumber, Bytes, CkbRelatedInfo, ExecutorContext, Hash,
Header, Metadata, Proposal, Receipt, SignedTransaction, TxResp, H160, H256,
Account, BigEndianHash, Block, BlockNumber, Bytes, CkbRelatedInfo, ExecutorContext,
HardforkInfo, Hash, Header, Metadata, Proposal, Receipt, SignedTransaction, TxResp, H160, H256,
MAX_BLOCK_GAS_LIMIT, NIL_DATA, RLP_NULL, U256,
};
use protocol::{async_trait, codec::ProtocolCodec, trie, ProtocolResult};
Expand Down Expand Up @@ -281,4 +281,8 @@ where
)?
.get_metadata_root())
}

async fn hardfork_info(&self, ctx: Context) -> ProtocolResult<HardforkInfo> {
MetadataHandle::new(self.get_metadata_root(ctx).await?).hardfork_infos()
}
}
11 changes: 10 additions & 1 deletion core/api/src/jsonrpc/impl/axon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use jsonrpsee::core::Error;

use protocol::async_trait;
use protocol::traits::{APIAdapter, Context};
use protocol::types::{Block, CkbRelatedInfo, Metadata, Proof, Proposal, U256};
use protocol::types::{Block, CkbRelatedInfo, HardforkInfo, Metadata, Proof, Proposal, U256};

use crate::jsonrpc::web3_types::BlockId;
use crate::jsonrpc::{AxonRpcServer, RpcResult};
Expand Down Expand Up @@ -96,4 +96,13 @@ impl<Adapter: APIAdapter + 'static> AxonRpcServer for AxonRpcImpl<Adapter> {

Ok(ret)
}

async fn hardfork_info(&self) -> RpcResult<HardforkInfo> {
let ret = self
.adapter
.hardfork_info(Context::new())
.await
.map_err(|e| Error::Custom(e.to_string()))?;
Ok(ret)
}
}
5 changes: 4 additions & 1 deletion core/api/src/jsonrpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use jsonrpsee::{core::Error, proc_macros::rpc};
use common_config_parser::types::Config;
use protocol::traits::APIAdapter;
use protocol::types::{
Block, CkbRelatedInfo, Hash, Hex, Metadata, Proof, Proposal, H160, H256, U256,
Block, CkbRelatedInfo, HardforkInfo, Hash, Hex, Metadata, Proof, Proposal, H160, H256, U256,
};
use protocol::ProtocolResult;

Expand Down Expand Up @@ -225,6 +225,9 @@ pub trait AxonRpc {

#[method(name = "axon_getCkbRelatedInfo")]
async fn get_ckb_related_info(&self) -> RpcResult<CkbRelatedInfo>;

#[method(name = "axon_getHardforkInfo")]
async fn hardfork_info(&self) -> RpcResult<HardforkInfo>;
}

#[rpc(server)]
Expand Down
1 change: 1 addition & 0 deletions core/executor/benches/bench_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl BenchAdapter {
gas_price: 85u64.into(),
block_gas_limit: 100_000_000_000u64.into(),
block_base_fee_per_gas: Default::default(),
extra_data: Default::default(),
},
)
.unwrap()
Expand Down
1 change: 1 addition & 0 deletions core/executor/benches/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub fn mock_executor_context() -> ExecutorContext {
gas_price: 85u64.into(),
block_gas_limit: 100_000_000_000u64.into(),
block_base_fee_per_gas: Default::default(),
extra_data: Default::default(),
}
}

Expand Down
1 change: 1 addition & 0 deletions core/executor/src/debugger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl EvmDebugger {
gas_price: 1u64.into(),
block_gas_limit: 4294967295000u64.into(),
block_base_fee_per_gas: 1337u64.into(),
extra_data: Default::default(),
};

AxonExecutorApplyAdapter::from_root(
Expand Down

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion core/executor/src/system_contract/metadata/handle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use protocol::types::{CkbRelatedInfo, Metadata, H160, H256};
use protocol::types::{CkbRelatedInfo, HardforkInfo, Metadata, H160, H256};
use protocol::ProtocolResult;

use crate::system_contract::metadata::MetadataStore;
Expand Down Expand Up @@ -47,4 +47,8 @@ impl MetadataHandle {
pub fn get_ckb_related_info(&self) -> ProtocolResult<CkbRelatedInfo> {
MetadataStore::new(self.root)?.get_ckb_related_info()
}

pub fn hardfork_infos(&self) -> ProtocolResult<HardforkInfo> {
MetadataStore::new(self.root)?.hardfork_infos()
}
}
28 changes: 22 additions & 6 deletions core/executor/src/system_contract/metadata/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ pub use abi::metadata_abi;
pub use handle::MetadataHandle;
pub use store::MetadataStore;

use std::num::NonZeroUsize;
use std::{num::NonZeroUsize, sync::Arc};

use arc_swap::ArcSwap;
use ethers::abi::AbiDecode;
use lru::LruCache;
use parking_lot::RwLock;

use protocol::codec::ProtocolCodec;
use protocol::traits::{ApplyBackend, ExecutorAdapter};
use protocol::types::{Hasher, Metadata, SignedTransaction, TxResp, H160, H256};
use protocol::types::{
HardforkInfoInner, Hasher, Metadata, SignedTransaction, TxResp, H160, H256, U256,
};

use crate::system_contract::utils::{
generate_mpt_root_changes, revert_resp, succeed_resp, update_states,
Expand All @@ -30,6 +34,8 @@ const METADATA_CACHE_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(1
lazy_static::lazy_static! {
static ref EPOCH_SEGMENT_KEY: H256 = Hasher::digest("epoch_segment");
static ref CKB_RELATED_INFO_KEY: H256 = Hasher::digest("ckb_related_info");
static ref HARDFORK_KEY: H256 = Hasher::digest("hardfork");
static ref HARDFORK_INFO: ArcSwap<U256> = ArcSwap::new(Arc::new(U256::zero()));
static ref METADATA_CACHE: RwLock<LruCache<Epoch, Metadata>> = RwLock::new(LruCache::new(METADATA_CACHE_SIZE));
}

Expand Down Expand Up @@ -117,10 +123,20 @@ impl<Adapter: ExecutorAdapter + ApplyBackend> SystemContract<Adapter>
}

let root = CURRENT_METADATA_ROOT.with(|r| *r.borrow());
if let Err(e) = MetadataStore::new(root)
.unwrap()
.update_propose_count(block_number.as_u64(), &adapter.origin())
{

let mut store = MetadataStore::new(root).unwrap();

if let Ok(data) = HardforkInfoInner::decode(adapter.get_ctx().extra_data) {
store
.set_hardfork_info(data.block_number, data.flags)
.expect("set new hardfork info fail")
}

let hardfork = store.hardfork_info(block_number.as_u64()).unwrap();

HARDFORK_INFO.swap(Arc::new(hardfork));

if let Err(e) = store.update_propose_count(block_number.as_u64(), &adapter.origin()) {
panic!("Update propose count at {:?} failed: {:?}", block_number, e)
}

Expand Down
59 changes: 57 additions & 2 deletions core/executor/src/system_contract/metadata/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ use std::collections::BTreeMap;
use std::sync::Arc;

use protocol::trie::Trie as _;
use protocol::types::{CkbRelatedInfo, Metadata, H160, H256};
use protocol::types::{
CkbRelatedInfo, HardforkInfo, HardforkInfoInner, Metadata, H160, H256, U256,
};
use protocol::{codec::ProtocolCodec, ProtocolResult};

use crate::system_contract::metadata::{
segment::EpochSegment, CKB_RELATED_INFO_KEY, EPOCH_SEGMENT_KEY,
segment::EpochSegment, CKB_RELATED_INFO_KEY, EPOCH_SEGMENT_KEY, HARDFORK_KEY,
};
use crate::system_contract::{error::SystemScriptError, METADATA_DB};
use crate::{adapter::RocksTrieDB, MPTTrie, CURRENT_METADATA_ROOT};
Expand Down Expand Up @@ -168,4 +170,57 @@ impl MetadataStore {
fn get_epoch_by_block_number(&self, block_number: u64) -> ProtocolResult<u64> {
self.get_epoch_segment()?.get_epoch_number(block_number)
}

pub fn set_hardfork_info(&mut self, block_number: u64, info: U256) -> ProtocolResult<()> {
let current_info = {
match self.trie.get(HARDFORK_KEY.as_bytes())? {
Some(data) => {
let mut hardfork_info = HardforkInfo::decode(data)?;

hardfork_info.push(HardforkInfoInner {
block_number,
flags: info,
});
hardfork_info
}
None => HardforkInfo {
inner: vec![HardforkInfoInner {
block_number,
flags: info,
}],
},
}
};
self.trie.insert(
HARDFORK_KEY.as_bytes().to_vec(),
current_info.encode()?.to_vec(),
)?;
let new_root = self.trie.commit()?;
CURRENT_METADATA_ROOT.with(|r| *r.borrow_mut() = new_root);
Ok(())
}

pub fn hardfork_info(&self, target_number: u64) -> ProtocolResult<U256> {
match self.trie.get(HARDFORK_KEY.as_bytes())? {
Some(data) => {
let hardfork_info = HardforkInfo::decode(data)?;

for k in hardfork_info.inner.iter().rev() {
if k.block_number > target_number {
continue;
}
return Ok(k.flags);
}
Ok(U256::zero())
}
None => Ok(U256::zero()),
}
}

pub fn hardfork_infos(&self) -> ProtocolResult<HardforkInfo> {
match self.trie.get(HARDFORK_KEY.as_bytes())? {
Some(data) => HardforkInfo::decode(data),
None => Ok(HardforkInfo::default()),
}
}
}
6 changes: 4 additions & 2 deletions protocol/src/traits/api.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::types::{
Account, Block, BlockNumber, Bytes, CkbRelatedInfo, Hash, Header, Metadata, Proposal, Receipt,
SignedTransaction, TxResp, H160, H256, U256,
Account, Block, BlockNumber, Bytes, CkbRelatedInfo, HardforkInfo, Hash, Header, Metadata,
Proposal, Receipt, SignedTransaction, TxResp, H160, H256, U256,
};
use crate::{async_trait, traits::Context, ProtocolResult};

Expand Down Expand Up @@ -103,4 +103,6 @@ pub trait APIAdapter: Send + Sync {
async fn get_image_cell_root(&self, ctx: Context) -> ProtocolResult<H256>;

async fn get_metadata_root(&self, ctx: Context) -> ProtocolResult<H256>;

async fn hardfork_info(&self, ctx: Context) -> ProtocolResult<HardforkInfo>;
}
4 changes: 4 additions & 0 deletions protocol/src/types/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub use evm::{backend::Log, Config, ExitError, ExitFatal, ExitReason, ExitRevert
use rlp_derive::{RlpDecodable, RlpEncodable};

use crate::types::{Bloom, Hash, Hasher, Header, MerkleRoot, Proposal, H160, U256};
use bytes::Bytes;

const BLOOM_BYTE_LENGTH: usize = 256;

Expand Down Expand Up @@ -52,6 +53,7 @@ pub struct ExecutorContext {
pub gas_price: U256,
pub block_gas_limit: U256,
pub block_base_fee_per_gas: U256,
pub extra_data: Bytes,
}

impl From<Proposal> for ExecutorContext {
Expand All @@ -65,6 +67,7 @@ impl From<Proposal> for ExecutorContext {
gas_price: U256::one(),
block_gas_limit: h.gas_limit,
block_base_fee_per_gas: h.base_fee_per_gas,
extra_data: h.extra_data,
}
}
}
Expand All @@ -80,6 +83,7 @@ impl From<&Header> for ExecutorContext {
gas_price: U256::one(),
block_gas_limit: h.gas_limit,
block_base_fee_per_gas: h.base_fee_per_gas,
extra_data: h.extra_data.clone(),
}
}
}
Expand Down
32 changes: 32 additions & 0 deletions protocol/src/types/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,38 @@ pub struct CkbRelatedInfo {
pub reward_smt_type_id: H256,
}

#[derive(
RlpEncodable, RlpDecodable, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default,
)]
pub struct HardforkInfo {
pub inner: Vec<HardforkInfoInner>,
}

impl HardforkInfo {
pub fn push(&mut self, mut other: HardforkInfoInner) {
if let Some(i) = self.inner.last_mut() {
other.flags &= i.flags;
if i.block_number == other.block_number {
i.flags = other.flags;
} else {
self.inner.push(other);
}
} else {
self.inner.push(other);
}

self.inner
.sort_by(|a, b| a.block_number.cmp(&b.block_number));
}
}

#[derive(RlpEncodable, RlpDecodable, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct HardforkInfoInner {
pub block_number: BlockNumber,
#[serde(serialize_with = "serialize_uint")]
pub flags: U256,
}

fn ensure_len(real: usize, expect: usize) -> ProtocolResult<()> {
if real != expect {
Err(TypesError::LengthMismatch { expect, real }.into())
Expand Down

0 comments on commit 827c369

Please sign in to comment.