diff --git a/core/consensus/src/engine.rs b/core/consensus/src/engine.rs index f8bbbcf34..078938c1f 100644 --- a/core/consensus/src/engine.rs +++ b/core/consensus/src/engine.rs @@ -18,13 +18,11 @@ use common_logger::{json, log}; use common_merkle::TrieMerkle; use protocol::traits::{ConsensusAdapter, Context, MessageTarget, NodeInfo}; use protocol::types::{ - Block, Bytes, ExecResp, Hash, Hasher, Hex, Log, MerkleRoot, Metadata, Proof, Proposal, Receipt, - SignedTransaction, ValidatorExtend, BASE_FEE_PER_GAS, MAX_BLOCK_GAS_LIMIT, RLP_NULL, U256, + Block, Bytes, ExecResp, Hash, Hasher, Hex, Metadata, Proof, Proposal, SignedTransaction, + ValidatorExtend, BASE_FEE_PER_GAS, MAX_BLOCK_GAS_LIMIT, RLP_NULL, }; use protocol::{async_trait, tokio::sync::Mutex as AsyncMutex, ProtocolError, ProtocolResult}; -use core_executor::logs_bloom; - use crate::message::{ END_GOSSIP_AGGREGATED_VOTE, END_GOSSIP_SIGNED_CHOKE, END_GOSSIP_SIGNED_PROPOSAL, END_GOSSIP_SIGNED_VOTE, @@ -591,13 +589,7 @@ impl ConsensusEngine { let block_number = block.header.number; let block_hash = block.hash(); - let (receipts, _logs) = generate_receipts_and_logs( - block_number, - block_hash, - block.header.state_root, - &txs, - &resp, - ); + let (receipts, _logs) = block.generate_receipts_and_logs(&txs, &resp); common_apm::metrics::consensus::ENGINE_ROUND_GAUGE.set(proof.round as i64); @@ -746,43 +738,6 @@ fn validate_timestamp( true } -pub fn generate_receipts_and_logs( - block_number: u64, - block_hash: Hash, - state_root: MerkleRoot, - txs: &[SignedTransaction], - resp: &ExecResp, -) -> (Vec, Vec>) { - let mut log_index = 0; - let receipts = txs - .iter() - .enumerate() - .zip(resp.tx_resp.iter()) - .map(|((idx, tx), res)| { - let receipt = Receipt { - tx_hash: tx.transaction.hash, - block_number, - block_hash, - tx_index: idx as u32, - state_root, - used_gas: U256::from(res.gas_used), - logs_bloom: logs_bloom(res.logs.iter()), - logs: res.logs.clone(), - log_index, - code_address: res.code_address, - sender: tx.sender, - ret: res.exit_reason.clone(), - removed: res.removed, - }; - log_index += res.logs.len() as u32; - receipt - }) - .collect::>(); - let logs = receipts.iter().map(|r| r.logs.clone()).collect::>(); - - (receipts, logs) -} - fn gauge_txs_len(proposal: &Proposal) { common_apm::metrics::consensus::ENGINE_ORDER_TX_GAUGE.set(proposal.tx_hashes.len() as i64); } diff --git a/core/consensus/src/lib.rs b/core/consensus/src/lib.rs index 8b33f5e9f..05ab83942 100644 --- a/core/consensus/src/lib.rs +++ b/core/consensus/src/lib.rs @@ -28,7 +28,7 @@ use protocol::{Display, ProtocolError, ProtocolErrorKind}; pub use crate::adapter::OverlordConsensusAdapter; pub use crate::consensus::OverlordConsensus; -pub use crate::synchronization::{OverlordSynchronization, RichBlock, SyncStatus, SYNC_STATUS}; +pub use crate::synchronization::{OverlordSynchronization, SyncStatus, SYNC_STATUS}; pub use crate::wal::{ConsensusWal, SignedTxsWAL}; pub use overlord::{types::Node, DurationConfig}; diff --git a/core/consensus/src/synchronization.rs b/core/consensus/src/synchronization.rs index cad1374f6..3b7c758dd 100644 --- a/core/consensus/src/synchronization.rs +++ b/core/consensus/src/synchronization.rs @@ -7,12 +7,12 @@ use common_apm::Instant; use common_apm_derive::trace_span; use protocol::tokio::{sync::Mutex, time::sleep}; use protocol::traits::{Context, Synchronization, SynchronizationAdapter}; -use protocol::types::{Block, Proof, Proposal, Receipt, SignedTransaction, U256}; +use protocol::types::{Block, Proof, Proposal, Receipt, RichBlock, SignedTransaction, U256}; use protocol::{async_trait, ProtocolResult}; use crate::status::{CurrentStatus, StatusAgent}; use crate::util::digest_signed_transactions; -use crate::{engine::generate_receipts_and_logs, ConsensusError}; +use crate::ConsensusError; const POLLING_BROADCAST: u64 = 2000; const ONCE_SYNC_BLOCK_LIMIT: u64 = 50; @@ -21,12 +21,6 @@ lazy_static::lazy_static! { pub static ref SYNC_STATUS: RwLock = RwLock::new(SyncStatus::default()); } -#[derive(Clone, Debug)] -pub struct RichBlock { - pub block: Block, - pub txs: Vec, -} - pub struct OverlordSynchronization { adapter: Arc, status: StatusAgent, @@ -346,13 +340,7 @@ impl OverlordSynchronization { .into()); } - let (receipts, _logs) = generate_receipts_and_logs( - block.header.number, - block_hash, - block.header.state_root, - &rich_block.txs, - &resp, - ); + let (receipts, _logs) = rich_block.generate_receipts_and_logs(&resp); let metadata = self .adapter diff --git a/core/consensus/src/tests/synchronization.rs b/core/consensus/src/tests/synchronization.rs index 42e6266d0..020309246 100644 --- a/core/consensus/src/tests/synchronization.rs +++ b/core/consensus/src/tests/synchronization.rs @@ -3,12 +3,12 @@ use std::sync::Arc; use protocol::{ tokio::{self, sync::Mutex as AsyncMutex}, traits::{Context, Synchronization}, - types::{Block, Header}, + types::{Block, Header, RichBlock}, }; use crate::{ status::{CurrentStatus, StatusAgent}, - synchronization::{OverlordSynchronization, RichBlock}, + synchronization::OverlordSynchronization, tests::MockSyncAdapter, util::time_now, }; diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 3edb4dbb3..a295021a0 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -11,9 +11,7 @@ mod utils; pub use crate::adapter::{AxonExecutorAdapter, MPTTrie, RocksTrieDB}; pub use crate::system_contract::{metadata::MetadataHandle, DataProvider}; -pub use crate::utils::{ - code_address, decode_revert_msg, logs_bloom, DefaultFeeAllocator, FeeInlet, -}; +pub use crate::utils::{code_address, decode_revert_msg, DefaultFeeAllocator, FeeInlet}; use std::cell::RefCell; use std::collections::BTreeMap; @@ -27,9 +25,9 @@ use common_merkle::TrieMerkle; use protocol::codec::ProtocolCodec; use protocol::traits::{Backend, Executor, ExecutorAdapter}; use protocol::types::{ - data_gas_cost, Account, Config, ExecResp, Hasher, SignedTransaction, TransactionAction, TxResp, - ValidatorExtend, GAS_CALL_TRANSACTION, GAS_CREATE_TRANSACTION, H160, H256, NIL_DATA, RLP_NULL, - U256, + data_gas_cost, logs_bloom, Account, Config, ExecResp, Hasher, SignedTransaction, + TransactionAction, TxResp, ValidatorExtend, GAS_CALL_TRANSACTION, GAS_CREATE_TRANSACTION, H160, + H256, NIL_DATA, RLP_NULL, U256, }; use crate::precompiles::build_precompile_set; diff --git a/core/executor/src/utils.rs b/core/executor/src/utils.rs index 2cdc1e7f4..cd5c0b947 100644 --- a/core/executor/src/utils.rs +++ b/core/executor/src/utils.rs @@ -1,4 +1,4 @@ -use protocol::types::{Bloom, Hasher, Log, H160, H256, U256}; +use protocol::types::{Hasher, H160, H256, U256}; use crate::FeeAllocate; @@ -6,7 +6,6 @@ const FUNC_SELECTOR_LEN: usize = 4; const U256_BE_BYTES_LEN: usize = 32; const REVERT_MSG_LEN_OFFSET: usize = FUNC_SELECTOR_LEN + U256_BE_BYTES_LEN; const REVERT_EFFECT_MSG_OFFSET: usize = REVERT_MSG_LEN_OFFSET + U256_BE_BYTES_LEN; -const BLOOM_BYTE_LENGTH: usize = 256; const EXEC_REVERT: &str = "execution reverted: "; #[derive(Clone, Debug, PartialEq, Eq)] @@ -73,29 +72,6 @@ pub fn decode_revert_msg(input: &[u8]) -> String { decode_reason(&input[REVERT_EFFECT_MSG_OFFSET..end_offset]) } -pub fn logs_bloom<'a, I>(logs: I) -> Bloom -where - I: Iterator, -{ - let mut bloom = Bloom::zero(); - - for log in logs { - m3_2048(&mut bloom, log.address.as_bytes()); - for topic in log.topics.iter() { - m3_2048(&mut bloom, topic.as_bytes()); - } - } - bloom -} - -fn m3_2048(bloom: &mut Bloom, x: &[u8]) { - let hash = Hasher::digest(x).0; - for i in [0, 2, 4] { - let bit = (hash[i + 1] as usize + ((hash[i] as usize) << 8)) & 0x7FF; - bloom.0[BLOOM_BYTE_LENGTH - 1 - bit / 8] |= 1 << (bit % 8); - } -} - #[cfg(test)] mod tests { use protocol::codec::{hex_decode, hex_encode}; diff --git a/core/run/src/lib.rs b/core/run/src/lib.rs index 6d5d97c7d..d65b1d432 100644 --- a/core/run/src/lib.rs +++ b/core/run/src/lib.rs @@ -173,7 +173,7 @@ impl Axon { log::info!("The genesis block is created {:?}", self.genesis.block); - save_block(storage, &self.genesis).await?; + save_block(storage, &self.genesis, &resp).await?; Ok(()) } @@ -1053,7 +1053,7 @@ where Ok(resp) } -async fn save_block(storage: &Arc, rich: &RichBlock) -> ProtocolResult<()> +async fn save_block(storage: &Arc, rich: &RichBlock, resp: &ExecResp) -> ProtocolResult<()> where S: Storage + 'static, { @@ -1066,6 +1066,9 @@ where storage .insert_transactions(Context::new(), rich.block.header.number, rich.txs.clone()) .await?; - + let (receipts, _logs) = rich.generate_receipts_and_logs(resp); + storage + .insert_receipts(Context::new(), rich.block.header.number, receipts) + .await?; Ok(()) } diff --git a/protocol/src/types/block.rs b/protocol/src/types/block.rs index dc22fa2ff..23a3819ec 100644 --- a/protocol/src/types/block.rs +++ b/protocol/src/types/block.rs @@ -5,8 +5,8 @@ use crate::codec::ProtocolCodec; #[cfg(feature = "hex-serialize")] use crate::codec::{serialize_bytes, serialize_uint}; use crate::types::{ - Bloom, BloomInput, Bytes, ExecResp, Hash, Hasher, MerkleRoot, SignedTransaction, H160, H64, - U256, + logs_bloom, Bloom, BloomInput, Bytes, ExecResp, Hash, Hasher, Log, MerkleRoot, Receipt, + SignedTransaction, H160, H64, U256, }; pub type BlockNumber = u64; @@ -142,6 +142,40 @@ impl Block { pub fn hash(&self) -> Hash { self.header.hash() } + + pub fn generate_receipts_and_logs( + &self, + txs: &[SignedTransaction], + resp: &ExecResp, + ) -> (Vec, Vec>) { + let mut log_index = 0; + let receipts = txs + .iter() + .enumerate() + .zip(resp.tx_resp.iter()) + .map(|((idx, tx), res)| { + let receipt = Receipt { + tx_hash: tx.transaction.hash, + block_number: self.header.number, + block_hash: self.hash(), + tx_index: idx as u32, + state_root: self.header.state_root, + used_gas: U256::from(res.gas_used), + logs_bloom: logs_bloom(res.logs.iter()), + logs: res.logs.clone(), + log_index, + code_address: res.code_address, + sender: tx.sender, + ret: res.exit_reason.clone(), + removed: res.removed, + }; + log_index += res.logs.len() as u32; + receipt + }) + .collect::>(); + let logs = receipts.iter().map(|r| r.logs.clone()).collect::>(); + (receipts, logs) + } } #[derive( @@ -205,6 +239,12 @@ pub struct RichBlock { pub txs: Vec, } +impl RichBlock { + pub fn generate_receipts_and_logs(&self, resp: &ExecResp) -> (Vec, Vec>) { + self.block.generate_receipts_and_logs(&self.txs, resp) + } +} + #[cfg(test)] mod tests { use crate::types::{ diff --git a/protocol/src/types/executor.rs b/protocol/src/types/executor.rs index 42a38fc6a..a2f39cc2c 100644 --- a/protocol/src/types/executor.rs +++ b/protocol/src/types/executor.rs @@ -3,7 +3,9 @@ pub use evm::{backend::Log, Config, ExitError, ExitFatal, ExitReason, ExitRevert use rlp_derive::{RlpDecodable, RlpEncodable}; -use crate::types::{Hash, Header, MerkleRoot, Proposal, H160, U256}; +use crate::types::{Bloom, Hash, Hasher, Header, MerkleRoot, Proposal, H160, U256}; + +const BLOOM_BYTE_LENGTH: usize = 256; #[derive(Clone, Debug, PartialEq, Eq)] pub struct ExecResp { @@ -87,3 +89,26 @@ impl From<&Header> for ExecutorContext { } } } + +pub fn logs_bloom<'a, I>(logs: I) -> Bloom +where + I: Iterator, +{ + let mut bloom = Bloom::zero(); + + for log in logs { + m3_2048(&mut bloom, log.address.as_bytes()); + for topic in log.topics.iter() { + m3_2048(&mut bloom, topic.as_bytes()); + } + } + bloom +} + +fn m3_2048(bloom: &mut Bloom, x: &[u8]) { + let hash = Hasher::digest(x).0; + for i in [0, 2, 4] { + let bit = (hash[i + 1] as usize + ((hash[i] as usize) << 8)) & 0x7FF; + bloom.0[BLOOM_BYTE_LENGTH - 1 - bit / 8] |= 1 << (bit % 8); + } +} diff --git a/protocol/src/types/mod.rs b/protocol/src/types/mod.rs index 04f9c1100..ee950dbd8 100644 --- a/protocol/src/types/mod.rs +++ b/protocol/src/types/mod.rs @@ -6,7 +6,8 @@ pub use bytes::{Buf, BufMut, Bytes, BytesMut}; pub use ckb_client::*; pub use evm::{backend::*, ExitError, ExitRevert, ExitSucceed}; pub use executor::{ - AccessList, AccessListItem, Account, Config, ExecResp, ExecutorContext, ExitReason, TxResp, + logs_bloom, AccessList, AccessListItem, Account, Config, ExecResp, ExecutorContext, ExitReason, + TxResp, }; pub use interoperation::*; pub use primitive::*; diff --git a/tests/e2e/src/eth_feeHistory.test.js b/tests/e2e/src/eth_feeHistory.test.js index 001aca3a6..bfdfe448e 100644 --- a/tests/e2e/src/eth_feeHistory.test.js +++ b/tests/e2e/src/eth_feeHistory.test.js @@ -24,7 +24,7 @@ describe("eth_feeHistory", () => { baseFeePerGas: ["0x539", "0x539"], gasUsedRatio: [0], oldestBlock: "0x0", - reward: [["0x0", "0x0"]], + reward: [["0x24f304", "0x0"]], }); }, 100000); @@ -79,7 +79,7 @@ describe("eth_feeHistory", () => { baseFeePerGas: ["0x539", "0x539"], gasUsedRatio: [0], oldestBlock: "0x0", - reward: [["0x0", "0x0"]], + reward: [["0x24f304", "0x0"]], }); }, 100000); });