Skip to content

Commit

Permalink
eip1559 support
Browse files Browse the repository at this point in the history
  • Loading branch information
harryliisme3 committed Dec 16, 2022
1 parent ab10674 commit bcced33
Show file tree
Hide file tree
Showing 37 changed files with 1,560 additions and 326 deletions.
3 changes: 3 additions & 0 deletions src/components/config/src/abci/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub struct CheckPointConfig {
// Fix the amount in the delegators that staking did not modify when it punished the validator.
pub fix_delegators_am_height: u64,
pub validators_limit_v2_height: u64,
pub enable_eip1559_height: u64,
}

impl CheckPointConfig {
Expand Down Expand Up @@ -127,6 +128,7 @@ impl CheckPointConfig {
proper_gas_set_height: 0,
fix_delegators_am_height: 0,
validators_limit_v2_height: 0,
enable_eip1559_height: 0,
};
#[cfg(not(feature = "debug_env"))]
let config = CheckPointConfig {
Expand Down Expand Up @@ -156,6 +158,7 @@ impl CheckPointConfig {
fix_undelegation_missing_reward_height: 3000000,
fix_delegators_am_height: 30000000,
validators_limit_v2_height: 30000000,
enable_eip1559_height: 40000000,
};
let content = toml::to_string(&config).unwrap();
file.write_all(content.as_bytes()).unwrap();
Expand Down
31 changes: 30 additions & 1 deletion src/components/contracts/baseapp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub mod tm_events;

use crate::modules::ModuleManager;
use abci::Header;
use ethereum::BlockV0 as Block;
use ethereum::BlockV2 as Block;
use evm_precompile::{self, FindoraPrecompiles};
use fin_db::{FinDB, RocksDB};
use fp_core::context::Context as Context2;
Expand All @@ -24,6 +24,7 @@ use fp_core::{
transaction::{ActionResult, Executable, ValidateUnsigned},
};
use fp_evm::BlockId;
use fp_traits::evm::FeeCalculator as FeeCalculator2;
use fp_traits::{
account::{AccountAsset, FeeCalculator},
base::BaseProvider,
Expand Down Expand Up @@ -54,6 +55,23 @@ const CHAIN_STATE_PATH: &str = "state.db";
const CHAIN_HISTORY_DATA_PATH: &str = "history.db";
const BLOCKS_IN_DAY: u64 = 4 * 60 * 24;

const INITIAL_BASE_FEE: u64 = 1000000000;
const ELASTICITY_MULTIPLIER: u64 = 2;
const BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;

#[inline(always)]
pub fn get_initial_base_fee() -> U256 {
U256::from(INITIAL_BASE_FEE)
}
#[inline(always)]
pub fn get_elasticity_multiplier() -> U256 {
U256::from(ELASTICITY_MULTIPLIER)
}
#[inline(always)]
pub fn get_base_fee_max_change_denominator() -> U256 {
U256::from(BASE_FEE_MAX_CHANGE_DENOMINATOR)
}

#[derive(Clone)]
pub struct BaseApp {
/// application name from abci.Info
Expand Down Expand Up @@ -467,4 +485,15 @@ impl BaseProvider for BaseApp {
None
}
}

/// Return the base fee at the given height.
#[allow(clippy::comparison_chain, clippy::question_mark)]
fn base_fee(&self, id: Option<BlockId>) -> Option<U256> {
let _ = id;
Some(
<BaseApp as module_evm::Config>::FeeCalculator::min_gas_price(
self.current_block_number()?.as_u64(),
),
)
}
}
10 changes: 10 additions & 0 deletions src/components/contracts/modules/account/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,14 @@ impl<C: Config> AccountAsset<Address> for App<C> {
) -> Result<()> {
Allowances::insert(ctx.state.write().borrow_mut(), owner, spender, &amount)
}

fn income(ctx: &Context, who: &Address, value: U256) -> Result<()> {
if value.is_zero() {
return Ok(());
}

let mut sa = Self::account_of(ctx, who, None).c(d!("account does not exist"))?;
sa.balance = sa.balance.checked_add(value).c(d!("balance overflow"))?;
AccountStore::insert(ctx.state.write().borrow_mut(), who, &sa)
}
}
219 changes: 161 additions & 58 deletions src/components/contracts/modules/ethereum/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use crate::storage::*;
use crate::{App, Config, ContractLog, TransactionExecuted};
use config::abci::global_cfg::CFG;
use ethereum::{
BlockV0 as Block, LegacyTransactionMessage, ReceiptV0 as Receipt,
TransactionV0 as Transaction,
};
use ethereum::{BlockV2 as Block, ReceiptV0 as Receipt, TransactionV2 as Transaction};
use ethereum_types::{Bloom, BloomInput, H160, H256, H64, U256};
use evm::{ExitFatal, ExitReason};
use fp_core::{
Expand All @@ -16,10 +13,8 @@ use fp_core::{
use fp_events::Event;
use fp_evm::{BlockId, CallOrCreateInfo, Runner, TransactionStatus};
use fp_storage::{Borrow, BorrowMut};
use fp_types::{
actions::evm as EvmAction,
crypto::{secp256k1_ecdsa_recover, HA256},
};
// use fp_types::crypto::secp256k1_ecdsa_recover;
use fp_types::{actions::evm as EvmAction, crypto::HA256};
use fp_utils::{proposer_converter, timestamp_converter};
use ruc::*;
use sha3::{Digest, Keccak256};
Expand Down Expand Up @@ -63,14 +58,28 @@ impl<C: Config> App<C> {
pub fn recover_signer(transaction: &Transaction) -> Option<H160> {
let mut sig = [0u8; 65];
let mut msg = [0u8; 32];
sig[0..32].copy_from_slice(&transaction.signature.r()[..]);
sig[32..64].copy_from_slice(&transaction.signature.s()[..]);
sig[64] = transaction.signature.standard_v();
msg.copy_from_slice(
&LegacyTransactionMessage::from(transaction.clone()).hash()[..],
);

let pubkey = secp256k1_ecdsa_recover(&sig, &msg).ok()?;
match transaction {
Transaction::Legacy(t) => {
sig[0..32].copy_from_slice(&t.signature.r()[..]);
sig[32..64].copy_from_slice(&t.signature.s()[..]);
sig[64] = t.signature.standard_v();
msg.copy_from_slice(
&ethereum::LegacyTransactionMessage::from(t.clone()).hash()[..],
);
}
Transaction::EIP1559(t) => {
sig[0..32].copy_from_slice(&t.r[..]);
sig[32..64].copy_from_slice(&t.s[..]);
sig[64] = t.odd_y_parity as u8;
msg.copy_from_slice(
&ethereum::EIP1559TransactionMessage::from(t.clone()).hash()[..],
);
}
_ => {
return None;
}
}
let pubkey = fp_types::crypto::secp256k1_ecdsa_recover(&sig, &msg).ok()?;
Some(H160::from(H256::from_slice(
Keccak256::digest(pubkey).as_slice(),
)))
Expand Down Expand Up @@ -225,8 +234,7 @@ impl<C: Config> App<C> {
let source = Self::recover_signer_fast(ctx, &transaction)
.ok_or_else(|| eg!("ExecuteTransaction: InvalidSignature"))?;

let transaction_hash =
H256::from_slice(Keccak256::digest(&rlp::encode(&transaction)).as_slice());
let transaction_hash = transaction.hash();

let transaction_index = if just_check {
0
Expand All @@ -236,22 +244,74 @@ impl<C: Config> App<C> {
txns.len() as u32
};

let gas_limit = transaction.gas_limit;
let nonce;
let gas_price;
let gas_limit;
let action;
let value;
let input;
let max_priority_fee_per_gas;
let max_fee_per_gas;
let _chain_id;
let mut _access_list = vec![];

let is_eip1559 = match &transaction {
Transaction::Legacy(legacy_transaction_transaction) => {
let transaction = legacy_transaction_transaction;
nonce = transaction.nonce;
gas_price = transaction.gas_price;
max_fee_per_gas = transaction.gas_price;
max_priority_fee_per_gas = U256::from(0);
gas_limit = transaction.gas_limit;
action = transaction.action;
value = transaction.value;
input = transaction.input.clone();
_chain_id = match transaction.signature.chain_id() {
Some(chain_id) => chain_id,
None => return Err(eg!("Must provide chainId")),
};

false
}
Transaction::EIP1559(eip1559_transaction_transaction) => {
let transaction = eip1559_transaction_transaction;
nonce = transaction.nonce;
gas_limit = transaction.gas_limit;
action = transaction.action;
value = transaction.value;
input = transaction.input.clone();
max_fee_per_gas = transaction.max_fee_per_gas;
max_priority_fee_per_gas = transaction.max_priority_fee_per_gas;
gas_price = transaction.max_fee_per_gas;
_chain_id = transaction.chain_id;
_access_list = transaction.access_list.clone();

true
}
_ => {
return Err(eg!("Transaction Type Error"));
}
};

// let gas_limit = transaction.gas_limit;

let execute_ret = Self::execute_transaction(
ctx,
source,
transaction.input.clone(),
transaction.value,
transaction.gas_limit,
Some(transaction.gas_price),
Some(transaction.nonce),
transaction.action,
input,
value,
gas_limit,
Some(gas_price),
Some(max_fee_per_gas),
Some(max_priority_fee_per_gas),
Some(nonce),
action,
is_eip1559,
);

if let Err(e) = execute_ret {
let mut to = Default::default();
if let ethereum::TransactionAction::Call(target) = transaction.action {
if let ethereum::TransactionAction::Call(target) = action {
to = target;
}
events.push(Event::emit_event(
Expand Down Expand Up @@ -410,42 +470,85 @@ impl<C: Config> App<C> {
value: U256,
gas_limit: U256,
gas_price: Option<U256>,
max_fee_per_gas: Option<U256>,
max_priority_fee_per_gas: Option<U256>,
nonce: Option<U256>,
action: ethereum::TransactionAction,
is_eip1559: bool,
) -> Result<(Option<H160>, Option<H160>, CallOrCreateInfo)> {
match action {
ethereum::TransactionAction::Call(target) => {
let res = C::Runner::call(
ctx,
EvmAction::Call {
source: from,
target,
input,
value,
gas_limit: gas_limit.low_u64(),
gas_price,
nonce,
},
C::config(),
)?;

Ok((Some(target), None, CallOrCreateInfo::Call(res)))
if is_eip1559 {
match action {
ethereum::TransactionAction::Call(target) => {
let res = C::Runner::call_eip1559(
ctx,
EvmAction::CallEip1559 {
source: from,
target,
input,
value,
gas_limit: gas_limit.low_u64(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
},
C::config(),
)?;

Ok((Some(target), None, CallOrCreateInfo::Call(res)))
}
ethereum::TransactionAction::Create => {
let res = C::Runner::create_eip1559(
ctx,
EvmAction::CreateEip1559 {
source: from,
init: input,
value,
gas_limit: gas_limit.low_u64(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
},
C::config(),
)?;

Ok((None, Some(res.value), CallOrCreateInfo::Create(res)))
}
}
ethereum::TransactionAction::Create => {
let res = C::Runner::create(
ctx,
EvmAction::Create {
source: from,
init: input,
value,
gas_limit: gas_limit.low_u64(),
gas_price,
nonce,
},
C::config(),
)?;

Ok((None, Some(res.value), CallOrCreateInfo::Create(res)))
} else {
match action {
ethereum::TransactionAction::Call(target) => {
let res = C::Runner::call(
ctx,
EvmAction::Call {
source: from,
target,
input,
value,
gas_limit: gas_limit.low_u64(),
gas_price,
nonce,
},
C::config(),
)?;

Ok((Some(target), None, CallOrCreateInfo::Call(res)))
}
ethereum::TransactionAction::Create => {
let res = C::Runner::create(
ctx,
EvmAction::Create {
source: from,
init: input,
value,
gas_limit: gas_limit.low_u64(),
gas_price,
nonce,
},
C::config(),
)?;

Ok((None, Some(res.value), CallOrCreateInfo::Create(res)))
}
}
}
}
Expand Down
Loading

0 comments on commit bcced33

Please sign in to comment.