Skip to content

Commit

Permalink
feat: first hardfork with contract limit
Browse files Browse the repository at this point in the history
  • Loading branch information
driftluo committed Sep 26, 2023
1 parent 83ea6f2 commit 7539a75
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 65 deletions.
3 changes: 1 addition & 2 deletions builtin-contract/metadata/contracts/metadata.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ contract MetadataManager {
uint64 tx_num_limit;
uint64 max_tx_size;
uint64 gas_limit;
uint64 gas_price;
uint64 interval;
uint64 max_contract_limit;
}

struct CkbRelatedInfo {
Expand Down Expand Up @@ -91,7 +91,6 @@ contract MetadataManager {
target.version = metadata.version;
target.epoch = metadata.epoch;
target.consensus_config.gas_limit = metadata.consensus_config.gas_limit;
target.consensus_config.gas_price = metadata.consensus_config.gas_price;
target.consensus_config.interval = metadata.consensus_config.interval;
target.consensus_config.propose_ratio = metadata
.consensus_config
Expand Down
1 change: 1 addition & 0 deletions common/config-parser/src/types/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,5 @@ impl From<HardforkInput> for HardforkInfoInner {
#[derive(Clone, Debug, Serialize, Deserialize, Copy, ValueEnum, EnumIter, PartialEq, Eq, Hash)]
pub enum HardforkName {
None = 0b0,
Andromeda = 0b1,
}
12 changes: 6 additions & 6 deletions core/executor/src/system_contract/metadata/abi/metadata_abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@
},
{
"internalType": "uint64",
"name": "gas_price",
"name": "interval",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "interval",
"name": "max_contract_limit",
"type": "uint64"
}
],
Expand Down Expand Up @@ -259,12 +259,12 @@
},
{
"internalType": "uint64",
"name": "gas_price",
"name": "interval",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "interval",
"name": "max_contract_limit",
"type": "uint64"
}
],
Expand Down Expand Up @@ -322,12 +322,12 @@
},
{
"internalType": "uint64",
"name": "gas_price",
"name": "interval",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "interval",
"name": "max_contract_limit",
"type": "uint64"
}
],
Expand Down
20 changes: 10 additions & 10 deletions core/executor/src/system_contract/metadata/abi/metadata_abi.rs

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions core/executor/src/system_contract/metadata/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,31 @@ impl From<Metadata> for metadata_abi::Metadata {
impl From<ConsensusConfig> for metadata_abi::ConsensusConfig {
fn from(value: ConsensusConfig) -> Self {
metadata_abi::ConsensusConfig {
propose_ratio: value.propose_ratio,
prevote_ratio: value.prevote_ratio,
precommit_ratio: value.precommit_ratio,
brake_ratio: value.brake_ratio,
tx_num_limit: value.tx_num_limit,
max_tx_size: value.max_tx_size,
gas_limit: value.gas_limit,
gas_price: value.gas_price,
interval: value.interval,
propose_ratio: value.propose_ratio,
prevote_ratio: value.prevote_ratio,
precommit_ratio: value.precommit_ratio,
brake_ratio: value.brake_ratio,
tx_num_limit: value.tx_num_limit,
max_tx_size: value.max_tx_size,
gas_limit: value.gas_limit,
interval: value.interval,
max_contract_limit: value.max_contract_limit,
}
}
}

impl From<metadata_abi::ConsensusConfig> for ConsensusConfig {
fn from(value: metadata_abi::ConsensusConfig) -> Self {
ConsensusConfig {
propose_ratio: value.propose_ratio,
prevote_ratio: value.prevote_ratio,
precommit_ratio: value.precommit_ratio,
brake_ratio: value.brake_ratio,
tx_num_limit: value.tx_num_limit,
max_tx_size: value.max_tx_size,
gas_limit: value.gas_limit,
gas_price: value.gas_price,
interval: value.interval,
propose_ratio: value.propose_ratio,
prevote_ratio: value.prevote_ratio,
precommit_ratio: value.precommit_ratio,
brake_ratio: value.brake_ratio,
tx_num_limit: value.tx_num_limit,
max_tx_size: value.max_tx_size,
gas_limit: value.gas_limit,
interval: value.interval,
max_contract_limit: value.max_contract_limit,
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion core/executor/src/system_contract/metadata/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ 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 CONSENSUS_CONFIG: H256 = Hasher::digest("consensus_config");
static ref HARDFORK_KEY: H256 = Hasher::digest("hardfork");
static ref HARDFORK_INFO: ArcSwap<H256> = ArcSwap::new(Arc::new(H256::zero()));
static ref METADATA_CACHE: RwLock<LruCache<Epoch, Metadata>> = RwLock::new(LruCache::new(METADATA_CACHE_SIZE));
Expand Down Expand Up @@ -97,7 +98,7 @@ impl<Adapter: ExecutorAdapter + ApplyBackend> SystemContract<Adapter>
}
metadata_abi::MetadataContractCalls::UpdateConsensusConfig(c) => {
exec_try!(
store.update_consensus_config(c.config),
store.update_consensus_config(c.config.into()),
gas_limit,
"[metadata] update consensus config"
);
Expand Down
100 changes: 85 additions & 15 deletions core/executor/src/system_contract/metadata/store.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
use std::collections::BTreeMap;
use std::sync::Arc;

use common_config_parser::types::spec::HardforkName;
use protocol::trie::Trie as _;
use protocol::types::{CkbRelatedInfo, HardforkInfo, HardforkInfoInner, Metadata, H160, H256};
use protocol::types::{
CkbRelatedInfo, ConsensusConfig, ConsensusConfigV0, HardforkInfo, HardforkInfoInner, Metadata,
MetadataInner, H160, H256,
};
use protocol::{codec::ProtocolCodec, ProtocolResult};

use crate::system_contract::metadata::{
segment::EpochSegment, CKB_RELATED_INFO_KEY, EPOCH_SEGMENT_KEY, HARDFORK_KEY,
segment::EpochSegment, CKB_RELATED_INFO_KEY, CONSENSUS_CONFIG, EPOCH_SEGMENT_KEY,
HARDFORK_INFO, HARDFORK_KEY,
};
use crate::system_contract::{error::SystemScriptError, METADATA_DB};
use crate::{adapter::RocksTrieDB, MPTTrie, CURRENT_METADATA_ROOT};

use super::metadata_abi::ConsensusConfig;

pub struct MetadataStore {
pub trie: MPTTrie<RocksTrieDB>,
}
Expand Down Expand Up @@ -86,13 +89,18 @@ impl MetadataStore {

epoch_segment.append_endpoint(metadata.version.end)?;

let (inner, config) = metadata.into_part();
let current_hardfork = **HARDFORK_INFO.load();

self.trie.insert(
EPOCH_SEGMENT_KEY.as_bytes().to_vec(),
epoch_segment.as_bytes(),
)?;
self.trie
.insert(inner.epoch.to_be_bytes().to_vec(), inner.encode()?.to_vec())?;
self.trie.insert(
metadata.epoch.to_be_bytes().to_vec(),
metadata.encode()?.to_vec(),
CONSENSUS_CONFIG.as_bytes().to_vec(),
encode_consensus_config(current_hardfork, config.encode()?.to_vec()),
)?;
let new_root = self.trie.commit()?;
CURRENT_METADATA_ROOT.with(|r| *r.borrow_mut() = new_root);
Expand All @@ -105,7 +113,7 @@ impl MetadataStore {
block_number: u64,
proposer: &H160,
) -> ProtocolResult<()> {
let mut metadata = self.get_metadata_by_block_number(block_number)?;
let mut metadata = self.get_metadata_inner(block_number)?;
if let Some(counter) = metadata
.propose_counter
.iter_mut()
Expand All @@ -130,11 +138,26 @@ impl MetadataStore {
}

pub fn get_metadata(&self, epoch: u64) -> ProtocolResult<Metadata> {
let inner = self.get_metadata_inner(epoch)?;
let config = self.get_consensus_config()?;
Ok(Metadata::from_parts(inner, config))
}

fn get_metadata_inner(&self, epoch: u64) -> ProtocolResult<MetadataInner> {
let raw = self
.trie
.get(&epoch.to_be_bytes())?
.ok_or_else(|| SystemScriptError::MissingRecord(epoch))?;
Metadata::decode(raw)
MetadataInner::decode(raw)
}

fn get_consensus_config(&self) -> ProtocolResult<ConsensusConfig> {
let raw = self
.trie
.get(CONSENSUS_CONFIG.as_bytes())?
.expect("Inner panic with can't find consensus config");

decode_consensus_config(raw)
}

pub fn get_metadata_by_block_number(&self, block_number: u64) -> ProtocolResult<Metadata> {
Expand All @@ -151,14 +174,10 @@ impl MetadataStore {
}

pub fn update_consensus_config(&mut self, config: ConsensusConfig) -> ProtocolResult<()> {
let epoch_segment = self.get_epoch_segment()?;
let latest_epoch = epoch_segment.get_latest_epoch_number();
let mut metadata = self.get_metadata(latest_epoch)?;

metadata.consensus_config = config.into();
let current_hardfork = **HARDFORK_INFO.load();
self.trie.insert(
metadata.epoch.to_be_bytes().to_vec(),
metadata.encode()?.to_vec(),
CONSENSUS_CONFIG.as_bytes().to_vec(),
encode_consensus_config(current_hardfork, config.encode()?.to_vec()),
)?;
let new_root = self.trie.commit()?;
CURRENT_METADATA_ROOT.with(|r| *r.borrow_mut() = new_root);
Expand Down Expand Up @@ -222,3 +241,54 @@ impl MetadataStore {
}
}
}

enum ConsensusConfigFlag {
V0 = 0b0,
V1 = 0b1,
}

impl From<u16> for ConsensusConfigFlag {
fn from(value: u16) -> Self {
match value {
0b0 => ConsensusConfigFlag::V0,
0b1 => ConsensusConfigFlag::V1,
_ => unreachable!(),
}
}
}

impl ConsensusConfigFlag {
fn new(flags: H256) -> Self {
let v1_name_flag = H256::from_low_u64_be((HardforkName::Andromeda as u64).to_be());
let res = flags & v1_name_flag;

if res & v1_name_flag == v1_name_flag {
ConsensusConfigFlag::V1
} else {
ConsensusConfigFlag::V0
}
}
}

fn decode_consensus_config(raw: Vec<u8>) -> ProtocolResult<ConsensusConfig> {
let raw_flag = {
let mut a = [0u8; 2];
a[0] = raw[0];
a[1] = raw[1];
a
};
let flag = ConsensusConfigFlag::from(u16::from_be_bytes(raw_flag));

match flag {
ConsensusConfigFlag::V0 => ConsensusConfigV0::decode(&raw[2..]).map(Into::into),
ConsensusConfigFlag::V1 => ConsensusConfig::decode(&raw[2..]),
}
}

fn encode_consensus_config(current_hardfork: H256, config: Vec<u8>) -> Vec<u8> {
let flag = ConsensusConfigFlag::new(current_hardfork);

let mut res = (flag as u16).to_be_bytes().to_vec();
res.extend(config);
res
}
18 changes: 9 additions & 9 deletions core/executor/src/tests/system_script/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,15 @@ fn prepare_metadata() -> Metadata {
verifier_list: vec![prepare_validator()],
propose_counter: vec![],
consensus_config: ConsensusConfig {
gas_limit: 1u64,
gas_price: 0u64,
interval: 0u64,
propose_ratio: 1u64,
prevote_ratio: 1u64,
precommit_ratio: 1u64,
brake_ratio: 1u64,
tx_num_limit: 1u64,
max_tx_size: 1u64,
gas_limit: 1u64,
interval: 0u64,
propose_ratio: 1u64,
prevote_ratio: 1u64,
precommit_ratio: 1u64,
brake_ratio: 1u64,
tx_num_limit: 1u64,
max_tx_size: 1u64,
max_contract_limit: 0x6000u64,
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion protocol/src/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,14 @@ mod tests {
}],
consensus_config: ConsensusConfig {
gas_limit: 4294967295,
gas_price: 1,
interval: 3000,
propose_ratio: 15,
prevote_ratio: 10,
precommit_ratio: 10,
brake_ratio: 10,
tx_num_limit: 20000,
max_tx_size: 1024,
max_contract_limit: 0x6000
}
};

Expand Down
Loading

0 comments on commit 7539a75

Please sign in to comment.