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

refactor(executor): abstract interface of system contract #901

Merged
merged 2 commits into from
Dec 12, 2022
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
190 changes: 96 additions & 94 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion common/memory-tracker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jemalloc-ctl = { version = "0.5", package = "tikv-jemalloc-ctl" }
libc = "0.2"
log = "0.4"
once_cell = "1.16.0"
rocksdb = { version = "0.18", package = "ckb-rocksdb" }
rocksdb = { version = "0.19", package = "ckb-rocksdb" }

common-apm = { path = "../apm" }
protocol = { path = "../../protocol", package = "axon-protocol" }
2 changes: 1 addition & 1 deletion core/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ protocol = { path = "../../protocol", package = "axon-protocol" }
rand = { version = "0.8", features = ["small_rng"] }
ripemd = "0.1"
rlp = "0.5"
rocksdb = { version = "0.18", package = "ckb-rocksdb" }
rocksdb = { version = "0.19", package = "ckb-rocksdb" }
rug = "1.18"
sha2 = "0.10"

Expand Down
19 changes: 8 additions & 11 deletions core/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ pub mod adapter;
#[cfg(test)]
mod debugger;
mod precompiles;
mod system;
pub mod system_contract;
#[cfg(test)]
mod tests;
mod utils;
mod vm;

pub use crate::adapter::{AxonExecutorAdapter, MPTTrie, RocksTrieDB};
pub use crate::system::NATIVE_TOKEN_ISSUE_ADDRESS;
pub use crate::utils::{
code_address, decode_revert_msg, logs_bloom, DefaultFeeAllocator, FeeInlet,
};
Expand All @@ -31,7 +30,8 @@ use protocol::types::{
ValidatorExtend, GAS_CALL_TRANSACTION, GAS_CREATE_TRANSACTION, H160, NIL_DATA, RLP_NULL, U256,
};

use crate::{precompiles::build_precompile_set, system::SystemExecutor};
use crate::precompiles::build_precompile_set;
use crate::system_contract::{system_contract_dispatch, NativeTokenContract, SystemContract};

