Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: add version field to block header and proposal #1319

Merged
merged 4 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/api/src/jsonrpc/impl/web3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,7 @@ fn next_block_base_fee_per_gas() -> U256 {

fn mock_header_by_call_req(latest_header: Header, call_req: &Web3CallRequest) -> Header {
Header {
version: latest_header.version,
prev_hash: latest_header.prev_hash,
proposer: latest_header.proposer,
state_root: latest_header.state_root,
Expand Down
20 changes: 15 additions & 5 deletions core/consensus/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ use protocol::traits::{
Network, PeerTrust, Priority, Rpc, Storage, SynchronizationAdapter,
};
use protocol::types::{
BatchSignedTxs, Block, BlockNumber, Bytes, ExecResp, Hash, Header, Hex, MerkleRoot, Metadata,
PackedTxHashes, Proof, Proposal, Receipt, SignedTransaction, Validator, U256,
BatchSignedTxs, Block, BlockNumber, BlockVersion, Bytes, ExecResp, Hash, Header, Hex,
MerkleRoot, Metadata, PackedTxHashes, Proof, Proposal, Receipt, SignedTransaction, Validator,
U256,
};
use protocol::{async_trait, tokio::task, trie, ProtocolResult};

use crate::consensus::gen_overlord_status;
use crate::message::{
BROADCAST_HEIGHT, RPC_SYNC_PULL_BLOCK, RPC_SYNC_PULL_PROOF, RPC_SYNC_PULL_TXS,
};
use crate::types::PullTxsRequest;
use crate::util::{convert_hex_to_bls_pubkeys, OverlordCrypto};
use crate::BlockHeaderField::PreviousBlockHash;
use crate::BlockHeaderField::{PreviousBlockHash, Version};
use crate::BlockProofField::{BitMap, HashMismatch, HeightMismatch, Signature, WeightNotFound};
use crate::{BlockProofField, ConsensusError};
use crate::{types::PullTxsRequest, BlockProofField, ConsensusError};

pub struct OverlordConsensusAdapter<
M: MemPool,
Expand Down Expand Up @@ -409,6 +409,16 @@ where
e
})?;

// Todo: refactor after the first hard fork occurs.
if previous_block.header.version != proposal.version {
log::error!(
"[consensus] verify_version, block.header.version: {:?}, correct version {:?}",
proposal.version,
BlockVersion::V0
);
return Err(ConsensusError::VerifyBlockHeader(proposal.number, Version).into());
}

let previous_block_hash = previous_block.hash();

if previous_block_hash != proposal.prev_hash {
Expand Down
5 changes: 3 additions & 2 deletions core/consensus/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ 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, Metadata, Proof, Proposal, SignedTransaction,
ValidatorExtend, BASE_FEE_PER_GAS, MAX_BLOCK_GAS_LIMIT, RLP_NULL,
Block, BlockVersion, 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};

Expand Down Expand Up @@ -79,6 +79,7 @@ impl<Adapter: ConsensusAdapter + 'static> Engine<Proposal> for ConsensusEngine<A
};

