Skip to content

Commit

Permalink
chore: add HaberFix upgrade and other optimization (#42)
Browse files Browse the repository at this point in the history
* chore: add `HaberFix` upgrade and other optimization

* trim system contracts bytecode
  • Loading branch information
pythonberg1997 authored Jun 27, 2024
1 parent 4086c81 commit fe5faf2
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 123 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 5 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -506,12 +506,11 @@ test-fuzz = "5"
iai-callgrind = "0.11"

[patch.crates-io]
revm = { git = "https://github.com/bnb-chain/revm", rev = "63b8ab893c6f1d2984131017de9872b2809b615b" }
revm-interpreter = { git = "https://github.com/bnb-chain/revm", rev = "63b8ab893c6f1d2984131017de9872b2809b615b" }
revm-precompile = { git = "https://github.com/bnb-chain/revm", rev = "63b8ab893c6f1d2984131017de9872b2809b615b" }
revm-primitives = { git = "https://github.com/bnb-chain/revm", rev = "63b8ab893c6f1d2984131017de9872b2809b615b" }
revm = { git = "https://github.com/bnb-chain/revm", rev = "dfca3edd9732372e19dea88462eaece1e74824f1" }
revm-interpreter = { git = "https://github.com/bnb-chain/revm", rev = "dfca3edd9732372e19dea88462eaece1e74824f1" }
revm-precompile = { git = "https://github.com/bnb-chain/revm", rev = "dfca3edd9732372e19dea88462eaece1e74824f1" }
revm-primitives = { git = "https://github.com/bnb-chain/revm", rev = "dfca3edd9732372e19dea88462eaece1e74824f1" }
alloy-chains = { git = "https://github.com/bnb-chain/alloy-chains-rs.git", rev = "b7c5379cf47345181f8dce350acafb958f47152a" }


[patch."https://github.com/bluealloy/revm"]
revm = { git = "https://github.com/bnb-chain/revm", rev = "63b8ab893c6f1d2984131017de9872b2809b615b" }
revm = { git = "https://github.com/bnb-chain/revm", rev = "dfca3edd9732372e19dea88462eaece1e74824f1" }
15 changes: 9 additions & 6 deletions crates/bsc/consensus/src/abi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::{Parlia, VoteAddress, STAKE_HUB_CONTRACT, VALIDATOR_CONTRACT};
use crate::{Parlia, VoteAddress};
use alloy_dyn_abi::{DynSolValue, FunctionExt, JsonAbiExt};
use lazy_static::lazy_static;
use reth_primitives::{Address, BlockNumber, Bytes, U256};
use reth_primitives::{
system_contracts::{STAKE_HUB_CONTRACT, VALIDATOR_CONTRACT},
Address, BlockNumber, Bytes, U256,
};

lazy_static! {
pub static ref VALIDATOR_SET_ABI: &'static str = r#"
Expand Down Expand Up @@ -5871,7 +5874,7 @@ impl Parlia {
self.validator_abi_before_luban.function("getValidators").unwrap().first().unwrap()
};

(*VALIDATOR_CONTRACT, Bytes::from(function.abi_encode_input(&[]).unwrap()))
(VALIDATOR_CONTRACT.parse().unwrap(), Bytes::from(function.abi_encode_input(&[]).unwrap()))
}

pub fn unpack_data_into_validator_set_before_luban(&self, data: &[u8]) -> Vec<Address> {
Expand All @@ -5892,7 +5895,7 @@ impl Parlia {
pub fn get_current_validators(&self) -> (Address, Bytes) {
let function = self.validator_abi.function("getMiningValidators").unwrap().first().unwrap();

(*VALIDATOR_CONTRACT, Bytes::from(function.abi_encode_input(&[]).unwrap()))
(VALIDATOR_CONTRACT.parse().unwrap(), Bytes::from(function.abi_encode_input(&[]).unwrap()))
}

pub fn unpack_data_into_validator_set(&self, data: &[u8]) -> (Vec<Address>, Vec<VoteAddress>) {
Expand Down Expand Up @@ -5922,7 +5925,7 @@ impl Parlia {
self.stake_hub_abi.function("getValidatorElectionInfo").unwrap().first().unwrap();

(
*STAKE_HUB_CONTRACT,
STAKE_HUB_CONTRACT.parse().unwrap(),
Bytes::from(
function
.abi_encode_input(&[
Expand Down Expand Up @@ -5961,7 +5964,7 @@ impl Parlia {
let function =
self.stake_hub_abi.function("maxElectedValidators").unwrap().first().unwrap();

(*STAKE_HUB_CONTRACT, Bytes::from(function.abi_encode_input(&[]).unwrap()))
(STAKE_HUB_CONTRACT.parse().unwrap(), Bytes::from(function.abi_encode_input(&[]).unwrap()))
}

pub fn unpack_data_into_max_elected_validators(&self, data: &[u8]) -> U256 {
Expand Down
55 changes: 29 additions & 26 deletions crates/bsc/consensus/src/system_tx.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::{
Parlia, BSC_GOVERNOR_CONTRACT, BSC_TIMELOCK_CONTRACT, CROSS_CHAIN_CONTRACT, GOV_TOKEN_CONTRACT,
LIGHT_CLIENT_CONTRACT, RELAYER_HUB_CONTRACT, RELAYER_INCENTIVIZE_CONTRACT, SLASH_CONTRACT,
STAKE_HUB_CONTRACT, SYSTEM_REWARD_CONTRACT, TOKEN_HUB_CONTRACT, TOKEN_RECOVER_PORTAL_CONTRACT,
VALIDATOR_CONTRACT,
};
use crate::Parlia;
use alloy_dyn_abi::{DynSolValue, JsonAbiExt};
use reth_primitives::{Address, Bytes, Transaction, TxKind, TxLegacy, U256};
use reth_primitives::{
system_contracts::{
CROSS_CHAIN_CONTRACT, GOVERNOR_CONTRACT, GOV_TOKEN_CONTRACT, LIGHT_CLIENT_CONTRACT,
RELAYER_HUB_CONTRACT, RELAYER_INCENTIVIZE_CONTRACT, SLASH_CONTRACT, STAKE_HUB_CONTRACT,
SYSTEM_REWARD_CONTRACT, TIMELOCK_CONTRACT, TOKEN_HUB_CONTRACT,
TOKEN_RECOVER_PORTAL_CONTRACT, VALIDATOR_CONTRACT,
},
Address, Bytes, Transaction, TxKind, TxLegacy, U256,
};

/// Assemble system tx
impl Parlia {
Expand All @@ -14,13 +17,13 @@ impl Parlia {
let input = function.abi_encode_input(&[]).unwrap();

let contracts = vec![
*VALIDATOR_CONTRACT,
*SLASH_CONTRACT,
*LIGHT_CLIENT_CONTRACT,
*RELAYER_HUB_CONTRACT,
*TOKEN_HUB_CONTRACT,
*RELAYER_INCENTIVIZE_CONTRACT,
*CROSS_CHAIN_CONTRACT,
VALIDATOR_CONTRACT,
SLASH_CONTRACT,
LIGHT_CLIENT_CONTRACT,
RELAYER_HUB_CONTRACT,
TOKEN_HUB_CONTRACT,
RELAYER_INCENTIVIZE_CONTRACT,
CROSS_CHAIN_CONTRACT,
];

contracts
Expand All @@ -33,7 +36,7 @@ impl Parlia {
gas_price: 0,
value: U256::ZERO,
input: Bytes::from(input.clone()),
to: TxKind::Call(contract),
to: TxKind::Call(contract.parse().unwrap()),
})
})
.collect()
Expand All @@ -44,11 +47,11 @@ impl Parlia {
let input = function.abi_encode_input(&[]).unwrap();

let contracts = vec![
*STAKE_HUB_CONTRACT,
*BSC_GOVERNOR_CONTRACT,
*GOV_TOKEN_CONTRACT,
*BSC_TIMELOCK_CONTRACT,
*TOKEN_RECOVER_PORTAL_CONTRACT,
STAKE_HUB_CONTRACT,
GOVERNOR_CONTRACT,
GOV_TOKEN_CONTRACT,
TIMELOCK_CONTRACT,
TOKEN_RECOVER_PORTAL_CONTRACT,
];

contracts
Expand All @@ -61,7 +64,7 @@ impl Parlia {
gas_price: 0,
value: U256::ZERO,
input: Bytes::from(input.clone()),
to: TxKind::Call(contract),
to: TxKind::Call(contract.parse().unwrap()),
})
})
.collect()
Expand All @@ -78,7 +81,7 @@ impl Parlia {
gas_price: 0,
value: U256::ZERO,
input: Bytes::from(input),
to: TxKind::Call(*SLASH_CONTRACT),
to: TxKind::Call(SLASH_CONTRACT.parse().unwrap()),
})
}

Expand All @@ -90,7 +93,7 @@ impl Parlia {
gas_price: 0,
value: U256::from(system_reward),
input: Bytes::default(),
to: TxKind::Call(*SYSTEM_REWARD_CONTRACT),
to: TxKind::Call(SYSTEM_REWARD_CONTRACT.parse().unwrap()),
})
}

Expand All @@ -105,7 +108,7 @@ impl Parlia {
gas_price: 0,
value: U256::from(block_reward),
input: Bytes::from(input),
to: TxKind::Call(*VALIDATOR_CONTRACT),
to: TxKind::Call(VALIDATOR_CONTRACT.parse().unwrap()),
})
}

Expand All @@ -130,7 +133,7 @@ impl Parlia {
gas_price: 0,
value: U256::ZERO,
input: Bytes::from(input),
to: TxKind::Call(*VALIDATOR_CONTRACT),
to: TxKind::Call(VALIDATOR_CONTRACT.parse().unwrap()),
})
}

