From beafdab95861e39942fb92c3d6bc37c3f6c8bb8c Mon Sep 17 00:00:00 2001 From: keroro Date: Sun, 11 Dec 2022 17:23:43 +0800 Subject: [PATCH] feat: use new form of timepoint --- crates/block-producer/src/block_producer.rs | 25 ++++------ crates/block-producer/src/produce_block.rs | 24 +++------ crates/block-producer/src/stake.rs | 20 +++----- crates/challenge/src/offchain/mock_block.rs | 21 +++----- crates/challenge/src/revert.rs | 50 +++++++++---------- crates/mem-pool/src/withdrawal.rs | 22 +++----- .../src/script_tests/withdrawal/finality.rs | 2 +- .../tests/src/tests/calc_finalizing_range.rs | 5 +- crates/utils/src/calc_finalizing_range.rs | 24 ++++++--- crates/utils/src/lib.rs | 2 + crates/utils/src/timepoint.rs | 36 +++++++++++++ 11 files changed, 119 insertions(+), 112 deletions(-) create mode 100644 crates/utils/src/timepoint.rs diff --git a/crates/block-producer/src/block_producer.rs b/crates/block-producer/src/block_producer.rs index 48a91f8f6..aabc871fb 100644 --- a/crates/block-producer/src/block_producer.rs +++ b/crates/block-producer/src/block_producer.rs @@ -22,7 +22,6 @@ use gw_mem_pool::{ }; use gw_rpc_client::{contract::ContractsCellDepManager, rpc_client::RPCClient}; use gw_store::Store; -use gw_types::core::Timepoint; use gw_types::offchain::{global_state_from_slice, CompatibleFinalizedTimepoint}; use gw_types::{ bytes::Bytes, @@ -34,9 +33,9 @@ use gw_types::{ prelude::*, }; use gw_utils::{ - fee::fill_tx_fee_with_local, genesis_info::CKBGenesisInfo, local_cells::LocalCellsManager, - query_rollup_cell, since::Since, transaction_skeleton::TransactionSkeleton, wallet::Wallet, - RollupContext, + block_timepoint, fee::fill_tx_fee_with_local, genesis_info::CKBGenesisInfo, + local_cells::LocalCellsManager, query_rollup_cell, since::Since, + transaction_skeleton::TransactionSkeleton, wallet::Wallet, RollupContext, }; use std::{collections::HashSet, sync::Arc, time::Instant}; use tokio::sync::Mutex; @@ -61,18 +60,12 @@ fn generate_custodian_cells( deposit_cells: &[DepositInfo], ) -> Vec<(CellOutput, Bytes)> { let block_hash: H256 = block.hash().into(); - let block_timepoint = { - let block_number = block.raw().number().unpack(); - if rollup_context - .fork_config - .use_timestamp_as_timepoint(block_number) - { - let block_timestamp = block.raw().timestamp().unpack(); - Timepoint::from_timestamp(block_timestamp) - } else { - Timepoint::from_block_number(block_number) - } - }; + let block_timepoint = block_timepoint( + &rollup_context.rollup_config, + &rollup_context.fork_config, + block.raw().number().unpack(), + block.raw().timestamp().unpack(), + ); let to_custodian = |deposit| -> _ { to_custodian_cell(rollup_context, &block_hash, &block_timepoint, deposit) .expect("sanitized deposit") diff --git a/crates/block-producer/src/produce_block.rs b/crates/block-producer/src/produce_block.rs index 8eeb94aaf..9547ac9eb 100644 --- a/crates/block-producer/src/produce_block.rs +++ b/crates/block-producer/src/produce_block.rs @@ -19,7 +19,6 @@ use gw_store::{ transaction::StoreTransaction, Store, }; -use gw_types::core::Timepoint; use gw_types::{ core::Status, offchain::{BlockParam, DepositInfo, FinalizedCustodianCapacity}, @@ -29,6 +28,7 @@ use gw_types::{ }, prelude::*, }; +use gw_utils::global_state_finalized_timepoint; use tracing::instrument; #[derive(Clone)] @@ -164,22 +164,12 @@ pub fn produce_block( .build() }; - let last_finalized_timepoint = if rollup_context - .fork_config - .use_timestamp_as_timepoint(number) - { - let finality_time_in_ms = rollup_context.rollup_config.finality_time_in_ms(); - Timepoint::from_timestamp( - block - .raw() - .timestamp() - .unpack() - .saturating_sub(finality_time_in_ms), - ) - } else { - let finality_as_blocks = rollup_context.rollup_config.finality_blocks().unpack(); - Timepoint::from_block_number(number.saturating_sub(finality_as_blocks)) - }; + let last_finalized_timepoint = global_state_finalized_timepoint( + &rollup_context.rollup_config, + &rollup_context.fork_config, + block.raw().number().unpack(), + block.raw().timestamp().unpack(), + ); let global_state = GlobalState::new_builder() .account(post_merkle_state) .block(post_block) diff --git a/crates/block-producer/src/stake.rs b/crates/block-producer/src/stake.rs index f2853758c..69111c73d 100644 --- a/crates/block-producer/src/stake.rs +++ b/crates/block-producer/src/stake.rs @@ -20,7 +20,7 @@ use gw_types::{ use gw_utils::local_cells::{ collect_local_and_indexer_cells, CollectLocalAndIndexerCursor, LocalCellsManager, }; -use gw_utils::RollupContext; +use gw_utils::{block_timepoint, RollupContext}; pub struct GeneratedStake { pub deps: Vec, @@ -39,18 +39,12 @@ pub async fn generate( local_cells_manager: &LocalCellsManager, ) -> Result { let owner_lock_hash = lock_script.hash(); - let stake_block_timepoint = { - let block_number: u64 = block.raw().number().unpack(); - if rollup_context - .fork_config - .use_timestamp_as_timepoint(block_number) - { - let block_timestamp: u64 = block.raw().timestamp().unpack(); - Timepoint::from_timestamp(block_timestamp) - } else { - Timepoint::from_block_number(block_number) - } - }; + let stake_block_timepoint = block_timepoint( + &rollup_context.rollup_config, + &rollup_context.fork_config, + block.raw().number().unpack(), + block.raw().timestamp().unpack(), + ); let lock_args: Bytes = { let stake_lock_args = StakeLockArgs::new_builder() .owner_lock_hash(owner_lock_hash.pack()) diff --git a/crates/challenge/src/offchain/mock_block.rs b/crates/challenge/src/offchain/mock_block.rs index f00f4b3f6..adf57d9f2 100644 --- a/crates/challenge/src/offchain/mock_block.rs +++ b/crates/challenge/src/offchain/mock_block.rs @@ -17,7 +17,7 @@ use gw_store::state::traits::JournalDB; use gw_store::state::MemStateDB; use gw_store::transaction::StoreTransaction; use gw_traits::CodeStore; -use gw_types::core::{ChallengeTargetType, Status, Timepoint}; +use gw_types::core::{ChallengeTargetType, Status}; use gw_types::offchain::RunResult; use gw_types::packed::{ AccountMerkleState, BlockMerkleState, Byte32, CCTransactionSignatureWitness, @@ -25,13 +25,12 @@ use gw_types::packed::{ RawL2Block, Script, SubmitTransactions, SubmitWithdrawals, Uint64, WithdrawalRequestExtra, }; use gw_types::prelude::*; -use gw_utils::RollupContext; +use gw_utils::{global_state_finalized_timepoint, RollupContext}; type MemTree = MemStateDB; pub struct MockBlockParam { rollup_context: RollupContext, - finality_blocks: u64, number: u64, rollup_config_hash: Byte32, block_producer: RegistryAddress, @@ -61,7 +60,6 @@ impl MockBlockParam { reverted_block_root: H256, ) -> Self { MockBlockParam { - finality_blocks: rollup_context.rollup_config.finality_blocks().unpack(), rollup_config_hash: rollup_context.rollup_config.hash().pack(), rollup_context, block_producer, @@ -316,15 +314,12 @@ impl MockBlockParam { .build() }; - let last_finalized_timepoint = if self - .rollup_context - .fork_config - .use_timestamp_as_timepoint(self.number) - { - unimplemented!() - } else { - Timepoint::from_block_number(self.number.saturating_sub(self.finality_blocks)) - }; + let last_finalized_timepoint = global_state_finalized_timepoint( + &self.rollup_context.rollup_config, + &self.rollup_context.fork_config, + self.number, + self.timestamp.unpack(), + ); let global_state = GlobalState::new_builder() .account(post_account) .block(post_block) diff --git a/crates/challenge/src/revert.rs b/crates/challenge/src/revert.rs index dbffdd741..0019bac0c 100644 --- a/crates/challenge/src/revert.rs +++ b/crates/challenge/src/revert.rs @@ -5,7 +5,7 @@ use ckb_types::prelude::Reader; use ckb_types::prelude::{Builder, Entity}; use gw_common::smt::Blake2bHasher; use gw_common::H256; -use gw_types::core::{Status, Timepoint}; +use gw_types::core::Status; use gw_types::offchain::CellInfo; use gw_types::packed::BlockMerkleState; use gw_types::packed::ChallengeLockArgsReader; @@ -19,11 +19,10 @@ use gw_types::{ bytes::Bytes, prelude::{Pack, Unpack}, }; -use gw_utils::RollupContext; +use gw_utils::{global_state_finalized_timepoint, RollupContext}; pub struct Revert<'a> { rollup_context: RollupContext, - finality_blocks: u64, reward_burn_rate: u8, prev_global_state: GlobalState, challenge_cell: &'a CellInfo, // capacity and rewards lock @@ -50,11 +49,9 @@ impl<'a> Revert<'a> { revert_context: RevertContext, ) -> Self { let reward_burn_rate = rollup_context.rollup_config.reward_burn_rate().into(); - let finality_blocks = rollup_context.rollup_config.finality_blocks().unpack(); Revert { rollup_context, - finality_blocks, prev_global_state, challenge_cell, stake_cells, @@ -99,26 +96,27 @@ impl<'a> Revert<'a> { .count(block_count) .build() }; - let last_finalized_timepoint = if self - .rollup_context - .fork_config - .use_timestamp_as_timepoint(first_reverted_block.number().unpack()) - { - Timepoint::Timestamp( - first_reverted_block - .timestamp() - .unpack() - .saturating_sub(self.rollup_context.rollup_config.finality_time_in_ms()), - ) - } else { - Timepoint::from_block_number( - first_reverted_block - .number() - .unpack() - .saturating_sub(1) - .saturating_sub(self.finality_blocks), - ) - }; + + // NOTE: When revert in v1, `Fork::use_timestamp_as_timepoint()` is disabled, + // revert the last_finalized_timepoint to the **the previous block that did not revert**; + // when revert in v2, `Fork::use_timestamp_as_timepoint()` is enabled, + // keep the last_finalized_timepoint up to date, which is the last block timestamp + let last_reverted_block = self + .revert_witness + .reverted_blocks + .clone() + .into_iter() + .last() + .ok_or_else(|| anyhow!("no last block"))?; + let last_block_timestamp = last_reverted_block.timestamp().unpack(); + let previous_non_reverted_block_number = + first_reverted_block.number().unpack().saturating_sub(1); + let reverted_last_finalized_timepoint = global_state_finalized_timepoint( + &self.rollup_context.rollup_config, + &self.rollup_context.fork_config, + previous_non_reverted_block_number, + last_block_timestamp, + ); let running_status: u8 = Status::Running.into(); let post_global_state = self @@ -128,7 +126,7 @@ impl<'a> Revert<'a> { .block(block_merkle_state) .tip_block_hash(first_reverted_block.parent_block_hash()) .tip_block_timestamp(self.revert_witness.new_tip_block.timestamp()) - .last_finalized_timepoint(last_finalized_timepoint.full_value().pack()) + .last_finalized_timepoint(reverted_last_finalized_timepoint.full_value().pack()) .reverted_block_root(self.post_reverted_block_root.pack()) .status(running_status.into()) .build(); diff --git a/crates/mem-pool/src/withdrawal.rs b/crates/mem-pool/src/withdrawal.rs index 50f0404b9..bd6261477 100644 --- a/crates/mem-pool/src/withdrawal.rs +++ b/crates/mem-pool/src/withdrawal.rs @@ -1,14 +1,13 @@ use anyhow::{anyhow, bail, Result}; use gw_common::H256; use gw_generator::generator::WithdrawalCellError; -use gw_types::core::Timepoint; use gw_types::{ bytes::Bytes, offchain::FinalizedCustodianCapacity, packed::{CellOutput, L2Block, Script, WithdrawalRequest, WithdrawalRequestExtra}, prelude::*, }; -use gw_utils::RollupContext; +use gw_utils::{block_timepoint, RollupContext}; use std::collections::HashMap; use crate::custodian::{ @@ -117,19 +116,12 @@ impl<'a> Generator<'a> { sudt_custodian.map(|sudt| sudt.script.to_owned()) }; let block_hash: H256 = block.hash().into(); - let block_timepoint = { - let block_number = block.raw().number().unpack(); - if self - .rollup_context - .fork_config - .use_timestamp_as_timepoint(block_number) - { - let block_timestamp = block.raw().timestamp().unpack(); - Timepoint::from_timestamp(block_timestamp) - } else { - Timepoint::from_block_number(block_number) - } - }; + let block_timepoint = block_timepoint( + &self.rollup_context.rollup_config, + &self.rollup_context.fork_config, + block.raw().number().unpack(), + block.raw().timestamp().unpack(), + ); let output = match gw_generator::utils::build_withdrawal_cell_output( self.rollup_context, req_extra, diff --git a/crates/tests/src/script_tests/withdrawal/finality.rs b/crates/tests/src/script_tests/withdrawal/finality.rs index 551fd5fc5..f0434f2ce 100644 --- a/crates/tests/src/script_tests/withdrawal/finality.rs +++ b/crates/tests/src/script_tests/withdrawal/finality.rs @@ -122,7 +122,7 @@ fn test_finality_of_withdrawal_lock() { // withdrawal_state_cell is finalized by block number, unlock via check_output_cell_has_same_content id: 5, tip_block_number, - global_state_last_finalized_timepoint: global_state_last_finalized_timepoint.clone(), + global_state_last_finalized_timepoint, withdrawal_block_timepoint: Timepoint::from_block_number( tip_block_number - DEFAULT_FINALITY_BLOCKS, ), diff --git a/crates/tests/src/tests/calc_finalizing_range.rs b/crates/tests/src/tests/calc_finalizing_range.rs index e36e90aa7..0ebb480f1 100644 --- a/crates/tests/src/tests/calc_finalizing_range.rs +++ b/crates/tests/src/tests/calc_finalizing_range.rs @@ -23,7 +23,7 @@ async fn test_calc_finalizing_range() { // // block[0].ts = 0 // block[i].ts = block[i-1].ts + random(1, rollup_config.finality_time_in_ms()) - // global_state[i].last_finalized_timepoint = block[i].ts - rollup_config.finality_time_in_ms() + // global_state[i].last_finalized_timepoint = block[i].ts // // Assertions: // - No overlapped finalizing ranges @@ -73,8 +73,7 @@ async fn test_calc_finalizing_range() { let finality_as_blocks = rollup_config.finality_blocks().unpack(); Timepoint::from_block_number(number.saturating_sub(finality_as_blocks)) } else { - let finality_time_in_mss = rollup_config.finality_time_in_ms(); - Timepoint::from_timestamp(timestamp.saturating_sub(finality_time_in_mss)) + Timepoint::from_timestamp(timestamp) }; GlobalState::new_builder() .version(version.into()) diff --git a/crates/utils/src/calc_finalizing_range.rs b/crates/utils/src/calc_finalizing_range.rs index 1c78681f7..e64324651 100644 --- a/crates/utils/src/calc_finalizing_range.rs +++ b/crates/utils/src/calc_finalizing_range.rs @@ -1,8 +1,8 @@ +use crate::block_timepoint; use anyhow::{Context, Result}; use gw_config::ForkConfig; use gw_store::traits::chain_store::ChainStore; use gw_types::{ - core::Timepoint, offchain::CompatibleFinalizedTimepoint, packed::{L2Block, RollupConfig}, prelude::*, @@ -11,6 +11,7 @@ use std::ops::Range; // Returns true is the block of `older_block_number` is finalized for `compatible_finalized_timepoint` fn is_older_block_finalized( + rollup_config: &RollupConfig, fork_config: &ForkConfig, db: &impl ChainStore, compatible_finalized_timepoint: &CompatibleFinalizedTimepoint, @@ -22,12 +23,13 @@ fn is_older_block_finalized( let older_block = db .get_block(&older_block_hash)? .context("get older block")?; - let older_timepoint = if fork_config.use_timestamp_as_timepoint(older_block_number) { - Timepoint::from_timestamp(older_block.raw().timestamp().unpack()) - } else { - Timepoint::from_block_number(older_block_number) - }; - Ok(compatible_finalized_timepoint.is_finalized(&older_timepoint)) + let older_block_timepoint = block_timepoint( + rollup_config, + fork_config, + older_block_number, + older_block.raw().timestamp().unpack(), + ); + Ok(compatible_finalized_timepoint.is_finalized(&older_block_timepoint)) } // Returns the highest block that is finalized for `block`. @@ -68,7 +70,13 @@ fn find_finalized_upper_bound( let mut r = block.raw().number().unpack().saturating_sub(1); while l < r { let mid = l + (r - l + 1) / 2; - if is_older_block_finalized(fork_config, db, &compatible_finalized_timepoint, mid)? { + if is_older_block_finalized( + rollup_config, + fork_config, + db, + &compatible_finalized_timepoint, + mid, + )? { l = mid; } else { r = mid.saturating_sub(1); diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index d44901392..655d864d1 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -13,6 +13,7 @@ mod query_rollup_cell; mod rollup_context; pub mod script_log; pub mod since; +pub mod timepoint; pub mod transaction_skeleton; pub mod wallet; pub mod withdrawal; @@ -20,3 +21,4 @@ pub mod withdrawal; pub use calc_finalizing_range::calc_finalizing_range; pub use query_rollup_cell::query_rollup_cell; pub use rollup_context::RollupContext; +pub use timepoint::{block_timepoint, global_state_finalized_timepoint}; diff --git a/crates/utils/src/timepoint.rs b/crates/utils/src/timepoint.rs new file mode 100644 index 000000000..93ee31cba --- /dev/null +++ b/crates/utils/src/timepoint.rs @@ -0,0 +1,36 @@ +use gw_config::ForkConfig; +use gw_types::core::Timepoint; +use gw_types::packed::RollupConfig; +use gw_types::prelude::*; + +pub fn block_timepoint( + rollup_config: &RollupConfig, + fork_config: &ForkConfig, + block_number: u64, + block_timestamp: u64, +) -> Timepoint { + if fork_config.use_timestamp_as_timepoint(block_number) { + // block.timepoint is in new form, represents the future finalized timestamp + let finality_time_in_ms = rollup_config.finality_time_in_ms(); + Timepoint::from_timestamp(block_timestamp + finality_time_in_ms) + } else { + // block.timepoint is in legacy form, represents the its block number + Timepoint::from_block_number(block_number) + } +} + +pub fn global_state_finalized_timepoint( + rollup_config: &RollupConfig, + fork_config: &ForkConfig, + block_number: u64, + block_timestamp: u64, +) -> Timepoint { + if fork_config.use_timestamp_as_timepoint(block_number) { + // GlobalState.last_finalized_timepoint is in new form, represents the current timestamp + Timepoint::from_timestamp(block_timestamp) + } else { + // GlobalState.last_finalized_timepoint is in legacy form, represents the already finalized block number + let finality_as_blocks = rollup_config.finality_blocks().unpack(); + Timepoint::from_block_number(block_number.saturating_sub(finality_as_blocks)) + } +}