Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for bsc parlia consensus
Browse files Browse the repository at this point in the history
pythonberg1997 committed May 4, 2024
1 parent ac29b4b commit cc03102
Showing 34 changed files with 2,994 additions and 156 deletions.
273 changes: 165 additions & 108 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ members = [
"crates/consensus/beacon/",
"crates/consensus/beacon-core/",
"crates/consensus/common/",
"crates/consensus/parlia/",
"crates/ethereum-forks/",
"crates/e2e-test-utils/",
"crates/etl/",
@@ -203,6 +204,7 @@ reth-auto-seal-consensus = { path = "crates/consensus/auto-seal" }
reth-basic-payload-builder = { path = "crates/payload/basic" }
reth-beacon-consensus = { path = "crates/consensus/beacon" }
reth-beacon-consensus-core = { path = "crates/consensus/beacon-core" }
reth-parlia-consensus = { path = "crates/consensus/parlia" }
reth-blockchain-tree = { path = "crates/blockchain-tree" }
reth-cli-runner = { path = "crates/cli/runner" }
reth-codecs = { path = "crates/storage/codecs" }
@@ -280,6 +282,7 @@ revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev =
alloy-chains = "0.1.15"
alloy-primitives = "0.7.0"
alloy-dyn-abi = "0.7.0"
alloy-json-abi = "0.7.0"
alloy-sol-types = "0.7.0"
alloy-rlp = "0.3.4"
alloy-trie = "0.3.1"
47 changes: 47 additions & 0 deletions crates/consensus/parlia/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[package]
name = "reth-parlia-consensus"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true

[lints]
workspace = true

[dependencies]
# reth
reth-consensus-common.workspace = true
reth-primitives.workspace = true
reth-interfaces.workspace = true
reth-provider.workspace = true
reth-rpc-types.workspace = true
reth-db.workspace = true

# eth
alloy-rlp.workspace = true
alloy-dyn-abi.workspace = true
alloy-json-abi.workspace = true

# crypto
secp256k1.workspace = true
enr.workspace = true
sha3 = "0.10.8"
blst = "0.3.11"

# misc
auto_impl.workspace = true
serde.workspace = true
serde_json.workspace = true
parking_lot.workspace = true
tracing.workspace = true
lazy_static = "1.4.0"
lru = "0.12"
bytes = "1.5"
bitset = "0.1.2"

[dev-dependencies]
reth-interfaces = { workspace = true, features = ["test-utils"] }
reth-provider = { workspace = true, features = ["test-utils"] }
mockall = "0.12"
25 changes: 25 additions & 0 deletions crates/consensus/parlia/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use reth_primitives::{constants::ETH_TO_WEI, U256};
use reth_rpc_types::beacon::constants::BLS_PUBLIC_KEY_BYTES_LEN;

/// Fixed number of extra-data prefix bytes reserved for signer vanity
pub const EXTRA_VANITY_LEN: usize = 32;
/// Fixed number of extra-data prefix bytes reserved for signer vanity add validator num
pub const EXTRA_VANITY_LEN_WITH_VALIDATOR_NUM: usize = 33;
/// Fixed number of extra-data suffix bytes reserved for signer seal
pub const EXTRA_SEAL_LEN: usize = 65;
/// Address length of signer
pub const ADDRESS_LENGTH: usize = 20;
/// Fixed number of extra-data suffix bytes reserved before Luban validator
pub const EXTRA_VALIDATOR_LEN_BEFORE_LUBAN: usize = ADDRESS_LENGTH;
/// Fixed number of extra-data suffix bytes reserved for Luban validator
pub const EXTRA_VALIDATOR_LEN: usize = EXTRA_VALIDATOR_LEN_BEFORE_LUBAN + BLS_PUBLIC_KEY_BYTES_LEN;
/// Difficulty for INTURN block
pub const DIFF_INTURN: U256 = U256::from(2);
/// Difficulty for NOTURN block
pub const DIFF_NOTURN: U256 = U256::from(1);
pub const SYSTEM_REWARD_PERCENT: usize = 4;
/// The max reward in system reward contract
pub const MAX_SYSTEM_REWARD: u128 = 100 * ETH_TO_WEI;
/// The distance to naturally justify a block
pub const NATURALLY_JUSTIFIED_DIST: u64 = 15;
pub(crate) const COLLECT_ADDITIONAL_VOTES_REWARD_RATIO: usize = 100;
378 changes: 378 additions & 0 deletions crates/consensus/parlia/src/contract_upgrade.rs

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions crates/consensus/parlia/src/feynman_fork.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use reth_primitives::{Address, U256};
use std::{cmp::Ordering, collections::BinaryHeap};

#[derive(Eq, PartialEq)]
pub struct ValidatorItem {
pub address: Address,
pub voting_power: U256,
pub vote_address: Vec<u8>,
}

impl Ord for ValidatorItem {
fn cmp(&self, other: &Self) -> Ordering {
match self.voting_power.cmp(&other.voting_power) {
Ordering::Equal => self.address.cmp(&other.address),
other => other,
}
}
}

impl PartialOrd for ValidatorItem {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

pub fn get_top_validators_by_voting_power(
consensus_addrs: Vec<Address>,
voting_powers: Vec<U256>,
vote_addresses: Vec<Vec<u8>>,
total_length: U256,
max_elected_validators: U256,
) -> Option<(Vec<Address>, Vec<U256>, Vec<Vec<u8>>)> {
if consensus_addrs.len() != total_length.into() ||
voting_powers.len() != total_length.into() ||
vote_addresses.len() != total_length.into()
{
return None;
}

let mut validator_heap: BinaryHeap<ValidatorItem> = BinaryHeap::new();
for i in 0..consensus_addrs.len() {
let item = ValidatorItem {
address: consensus_addrs[i],
voting_power: voting_powers[i],
vote_address: vote_addresses[i].clone(),
};
if item.voting_power > U256::ZERO {
validator_heap.push(item);
}
}

let top_n = max_elected_validators.as_usize();
let top_n = if top_n > validator_heap.len() { validator_heap.len() } else { top_n };
let mut e_validators = Vec::with_capacity(top_n);
let mut e_voting_powers = Vec::with_capacity(top_n);
let mut e_vote_addrs = Vec::with_capacity(top_n);
for _ in 0..top_n {
let item = validator_heap.pop().unwrap();
e_validators.push(item.address);
// as the decimal in BNB Beacon Chain is 1e8 and in BNB Smart Chain is 1e18, we need to
// divide it by 1e10
e_voting_powers.push((item.voting_power / U256::from(10u64.pow(10))).as_u64());
e_vote_addrs.push(item.vote_address);
}

(e_validators, e_voting_powers, e_vote_addrs)
}
Loading

0 comments on commit cc03102

Please sign in to comment.