Expand Down Expand Up @@ -161,7 +164,7 @@ impl Parlia {
gas_price: 0,
value: U256::ZERO,
input: Bytes::from(input),
to: TxKind::Call(*VALIDATOR_CONTRACT),
to: TxKind::Call(VALIDATOR_CONTRACT.parse().unwrap()),
})
}
}
51 changes: 12 additions & 39 deletions crates/bsc/consensus/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,9 @@
use crate::EXTRA_SEAL_LEN;
use alloy_rlp::Encodable;
use lazy_static::lazy_static;
use reth_primitives::{
keccak256, Address, BufMut, BytesMut, Header, TransactionSigned, B256, B64, U256,
keccak256, system_contracts::SYSTEM_CONTRACTS_SET, Address, BufMut, BytesMut, Header,
TransactionSigned, B256, B64, U256,
};
use std::str::FromStr;

lazy_static! {
// preset contracts
pub static ref VALIDATOR_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001000").unwrap();
pub static ref SLASH_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001001").unwrap();
pub static ref SYSTEM_REWARD_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001002").unwrap();
pub static ref LIGHT_CLIENT_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001003").unwrap();
pub static ref TOKEN_HUB_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001004").unwrap();
pub static ref RELAYER_INCENTIVIZE_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001005").unwrap();
pub static ref RELAYER_HUB_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001006").unwrap();
pub static ref GOV_HUB_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000001007").unwrap();
pub static ref CROSS_CHAIN_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000002000").unwrap();
pub static ref STAKE_HUB_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000002002").unwrap();
pub static ref BSC_GOVERNOR_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000002004").unwrap();
pub static ref GOV_TOKEN_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000002005").unwrap();
pub static ref BSC_TIMELOCK_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000002006").unwrap();
pub static ref TOKEN_RECOVER_PORTAL_CONTRACT: Address = Address::from_str("0x0000000000000000000000000000000000003000").unwrap();

pub static ref SYSTEM_CONTRACTS: Vec<Address> = vec![
*VALIDATOR_CONTRACT,
*SLASH_CONTRACT,
*SYSTEM_REWARD_CONTRACT,
*LIGHT_CLIENT_CONTRACT,
*TOKEN_HUB_CONTRACT,
*RELAYER_INCENTIVIZE_CONTRACT,
*RELAYER_HUB_CONTRACT,
*GOV_HUB_CONTRACT,
*CROSS_CHAIN_CONTRACT,
*STAKE_HUB_CONTRACT,
*BSC_GOVERNOR_CONTRACT,
*GOV_TOKEN_CONTRACT,
*BSC_TIMELOCK_CONTRACT,
*TOKEN_RECOVER_PORTAL_CONTRACT,
];
}

