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!: change timepoint interpretation #897

Merged
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
25 changes: 9 additions & 16 deletions crates/block-producer/src/block_producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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")
Expand Down
24 changes: 7 additions & 17 deletions crates/block-producer/src/produce_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use gw_store::{
transaction::StoreTransaction,
Store,
};
use gw_types::core::Timepoint;
use gw_types::{
core::Status,
offchain::{BlockParam, DepositInfo, FinalizedCustodianCapacity},
Expand All @@ -29,6 +28,7 @@ use gw_types::{
},
prelude::*,
};
use gw_utils::global_state_finalized_timepoint;
use tracing::instrument;

#[derive(Clone)]
Expand Down Expand Up @@ -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)
Expand Down
20 changes: 7 additions & 13 deletions crates/block-producer/src/stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<CellDep>,
Expand All @@ -39,18 +39,12 @@ pub async fn generate(
local_cells_manager: &LocalCellsManager,
) -> Result<GeneratedStake> {
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())
Expand Down
16 changes: 15 additions & 1 deletion crates/block-producer/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::debugger;
use gw_rpc_client::rpc_client::RPCClient;
use gw_types::packed::Transaction;
use gw_types::core::Timepoint;
use gw_types::packed::{GlobalState, Transaction};
use gw_types::prelude::Unpack;
use gw_utils::since::Since;
use std::path::Path;

pub async fn dump_transaction<P: AsRef<Path>>(dir: P, rpc_client: &RPCClient, tx: &Transaction) {
Expand All @@ -12,3 +15,14 @@ pub async fn dump_transaction<P: AsRef<Path>>(dir: P, rpc_client: &RPCClient, tx
);
}
}

