Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: first hardfork with contract size limit #1451

Merged
merged 5 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ library MetadataType {
uint64 max_tx_size;
uint64 gas_limit;
uint64 interval;
uint64 max_contract_limit;
}

struct CkbRelatedInfo {
Expand All @@ -56,7 +57,11 @@ library MetadataType {
interface MetadataManager {
function appendMetadata(MetadataType.Metadata memory metadata) external;

function updateConsensusConfig(MetadataType.ConsensusConfig memory config) external;
function updateConsensusConfig(
MetadataType.ConsensusConfig memory config
) external;

function setCkbRelatedInfo(MetadataType.CkbRelatedInfo memory info) external;
function setCkbRelatedInfo(
MetadataType.CkbRelatedInfo memory info
) external;
}
55 changes: 38 additions & 17 deletions common/config-parser/src/types/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use clap::{
Args, ValueEnum,
};
use serde::{Deserialize, Serialize};
use strum::IntoEnumIterator;
use strum_macros::EnumIter;

use common_crypto::Secp256k1RecoverablePrivateKey;
use protocol::{
codec::{decode_256bits_key, deserialize_address, ProtocolCodec},
codec::{decode_256bits_key, deserialize_address},
types::{
ExtraData, HardforkInfoInner, Header, Key256Bits, Metadata, H160, H256, RLP_EMPTY_LIST,
RLP_NULL, U256,
HardforkInfoInner, Header, Key256Bits, Metadata, H160, H256, RLP_EMPTY_LIST, RLP_NULL, U256,
},
};

Expand Down Expand Up @@ -209,23 +209,18 @@ impl Genesis {
transactions_root: RLP_NULL,
signed_txs_hash: RLP_EMPTY_LIST,
timestamp: self.timestamp,
// todo: if Hardforkinput is empty, it must change to latest hardfork info to init
// genesis
extra_data: {
vec![ExtraData {
inner: Into::<HardforkInfoInner>::into(HardforkInput {
hardforks: self.hardforks.clone(),
block_number: 0,
})
.encode()
.unwrap(),
}]
},
base_fee_per_gas: self.base_fee_per_gas,
chain_id: self.chain_id,
..Default::default()
}
}

pub fn generate_hardfork_info(&self) -> HardforkInfoInner {
Into::<HardforkInfoInner>::into(HardforkInput {
hardforks: self.hardforks.clone(),
block_number: 0,
})
}
}

#[derive(Clone, Debug, Deserialize, Args)]
Expand All @@ -242,20 +237,46 @@ pub struct HardforkInput {

impl From<HardforkInput> for HardforkInfoInner {
fn from(value: HardforkInput) -> Self {
let flags = {
let r = value.hardforks.into_iter().fold(0, |acc, s| acc | s as u64);
let convert_fn = |hardforks: Vec<HardforkName>| -> H256 {
let r = hardforks.into_iter().fold(0, |acc, s| acc | s as u64);

H256::from_low_u64_be(r.to_be())
};

let flags = if value.hardforks.is_empty() {
H256::from_low_u64_be(HardforkName::all().to_be())
} else if value.hardforks.len() == 1 {
if value.hardforks[0] == HardforkName::None {
H256::zero()
} else {
convert_fn(value.hardforks)
}
} else {
convert_fn(value.hardforks)
};

HardforkInfoInner {
block_number: value.block_number,
flags,
}
}
}

/// inspired by https://www.wikiwand.com/en/IAU_designated_constellations#List
#[derive(Clone, Debug, Serialize, Deserialize, Copy, ValueEnum, EnumIter, PartialEq, Eq, Hash)]
pub enum HardforkName {
None = 0b0,
driftluo marked this conversation as resolved.
Show resolved Hide resolved
/// If this hardfork is activated, chain validators can modify the EVM
/// contract size limit.
Andromeda = 0b1,
driftluo marked this conversation as resolved.
Show resolved Hide resolved
}

impl HardforkName {
pub fn all() -> u64 {
let mut res = 0u64;
for name in HardforkName::iter() {
res |= name as u64
}
res
}
}
6 changes: 3 additions & 3 deletions core/api/src/jsonrpc/impl/axon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,10 @@ fn enabled_and_determined(iter: &[HardforkInfoInner], current_number: u64) -> (H
if iter.len() < 2 {
match iter.last() {
Some(latest) => {
if latest.block_number >= current_number {
(latest.flags, H256::zero())
} else {
if latest.block_number > current_number {
(H256::zero(), latest.flags)
} else {
(latest.flags, H256::zero())
}
}
None => (H256::zero(), H256::zero()),
Expand Down
27 changes: 24 additions & 3 deletions core/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ mod utils;
pub use crate::adapter::{
AxonExecutorApplyAdapter, AxonExecutorReadOnlyAdapter, MPTTrie, RocksTrieDB,
};
pub use crate::system_contract::{metadata::MetadataHandle, DataProvider};
pub use crate::system_contract::{
metadata::{MetadataHandle, HARDFORK_INFO},
DataProvider,
};
pub use crate::utils::{code_address, decode_revert_msg, DefaultFeeAllocator, FeeInlet};

use std::cell::RefCell;
use std::collections::BTreeMap;
use std::iter::FromIterator;

use arc_swap::ArcSwap;
use common_config_parser::types::spec::HardforkName;
use evm::executor::stack::{MemoryStackState, PrecompileFn, StackExecutor, StackSubstateMetadata};
use evm::CreateScheme;

Expand Down Expand Up @@ -69,7 +73,7 @@ impl Executor for AxonExecutor {
value: U256,
data: Vec<u8>,
) -> TxResp {
let config = Config::london();
let config = self.config();
let metadata = StackSubstateMetadata::new(gas_limit, &config);
let state = MemoryStackState::new(metadata, backend);
let precompiles = build_precompile_set();
Expand Down Expand Up @@ -134,7 +138,7 @@ impl Executor for AxonExecutor {
let mut hashes = Vec::with_capacity(txs_len);
let (mut gas, mut fee) = (0u64, U256::zero());
let precompiles = build_precompile_set();
let config = Config::london();
let config = self.config();

self.init_local_system_contract_roots(adapter);

Expand Down Expand Up @@ -316,6 +320,23 @@ impl AxonExecutor {
});
}

fn config(&self) -> Config {
let mut config = Config::london();
let create_contract_limit = {
let latest_hardfork_info = &**HARDFORK_INFO.load();
let enable_contract_limit_flag = H256::from_low_u64_be(HardforkName::Andromeda as u64);
if latest_hardfork_info & &enable_contract_limit_flag == enable_contract_limit_flag {
let handle = MetadataHandle::new(CURRENT_METADATA_ROOT.with(|r| *r.borrow()));
let config = handle.get_consensus_config().unwrap();
Some(config.max_contract_limit as usize)
} else {
None
}
};
config.create_contract_limit = create_contract_limit;
config
}

#[cfg(test)]
fn test_exec<Adapter: ExecutorAdapter>(
&self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
"internalType": "uint64",
"name": "interval",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "max_contract_limit",
"type": "uint64"
}
],
"internalType": "struct MetadataType.ConsensusConfig",
Expand Down Expand Up @@ -220,6 +225,11 @@
"internalType": "uint64",
"name": "interval",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "max_contract_limit",
"type": "uint64"
}
],
"internalType": "struct MetadataType.ConsensusConfig",
Expand Down
Loading
Loading