const SECONDS_PER_DAY: u64 = 86400; // 24 * 60 * 60

Expand All @@ -66,7 +30,7 @@ pub fn is_system_transaction(tx: &TransactionSigned, sender: Address, header: &H

/// whether the contract is system or not
pub fn is_invoke_system_contract(addr: &Address) -> bool {
SYSTEM_CONTRACTS.contains(addr)
SYSTEM_CONTRACTS_SET.contains(addr)
}

pub fn hash_with_chain_id(header: &Header, chain_id: u64) -> B256 {
Expand Down Expand Up @@ -166,4 +130,13 @@ mod tests {
println!("encode hash: {:?}", hex::encode(hash.as_slice()));
assert_eq!(hex::encode(hash.as_slice()), expected_hash);
}

#[test]
fn test_is_system_contract() {
let addr1 = address!("0000000000000000000000000000000000001000");
let addr2 = address!("0000000000000000000000000000000000001100");

assert_eq!(super::is_invoke_system_contract(&addr1), true);
assert_eq!(super::is_invoke_system_contract(&addr2), false);
}
}
12 changes: 8 additions & 4 deletions crates/bsc/evm/src/post_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use crate::{BscBlockExecutionError, BscBlockExecutor};
use bitset::BitSet;
use reth_bsc_consensus::{
get_top_validators_by_voting_power, is_breathe_block, ElectedValidators, ValidatorElectionInfo,
COLLECT_ADDITIONAL_VOTES_REWARD_RATIO, DIFF_INTURN, MAX_SYSTEM_REWARD, SYSTEM_REWARD_CONTRACT,
SYSTEM_REWARD_PERCENT,
COLLECT_ADDITIONAL_VOTES_REWARD_RATIO, DIFF_INTURN, MAX_SYSTEM_REWARD, SYSTEM_REWARD_PERCENT,
};
use reth_errors::{BlockExecutionError, BlockValidationError, ProviderError};
use reth_evm::ConfigureEvm;
use reth_primitives::{
hex,
parlia::{Snapshot, VoteAddress, VoteAttestation},
system_contracts::SYSTEM_REWARD_CONTRACT,
Address, BlockWithSenders, GotExpected, Header, Receipt, TransactionSigned, U256,
};
use reth_provider::ParliaProvider;
Expand Down Expand Up @@ -287,8 +287,12 @@ where
.increment_balances(balance_increment)
.map_err(|_| BlockValidationError::IncrementBalanceFailed)?;

let system_reward_balance =
self.state.basic(*SYSTEM_REWARD_CONTRACT).unwrap().unwrap_or_default().balance;
let system_reward_balance = self
.state
.basic(SYSTEM_REWARD_CONTRACT.parse().unwrap())
.unwrap()
.unwrap_or_default()
.balance;
if !self.parlia().chain_spec().is_kepler_active_at_timestamp(header.timestamp) &&
system_reward_balance < U256::from(MAX_SYSTEM_REWARD)
{
Expand Down
32 changes: 32 additions & 0 deletions crates/chainspec/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub static BSC_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
(Hardfork::FeynmanFix, ForkCondition::Timestamp(1713419340)),
(Hardfork::Cancun, ForkCondition::Timestamp(1718863500)),
(Hardfork::Haber, ForkCondition::Timestamp(1718863500)),
(Hardfork::HaberFix, ForkCondition::Timestamp(1720591588)),
]),
deposit_contract: None,
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::new(1, 1)),
Expand Down Expand Up @@ -137,6 +138,7 @@ pub static BSC_TESTNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
(Hardfork::FeynmanFix, ForkCondition::Timestamp(1711342800)),
(Hardfork::Cancun, ForkCondition::Timestamp(1713330442)),
(Hardfork::Haber, ForkCondition::Timestamp(1716962820)),
(Hardfork::HaberFix, ForkCondition::Timestamp(1719986788)),
]),
deposit_contract: None,
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::new(1, 1)),
Expand Down Expand Up @@ -1002,6 +1004,21 @@ impl ChainSpec {
self.is_fork_active_at_timestamp(Hardfork::Feynman, timestamp)
}

