diff --git a/src/consensus/beacon.rs b/src/consensus/beacon.rs index fdd1ca91f4d34aa8b85b7dfe417c04877e7565ee..fcc9d6f7baf74ec36343345ef93c2ea8b8dd43e7 100644 --- a/src/consensus/beacon.rs +++ b/src/consensus/beacon.rs @@ -6,6 +6,7 @@ use crate::{ TaskGuard, }; use async_trait::async_trait; +use bitvec::macros::internal::funty::Fundamental; use ethereum_jsonrpc::*; use jsonrpsee::{ core::{server::rpc_module::Methods, RpcResult}, @@ -281,36 +282,32 @@ impl Consensus for BeaconConsensus { fn finalize( &self, - header: &crate::models::BlockHeader, - ommers: &[crate::models::BlockHeader], - ) -> anyhow::Result<Vec<super::FinalizationChange>> { - let block_number = header.number; - let block_reward = self.block_reward.for_block(block_number); - - Ok(if block_reward > 0 { - let mut changes = Vec::with_capacity(1 + ommers.len()); - - let mut miner_reward = block_reward; - for ommer in ommers { - let ommer_reward = - (U256::from(8 + ommer.number.0 - block_number.0) * block_reward) >> 3; - changes.push(FinalizationChange::Reward { - address: ommer.beneficiary, - amount: ommer_reward, - ommer: true, - }); - miner_reward += block_reward / 32; + block: &BlockHeaderOrSender, + ommers: &[BlockHeader], + ) -> anyhow::Result<Vec<FinalizationChange>> { + let mut miner_reward: U256 = U256::ZERO; + let mut finalization_changes = vec![]; + match block { + BlockHeaderOrSender::WithSender(block) => { + for behaviors in &block.behaviors { + miner_reward += U256::from( + (behaviors.behavior.quantity.as_f32() + * REWARD_PER_BEHAVIOR_QUANTITY + * MINER_RATE_ON_BEHAVIOR_QUANTITY) + .as_u32(), + ); + } + let amount_from_transaction: u32 = + (block.transactions.len().as_u32() * MINER_FIXED_REWARD_PER_TRANSACTION) as u32; + miner_reward += U256::from(amount_from_transaction); + finalization_changes.push(FinalizationChange::Reward { + address: block.header.beneficiary, + amount: miner_reward, + ommer: false, + }) } - - changes.push(FinalizationChange::Reward { - address: header.beneficiary, - amount: miner_reward, - ommer: false, - }); - - changes - } else { - vec![] - }) + _ => {} + } + Ok(finalization_changes) } } diff --git a/src/consensus/clique/mod.rs b/src/consensus/clique/mod.rs index 44f4c79aa94aef7d064a3afee817ee7cffb46655..494e6cb55530595d18769d4cb72b9272ccf1ac5d 100644 --- a/src/consensus/clique/mod.rs +++ b/src/consensus/clique/mod.rs @@ -1,6 +1,8 @@ pub mod state; + pub use state::CliqueState; +use crate::consensus::BlockHeaderOrSender; use crate::{ consensus::{ fork_choice_graph::ForkChoiceGraph, state::CliqueBlock, CliqueError, Consensus, @@ -217,20 +219,24 @@ impl Consensus for Clique { fn finalize( &self, - block: &BlockHeader, - _ommers: &[BlockHeader], + block: &BlockHeaderOrSender, + ommers: &[BlockHeader], ) -> anyhow::Result<Vec<FinalizationChange>> { - let clique_block = CliqueBlock::from_header(block)?; - - let mut state = self.state.lock(); + match block { + BlockHeaderOrSender::Header(block) => { + let clique_block = CliqueBlock::from_header(block)?; - state - .validate(&clique_block, false) - .map_err(DuoError::Validation)?; - state.finalize(clique_block); + let mut state = self.state.lock(); - state.set_block_hash(block.hash()); + state + .validate(&clique_block, false) + .map_err(DuoError::Validation)?; + state.finalize(clique_block); + state.set_block_hash(block.hash()); + } + _ => {} + } Ok(vec![]) } diff --git a/src/consensus/mod.rs b/src/consensus/mod.rs index 2abdb7d32527fc0db2d4ebeee2f098bb85c56dd8..ece3801d215b96e2f82fb4c2e3c2546f08753aa0 100644 --- a/src/consensus/mod.rs +++ b/src/consensus/mod.rs @@ -64,6 +64,11 @@ pub enum ForkChoiceMode { Difficulty(Arc<Mutex<ForkChoiceGraph>>), } +pub enum BlockHeaderOrSender { + Header(BlockHeader), + WithSender(BlockWithSenders), +} + pub trait Consensus: Debug + Send + Sync + 'static { fn fork_choice_mode(&self) -> ForkChoiceMode; @@ -88,7 +93,7 @@ pub trait Consensus: Debug + Send + Sync + 'static { /// NOTE: For Ethash See YP Section 11.3 "Reward Application". fn finalize( &self, - block: &BlockHeader, + block: &BlockHeaderOrSender, ommers: &[BlockHeader], ) -> anyhow::Result<Vec<FinalizationChange>>; @@ -123,17 +128,20 @@ pub trait Consensus: Debug + Send + Sync + 'static { pub enum BadTransactionError { SenderNoEOA { sender: Address, - }, // EIP-3607: σ[S(T)]c ≠KEC( () ) + }, + // EIP-3607: σ[S(T)]c ≠KEC( () ) WrongNonce { account: Address, expected: u64, got: u64, - }, // Tn ≠σ[S(T)]n + }, + // Tn ≠σ[S(T)]n InsufficientFunds { account: Address, available: U512, required: U512, - }, // v0 > σ[S(T)]b + }, + // v0 > σ[S(T)]b BlockGasLimitExceeded { available: u64, required: u64, @@ -182,11 +190,13 @@ pub enum ValidationError { WrongStateRoot { expected: H256, got: H256, - }, // wrong Hr + }, + // wrong Hr WrongOmmersHash { expected: H256, got: H256, - }, // wrong Ho + }, + // wrong Ho WrongHeaderNonce { expected: H64, got: H64, @@ -194,11 +204,13 @@ pub enum ValidationError { WrongTransactionsRoot { expected: H256, got: H256, - }, // wrong Ht + }, + // wrong Ht WrongReceiptsRoot { expected: H256, got: H256, - }, // wrong He + }, + // wrong He WrongLogsBloom { expected: Bloom, got: Bloom, @@ -208,46 +220,62 @@ pub enum ValidationError { UnknownParent { number: BlockNumber, parent_hash: H256, - }, // P(H) = ∅ ∨ Hi ≠P(H)Hi + 1 - WrongDifficulty, // Hd ≠D(H) + }, + // P(H) = ∅ ∨ Hi ≠P(H)Hi + 1 + WrongDifficulty, + // Hd ≠D(H) GasAboveLimit { used: u64, limit: u64, - }, // Hg > Hl - InvalidGasLimit, // |Hl-P(H)Hl|≥P(H)Hl/1024 ∨ Hl<5000 + }, + // Hg > Hl + InvalidGasLimit, + // |Hl-P(H)Hl|≥P(H)Hl/1024 ∨ Hl<5000 InvalidTimestamp { parent: u64, current: u64, - }, // Hs ≤ P(H)Hs - ExtraDataTooLong, // ‖Hx‖ > 32 - WrongDaoExtraData, // see EIP-779 + }, + // Hs ≤ P(H)Hs + ExtraDataTooLong, + // ‖Hx‖ > 32 + WrongDaoExtraData, + // see EIP-779 WrongBaseFee { expected: Option<U256>, got: Option<U256>, - }, // see EIP-1559 - MissingBaseFee, // see EIP-1559 - InvalidSeal, // Nonce or mix_hash + }, + // see EIP-1559 + MissingBaseFee, + // see EIP-1559 + InvalidSeal, // Nonce or mix_hash // See [YP] Section 6.2 "Execution", Eq (58) - MissingSender, // S(T) = ∅ + MissingSender, + // S(T) = ∅ BadTransaction { index: usize, error: BadTransactionError, }, - IntrinsicGas, // g0 > Tg - MaxFeeLessThanBase, // max_fee_per_gas < base_fee_per_gas (EIP-1559) + IntrinsicGas, + // g0 > Tg + MaxFeeLessThanBase, + // max_fee_per_gas < base_fee_per_gas (EIP-1559) MaxPriorityFeeGreaterThanMax, // max_priority_fee_per_gas > max_fee_per_gas (EIP-1559) // See [YP] Section 11.1 "Ommer Validation", Eq (157) OmmerUnknownParent { number: BlockNumber, parent_hash: H256, - }, // P(H) = ∅ ∨ Hi ≠P(H)Hi + 1 - TooManyOmmers, // ‖BU‖ > 2 + }, + // P(H) = ∅ ∨ Hi ≠P(H)Hi + 1 + TooManyOmmers, + // ‖BU‖ > 2 InvalidOmmerHeader { inner: Box<ValidationError>, - }, // ¬V(U) - NotAnOmmer, // ¬k(U, P(BH)H, 6) + }, + // ¬V(U) + NotAnOmmer, + // ¬k(U, P(BH)H, 6) DuplicateOmmer, // not well covered by the YP actually // See [YP] Section 11.2 "Transaction Validation", Eq (160) diff --git a/src/consensus/pob/mod.rs b/src/consensus/pob/mod.rs index 9d3d8a82f4fd68f4bbd7c47446d2af7a3bc337e7..a3c9b08266a89b2641308b873a8d6cf5f4a60200 100644 --- a/src/consensus/pob/mod.rs +++ b/src/consensus/pob/mod.rs @@ -1,6 +1,7 @@ use std::{num::NonZeroUsize, sync::Arc}; use ::ethash::LightDAG; +use bitvec::macros::internal::funty::Fundamental; use lru::LruCache; use parking_lot::Mutex; @@ -24,6 +25,10 @@ pub trait Verifiable<T> { fn verify(&self) -> bool; } +pub const MINER_RATE_ON_BEHAVIOR_QUANTITY: f32 = 0.1; +pub const REWARD_PER_BEHAVIOR_QUANTITY: f32 = 1.; +pub const MINER_FIXED_REWARD_PER_TRANSACTION: u32 = 10; + type Dag = LightDAG; #[derive(Debug)] @@ -184,36 +189,33 @@ impl Consensus for Pob { } fn finalize( &self, - header: &BlockHeader, + block: &BlockHeaderOrSender, ommers: &[BlockHeader], ) -> anyhow::Result<Vec<FinalizationChange>> { - let block_number = header.number; - let block_reward = self.block_reward.for_block(block_number); - - Ok(if block_reward > 0 { - let mut changes = Vec::with_capacity(1 + ommers.len()); - let mut miner_reward = block_reward; - for ommer in ommers { - let ommer_reward = - (U256::from(8 + ommer.number.0 - block_number.0) * block_reward) >> 3; - changes.push(FinalizationChange::Reward { - address: ommer.beneficiary, - amount: ommer_reward, - ommer: true, - }); - miner_reward += block_reward / 32; + let mut miner_reward: U256 = U256::ZERO; + let mut finalization_changes = vec![]; + match block { + BlockHeaderOrSender::WithSender(block) => { + for behaviors in &block.behaviors { + miner_reward += U256::from( + (behaviors.behavior.quantity.as_f32() + * REWARD_PER_BEHAVIOR_QUANTITY + * MINER_RATE_ON_BEHAVIOR_QUANTITY) + .as_u32(), + ); + } + let amount_from_transaction: u32 = + (block.transactions.len().as_u32() * MINER_FIXED_REWARD_PER_TRANSACTION) as u32; + miner_reward += U256::from(amount_from_transaction); + finalization_changes.push(FinalizationChange::Reward { + address: block.header.beneficiary, + amount: miner_reward, + ommer: false, + }) } - - changes.push(FinalizationChange::Reward { - address: header.beneficiary, - amount: miner_reward, - ommer: false, - }); - - changes - } else { - vec![] - }) + _ => {} + } + Ok(finalization_changes) } fn needs_parallel_validation(&self) -> bool { diff --git a/src/execution/processor.rs b/src/execution/processor.rs index f4e8d4ff5ae96480858fb3ffaf5b98dfd97942d3..7ffd4ed7d3d64ac5c6ef27fccab18f5efb7db47a 100644 --- a/src/execution/processor.rs +++ b/src/execution/processor.rs @@ -331,7 +331,10 @@ where receipts.push(self.execute_transaction(&txn.message, txn.sender)?); } - for change in self.engine.finalize(self.header, &self.block.ommers)? { + for change in self.engine.finalize( + &BlockHeaderOrSender::Header(self.header.clone()), + &self.block.ommers, + )? { match change { FinalizationChange::Reward { address, amount, .. diff --git a/src/rpc/otterscan.rs b/src/rpc/otterscan.rs index bade167c12d1ea63c706e64ff08c7461a085dc11..3a8192a432e54548d173a124f563751230ca3ba4 100644 --- a/src/rpc/otterscan.rs +++ b/src/rpc/otterscan.rs @@ -1,4 +1,5 @@ use super::helpers; +use crate::consensus::BlockHeaderOrSender; use crate::{ accessors::chain, consensus::{engine_factory, FinalizationChange}, @@ -54,8 +55,8 @@ where let chainspec = tx .get(tables::Config, ())? .ok_or_else(|| format_err!("no chainspec found"))?; - let finalization_changes = - engine_factory(None, chainspec, None)?.finalize(&header, &ommers)?; + let finalization_changes = engine_factory(None, chainspec, None)? + .finalize(&BlockHeaderOrSender::Header(header), &ommers)?; let mut block_reward = U256::ZERO; let mut uncle_reward = U256::ZERO; @@ -472,8 +473,8 @@ where Ok(vec![]) }) - .await - .unwrap_or_else(helpers::joinerror_to_result) + .await + .unwrap_or_else(helpers::joinerror_to_result) } async fn search_transactions_before( &self, @@ -820,8 +821,8 @@ where None }) }) - .await - .unwrap_or_else(helpers::joinerror_to_result) + .await + .unwrap_or_else(helpers::joinerror_to_result) } async fn get_contract_creator(&self, addr: Address) -> RpcResult<Option<ContractCreatorData>> { let _ = addr; diff --git a/src/rpc/trace.rs b/src/rpc/trace.rs index 66846297405a01c85befd21a90d6f13982c588fc..73ed5213f8e2277d1e75c5ff9cdfd390f76e932e 100644 --- a/src/rpc/trace.rs +++ b/src/rpc/trace.rs @@ -1,4 +1,5 @@ use super::helpers; +use crate::consensus::BlockHeaderOrSender; use crate::{ bitmapdb, consensus::engine_factory, @@ -389,7 +390,9 @@ where let mut rewards = vec![]; if let Some(ommers) = ommers_for_finalization { - for change in engine_factory(None, chain_spec, None)?.finalize(&header, &ommers)? { + for change in engine_factory(None, chain_spec, None)? + .finalize(&BlockHeaderOrSender::Header(header), &ommers)? + { match change { crate::consensus::FinalizationChange::Reward { address, @@ -842,9 +845,9 @@ where let block_hash = crate::accessors::chain::canonical_hash::read(&txn, block_number)? .ok_or_else(|| format_err!("canonical hash for block #{block_number} not found"))?; let transactions = crate::accessors::chain::block_body::read_without_senders( - &txn, - block_number, - )?.ok_or_else(|| format_err!("body not found for block #{block_number}/{block_hash}"))? + &txn, + block_number, + )?.ok_or_else(|| format_err!("body not found for block #{block_number}/{block_hash}"))? .transactions; let (index, signed_message) = transactions .iter() @@ -871,15 +874,15 @@ where .map(|(signed_message, sender)| (sender, signed_message.message, hashset![])) .take(index) .chain(once((sender, message, trace_types))) - .collect(),None, + .collect(), None, )?.0 - .pop().unwrap()); + .pop().unwrap()); } Err(RpcError::Custom("tx not found".to_string())) }) - .await - .unwrap_or_else(helpers::joinerror_to_result) + .await + .unwrap_or_else(helpers::joinerror_to_result) } async fn block(