/// Convert global_state.last_finalized_timepoint to the form fo Since.
pub fn global_state_last_finalized_timepoint_to_since(global_state: &GlobalState) -> u64 {
match Timepoint::from_full_value(global_state.last_finalized_timepoint().unpack()) {
Timepoint::BlockNumber(_) => 0,
Timepoint::Timestamp(time_ms) => {
// ATTENTION: I am not sure if I am do right. Please review intensively.
Since::new_timestamp_seconds(time_ms.saturating_div(1000).saturating_sub(1)).as_u64()
jjyr marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
48 changes: 41 additions & 7 deletions crates/block-producer/src/withdrawal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use anyhow::{anyhow, Result};
use gw_common::H256;
use gw_config::ContractsCellDep;
use gw_mem_pool::{custodian::sum_withdrawals, withdrawal::Generator};
use gw_types::core::Timepoint;
use gw_types::offchain::CompatibleFinalizedTimepoint;
use gw_types::packed::RollupConfig;
use gw_types::{
Expand All @@ -17,6 +18,7 @@ use gw_types::{
},
prelude::*,
};
use gw_utils::withdrawal::parse_lock_args;
use gw_utils::RollupContext;
use std::{
collections::HashMap,
Expand Down Expand Up @@ -202,6 +204,7 @@ pub fn unlock_to_owner(
rollup_config: &RollupConfig,
contracts_dep: &ContractsCellDep,
withdrawal_cells: Vec<CellInfo>,
global_state_since: u64,
) -> Result<Option<UnlockedWithdrawals>> {
if withdrawal_cells.is_empty() {
return Ok(None);
Expand Down Expand Up @@ -229,6 +232,7 @@ pub fn unlock_to_owner(
rollup_config.finality_blocks().unpack(),
);
let l1_sudt_script_hash = rollup_config.l1_sudt_script_type_hash();
let mut if_exist_v1_withdrawal_cells = false;
for withdrawal_cell in withdrawal_cells {
// Double check
if let Err(err) = gw_rpc_client::withdrawal::verify_unlockable_to_owner(
Expand All @@ -240,6 +244,10 @@ pub fn unlock_to_owner(
continue;
}

if !if_exist_v1_withdrawal_cells {
if_exist_v1_withdrawal_cells = is_v1_withdrawal_cell(&withdrawal_cell);
}

let owner_lock = {
let args: Bytes = withdrawal_cell.output.lock().args().unpack();
match gw_utils::withdrawal::parse_lock_args(&args) {
Expand All @@ -254,6 +262,7 @@ pub fn unlock_to_owner(
let withdrawal_input = {
let input = CellInput::new_builder()
.previous_output(withdrawal_cell.out_point.clone())
.since(global_state_since.pack())
.build();

InputCellInfo {
Expand Down Expand Up @@ -282,12 +291,21 @@ pub fn unlock_to_owner(
let withdrawal_lock_dep = contracts_dep.withdrawal_cell_lock.clone();
let sudt_type_dep = contracts_dep.l1_sudt_type.clone();

let mut cell_deps = vec![
// rollup_dep and rollup_config_dep will be used by withdrawal_lock_script
rollup_dep,
rollup_config_dep.into(),
withdrawal_lock_dep.into(),
];
let mut cell_deps = if if_exist_v1_withdrawal_cells {
// Some withdrawal cells were born at v1, withdrawal_lock_script checks finality of withdrawal
// cells by comparing with GlobalState.last_finalized_timepoint, so rollup_dep and
// rollup_config_dep are required
vec![
rollup_dep,
rollup_config_dep.into(),
withdrawal_lock_dep.into(),
]
} else {
// All withdrawal cells were born at v2, withdrawal_lock_script checks finality of withdrawal
// cells by comparing with `since`.
vec![withdrawal_lock_dep.into()]
};

if unlocked_to_owner_outputs
.iter()
.any(|output| output.0.type_().to_opt().is_some())
Expand All @@ -303,6 +321,20 @@ pub fn unlock_to_owner(
}))
}

fn is_v1_withdrawal_cell(withdrawal_cell: &CellInfo) -> bool {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn is_v1_withdrawal_cell(withdrawal_cell: &CellInfo) -> bool {
fn is_block_finalized_withdrawal_cell(withdrawal_cell: &CellInfo) -> bool {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"is_block_finalized_withdrawal_cell" is more confusing for me. How about "is_legacy_withdrawal_cell"?

let withdrawal_lock_args = parse_lock_args(&withdrawal_cell.output.lock().args().raw_data())
.expect("parse withdrawal lock args");
match Timepoint::from_full_value(
withdrawal_lock_args
.lock_args
.withdrawal_block_timepoint()
.unpack(),
) {
Timepoint::BlockNumber(_) => true,
Timepoint::Timestamp(_) => false,
}
}

#[cfg(test)]
mod test {
use std::collections::HashMap;
Expand Down Expand Up @@ -430,7 +462,7 @@ mod test {
}

#[test]
fn test_unlock_to_owner() {
fn test_unlock_to_owner_v1() {
// Output should only change lock to owner lock
let last_finalized_timepoint = Timepoint::from_block_number(100);
let global_state = GlobalState::new_builder()
Expand Down Expand Up @@ -532,6 +564,7 @@ mod test {
}
};

let withdrawal_input_since = 0;
let unlocked = unlock_to_owner(
rollup_cell.clone(),
&rollup_context.rollup_config,
Expand All @@ -540,6 +573,7 @@ mod test {
withdrawal_without_owner_lock,
withdrawal_with_owner_lock.clone(),
],
withdrawal_input_since,
)
.expect("unlock")
.expect("some unlocked");
Expand Down
3 changes: 3 additions & 0 deletions crates/block-producer/src/withdrawal_unlocker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use tracing::instrument;
use crate::types::ChainEvent;
use crate::utils;

use crate::utils::global_state_last_finalized_timepoint_to_since;
pub use gw_rpc_client::contract::Guard;

const TRANSACTION_FAILED_TO_RESOLVE_ERROR: &str = "TransactionFailedToResolve";
Expand Down Expand Up @@ -197,11 +198,13 @@ pub trait BuildUnlockWithdrawalToOwner {
unlockable_withdrawals.len()
);

let global_state_since = global_state_last_finalized_timepoint_to_since(&global_state);
let to_unlock = match crate::withdrawal::unlock_to_owner(
rollup_cell,
self.rollup_config(),
&self.contracts_dep(),
unlockable_withdrawals,
global_state_since,
)? {
Some(to_unlock) => to_unlock,
None => return Ok(None),
Expand Down
21 changes: 8 additions & 13 deletions crates/challenge/src/offchain/mock_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,20 @@ 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,
CCWithdrawalWitness, CKBMerkleProof, ChallengeTarget, GlobalState, L2Block, L2Transaction,
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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
Loading