diff --git a/gwos/README.md b/gwos/README.md index 476d79d72..7d707ccbc 100644 --- a/gwos/README.md +++ b/gwos/README.md @@ -102,7 +102,7 @@ Withdrawal cells are generated in the `RollupSubmitBlock` action according to th The withdrawal lock has two unlock paths: -1. Unlock by withdrawer after the `WithdrawalLockArgs#withdrawal_block_timepoint` is finalized. +1. Unlock by withdrawer after the `WithdrawalLockArgs#withdrawal_block_number` is finalized. 2. Unlock as a reverted cell in the `RollupSubmitBlock` action, a corresponded custodian cell will be generated. ### Challenge lock diff --git a/gwos/c/godwoken.mol b/gwos/c/godwoken.mol index f14481033..7c6046d32 100644 --- a/gwos/c/godwoken.mol +++ b/gwos/c/godwoken.mol @@ -187,7 +187,7 @@ table DepositLockArgs { // a rollup_type_hash exists before this args, to make args friendly to prefix search table CustodianLockArgs { deposit_block_hash: Byte32, - deposit_block_timepoint: Uint64, + deposit_block_number: Uint64, // used for revert this cell to deposit request cell // after finalize, this lock is meaningless deposit_lock_args: DepositLockArgs, @@ -203,7 +203,7 @@ struct UnlockCustodianViaRevertWitness { // a rollup_type_hash exists before this args, to make args friendly to prefix search struct WithdrawalLockArgs { withdrawal_block_hash: Byte32, - withdrawal_block_timepoint: Uint64, + withdrawal_block_number: Uint64, account_script_hash: Byte32, // layer1 lock to withdraw after challenge period owner_lock_hash: Byte32, @@ -224,7 +224,7 @@ struct UnlockWithdrawalViaRevert { // a rollup_type_hash exists before this args, to make args friendly to prefix search struct StakeLockArgs { owner_lock_hash: Byte32, - stake_block_timepoint: Uint64, + stake_block_number: Uint64, } // --- end of stake lock --- diff --git a/gwos/contracts/Cargo.lock b/gwos/contracts/Cargo.lock index 25a26c608..0c99eb9c2 100644 --- a/gwos/contracts/Cargo.lock +++ b/gwos/contracts/Cargo.lock @@ -11,9 +11,9 @@ dependencies = [ [[package]] name = "blake2b-ref" -version = "0.3.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "294d17c72e0ba59fad763caa112368d0672083779cdebbb97164f4bb4c1e339a" +checksum = "95916998c798756098a4eb1b3f2cd510659705a9817bf203d61abd30fbec3e7b" [[package]] name = "blake2b-rs" @@ -279,8 +279,8 @@ dependencies = [ [[package]] name = "gw-common" -version = "1.7.0-rc2" -source = "git+https://github.com/keroro520/godwoken.git?branch=new-finality-rule-based-on-timestamp#20348314cfef0b0d61431bd953c1a1ec1928cd88" +version = "0.1.0" +source = "git+https://github.com/nervosnetwork/godwoken.git?rev=91c324544424292b4d715ce376d31bc45aa3cb5d#91c324544424292b4d715ce376d31bc45aa3cb5d" dependencies = [ "cfg-if 0.1.10", "gw-hash", @@ -291,8 +291,8 @@ dependencies = [ [[package]] name = "gw-hash" -version = "1.7.0-rc2" -source = "git+https://github.com/keroro520/godwoken.git?branch=new-finality-rule-based-on-timestamp#20348314cfef0b0d61431bd953c1a1ec1928cd88" +version = "0.1.0" +source = "git+https://github.com/nervosnetwork/godwoken.git?rev=91c324544424292b4d715ce376d31bc45aa3cb5d#91c324544424292b4d715ce376d31bc45aa3cb5d" dependencies = [ "blake2b-ref", ] @@ -307,8 +307,8 @@ dependencies = [ [[package]] name = "gw-types" -version = "1.7.0-rc2" -source = "git+https://github.com/keroro520/godwoken.git?branch=new-finality-rule-based-on-timestamp#20348314cfef0b0d61431bd953c1a1ec1928cd88" +version = "0.1.0" +source = "git+https://github.com/nervosnetwork/godwoken.git?rev=91c324544424292b4d715ce376d31bc45aa3cb5d#91c324544424292b4d715ce376d31bc45aa3cb5d" dependencies = [ "cfg-if 0.1.10", "gw-hash", diff --git a/gwos/contracts/custodian-lock/src/entry.rs b/gwos/contracts/custodian-lock/src/entry.rs index 9d9382623..5d8d61fa4 100644 --- a/gwos/contracts/custodian-lock/src/entry.rs +++ b/gwos/contracts/custodian-lock/src/entry.rs @@ -20,7 +20,7 @@ use crate::ckb_std::{ high_level::load_script, high_level::load_witness_args, }; use gw_types::{ - core::{ScriptHashType, Timepoint}, + core::ScriptHashType, packed::{ CustodianLockArgs, CustodianLockArgsReader, UnlockCustodianViaRevertWitness, UnlockCustodianViaRevertWitnessReader, @@ -29,6 +29,7 @@ use gw_types::{ }; use gw_utils::finality::is_finalized; use gw_utils::gw_types; +use gw_utils::Timepoint; use crate::error::Error; @@ -64,7 +65,7 @@ pub fn main() -> Result<(), Error> { let is_finalized = is_finalized( &config, &global_state, - &Timepoint::from_full_value(lock_args.deposit_block_timepoint().unpack()), + &Timepoint::from_full_value(lock_args.deposit_block_number().unpack()), ); if is_finalized { // this custodian lock is already finalized, rollup will handle the logic diff --git a/gwos/contracts/gw-utils/Cargo.toml b/gwos/contracts/gw-utils/Cargo.toml index 27afb0e44..4263023d3 100644 --- a/gwos/contracts/gw-utils/Cargo.toml +++ b/gwos/contracts/gw-utils/Cargo.toml @@ -8,5 +8,5 @@ edition = "2018" [dependencies] ckb-std = "0.9.0" -gw-types = { git = "https://github.com/keroro520/godwoken.git", branch = "new-finality-rule-based-on-timestamp", default-features = false } -gw-common = { git = "https://github.com/keroro520/godwoken.git", branch = "new-finality-rule-based-on-timestamp", default-features = false } +gw-types = { git = "https://github.com/nervosnetwork/godwoken.git", rev = "91c324544424292b4d715ce376d31bc45aa3cb5d", default-features = false } +gw-common = { git = "https://github.com/nervosnetwork/godwoken.git", rev = "91c324544424292b4d715ce376d31bc45aa3cb5d", default-features = false } diff --git a/gwos/contracts/gw-utils/src/finality.rs b/gwos/contracts/gw-utils/src/finality.rs index 85ab2eb16..255a1cf76 100644 --- a/gwos/contracts/gw-utils/src/finality.rs +++ b/gwos/contracts/gw-utils/src/finality.rs @@ -9,8 +9,8 @@ //! - Otherwise, we know it is switching versions, so the corresponding entity //! is surely not finalized. +use crate::Timepoint; use ckb_std::debug; -use gw_types::core::Timepoint; use gw_types::packed::{GlobalState, RollupConfig}; use gw_types::prelude::Unpack; diff --git a/gwos/contracts/gw-utils/src/lib.rs b/gwos/contracts/gw-utils/src/lib.rs index eb0b7b551..0f866a6c3 100644 --- a/gwos/contracts/gw-utils/src/lib.rs +++ b/gwos/contracts/gw-utils/src/lib.rs @@ -13,5 +13,8 @@ pub mod cells; pub mod error; pub mod finality; pub mod signature; +mod timepoint; pub mod type_id; pub mod withdrawal; + +pub use timepoint::Timepoint; diff --git a/gwos/contracts/gw-utils/src/timepoint.rs b/gwos/contracts/gw-utils/src/timepoint.rs new file mode 100644 index 000000000..522c53c5e --- /dev/null +++ b/gwos/contracts/gw-utils/src/timepoint.rs @@ -0,0 +1,38 @@ +//! This file is copied from Godwoken `crates/types/src/core.rs`. + +/// Timepoint encodes in the below layout into u64 in order to support representing two kinds of +/// time points, block number and timestamp. +/// - the highest 1 bit represent whether the time point is block-number-based or timestamp-based +/// - the rest 63 bits represent the value of time point +pub enum Timepoint { + BlockNumber(u64), + Timestamp(u64), +} + +impl Timepoint { + const MASK: u64 = 1 << 63; + + pub fn from_block_number(block_number: u64) -> Self { + Timepoint::BlockNumber(block_number) + } + + pub fn from_timestamp(timestamp: u64) -> Self { + Timepoint::Timestamp(timestamp) + } + + pub fn from_full_value(full_value: u64) -> Self { + let is_block_number = (Self::MASK & full_value) == 0; + if is_block_number { + Timepoint::BlockNumber(full_value) + } else { + Timepoint::Timestamp(Self::MASK ^ full_value) + } + } + + pub fn full_value(&self) -> u64 { + match self { + Timepoint::BlockNumber(block_number) => *block_number, + Timepoint::Timestamp(timestamp) => Self::MASK | *timestamp, + } + } +} diff --git a/gwos/contracts/stake-lock/src/entry.rs b/gwos/contracts/stake-lock/src/entry.rs index 7ebe67c43..5980fd0dc 100644 --- a/gwos/contracts/stake-lock/src/entry.rs +++ b/gwos/contracts/stake-lock/src/entry.rs @@ -21,9 +21,9 @@ use gw_utils::cells::{ }; use gw_utils::finality::is_finalized; use gw_utils::gw_types; +use gw_utils::Timepoint; use gw_types::{ - core::Timepoint, packed::{StakeLockArgs, StakeLockArgsReader}, prelude::*, }; @@ -60,7 +60,7 @@ pub fn main() -> Result<(), Error> { let is_finalized = is_finalized( &config, &global_state, - &Timepoint::from_full_value(lock_args.stake_block_timepoint().unpack()), + &Timepoint::from_full_value(lock_args.stake_block_number().unpack()), ); if is_finalized && search_lock_hash(&lock_args.owner_lock_hash().unpack(), Source::Input).is_some() diff --git a/gwos/contracts/state-validator/src/verifications/revert.rs b/gwos/contracts/state-validator/src/verifications/revert.rs index 8c8ac3e94..26e664966 100644 --- a/gwos/contracts/state-validator/src/verifications/revert.rs +++ b/gwos/contracts/state-validator/src/verifications/revert.rs @@ -4,7 +4,7 @@ use gw_common::{ H256, }; use gw_types::{ - core::{Status, Timepoint}, + core::Status, packed::{BlockMerkleState, Byte32, GlobalState, RawL2Block, RollupConfig}, prelude::*, }; @@ -29,6 +29,7 @@ use gw_utils::{ use gw_utils::{ gw_common, gw_types::packed::{RawL2BlockReader, RollupRevertReader}, + Timepoint, }; use super::{check_rollup_lock_cells_except_stake, check_status}; diff --git a/gwos/contracts/state-validator/src/verifications/submit_block.rs b/gwos/contracts/state-validator/src/verifications/submit_block.rs index 3a6e624dc..9e789d5ef 100644 --- a/gwos/contracts/state-validator/src/verifications/submit_block.rs +++ b/gwos/contracts/state-validator/src/verifications/submit_block.rs @@ -31,6 +31,7 @@ use gw_utils::{ utils::build_l2_sudt_script, }, error::Error, + Timepoint, }; use gw_common::{ @@ -43,7 +44,7 @@ use gw_common::{ }; use gw_types::{ bytes::Bytes, - core::{ScriptHashType, Status, Timepoint}, + core::{ScriptHashType, Status}, packed::{Byte32, GlobalState, RawL2Block, RollupConfig}, prelude::*, }; @@ -84,7 +85,7 @@ fn check_withdrawal_cells<'a>( } else { Timepoint::from_timestamp(context.timestamp) }; - if cell.args.withdrawal_block_timepoint().unpack() != expected_timepoint.full_value() { + if cell.args.withdrawal_block_number().unpack() != expected_timepoint.full_value() { debug!("withdrawal cell mismatch timepoint"); return Err(Error::InvalidWithdrawalCell); } @@ -137,7 +138,7 @@ fn check_input_custodian_cells( is_finalized( config, prev_global_state, - &Timepoint::from_full_value(cell.args.deposit_block_timepoint().unpack()), + &Timepoint::from_full_value(cell.args.deposit_block_number().unpack()), ) }); // check unfinalized custodian cells == reverted deposit requests @@ -186,7 +187,7 @@ fn check_output_custodian_cells( is_finalized( config, prev_global_state, - &Timepoint::from_full_value(cell.args.deposit_block_timepoint().unpack()), + &Timepoint::from_full_value(cell.args.deposit_block_number().unpack()), ) }); // check deposits request cells == unfinalized custodian cells @@ -203,7 +204,7 @@ fn check_output_custodian_cells( .position(|cell| { custodian_cell.args.deposit_lock_args() == cell.args && custodian_cell.args.deposit_block_hash() == context.block_hash.pack() - && custodian_cell.args.deposit_block_timepoint().unpack() + && custodian_cell.args.deposit_block_number().unpack() == expected_timepoint.full_value() && custodian_cell.value == cell.value }) @@ -577,7 +578,7 @@ fn verify_block_producer( let expected_stake_lock_args = input_stake_cell .args .as_builder() - .stake_block_timepoint(expected_timepoint.full_value().pack()) + .stake_block_number(expected_timepoint.full_value().pack()) .build(); if expected_stake_lock_args != output_stake_cell.args || input_stake_cell.capacity > output_stake_cell.capacity @@ -774,7 +775,7 @@ fn check_block_timestamp( // 4 hours, 4 * 60 * 60 * 1000 = 14400000ms const BACKBONE_BIAS: u64 = 14400000; let backbone = post_global_state.last_finalized_block_number().unpack() - + rollup_config.finality_as_duration(); + + finality_as_duration(rollup_config); if !(backbone.saturating_sub(BACKBONE_BIAS) <= block_timestamp && block_timestamp <= backbone.saturating_add(BACKBONE_BIAS)) { diff --git a/gwos/contracts/withdrawal-lock/src/entry.rs b/gwos/contracts/withdrawal-lock/src/entry.rs index 14ce05307..665b89ec0 100644 --- a/gwos/contracts/withdrawal-lock/src/entry.rs +++ b/gwos/contracts/withdrawal-lock/src/entry.rs @@ -19,10 +19,8 @@ use gw_utils::gw_types::packed::{ }; use gw_utils::{ cells::rollup::MAX_ROLLUP_WITNESS_SIZE, - gw_types::{ - self, - core::{ScriptHashType, Timepoint}, - }, + gw_types::{self, core::ScriptHashType}, + Timepoint, }; use gw_utils::{cells::utils::search_lock_hash, ckb_std::high_level::load_cell_lock}; @@ -138,8 +136,8 @@ pub fn main() -> Result<(), Error> { }; let custodian_deposit_block_hash: [u8; 32] = custodian_lock_args.deposit_block_hash().unpack(); - let custodian_deposit_block_timepoint : u64 = - custodian_lock_args.deposit_block_timepoint().unpack(); + let custodian_deposit_block_timepoint: u64 = + custodian_lock_args.deposit_block_number().unpack(); let global_state = search_rollup_state(&rollup_type_hash, Source::Input)? .ok_or(Error::RollupCellNotFound)?; let config = load_rollup_config(&global_state.rollup_config_hash().unpack())?; @@ -172,7 +170,7 @@ pub fn main() -> Result<(), Error> { let is_finalized = is_finalized( &config, &global_state, - &Timepoint::from_full_value(lock_args.withdrawal_block_timepoint().unpack()), + &Timepoint::from_full_value(lock_args.withdrawal_block_number().unpack()), ); if !is_finalized { return Err(Error::NotFinalized);