lazy_static::lazy_static! {
pub static ref FEE_ALLOCATOR: ArcSwap<Box<dyn FeeAllocate>> = ArcSwap::from_pointee(Box::new(DefaultFeeAllocator::default()));
Expand Down Expand Up @@ -125,20 +125,17 @@ impl Executor for AxonExecutor {
let mut res = Vec::with_capacity(txs_len);
let mut hashes = Vec::with_capacity(txs_len);
let (mut gas, mut fee) = (0u64, U256::zero());

let sys_executor = SystemExecutor::new();
let precompiles = build_precompile_set();
let config = Config::london();

for tx in txs.iter() {
backend.set_gas_price(tx.transaction.unsigned.gas_price());
backend.set_origin(tx.sender);

let mut r = if is_call_system_script(tx.transaction.unsigned.action()) {
sys_executor.inner_exec(backend, tx)
} else {
Self::evm_exec(backend, &config, &precompiles, tx)
};
// Execute a transaction, if system contract dispatch return None, means the
// transaction called EVM
let mut r = system_contract_dispatch(backend, tx)
.unwrap_or_else(|| Self::evm_exec(backend, &config, &precompiles, tx));

r.logs = backend.get_logs();
gas += r.gas_used;
Expand Down Expand Up @@ -291,7 +288,7 @@ impl AxonExecutor {

pub fn is_call_system_script(action: &TransactionAction) -> bool {
match action {
TransactionAction::Call(addr) => addr == &NATIVE_TOKEN_ISSUE_ADDRESS,
TransactionAction::Call(addr) => addr == &NativeTokenContract::ADDRESS,
TransactionAction::Create => false,
}
}
Expand Down
33 changes: 33 additions & 0 deletions core/executor/src/system_contract/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
mod native_token;

pub use crate::system_contract::native_token::NativeTokenContract;

use protocol::traits::{ApplyBackend, Backend};
use protocol::types::{SignedTransaction, TxResp, H160};

pub const fn system_contract_address(addr: u8) -> H160 {
H160([
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, addr,
])
}

pub trait SystemContract {
const ADDRESS: H160;

fn exec_<B: Backend + ApplyBackend>(&self, backend: &mut B, tx: &SignedTransaction) -> TxResp;
}

pub fn system_contract_dispatch<B: Backend + ApplyBackend>(
backend: &mut B,
tx: &SignedTransaction,
) -> Option<TxResp> {
let native_token_address = NativeTokenContract::ADDRESS;
if let Some(addr) = tx.get_to() {
if addr == native_token_address {
return Some(NativeTokenContract::default().exec_(backend, tx));
}
}

None
}
Original file line number Diff line number Diff line change
@@ -1,69 +1,18 @@
use protocol::codec::ProtocolCodec;
use protocol::traits::{ApplyBackend, Backend};
use protocol::types::{
ExitReason, ExitRevert, SignedTransaction, TransactionAction, TxResp, H160, U256,
Apply, Basic, ExitReason, ExitRevert, ExitSucceed, SignedTransaction, TxResp, H160, U256,
};

pub const NATIVE_TOKEN_ISSUE_ADDRESS: H160 = H160([
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
]);
use crate::system_contract::{system_contract_address, SystemContract};

#[derive(Default)]
pub struct SystemExecutor;
pub struct NativeTokenContract;

impl SystemExecutor {
pub fn new() -> Self {
SystemExecutor::default()
}

pub fn inner_exec<B: Backend + ApplyBackend>(
&self,
backend: &mut B,
tx: &SignedTransaction,
) -> TxResp {
match classify_script(tx.transaction.unsigned.action()) {
SystemScriptCategory::NativeToken => native_token::call_native_token(backend, tx),
}
}
}

enum SystemScriptCategory {
NativeToken,
}

fn classify_script(action: &TransactionAction) -> SystemScriptCategory {
match action {
TransactionAction::Call(_addr) => SystemScriptCategory::NativeToken,
TransactionAction::Create => unreachable!(),
}
}

fn revert_resp(gas_limit: U256) -> TxResp {
TxResp {
exit_reason: ExitReason::Revert(ExitRevert::Reverted),
ret: vec![],
gas_used: 1u64,
remain_gas: (gas_limit - 1).as_u64(),
fee_cost: U256::one(),
logs: vec![],
code_address: None,
removed: false,
}
}

mod native_token {
use protocol::codec::ProtocolCodec;
use protocol::traits::{ApplyBackend, Backend};
use protocol::types::{
Apply, Basic, ExitReason, ExitSucceed, SignedTransaction, TxResp, H160, U256,
};
impl SystemContract for NativeTokenContract {
const ADDRESS: H160 = system_contract_address(0x0);

use crate::system::revert_resp;

pub fn call_native_token<B: Backend + ApplyBackend>(
backend: &mut B,
tx: &SignedTransaction,
) -> TxResp {
fn exec_<B: Backend + ApplyBackend>(&self, backend: &mut B, tx: &SignedTransaction) -> TxResp {
let tx = &tx.transaction.unsigned;
let tx_data = tx.data();
let tx_value = *tx.value();
Expand Down Expand Up @@ -113,3 +62,16 @@ mod native_token {
}
}
}

fn revert_resp(gas_limit: U256) -> TxResp {
TxResp {
exit_reason: ExitReason::Revert(ExitRevert::Reverted),
ret: vec![],
gas_used: 1u64,
remain_gas: (gas_limit - 1).as_u64(),
fee_cost: U256::one(),
logs: vec![],
code_address: None,
removed: false,
}
}
20 changes: 10 additions & 10 deletions core/executor/src/tests/system_script.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::{SystemExecutor, NATIVE_TOKEN_ISSUE_ADDRESS};
use crate::system_contract::{NativeTokenContract, SystemContract};

fn mock_data(direction: u8, address: H160) -> Vec<u8> {
let mut ret = vec![direction];
Expand All @@ -11,12 +11,12 @@ fn mock_data(direction: u8, address: H160) -> Vec<u8> {
fn test_issue_token() {
let vicinity = gen_vicinity();
let mut backend = MemoryBackend::new(&vicinity, BTreeMap::new());
let executor = SystemExecutor::default();
let executor = NativeTokenContract::default();
let addr = H160::from_str("0xf000000000000000000000000000000000000000").unwrap();
let data = mock_data(0, addr);
let tx = gen_tx(addr, NATIVE_TOKEN_ISSUE_ADDRESS, 1000, data);
let tx = gen_tx(addr, NativeTokenContract::ADDRESS, 1000, data);

let r = executor.inner_exec(&mut backend, &tx);
let r = executor.exec_(&mut backend, &tx);
assert!(r.exit_reason.is_succeed());
assert_eq!(r.ret, rlp::encode(&U256::from(1000)).to_vec());

Expand All @@ -37,11 +37,11 @@ fn test_burn_token() {
});
let vicinity = gen_vicinity();
let mut backend = MemoryBackend::new(&vicinity, state);
let executor = SystemExecutor::default();
let executor = NativeTokenContract::default();
let data = mock_data(1, addr);
let tx = gen_tx(addr, NATIVE_TOKEN_ISSUE_ADDRESS, 1000, data);
let tx = gen_tx(addr, NativeTokenContract::ADDRESS, 1000, data);

let r = executor.inner_exec(&mut backend, &tx);
let r = executor.exec_(&mut backend, &tx);
assert!(r.exit_reason.is_succeed());
assert_eq!(r.ret, rlp::encode(&U256::from(1000)).to_vec());

Expand All @@ -62,11 +62,11 @@ fn test_burn_token_failed() {
});
let vicinity = gen_vicinity();
let mut backend = MemoryBackend::new(&vicinity, state);
let executor = SystemExecutor::default();
let executor = NativeTokenContract::default();
let data = mock_data(1, addr);
let tx = gen_tx(addr, NATIVE_TOKEN_ISSUE_ADDRESS, 1000, data);
let tx = gen_tx(addr, NativeTokenContract::ADDRESS, 1000, data);

let r = executor.inner_exec(&mut backend, &tx);
let r = executor.exec_(&mut backend, &tx);
assert!(r.exit_reason.is_revert());
assert!(r.ret.is_empty());

Expand Down
7 changes: 4 additions & 3 deletions core/mempool/benches/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ use common_crypto::{
Crypto, PrivateKey, Secp256k1Recoverable, Secp256k1RecoverablePrivateKey,
Secp256k1RecoverablePublicKey, Signature, ToPublicKey, UncompressedPublicKey,
};
use core_executor::NATIVE_TOKEN_ISSUE_ADDRESS;
use core_executor::system_contract::system_contract_address;
use protocol::traits::{Context, MemPool, MemPoolAdapter};
use protocol::types::{
public_to_address, recover_intact_pub_key, Bytes, Eip1559Transaction, Hash, PackedTxHashes,
Public, SignedTransaction, TransactionAction, UnsignedTransaction, UnverifiedTransaction, H256,
U256,
Public, SignedTransaction, TransactionAction, UnsignedTransaction, UnverifiedTransaction, H160,
H256, U256,
};
use protocol::{async_trait, tokio, ProtocolResult};

Expand All @@ -26,6 +26,7 @@ pub const POOL_SIZE: usize = 100_000;
pub const MAX_TX_SIZE: u64 = 1024; // 1KB
pub const TIMEOUT: u64 = 1000;
pub const TIMEOUT_GAP: u64 = 100;
pub const NATIVE_TOKEN_ISSUE_ADDRESS: H160 = system_contract_address(0x0);

pub struct HashMemPoolAdapter {
network_txs: DashMap<Hash, SignedTransaction>,
Expand Down
7 changes: 4 additions & 3 deletions core/mempool/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ use common_crypto::{
Crypto, PrivateKey, Secp256k1Recoverable, Secp256k1RecoverablePrivateKey,
Secp256k1RecoverablePublicKey, Signature, ToPublicKey, UncompressedPublicKey,
};
use core_executor::NATIVE_TOKEN_ISSUE_ADDRESS;
use core_executor::system_contract::system_contract_address;
use protocol::traits::{Context, MemPool, MemPoolAdapter};
use protocol::types::{
public_to_address, recover_intact_pub_key, Bytes, Eip1559Transaction, Hash, PackedTxHashes,
Public, SignedTransaction, TransactionAction, UnsignedTransaction, UnverifiedTransaction, H256,
U256,
Public, SignedTransaction, TransactionAction, UnsignedTransaction, UnverifiedTransaction, H160,
H256, U256,
};
use protocol::{async_trait, tokio, ProtocolResult};

Expand All @@ -28,6 +28,7 @@ const POOL_SIZE: usize = 100_000;
const MAX_TX_SIZE: u64 = 1024; // 1KB
const TIMEOUT: u64 = 1000;
const TIMEOUT_GAP: u64 = 100;
const NATIVE_TOKEN_ISSUE_ADDRESS: H160 = system_contract_address(0x0);

pub struct HashMemPoolAdapter {
network_txs: DashMap<Hash, SignedTransaction>,
Expand Down
2 changes: 1 addition & 1 deletion core/storage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ lazy_static = "1.4"
log = "0.4"
lru = "0.8"
parking_lot = "0.12"
rocksdb = { version = "0.18", package = "ckb-rocksdb" }
rocksdb = { version = "0.19", package = "ckb-rocksdb" }

common-apm = { path = "../../common/apm" }
common-apm-derive = { path = "../../common/apm-derive" }
Expand Down