From 13f288855f051988f073a980e23906ba3f6d1ee8 Mon Sep 17 00:00:00 2001 From: erwanor Date: Mon, 11 Dec 2023 22:09:14 -0500 Subject: [PATCH 1/2] jmt(types): remove `BlockInfo` --- src/types/block_info.rs | 210 ---------------------------------------- 1 file changed, 210 deletions(-) delete mode 100644 src/types/block_info.rs diff --git a/src/types/block_info.rs b/src/types/block_info.rs deleted file mode 100644 index 83fda06..0000000 --- a/src/types/block_info.rs +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::types::{epoch_state::EpochState, on_chain_config::ValidatorSet, transaction::Version}; -use core::fmt::{Display, Formatter}; -use diem_crypto::hash::{HashValue, ACCUMULATOR_PLACEHOLDER_HASH}; -#[cfg(any(test))] -use proptest_derive::Arbitrary; -use serde::{Deserialize, Serialize}; - -/// The round of a block is a consensus-internal counter, which starts with 0 and increases -/// monotonically. -pub type Round = u64; - -// Constants for the initial genesis block. -pub const GENESIS_EPOCH: u64 = 0; -pub const GENESIS_ROUND: Round = 0; -pub const GENESIS_VERSION: Version = 0; -pub const GENESIS_TIMESTAMP_USECS: u64 = 0; - -/// This structure contains all the information needed for tracking a block -/// without having access to the block or its execution output state. It -/// assumes that the block is the last block executed within the ledger. -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[cfg_attr(any(test), derive(Arbitrary))] -pub struct BlockInfo { - /// Epoch number corresponds to the set of validators that are active for this block. - epoch: u64, - /// The consensus protocol is executed in rounds, which monotonically increase per epoch. - round: Round, - /// The identifier (hash) of the block. - id: HashValue, - /// The accumulator root hash after executing this block. - executed_state_id: HashValue, - /// The version of the latest transaction after executing this block. - version: Version, - /// The timestamp this block was proposed by a proposer. - timestamp_usecs: u64, - /// An optional field containing the next epoch info - next_epoch_state: Option, -} - -impl BlockInfo { - pub fn new( - epoch: u64, - round: Round, - id: HashValue, - executed_state_id: HashValue, - version: Version, - timestamp_usecs: u64, - next_epoch_state: Option, - ) -> Self { - Self { - epoch, - round, - id, - executed_state_id, - version, - timestamp_usecs, - next_epoch_state, - } - } - - pub fn empty() -> Self { - Self { - epoch: 0, - round: 0, - id: HashValue::zero(), - executed_state_id: HashValue::zero(), - version: 0, - timestamp_usecs: 0, - next_epoch_state: None, - } - } - - #[cfg(any(test))] - pub fn random(round: Round) -> Self { - Self { - epoch: 1, - round, - id: HashValue::zero(), - executed_state_id: HashValue::zero(), - version: 0, - timestamp_usecs: 0, - next_epoch_state: None, - } - } - - /// Create a new genesis block. The genesis block is effectively the - /// blockchain state after executing the initial genesis transaction. - /// - /// * `genesis_state_root_hash` - the state tree root hash after executing the - /// initial genesis transaction. - /// - /// * `validator_set` - the initial validator set, configured when generating - /// the genesis transaction itself and emitted after executing the genesis - /// transaction. Using this genesis block means transitioning to a new epoch - /// (GENESIS_EPOCH + 1) with this `validator_set`. - pub fn genesis(genesis_state_root_hash: HashValue, validator_set: ValidatorSet) -> Self { - Self { - epoch: GENESIS_EPOCH, - round: GENESIS_ROUND, - id: HashValue::zero(), - executed_state_id: genesis_state_root_hash, - version: GENESIS_VERSION, - timestamp_usecs: GENESIS_TIMESTAMP_USECS, - next_epoch_state: Some(EpochState { - epoch: 1, - verifier: (&validator_set).into(), - }), - } - } - - /// Create a mock genesis `BlockInfo` with an empty state tree and empty - /// validator set. - #[cfg(any(test))] - pub fn mock_genesis(validator_set: Option) -> Self { - let validator_set = validator_set.unwrap_or_else(ValidatorSet::empty); - Self::genesis(*ACCUMULATOR_PLACEHOLDER_HASH, validator_set) - } - - /// The epoch after this block committed - pub fn next_block_epoch(&self) -> u64 { - self.next_epoch_state().map_or(self.epoch(), |e| e.epoch) - } - - pub fn change_timestamp(&mut self, timestamp: u64) { - assert!(self.allow_timestamp_change(timestamp)); - self.timestamp_usecs = timestamp; - } - - /// For reconfiguration suffix blocks only, with decoupled-execution proposal-generator can't - /// guarantee suffix blocks have the same timestamp as parent thus violate the invariant that - /// block.timestamp should always equal timestamp stored onchain. - /// We allow it to be updated backwards to the actual reconfiguration block's timestamp. - fn allow_timestamp_change(&self, timestamp: u64) -> bool { - self.has_reconfiguration() && self.timestamp_usecs >= timestamp - } - - pub fn epoch(&self) -> u64 { - self.epoch - } - - pub fn executed_state_id(&self) -> HashValue { - self.executed_state_id - } - - pub fn has_reconfiguration(&self) -> bool { - self.next_epoch_state.is_some() - } - - pub fn id(&self) -> HashValue { - self.id - } - - pub fn next_epoch_state(&self) -> Option<&EpochState> { - self.next_epoch_state.as_ref() - } - - pub fn round(&self) -> Round { - self.round - } - - pub fn timestamp_usecs(&self) -> u64 { - self.timestamp_usecs - } - - pub fn version(&self) -> Version { - self.version - } - - /// This function checks if the current BlockInfo has - /// exactly the same values in those fields that will not change - /// after execution, compared to a given BlockInfo - pub fn match_ordered_only(&self, executed_block_info: &BlockInfo) -> bool { - self.epoch == executed_block_info.epoch - && self.round == executed_block_info.round - && self.id == executed_block_info.id - && (self.timestamp_usecs == executed_block_info.timestamp_usecs - // executed block info has changed its timestamp because it's a reconfiguration suffix - || (self.timestamp_usecs > executed_block_info.timestamp_usecs - && executed_block_info.has_reconfiguration())) - } - - /// This function checks if the current BlockInfo is consistent - /// with the dummy values we put in the ordering state computer - /// and it is not empty - pub fn is_ordered_only(&self) -> bool { - *self != BlockInfo::empty() - && self.next_epoch_state == None - && self.executed_state_id == *ACCUMULATOR_PLACEHOLDER_HASH - && self.version == 0 - } -} - -impl Display for BlockInfo { - fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { - write!( - f, - "BlockInfo: [epoch: {}, round: {}, id: {}, executed_state_id: {}, version: {}, timestamp (us): {}, next_epoch_state: {}]", - self.epoch(), - self.round(), - self.id(), - self.executed_state_id(), - self.version(), - self.timestamp_usecs(), - self.next_epoch_state.as_ref().map_or("None".to_string(), |epoch_state| format!("{}", epoch_state)), - ) - } -} From 5d8f1f6fba3bb74cc9c213eb5f8324521c81167b Mon Sep 17 00:00:00 2001 From: Erwan Date: Tue, 12 Dec 2023 09:16:33 -0500 Subject: [PATCH 2/2] jmt(types): remove access path and change sets --- src/types/access_path.rs | 163 ---------------------------- src/types/transaction/change_set.rs | 29 ----- 2 files changed, 192 deletions(-) delete mode 100644 src/types/access_path.rs delete mode 100644 src/types/transaction/change_set.rs diff --git a/src/types/access_path.rs b/src/types/access_path.rs deleted file mode 100644 index 7291449..0000000 --- a/src/types/access_path.rs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -//! Suppose we have the following data structure in a smart contract: -//! -//! struct B { -//! Map mymap; -//! } -//! -//! struct A { -//! B b; -//! int my_int; -//! } -//! -//! struct C { -//! List mylist; -//! } -//! -//! A a; -//! C c; -//! -//! and the data belongs to Alice. Then an access to `a.b.mymap` would be translated to an access -//! to an entry in key-value store whose key is `/a/b/mymap`. In the same way, the access to -//! `c.mylist` would need to query `/c/mylist`. -//! -//! So an account stores its data in a directory structure, for example: -//! /balance: 10 -//! /a/b/mymap: {"Bob" => "abcd", "Carol" => "efgh"} -//! /a/myint: 20 -//! /c/mylist: [3, 5, 7, 9] -//! -//! If someone needs to query the map above and find out what value associated with "Bob" is, -//! `address` will be set to Alice and `path` will be set to "/a/b/mymap/Bob". -//! -//! On the other hand, if you want to query only /a/*, `address` will be set to Alice and -//! `path` will be set to "/a" and use the `get_prefix()` method from statedb - -use crate::types::account_address::AccountAddress; -use diem_crypto::hash::HashValue; -use move_core_types::language_storage::{ModuleId, ResourceKey, StructTag, CODE_TAG, RESOURCE_TAG}; -#[cfg(any(test))] -use proptest_derive::Arbitrary; -use serde::{Deserialize, Serialize}; -use std::{convert::TryFrom, fmt}; - -#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Ord, PartialOrd)] -#[cfg_attr(any(test), derive(Arbitrary))] -pub struct AccessPath { - pub address: AccountAddress, - #[serde(with = "serde_bytes")] - pub path: Vec, -} - -#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Ord, PartialOrd)] -pub enum Path { - Code(ModuleId), - Resource(StructTag), -} - -impl AccessPath { - pub fn new(address: AccountAddress, path: Vec) -> Self { - AccessPath { address, path } - } - - pub fn resource_access_vec(tag: StructTag) -> Vec { - bcs::to_bytes(&Path::Resource(tag)).expect("Unexpected serialization error") - } - - /// Convert Accesses into a byte offset which would be used by the storage layer to resolve - /// where fields are stored. - pub fn resource_access_path(key: ResourceKey) -> AccessPath { - let path = AccessPath::resource_access_vec(key.type_); - AccessPath { - address: key.address, - path, - } - } - - fn code_access_path_vec(key: ModuleId) -> Vec { - bcs::to_bytes(&Path::Code(key)).expect("Unexpected serialization error") - } - - pub fn code_access_path(key: ModuleId) -> AccessPath { - let address = *key.address(); - let path = AccessPath::code_access_path_vec(key); - AccessPath { address, path } - } - - /// Extract the structured resource or module `Path` from `self` - pub fn get_path(&self) -> Path { - bcs::from_bytes::(&self.path).expect("Unexpected serialization error") - } - - /// Extract a StructTag from `self`. Returns Some if this is a resource access - /// path and None otherwise - pub fn get_struct_tag(&self) -> Option { - match self.get_path() { - Path::Resource(s) => Some(s), - Path::Code(_) => None, - } - } -} - -impl fmt::Debug for AccessPath { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "AccessPath {{ address: {:x}, path: {} }}", - self.address, - hex::encode(&self.path) - ) - } -} - -impl fmt::Display for AccessPath { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.path.len() < 1 + HashValue::LENGTH { - write!(f, "{:?}", self) - } else { - write!(f, "AccessPath {{ address: {:x}, ", self.address)?; - match self.path[0] { - RESOURCE_TAG => write!(f, "type: Resource, ")?, - CODE_TAG => write!(f, "type: Module, ")?, - tag => write!(f, "type: {:?}, ", tag)?, - }; - write!( - f, - "hash: {:?}, ", - hex::encode(&self.path[1..=HashValue::LENGTH]) - )?; - write!( - f, - "suffix: {:?} }} ", - String::from_utf8_lossy(&self.path[1 + HashValue::LENGTH..]) - ) - } - } -} - -impl From<&ModuleId> for AccessPath { - fn from(id: &ModuleId) -> AccessPath { - AccessPath { - address: *id.address(), - path: id.access_vector(), - } - } -} - -impl TryFrom<&[u8]> for Path { - type Error = bcs::Error; - - fn try_from(bytes: &[u8]) -> Result { - bcs::from_bytes::(bytes) - } -} - -impl TryFrom<&Vec> for Path { - type Error = bcs::Error; - - fn try_from(bytes: &Vec) -> Result { - bcs::from_bytes::(bytes) - } -} diff --git a/src/types/transaction/change_set.rs b/src/types/transaction/change_set.rs deleted file mode 100644 index 8a6b0a5..0000000 --- a/src/types/transaction/change_set.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::types::{contract_event::ContractEvent, write_set::WriteSet}; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub struct ChangeSet { - write_set: WriteSet, - events: Vec, -} - -impl ChangeSet { - pub fn new(write_set: WriteSet, events: Vec) -> Self { - Self { write_set, events } - } - - pub fn into_inner(self) -> (WriteSet, Vec) { - (self.write_set, self.events) - } - - pub fn write_set(&self) -> &WriteSet { - &self.write_set - } - - pub fn events(&self) -> &[ContractEvent] { - &self.events - } -}