let proposal = Proposal {
version: BlockVersion::V0,
prev_hash: status.prev_hash,
proposer: self.node_info.self_address.0,
prev_state_root: self.status.inner().last_state_root,
Expand Down
3 changes: 3 additions & 0 deletions core/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ pub enum BlockHeaderField {

#[display(fmt = "There is at least one validator's weight mismatch")]
Weight,

#[display(fmt = "The block version")]
Version,
}

#[derive(Debug, Display)]
Expand Down
1 change: 1 addition & 0 deletions core/consensus/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const _HEIGHT_TEN: u64 = 10;

fn _mock_block_from_status(status: &CurrentStatus) -> Block {
let block_header = Header {
version: Default::default(),
chain_id: 0,
number: status.last_number + 1,
prev_hash: status.prev_hash,
Expand Down
1 change: 1 addition & 0 deletions core/consensus/src/tests/synchronization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub fn get_mock_rick_block() -> RichBlock {
block: Block {
tx_hashes: vec![],
header: Header {
version: Default::default(),
prev_hash: Default::default(),
proposer: Default::default(),
state_root: Default::default(),
Expand Down
1 change: 1 addition & 0 deletions core/interoperation/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ impl TestHandle {

fn mock_proposal() -> Proposal {
Proposal {
version: Default::default(),
prev_hash: Default::default(),
proposer: Default::default(),
prev_state_root: Default::default(),
Expand Down
2 changes: 1 addition & 1 deletion core/run/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const DEV_CONFIG_DIR: &str = "../../devtools/chain";
const GENESIS_FILE: &str = "genesis_single_node.json";
const CONFIG_FILE: &str = "config.toml";

const GENESIS_HASH: &str = "0x69eca8420bb4b072d732db96260a656f0e10201c6841b215a8ed107681e17d1c";
const GENESIS_HASH: &str = "0x2cc987996d5d26d18cb76dceb85d9b46e4f05f11ff331247225d983ec7a7b78f";
const GENESIS_STATE_ROOT: &str =
"0x65f57a6a666e656de33ed68957e04b35b3fe1b35a90f6eafb6f283c907dc3d77";
const GENESIS_RECEIPTS_ROOT: &str =
Expand Down
1 change: 1 addition & 0 deletions core/storage/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ fn mock_receipt(hash: Hash) -> Receipt {
fn mock_block(height: u64, _block_hash: Hash) -> Block {
let _nonce = Hasher::digest(Bytes::from("XXXX"));
let header = Header {
version: Default::default(),
prev_hash: Default::default(),
proposer: Default::default(),
state_root: Default::default(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"block": {
"header": {
"version": "V0",
"prev_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"proposer": "0x0000000000000000000000000000000000000000",
"state_root": "0x0000000000000000000000000000000000000000000000000000000000000000",
Expand Down
1 change: 1 addition & 0 deletions devtools/chain/genesis_single_node.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"block": {
"header": {
"version": "V0",
"prev_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"proposer": "0x0000000000000000000000000000000000000000",
"state_root": "0x0000000000000000000000000000000000000000000000000000000000000000",
Expand Down
1 change: 1 addition & 0 deletions devtools/chain/nodes/genesis_multi_nodes.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"block": {
"header": {
"version": "V0",
"prev_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"proposer": "0x0000000000000000000000000000000000000000",
"state_root": "0x0000000000000000000000000000000000000000000000000000000000000000",
Expand Down
50 changes: 38 additions & 12 deletions protocol/src/codec/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,28 @@ use std::error::Error;
use overlord::Codec;
use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};

use crate::types::{Bytes, Proposal, BASE_FEE_PER_GAS, MAX_BLOCK_GAS_LIMIT};
use crate::types::{BlockVersion, Bytes, Proposal, BASE_FEE_PER_GAS, MAX_BLOCK_GAS_LIMIT};
use crate::{codec::error::CodecError, lazy::CHAIN_ID, ProtocolError};

impl Encodable for BlockVersion {
fn rlp_append(&self, s: &mut RlpStream) {
let ver: u8 = (*self).into();
s.begin_list(1).append(&ver);
}
}

impl Decodable for BlockVersion {
fn decode(r: &Rlp) -> Result<Self, DecoderError> {
let ver: u8 = r.val_at(0)?;
ver.try_into()
.map_err(|_| DecoderError::Custom("Invalid block version"))
}
}

impl Encodable for Proposal {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(10)
s.begin_list(11)
.append(&self.version)
.append(&self.prev_hash)
.append(&self.proposer)
.append(&self.prev_state_root)
Expand All @@ -25,21 +41,22 @@ impl Encodable for Proposal {
impl Decodable for Proposal {
fn decode(r: &Rlp) -> Result<Self, DecoderError> {
Ok(Proposal {
prev_hash: r.val_at(0)?,
proposer: r.val_at(1)?,
prev_state_root: r.val_at(2)?,
transactions_root: r.val_at(3)?,
signed_txs_hash: r.val_at(4)?,
timestamp: r.val_at(5)?,
number: r.val_at(6)?,
version: r.val_at(0)?,
prev_hash: r.val_at(1)?,
proposer: r.val_at(2)?,
prev_state_root: r.val_at(3)?,
transactions_root: r.val_at(4)?,
signed_txs_hash: r.val_at(5)?,
timestamp: r.val_at(6)?,
number: r.val_at(7)?,
gas_limit: MAX_BLOCK_GAS_LIMIT.into(),
extra_data: Default::default(),
mixed_hash: None,
base_fee_per_gas: BASE_FEE_PER_GAS.into(),
proof: r.val_at(7)?,
proof: r.val_at(8)?,
chain_id: **CHAIN_ID.load(),
call_system_script_count: r.val_at(8)?,
tx_hashes: r.list_at(9)?,
call_system_script_count: r.val_at(9)?,
tx_hashes: r.list_at(10)?,
})
}
}
Expand All @@ -63,6 +80,15 @@ mod tests {

use super::*;

#[test]
fn test_version_codec() {
let ver = BlockVersion::V0;
let bytes = rlp::encode(&ver);
assert_eq!(bytes, ver.rlp_bytes());
let decode: BlockVersion = rlp::decode(bytes.as_ref()).unwrap();
assert_eq!(ver, decode);
}

#[test]
fn test_block_codec() {
let block = Block::default();
Expand Down
47 changes: 44 additions & 3 deletions protocol/src/types/block.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use rlp_derive::{RlpDecodable, RlpEncodable};
use serde::{Deserialize, Serialize};

use crate::codec::ProtocolCodec;
#[cfg(feature = "hex-serialize")]
use crate::codec::{serialize_bytes, serialize_uint};
use crate::types::{
logs_bloom, Bloom, BloomInput, Bytes, ExecResp, Hash, Hasher, Log, MerkleRoot, Receipt,
SignedTransaction, H160, H64, U256,
};
use crate::{codec::ProtocolCodec, types::TypesError};

pub type BlockNumber = u64;

Expand All @@ -19,8 +19,34 @@ pub const MAX_FEE_HISTORY: u64 = 1024;
pub const MAX_RPC_GAS_CAP: u64 = 50_000_000;
pub const BASE_FEE_PER_GAS: u64 = 0x539;

#[derive(Serialize, Deserialize, Default, Copy, Clone, Debug, PartialEq, Eq)]
pub enum BlockVersion {
#[default]
V0,
}

impl From<BlockVersion> for u8 {
fn from(value: BlockVersion) -> Self {
match value {
BlockVersion::V0 => 0,
}
}
}

impl TryFrom<u8> for BlockVersion {
type Error = TypesError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(BlockVersion::V0),
_ => Err(TypesError::InvalidBlockVersion(value)),
}
}
}

#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
pub struct Proposal {
pub version: BlockVersion,
pub prev_hash: Hash,
pub proposer: H160,
pub prev_state_root: MerkleRoot,
Expand Down Expand Up @@ -50,6 +76,7 @@ impl Proposal {

pub fn new_with_state_root(h: &Header, state_root: MerkleRoot, hashes: Vec<Hash>) -> Self {
Proposal {
version: h.version,
prev_hash: h.prev_hash,
proposer: h.proposer,
prev_state_root: state_root,
Expand All @@ -70,6 +97,7 @@ impl Proposal {

pub fn new_without_state_root(h: &Header) -> Self {
Proposal {
version: h.version,
prev_hash: h.prev_hash,
proposer: h.proposer,
prev_state_root: Default::default(),
Expand Down Expand Up @@ -110,6 +138,7 @@ impl Block {
.map(|r| Bloom::from(BloomInput::Raw(rlp::encode_list(&r.logs).as_ref())))
.collect::<Vec<_>>();
let header = Header {
version: proposal.version,
prev_hash: proposal.prev_hash,
proposer: proposal.proposer,
state_root: exec_resp.state_root,
Expand Down Expand Up @@ -182,6 +211,7 @@ impl Block {
RlpEncodable, RlpDecodable, Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq,
)]
pub struct Header {
pub version: BlockVersion,
pub prev_hash: Hash,
pub proposer: H160,
pub state_root: MerkleRoot,
Expand Down Expand Up @@ -248,8 +278,8 @@ impl RichBlock {
#[cfg(test)]
mod tests {
use crate::types::{
Block, Header, Hex, Metadata, MetadataVersion, ProposeCount, RichBlock, ValidatorExtend,
H160,
Block, BlockVersion, Header, Hex, Metadata, MetadataVersion, ProposeCount, RichBlock,
ValidatorExtend, H160,
};
use std::time::{SystemTime, UNIX_EPOCH};

Expand All @@ -260,13 +290,24 @@ mod tests {
.as_millis() as u64
}

#[test]
fn test_invalid_version() {
assert_eq!(BlockVersion::try_from(0).unwrap(), BlockVersion::V0);

let ver = rand::random::<u8>();
if ver != 0 {
assert!(BlockVersion::try_from(ver).is_err());
}
}

#[test]
fn print_genesis() {
let genesis = RichBlock {
txs: vec![],
block: Block {
tx_hashes: vec![],
header: Header {
version: Default::default(),
prev_hash: Default::default(),
proposer: Default::default(),
state_root: Default::default(),
Expand Down
3 changes: 3 additions & 0 deletions protocol/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ pub enum TypesError {

#[display(fmt = "Missing interoperation sender")]
MissingInteroperationSender,

#[display(fmt = "InvalidBlockVersion {:?}", _0)]
InvalidBlockVersion(u8),
}

impl Error for TypesError {}
Expand Down