/// Convenience method to check if [`Hardfork::FeynmanFix`] is firstly active at a given
/// timestamp and parent timestamp.
#[cfg(feature = "bsc")]
#[inline]
pub fn is_on_feynman_fix_at_timestamp(&self, timestamp: u64, parent_timestamp: u64) -> bool {
self.fork(Hardfork::FeynmanFix).transitions_at_timestamp(timestamp, parent_timestamp)
}

/// Convenience method to check if [`Hardfork::FeynmanFix`] is active at a given timestamp.
#[cfg(feature = "bsc")]
#[inline]
pub fn is_feynman_fix_active_at_timestamp(&self, timestamp: u64) -> bool {
self.is_fork_active_at_timestamp(Hardfork::FeynmanFix, timestamp)
}

/// Convenience method to check if [`Hardfork::Haber`] is firstly active at a given timestamp
/// and parent timestamp.
#[cfg(feature = "bsc")]
Expand All @@ -1017,6 +1034,21 @@ impl ChainSpec {
self.is_fork_active_at_timestamp(Hardfork::Haber, timestamp)
}

/// Convenience method to check if [`Hardfork::HaberFix`] is firstly active at a given timestamp
/// and parent timestamp.
#[cfg(feature = "bsc")]
#[inline]
pub fn is_on_haber_fix_at_timestamp(&self, timestamp: u64, parent_timestamp: u64) -> bool {
self.fork(Hardfork::HaberFix).transitions_at_timestamp(timestamp, parent_timestamp)
}

/// Convenience method to check if [`Hardfork::HaberFix`] is active at a given timestamp.
#[cfg(feature = "bsc")]
#[inline]
pub fn is_haber_fix_active_at_timestamp(&self, timestamp: u64) -> bool {
self.is_fork_active_at_timestamp(Hardfork::HaberFix, timestamp)
}

/// Creates a [`ForkFilter`] for the block described by [Head].
pub fn fork_filter(&self, head: Head) -> ForkFilter {
let forks = self.forks_iter().filter_map(|(_, condition)| {
Expand Down
2 changes: 2 additions & 0 deletions crates/ethereum-forks/src/hardfork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ pub enum Hardfork {
// ArbOS20Atlas,
/// BSC `Haber` hardfork
Haber,
/// BSC `Haber` hardfork
HaberFix,

// Upcoming
/// Prague: <https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/prague.md>
Expand Down
Loading

0 comments on commit fe5faf2

Please sign in to comment.