diff --git a/Cargo.lock b/Cargo.lock index c2c00bf5f6..821d328656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1756,7 +1756,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "franklin-crypto" version = "0.0.5" -source = "git+https://github.com/matter-labs/franklin-crypto.git?branch=beta#b39a82a4539f389cf056b3f7cc916f1b7df3447d" +source = "git+https://github.com/matter-labs/franklin-crypto.git?branch=beta#4a706d93628980e036249e3b182b91af8797ce8c" dependencies = [ "bellman_ce", "bit-vec", diff --git a/contracts/package.json b/contracts/package.json index 06c3dbdc03..7d251ae420 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -4,7 +4,7 @@ "license": "MIT", "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.0", - "@nomiclabs/hardhat-etherscan": "^2.0.1", + "@nomiclabs/hardhat-etherscan": "^2.1.0", "@nomiclabs/hardhat-solpp": "^2.0.0", "@nomiclabs/hardhat-waffle": "^2.0.0", "@openzeppelin/contracts": "3.2.1-solc-0.7", @@ -16,12 +16,13 @@ "axios": "^0.21.0", "chai": "^4.2.0", "chalk": "^4.1.0", + "commander": "^6.0.0", "ethereum-waffle": "^3.0.0", "ethereumjs-abi": "^0.6.8", "ethers": "^5.0.0", "ethjs": "^0.4.0", "fs": "^0.0.1-security", - "hardhat": "^2.0.2", + "hardhat": "^2.0.8", "hardhat-contract-sizer": "^2.0.2", "hardhat-typechain": "^0.3.3", "mocha": "^6.2.0", @@ -34,7 +35,6 @@ "ts-node": "^9.0.0", "typechain": "^4.0.0", "typescript": "^4.0.5", - "commander": "^6.0.0", "zksync": "link:../sdk/zksync.js" }, "scripts": { diff --git a/core/bin/data_restore/src/contract/default.rs b/core/bin/data_restore/src/contract/default.rs index 30d7540fb8..46aea9b157 100644 --- a/core/bin/data_restore/src/contract/default.rs +++ b/core/bin/data_restore/src/contract/default.rs @@ -181,8 +181,7 @@ mod test { 20u32.into(), 20u32.into(), 3, - 0, - u32::MAX, + Default::default(), None, ); let op1 = ZkSyncOp::TransferToNew(Box::new(TransferToNewOp { @@ -209,8 +208,7 @@ mod test { 20u32.into(), 10u32.into(), 3, - 0, - u32::MAX, + Default::default(), None, ); let op1 = ZkSyncOp::Transfer(Box::new(TransferOp { diff --git a/core/bin/data_restore/src/tree_state.rs b/core/bin/data_restore/src/tree_state.rs index 9b10fc2045..bfa3d8330e 100644 --- a/core/bin/data_restore/src/tree_state.rs +++ b/core/bin/data_restore/src/tree_state.rs @@ -495,8 +495,7 @@ mod test { BigUint::from(40u32), BigUint::from(1u32), 3, - 0, - u32::MAX, + Default::default(), None, ); let op3 = ZkSyncOp::TransferToNew(Box::new(TransferToNewOp { @@ -521,8 +520,7 @@ mod test { BigUint::from(19u32), BigUint::from(1u32), 1, - 0, - u32::MAX, + Default::default(), None, ); let op4 = ZkSyncOp::Transfer(Box::new(TransferOp { @@ -715,8 +713,7 @@ mod test { BigUint::from(40u32), BigUint::from(1u32), 3, - 0, - u32::MAX, + Default::default(), None, ); let op3 = ZkSyncOp::TransferToNew(Box::new(TransferToNewOp { @@ -734,8 +731,7 @@ mod test { BigUint::from(19u32), BigUint::from(1u32), 1, - 0, - u32::MAX, + Default::default(), None, ); let op4 = ZkSyncOp::Transfer(Box::new(TransferOp { diff --git a/core/bin/zksync_api/src/api_server/rest/v1/test_utils.rs b/core/bin/zksync_api/src/api_server/rest/v1/test_utils.rs index 9eeeffb5f7..5e2c82c74d 100644 --- a/core/bin/zksync_api/src/api_server/rest/v1/test_utils.rs +++ b/core/bin/zksync_api/src/api_server/rest/v1/test_utils.rs @@ -132,8 +132,7 @@ impl TestServerConfig { &to.address, None, false, - 0, - u32::MAX, + Default::default(), ) .0; @@ -169,8 +168,7 @@ impl TestServerConfig { &to.address, None, false, - 0, - u32::MAX, + Default::default(), ) .0; @@ -205,8 +203,7 @@ impl TestServerConfig { 2_u64.into(), fee.into(), 0, - 0, - u32::MAX, + Default::default(), None, ); diff --git a/core/bin/zksync_api/src/api_server/rest/v1/transactions.rs b/core/bin/zksync_api/src/api_server/rest/v1/transactions.rs index 6ead407bbd..2639f7f766 100644 --- a/core/bin/zksync_api/src/api_server/rest/v1/transactions.rs +++ b/core/bin/zksync_api/src/api_server/rest/v1/transactions.rs @@ -716,8 +716,7 @@ mod tests { &to.address, None, false, - 0, - u32::MAX, + Default::default(), ); client .submit_tx( diff --git a/core/bin/zksync_api/src/api_server/tx_sender.rs b/core/bin/zksync_api/src/api_server/tx_sender.rs index e51238f8e6..80bbf45737 100644 --- a/core/bin/zksync_api/src/api_server/tx_sender.rs +++ b/core/bin/zksync_api/src/api_server/tx_sender.rs @@ -199,16 +199,6 @@ impl TxSender { withdraw.fast = fast_processing; } - if let ZkSyncTx::Transfer(transfer) = &mut tx { - let valid_from = transfer.valid_from.unwrap_or(0); - let valid_until = transfer.valid_until.unwrap_or(u32::MAX); - if valid_from > valid_until { - return Err(SubmitError::IncorrectTx( - "Incorrect time segment when transfer execution is valid".to_string(), - )); - } - } - let msg_to_sign = self.tx_message_to_sign(&tx).await?; let tx_fee_info = tx.get_fee_info(); diff --git a/core/bin/zksync_core/src/mempool/mempool_transactions_queue.rs b/core/bin/zksync_core/src/mempool/mempool_transactions_queue.rs index 4d07d7f9d2..a795fba382 100644 --- a/core/bin/zksync_core/src/mempool/mempool_transactions_queue.rs +++ b/core/bin/zksync_core/src/mempool/mempool_transactions_queue.rs @@ -105,9 +105,9 @@ impl MempoolTransactionsQueue { mod tests { use super::*; use crate::mempool::Address; - use zksync_types::tx::{Transfer, Withdraw}; + use zksync_types::tx::{TimeRange, Transfer, Withdraw}; - fn get_transfer_with_timestamps(valid_from: u32, valid_until: u32) -> SignedTxVariant { + fn get_transfer_with_timestamps(valid_from: u64, valid_until: u64) -> SignedTxVariant { let transfer = Transfer::new( 4242, Address::random(), @@ -116,8 +116,7 @@ mod tests { 500u32.into(), 20u32.into(), 11, - valid_from, - valid_until, + TimeRange::new(valid_from, valid_until), None, ); diff --git a/core/bin/zksync_core/src/state_keeper/mod.rs b/core/bin/zksync_core/src/state_keeper/mod.rs index 532bec2825..2df561f29f 100644 --- a/core/bin/zksync_core/src/state_keeper/mod.rs +++ b/core/bin/zksync_core/src/state_keeper/mod.rs @@ -703,13 +703,15 @@ impl ZkSyncStateKeeper { ) -> Result<(), anyhow::Error> { match tx { ZkSyncTx::Transfer(tx) => { - let valid_from = u64::from(tx.valid_from.unwrap_or(0)); - let valid_until = u64::from(tx.valid_until.unwrap_or(u32::MAX)); + let time_range = tx.time_range.unwrap_or_default(); ensure!( - valid_from <= block_timestamp && block_timestamp <= valid_until, + time_range.is_valid(block_timestamp), "The transaction can't be executed in the block because of an invalid timestamp" ); } + ZkSyncTx::Withdraw(tx) => { + // todo!("should check withdraw tx here too") + } _ => { // There are no timestamps in other transactions } diff --git a/core/bin/zksync_core/src/state_keeper/tests.rs b/core/bin/zksync_core/src/state_keeper/tests.rs index d7b44cb742..e11e75c5c4 100644 --- a/core/bin/zksync_core/src/state_keeper/tests.rs +++ b/core/bin/zksync_core/src/state_keeper/tests.rs @@ -90,8 +90,6 @@ fn create_account_and_transfer>( account_id: AccountId, balance: B, transfer_amount: B, - valid_from: u32, - valid_until: u32, ) -> SignedZkSyncTx { let (account, sk) = tester.add_account(account_id); tester.set_balance(account_id, token_id, balance); @@ -104,8 +102,7 @@ fn create_account_and_transfer>( transfer_amount.into(), BigUint::from(1u32), account.nonce, - valid_from, - valid_until, + Default::default(), &sk, ) .unwrap(); @@ -210,7 +207,7 @@ pub fn create_deposit(token: TokenId, amount: impl Into) -> PriorityOp } async fn apply_single_transfer(tester: &mut StateKeeperTester) { - let transfer = create_account_and_transfer(tester, 0, 1, 200u32, 100u32, 0, u32::MAX); + let transfer = create_account_and_transfer(tester, 0, 1, 200u32, 100u32); let proposed_block = ProposedBlock { txs: vec![SignedTxVariant::Tx(transfer)], priority_ops: Vec::new(), @@ -222,8 +219,8 @@ async fn apply_single_transfer(tester: &mut StateKeeperTester) { } async fn apply_batch_with_two_transfers(tester: &mut StateKeeperTester) { - let first_transfer = create_account_and_transfer(tester, 0, 1, 200u32, 100u32, 0, u32::MAX); - let second_transfer = create_account_and_transfer(tester, 0, 2, 200u32, 100u32, 0, u32::MAX); + let first_transfer = create_account_and_transfer(tester, 0, 1, 200u32, 100u32); + let second_transfer = create_account_and_transfer(tester, 0, 2, 200u32, 100u32); let proposed_block = ProposedBlock { txs: vec![SignedTxVariant::Batch(SignedTxsBatch { txs: vec![first_transfer, second_transfer], @@ -998,17 +995,22 @@ mod execute_proposed_block { balance.into(), fee.into(), 0, - 0, - u32::MAX, + Default::default(), &sk_from, ) .unwrap(); let mut premature_transfer = correct_transfer.clone(); - premature_transfer.valid_from = Some(u32::MAX); + premature_transfer + .time_range + .as_mut() + .map(|t| t.valid_from = u64::max_value()); let mut belated_transfer = correct_transfer.clone(); - belated_transfer.valid_until = Some(0); + belated_transfer + .time_range + .as_mut() + .map(|t| t.valid_until = 0); let correct_transfer = SignedZkSyncTx { tx: ZkSyncTx::Transfer(Box::new(correct_transfer)), diff --git a/core/lib/circuit/benches/criterion/transfer.rs b/core/lib/circuit/benches/criterion/transfer.rs index b5423cc54f..d0fb110185 100644 --- a/core/lib/circuit/benches/criterion/transfer.rs +++ b/core/lib/circuit/benches/criterion/transfer.rs @@ -26,8 +26,7 @@ fn transfer_apply_tx(b: &mut Bencher<'_>, number_of_accounts: &usize) { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -57,8 +56,7 @@ fn transfer_get_pubdata(b: &mut Bencher<'_>) { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -88,8 +86,7 @@ fn transfer_calculate_operations(b: &mut Bencher<'_>) { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, diff --git a/core/lib/circuit/benches/criterion/transfer_to_new.rs b/core/lib/circuit/benches/criterion/transfer_to_new.rs index 9450541afb..4575686191 100644 --- a/core/lib/circuit/benches/criterion/transfer_to_new.rs +++ b/core/lib/circuit/benches/criterion/transfer_to_new.rs @@ -27,8 +27,7 @@ fn transfer_to_new_apply_tx(b: &mut Bencher<'_>, number_of_accounts: &usize) { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -58,8 +57,7 @@ fn transfer_to_new_get_pubdata(b: &mut Bencher<'_>) { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -89,8 +87,7 @@ fn transfer_to_new_calculate_operations(b: &mut Bencher<'_>) { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, diff --git a/core/lib/circuit/src/circuit.rs b/core/lib/circuit/src/circuit.rs index 13eaa4da9c..d703d4ae2d 100644 --- a/core/lib/circuit/src/circuit.rs +++ b/core/lib/circuit/src/circuit.rs @@ -1147,10 +1147,9 @@ impl<'a, E: RescueEngine + JubjubEngine> ZkSyncCircuit<'a, E> { &op_data, )?; - let is_serialized_tx_correct = Boolean::xor( + let is_serialized_tx_correct = multi_or( cs.namespace(|| "is_serialized_tx_correct"), - &is_new_serialized_tx_correct, - &is_old_serialized_tx_correct, + &[is_new_serialized_tx_correct, is_old_serialized_tx_correct], )?; let is_signed_correctly = multi_and( cs.namespace(|| "is_signed_correctly"), @@ -1619,10 +1618,9 @@ impl<'a, E: RescueEngine + JubjubEngine> ZkSyncCircuit<'a, E> { &op_data, )?; - let is_serialized_tx_correct = Boolean::xor( + let is_serialized_tx_correct = multi_or( cs.namespace(|| "is_serialized_tx_correct"), - &is_new_serialized_tx_correct, - &is_old_serialized_tx_correct, + &[is_new_serialized_tx_correct, is_old_serialized_tx_correct], )?; let (is_equal_pubdata, packed_pubdata) = vectorized_compare( @@ -1982,10 +1980,9 @@ impl<'a, E: RescueEngine + JubjubEngine> ZkSyncCircuit<'a, E> { &op_data, )?; - let is_serialized_tx_correct = Boolean::xor( + let is_serialized_tx_correct = multi_or( cs.namespace(|| "old_or_new_signature_correct"), - &is_new_serialized_tx_correct, - &is_old_serialized_tx_correct, + &[is_new_serialized_tx_correct, is_old_serialized_tx_correct], )?; log::debug!( @@ -2252,10 +2249,9 @@ impl<'a, E: RescueEngine + JubjubEngine> ZkSyncCircuit<'a, E> { &op_data, )?; - let is_serialized_tx_correct = Boolean::xor( + let is_serialized_tx_correct = multi_or( cs.namespace(|| "is_serialized_tx_correct"), - &is_new_serialized_tx_correct, - &is_old_serialized_tx_correct, + &[is_new_serialized_tx_correct, is_old_serialized_tx_correct], )?; lhs_valid_flags.push(is_serialized_tx_correct); diff --git a/core/lib/circuit/src/witness/tests/forced_exit.rs b/core/lib/circuit/src/witness/tests/forced_exit.rs index 5fdcfc1c70..a01e050be2 100644 --- a/core/lib/circuit/src/witness/tests/forced_exit.rs +++ b/core/lib/circuit/src/witness/tests/forced_exit.rs @@ -175,8 +175,7 @@ fn test_incorrect_target() { ); } -/// Checks that executing a transfer operation with incorrect -/// data (target account has signing key set) results in an error. +/// Checks that executing a forced exit operation for target account with pubkey set is correct #[test] #[ignore] fn test_target_has_key_set() { @@ -184,9 +183,6 @@ fn test_target_has_key_set() { const FEE_AMOUNT: u64 = 3; const WITHDRAW_AMOUNT: u64 = 100; - // Operation is not valid, since account has signing key set. - const ERR_MSG: &str = "op_valid is true/enforce equal to one"; - // Input data: we DO NOT reset the signing key for the second account. let accounts = vec![ WitnessTestAccount::new(1, FEE_AMOUNT), @@ -212,16 +208,17 @@ fn test_target_has_key_set() { let input = SigDataInput::from_forced_exit_op(&forced_exit_op).expect("SigDataInput creation failed"); - incorrect_op_test_scenario::, _>( + generic_test_scenario::, _>( &accounts, forced_exit_op, input, - ERR_MSG, - || { - vec![CollectedFee { - token: TOKEN_ID, - amount: FEE_AMOUNT.into(), - }] + |plasma_state, op| { + let fee = >::apply_op(plasma_state, &op) + .expect("ForcedExit failed") + .0 + .unwrap(); + + vec![fee] }, ); } diff --git a/core/lib/circuit/src/witness/tests/mod.rs b/core/lib/circuit/src/witness/tests/mod.rs index 07a1547c90..4d315ed494 100644 --- a/core/lib/circuit/src/witness/tests/mod.rs +++ b/core/lib/circuit/src/witness/tests/mod.rs @@ -92,8 +92,7 @@ fn apply_many_ops() -> ZkSyncCircuit<'static, Bn256> { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account.id, @@ -115,8 +114,7 @@ fn apply_many_ops() -> ZkSyncCircuit<'static, Bn256> { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account.id, diff --git a/core/lib/circuit/src/witness/tests/test_utils.rs b/core/lib/circuit/src/witness/tests/test_utils.rs index ac73308f78..58cb186301 100644 --- a/core/lib/circuit/src/witness/tests/test_utils.rs +++ b/core/lib/circuit/src/witness/tests/test_utils.rs @@ -17,6 +17,7 @@ use crate::{circuit::ZkSyncCircuit, witness::Witness}; pub use crate::witness::utils::WitnessBuilder; pub const FEE_ACCOUNT_ID: u32 = 0; +pub const BLOCK_TIMESTAMP: u64 = 0x12345678u64; /// Verifies that circuit has no unsatisfied constraints, and returns an error otherwise. pub fn check_circuit_non_panicking(circuit: ZkSyncCircuit) -> Result<(), String> { @@ -137,15 +138,13 @@ pub fn generic_test_scenario( W: Witness, F: FnOnce(&mut ZkSyncState, &W::OperationType) -> Vec, { - let block_timestamp = 0x12345678u64; - // Initialize Plasma and WitnessBuilder. let (mut plasma_state, mut circuit_account_tree) = ZkSyncStateGenerator::generate(&accounts); let mut witness_accum = WitnessBuilder::new( &mut circuit_account_tree, FEE_ACCOUNT_ID, 1, - block_timestamp, + BLOCK_TIMESTAMP, ); // Apply op on plasma @@ -194,14 +193,13 @@ pub fn corrupted_input_test_scenario( W::CalculateOpsInput: Clone + std::fmt::Debug, F: FnOnce(&mut ZkSyncState, &W::OperationType) -> Vec, { - let block_timestamp = 0x12345678u64; // Initialize Plasma and WitnessBuilder. let (mut plasma_state, mut circuit_account_tree) = ZkSyncStateGenerator::generate(&accounts); let mut witness_accum = WitnessBuilder::new( &mut circuit_account_tree, FEE_ACCOUNT_ID, 1, - block_timestamp, + BLOCK_TIMESTAMP, ); // Apply op on plasma @@ -259,14 +257,13 @@ pub fn incorrect_op_test_scenario( W::CalculateOpsInput: Clone + std::fmt::Debug, F: FnOnce() -> Vec, { - let block_timestamp = 0x12345678u64; // Initialize WitnessBuilder. let (_, mut circuit_account_tree) = ZkSyncStateGenerator::generate(&accounts); let mut witness_accum = WitnessBuilder::new( &mut circuit_account_tree, FEE_ACCOUNT_ID, 1, - block_timestamp, + BLOCK_TIMESTAMP, ); // Collect fees without actually applying the tx on plasma diff --git a/core/lib/circuit/src/witness/tests/transfer.rs b/core/lib/circuit/src/witness/tests/transfer.rs index 79a5a4370d..7fd060c005 100644 --- a/core/lib/circuit/src/witness/tests/transfer.rs +++ b/core/lib/circuit/src/witness/tests/transfer.rs @@ -6,12 +6,15 @@ use zksync_state::{ handler::TxHandler, state::{CollectedFee, TransferOutcome, ZkSyncState}, }; -use zksync_types::{operations::TransferOp, tx::Transfer}; +use zksync_types::{ + operations::TransferOp, + tx::{TimeRange, Transfer}, +}; // Local deps use crate::witness::{ tests::test_utils::{ corrupted_input_test_scenario, generic_test_scenario, incorrect_op_test_scenario, - WitnessTestAccount, + WitnessTestAccount, BLOCK_TIMESTAMP, }, transfer::TransferWitness, utils::SigDataInput, @@ -49,8 +52,7 @@ fn test_transfer_success() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -96,8 +98,7 @@ fn test_transfer_to_self() { &account.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account.id, @@ -144,8 +145,7 @@ fn corrupted_ops_input() { &account.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account.id, @@ -209,8 +209,7 @@ fn test_incorrect_transfer_account_from() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -265,8 +264,7 @@ fn test_incorrect_transfer_account_to() { &incorrect_account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -325,8 +323,7 @@ fn test_incorrect_transfer_amount() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -389,8 +386,7 @@ fn test_transfer_replay() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_copy.id, @@ -417,16 +413,19 @@ fn test_transfer_replay() { #[test] #[ignore] fn test_incorrect_transfer_timestamp() { - // Test vector of (initial_balance, transfer_amount, fee_amount, valid_from, valid_until). + // Test vector of (initial_balance, transfer_amount, fee_amount, time_range). let test_vector = vec![ - (10u64, 7u64, 3u64, 0, 0), // Basic transfer - (0, 0, 0, 0, 0), // Zero transfer - (std::u64::MAX, 1, 1, 0, 0), // Small transfer from rich account, - (std::u64::MAX, 10000, 1, u32::MAX, u32::MAX), // Big transfer from rich account (too big values can't be used, since they're not packable), - (std::u64::MAX, 1, 10000, u32::MAX, u32::MAX), // Very big fee + (10u64, 7u64, 3u64, TimeRange::new(0, 0)), + (10u64, 7u64, 3u64, TimeRange::new(0, BLOCK_TIMESTAMP - 1)), + ( + 10u64, + 7u64, + 3u64, + TimeRange::new(BLOCK_TIMESTAMP + 1, u64::max_value()), + ), ]; - for (initial_balance, transfer_amount, fee_amount, valid_from, valid_until) in test_vector { + for (initial_balance, transfer_amount, fee_amount, time_range) in test_vector { // Input data. let accounts = vec![ WitnessTestAccount::new(1, initial_balance), @@ -444,8 +443,7 @@ fn test_incorrect_transfer_timestamp() { &account_to.account.address, None, true, - valid_from, - valid_until, + time_range, ) .0, from: account_from.id, diff --git a/core/lib/circuit/src/witness/tests/transfer_to_new.rs b/core/lib/circuit/src/witness/tests/transfer_to_new.rs index 6477f71e57..33ee4c5862 100644 --- a/core/lib/circuit/src/witness/tests/transfer_to_new.rs +++ b/core/lib/circuit/src/witness/tests/transfer_to_new.rs @@ -9,6 +9,7 @@ use zksync_state::{ }; use zksync_types::{operations::TransferToNewOp, tx::Transfer}; // Local deps +use crate::witness::tests::test_utils::BLOCK_TIMESTAMP; use crate::witness::{ tests::test_utils::{ corrupted_input_test_scenario, generic_test_scenario, incorrect_op_test_scenario, @@ -17,6 +18,7 @@ use crate::witness::{ transfer_to_new::TransferToNewWitness, utils::SigDataInput, }; +use zksync_types::tx::TimeRange; /// Basic check for execution of `TransferToNew` operation in circuit. /// Here we create one account and perform a transfer to a new account. @@ -48,8 +50,7 @@ fn test_transfer_to_new_success() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -99,8 +100,7 @@ fn corrupted_ops_input() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -163,8 +163,7 @@ fn test_incorrect_transfer_account_from() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -220,8 +219,7 @@ fn test_incorrect_transfer_account_to() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -280,8 +278,7 @@ fn test_incorrect_transfer_amount() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_from.id, @@ -346,8 +343,7 @@ fn test_transfer_replay() { &account_to.account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: account_copy.id, @@ -375,16 +371,19 @@ fn test_transfer_replay() { #[test] #[ignore] fn test_incorrect_transfer_to_new_timestamp() { - // Test vector of (initial_balance, transfer_amount, fee_amount, valid_from, valid_until). + // Test vector of (initial_balance, transfer_amount, fee_amount, time_range). let test_vector = vec![ - (10u64, 7u64, 3u64, 0, 0), // Basic transfer - (0, 0, 0, 0, 0), // Zero transfer - (std::u64::MAX, 1, 1, 0, 0), // Small transfer from rich account, - (std::u64::MAX, 10000, 1, u32::MAX, u32::MAX), // Big transfer from rich account (too big values can't be used, since they're not packable), - (std::u64::MAX, 1, 10000, u32::MAX, u32::MAX), // Very big fee + (10u64, 7u64, 3u64, TimeRange::new(0, 0)), + (10u64, 7u64, 3u64, TimeRange::new(0, BLOCK_TIMESTAMP - 1)), + ( + 10u64, + 7u64, + 3u64, + TimeRange::new(BLOCK_TIMESTAMP + 1, u64::max_value()), + ), ]; - for (initial_balance, transfer_amount, fee_amount, valid_from, valid_until) in test_vector { + for (initial_balance, transfer_amount, fee_amount, time_range) in test_vector { // Input data. let accounts = vec![WitnessTestAccount::new(1, initial_balance)]; let account_from = &accounts[0]; @@ -400,8 +399,7 @@ fn test_incorrect_transfer_to_new_timestamp() { &account_to.account.address, None, true, - valid_from, - valid_until, + time_range, ) .0, from: account_from.id, diff --git a/core/lib/circuit/src/witness/transfer.rs b/core/lib/circuit/src/witness/transfer.rs index 390ff25468..c2680bf8bd 100644 --- a/core/lib/circuit/src/witness/transfer.rs +++ b/core/lib/circuit/src/witness/transfer.rs @@ -38,8 +38,8 @@ pub struct TransferData { pub token: u32, pub from_account_address: u32, pub to_account_address: u32, - pub valid_from: u32, - pub valid_until: u32, + pub valid_from: u64, + pub valid_until: u64, } pub struct TransferWitness { @@ -61,14 +61,15 @@ impl Witness for TransferWitness { type CalculateOpsInput = SigDataInput; fn apply_tx(tree: &mut CircuitAccountTree, transfer: &TransferOp) -> Self { + let time_range = transfer.tx.time_range.unwrap_or_default(); let transfer_data = TransferData { amount: transfer.tx.amount.to_u128().unwrap(), fee: transfer.tx.fee.to_u128().unwrap(), token: u32::from(transfer.tx.token), from_account_address: transfer.from, to_account_address: transfer.to, - valid_from: transfer.tx.valid_from.unwrap_or(0), - valid_until: transfer.tx.valid_until.unwrap_or(u32::MAX), + valid_from: time_range.valid_from, + valid_until: time_range.valid_until, }; // le_bit_vector_into_field_element() Self::apply_data(tree, &transfer_data) diff --git a/core/lib/circuit/src/witness/transfer_to_new.rs b/core/lib/circuit/src/witness/transfer_to_new.rs index 50d6d7703e..134b8e5511 100644 --- a/core/lib/circuit/src/witness/transfer_to_new.rs +++ b/core/lib/circuit/src/witness/transfer_to_new.rs @@ -38,8 +38,8 @@ pub struct TransferToNewData { pub from_account_address: u32, pub to_account_address: u32, pub new_address: Fr, - pub valid_from: u32, - pub valid_until: u32, + pub valid_from: u64, + pub valid_until: u64, } pub struct TransferToNewWitness { @@ -61,6 +61,7 @@ impl Witness for TransferToNewWitness { type CalculateOpsInput = SigDataInput; fn apply_tx(tree: &mut CircuitAccountTree, transfer_to_new: &TransferToNewOp) -> Self { + let time_range = transfer_to_new.tx.time_range.unwrap_or_default(); let transfer_data = TransferToNewData { amount: transfer_to_new.tx.amount.to_string().parse().unwrap(), fee: transfer_to_new.tx.fee.to_string().parse().unwrap(), @@ -68,8 +69,8 @@ impl Witness for TransferToNewWitness { from_account_address: transfer_to_new.from, to_account_address: transfer_to_new.to, new_address: eth_address_to_fr(&transfer_to_new.tx.to), - valid_from: transfer_to_new.tx.valid_from.unwrap_or(0), - valid_until: transfer_to_new.tx.valid_until.unwrap_or(u32::MAX), + valid_from: time_range.valid_from, + valid_until: time_range.valid_until, }; // le_bit_vector_into_field_element() Self::apply_data(tree, &transfer_data) diff --git a/core/lib/state/benches/criterion/ops.rs b/core/lib/state/benches/criterion/ops.rs index 9e6a9a6f9e..8b264779d2 100644 --- a/core/lib/state/benches/criterion/ops.rs +++ b/core/lib/state/benches/criterion/ops.rs @@ -74,8 +74,7 @@ fn apply_transfer_to_new_op(b: &mut Bencher<'_>) { 10u32.into(), 1u32.into(), 0, - 0, - u32::MAX, + Default::default(), private_key, ) .expect("failed to sign transfer"); @@ -110,8 +109,7 @@ fn apply_transfer_tx(b: &mut Bencher<'_>) { 10u32.into(), 1u32.into(), 0, - 0, - u32::MAX, + Default::default(), private_key, ) .expect("failed to sign transfer"); diff --git a/core/lib/state/src/tests/operations/transfer.rs b/core/lib/state/src/tests/operations/transfer.rs index 764650226e..e9800b431b 100644 --- a/core/lib/state/src/tests/operations/transfer.rs +++ b/core/lib/state/src/tests/operations/transfer.rs @@ -25,8 +25,7 @@ fn to_existing() { amount.clone(), fee.clone(), from_account.nonce, - 0, - u32::MAX, + Default::default(), &from_sk, ) .unwrap(); @@ -76,8 +75,7 @@ fn insufficient_funds() { amount, fee, from_account.nonce, - 0, - u32::MAX, + Default::default(), &from_sk, ) .unwrap(); @@ -108,8 +106,7 @@ fn to_new() { amount.clone(), fee.clone(), account.nonce, - 0, - u32::MAX, + Default::default(), &sk, ) .unwrap(); @@ -164,8 +161,7 @@ fn to_self() { amount.clone(), fee.clone(), account.nonce, - 0, - u32::MAX, + Default::default(), &sk, ) .unwrap(); @@ -203,8 +199,7 @@ fn nonce_mismatch() { amount, fee, account.nonce + 1, - 0, - u32::MAX, + Default::default(), &sk, ) .unwrap(); @@ -234,8 +229,7 @@ fn invalid_account_id() { amount, fee, account.nonce, - 0, - u32::MAX, + Default::default(), &sk, ) .unwrap(); diff --git a/core/lib/storage/src/tests/chain/block.rs b/core/lib/storage/src/tests/chain/block.rs index a2dee296d4..3c14fb5527 100644 --- a/core/lib/storage/src/tests/chain/block.rs +++ b/core/lib/storage/src/tests/chain/block.rs @@ -708,8 +708,7 @@ async fn pending_block_workflow(mut storage: StorageProcessor<'_>) -> QueryResul &to_zksync_account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0; diff --git a/core/lib/storage/src/tests/chain/mempool.rs b/core/lib/storage/src/tests/chain/mempool.rs index bca5119b80..92b2b9be50 100644 --- a/core/lib/storage/src/tests/chain/mempool.rs +++ b/core/lib/storage/src/tests/chain/mempool.rs @@ -27,8 +27,7 @@ fn franklin_txs() -> Vec { 100u32.into(), 10u32.into(), 10, - 0, - u32::MAX, + Default::default(), None, ); @@ -40,8 +39,7 @@ fn franklin_txs() -> Vec { 500u32.into(), 20u32.into(), 11, - 0, - u32::MAX, + Default::default(), None, ); @@ -106,8 +104,7 @@ fn gen_transfers(n: usize) -> Vec { 100u32.into(), 10u32.into(), 10, - 0, - u32::MAX, + Default::default(), None, ); diff --git a/core/lib/storage/src/tests/chain/operations_ext/setup.rs b/core/lib/storage/src/tests/chain/operations_ext/setup.rs index 88e1f902ae..5fca9f01ca 100644 --- a/core/lib/storage/src/tests/chain/operations_ext/setup.rs +++ b/core/lib/storage/src/tests/chain/operations_ext/setup.rs @@ -212,8 +212,7 @@ impl TransactionsHistoryTestSetup { &self.to_zksync_account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: self.from_zksync_account.get_account_id().unwrap(), @@ -245,8 +244,7 @@ impl TransactionsHistoryTestSetup { &self.to_zksync_account.address, None, true, - 0, - u32::MAX, + Default::default(), ) .0, from: self.from_zksync_account.get_account_id().unwrap(), diff --git a/core/lib/types/src/gas_counter.rs b/core/lib/types/src/gas_counter.rs index 109d270f7a..0cdc4db7f0 100644 --- a/core/lib/types/src/gas_counter.rs +++ b/core/lib/types/src/gas_counter.rs @@ -260,8 +260,7 @@ mod tests { Default::default(), Default::default(), 0, - 0, - u32::MAX, + Default::default(), None, ), from: 1, @@ -276,8 +275,7 @@ mod tests { Default::default(), Default::default(), 0, - 0, - u32::MAX, + Default::default(), None, ), from: 1, diff --git a/core/lib/types/src/operations/transfer_op.rs b/core/lib/types/src/operations/transfer_op.rs index cbae69c9cf..6ab89b19c5 100644 --- a/core/lib/types/src/operations/transfer_op.rs +++ b/core/lib/types/src/operations/transfer_op.rs @@ -67,8 +67,7 @@ impl TransferOp { .ok_or_else(|| format_err!("Cant get from account id from transfer pubdata"))?; let to_id = u32::from_bytes(&bytes[to_offset..to_offset + ACCOUNT_ID_BIT_WIDTH / 8]) .ok_or_else(|| format_err!("Cant get to account id from transfer pubdata"))?; - let valid_from = 0; // It is unknown from pubdata - let valid_until = u32::MAX; // It is unknown from pubdata + let time_range = Default::default(); Ok(Self { tx: Transfer::new( @@ -79,8 +78,7 @@ impl TransferOp { amount, fee, nonce, - valid_from, - valid_until, + time_range, None, ), from: from_id, diff --git a/core/lib/types/src/operations/transfer_to_new_op.rs b/core/lib/types/src/operations/transfer_to_new_op.rs index ee0edd2ad0..c3d6557877 100644 --- a/core/lib/types/src/operations/transfer_to_new_op.rs +++ b/core/lib/types/src/operations/transfer_to_new_op.rs @@ -69,21 +69,11 @@ impl TransferToNewOp { ) .ok_or_else(|| format_err!("Cant get fee from transfer to new pubdata"))?; let nonce = 0; // It is unknown from pubdata - let valid_from = 0; // It is unknown from pubdata - let valid_until = u32::MAX; // It is unknown from pubdata + let time_range = Default::default(); Ok(Self { tx: Transfer::new( - from_id, - from, - to, - token, - amount, - fee, - nonce, - valid_from, - valid_until, - None, + from_id, from, to, token, amount, fee, nonce, time_range, None, ), from: from_id, to: to_id, diff --git a/core/lib/types/src/tests/hardcoded.rs b/core/lib/types/src/tests/hardcoded.rs index 4cd61055c2..e47e66f4cd 100644 --- a/core/lib/types/src/tests/hardcoded.rs +++ b/core/lib/types/src/tests/hardcoded.rs @@ -79,8 +79,7 @@ pub mod operations_test { BigUint::from(42u32), BigUint::from(42u32), 42, - 0, - u32::MAX, + Default::default(), None, ); let (from, to) = (1u32, 2u32); @@ -300,8 +299,7 @@ pub mod tx_conversion_test { (*AMOUNT).clone(), (*FEE).clone(), NONCE, - 0, - u32::MAX, + Default::default(), None, ); diff --git a/core/lib/types/src/tx/mod.rs b/core/lib/types/src/tx/mod.rs index 87dffd13ef..0fd325b147 100644 --- a/core/lib/types/src/tx/mod.rs +++ b/core/lib/types/src/tx/mod.rs @@ -29,7 +29,7 @@ pub use self::primitives::{ batch_sign_data::BatchSignData, eip1271_signature::EIP1271Signature, eth_signature::TxEthSignature, packed_eth_signature::PackedEthSignature, packed_public_key::PackedPublicKey, packed_signature::PackedSignature, signature::TxSignature, - tx_hash::TxHash, + time_range::TimeRange, tx_hash::TxHash, }; pub(crate) use self::primitives::signature_cache::VerifiedSignatureCache; diff --git a/core/lib/types/src/tx/primitives/mod.rs b/core/lib/types/src/tx/primitives/mod.rs index 656017dc47..ab1bf0a8a9 100644 --- a/core/lib/types/src/tx/primitives/mod.rs +++ b/core/lib/types/src/tx/primitives/mod.rs @@ -6,6 +6,7 @@ pub mod packed_public_key; pub mod packed_signature; pub mod signature; pub mod signature_cache; +pub mod time_range; pub mod tx_hash; #[cfg(test)] diff --git a/core/lib/types/src/tx/primitives/tests.rs b/core/lib/types/src/tx/primitives/tests.rs index b57746ba47..d7de4bc1f9 100644 --- a/core/lib/types/src/tx/primitives/tests.rs +++ b/core/lib/types/src/tx/primitives/tests.rs @@ -27,8 +27,7 @@ fn get_batch() -> Vec { 500u32.into(), 20u32.into(), 11, - 0, - u32::MAX, + Default::default(), None, ); diff --git a/core/lib/types/src/tx/primitives/time_range.rs b/core/lib/types/src/tx/primitives/time_range.rs new file mode 100644 index 0000000000..5fe7da2a2a --- /dev/null +++ b/core/lib/types/src/tx/primitives/time_range.rs @@ -0,0 +1,46 @@ +use serde::{Deserialize, Serialize}; +use std::convert::TryInto; + +/// Defines time range `[valid_from, valid_until]` for which transaction is valid, +/// time format is the same as Ethereum (UNIX timestamp in seconds) +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub struct TimeRange { + pub valid_from: u64, + pub valid_until: u64, +} + +impl TimeRange { + pub fn new(valid_from: u64, valid_until: u64) -> Self { + Self { + valid_from, + valid_until, + } + } + + pub fn to_be_bytes(&self) -> [u8; 16] { + [ + self.valid_from.to_be_bytes(), + self.valid_until.to_be_bytes(), + ] + .concat() + .try_into() + .expect("valid_from and valid_until should be u64") + } + + pub fn check_correctness(&self) -> bool { + self.valid_from <= self.valid_until + } + + pub fn is_valid(&self, block_timestamp: u64) -> bool { + self.valid_from <= block_timestamp && block_timestamp <= self.valid_until + } +} + +impl Default for TimeRange { + fn default() -> Self { + Self { + valid_from: 0, + valid_until: u64::max_value(), + } + } +} diff --git a/core/lib/types/src/tx/tests.rs b/core/lib/types/src/tx/tests.rs index 451ff2f7b7..1f2957a400 100644 --- a/core/lib/types/src/tx/tests.rs +++ b/core/lib/types/src/tx/tests.rs @@ -48,8 +48,7 @@ fn test_print_transfer_for_protocol() { BigUint::from(12_340_000_000_000u64), BigUint::from(56_700_000_000u64), rng.gen(), - 0, - u32::MAX, + Default::default(), &key, ) .expect("failed to sign transfer"); diff --git a/core/lib/types/src/tx/transfer.rs b/core/lib/types/src/tx/transfer.rs index 12e65af27b..c5daea7d6a 100644 --- a/core/lib/types/src/tx/transfer.rs +++ b/core/lib/types/src/tx/transfer.rs @@ -2,6 +2,7 @@ use crate::{ helpers::{ is_fee_amount_packable, is_token_amount_packable, pack_fee_amount, pack_token_amount, }, + tx::TimeRange, AccountId, Nonce, TokenId, }; use num::BigUint; @@ -37,10 +38,10 @@ pub struct Transfer { pub fee: BigUint, /// Current account nonce. pub nonce: Nonce, - /// Unix epoch format of the time when the transaction is valid + /// Time range when the transaction is valid /// This fields must be Option<...> because of backward compatibility with first version of ZkSync - pub valid_from: Option, - pub valid_until: Option, + #[serde(flatten)] + pub time_range: Option, /// Transaction zkSync signature. pub signature: TxSignature, #[serde(skip)] @@ -64,8 +65,7 @@ impl Transfer { amount: BigUint, fee: BigUint, nonce: Nonce, - valid_from: u32, - valid_until: u32, + time_range: TimeRange, signature: Option, ) -> Self { let mut tx = Self { @@ -76,8 +76,7 @@ impl Transfer { amount, fee, nonce, - valid_from: Some(valid_from), - valid_until: Some(valid_until), + time_range: Some(time_range), signature: signature.clone().unwrap_or_default(), cached_signer: VerifiedSignatureCache::NotCached, }; @@ -98,21 +97,11 @@ impl Transfer { amount: BigUint, fee: BigUint, nonce: Nonce, - valid_from: u32, - valid_until: u32, + time_range: TimeRange, private_key: &PrivateKey, ) -> Result { let mut tx = Self::new( - account_id, - from, - to, - token, - amount, - fee, - nonce, - valid_from, - valid_until, - None, + account_id, from, to, token, amount, fee, nonce, time_range, None, ); tx.signature = TxSignature::sign_musig(private_key, &tx.get_bytes()); if !tx.check_correctness() { @@ -132,11 +121,8 @@ impl Transfer { out.extend_from_slice(&pack_token_amount(&self.amount)); out.extend_from_slice(&pack_fee_amount(&self.fee)); out.extend_from_slice(&self.nonce.to_be_bytes()); - if let Some(valid_from) = &self.valid_from { - out.extend_from_slice(&u64::from(*valid_from).to_be_bytes()); - } - if let Some(valid_until) = &self.valid_from { - out.extend_from_slice(&u64::from(*valid_until).to_be_bytes()); + if let Some(time_range) = &self.time_range { + out.extend_from_slice(&time_range.to_be_bytes()); } out } @@ -157,7 +143,10 @@ impl Transfer { && self.account_id <= max_account_id() && self.token <= max_token_id() && self.to != Address::zero() - && self.valid_from.unwrap_or(0) <= self.valid_until.unwrap_or(u32::MAX); + && self + .time_range + .map(|r| r.check_correctness()) + .unwrap_or(true); if valid { let signer = self.verify_signature(); valid = valid && signer.is_some(); diff --git a/core/lib/types/src/tx/zksync_tx.rs b/core/lib/types/src/tx/zksync_tx.rs index b9f605f10c..30459c0baf 100644 --- a/core/lib/types/src/tx/zksync_tx.rs +++ b/core/lib/types/src/tx/zksync_tx.rs @@ -224,7 +224,7 @@ impl ZkSyncTx { /// Returns the unix format timestamp of the first moment when transaction execution is valid. pub fn valid_from(&self) -> u32 { match self { - ZkSyncTx::Transfer(tx) => tx.valid_from.unwrap_or(0), + ZkSyncTx::Transfer(tx) => tx.time_range.map(|t| t.valid_from).unwrap_or(0) as u32, ZkSyncTx::Withdraw(tx) => tx.valid_from.unwrap_or(0), ZkSyncTx::ChangePubKey(tx) => tx.valid_from.unwrap_or(0), ZkSyncTx::ForcedExit(tx) => tx.valid_from.unwrap_or(0), diff --git a/core/tests/test_account/src/lib.rs b/core/tests/test_account/src/lib.rs index a32857f052..e5fa2f44fd 100644 --- a/core/tests/test_account/src/lib.rs +++ b/core/tests/test_account/src/lib.rs @@ -7,7 +7,8 @@ use zksync_basic_types::H256; use zksync_crypto::rand::{thread_rng, Rng}; use zksync_crypto::{priv_key_from_fs, PrivateKey}; use zksync_types::tx::{ - ChangePubKey, ChangePubKeyECDSAData, ChangePubKeyEthAuthData, PackedEthSignature, TxSignature, + ChangePubKey, ChangePubKeyECDSAData, ChangePubKeyEthAuthData, PackedEthSignature, TimeRange, + TxSignature, }; use zksync_types::{ AccountId, Address, Close, ForcedExit, Nonce, PubKeyHash, TokenId, Transfer, Withdraw, @@ -124,8 +125,7 @@ impl ZkSyncAccount { to: &Address, nonce: Option, increment_nonce: bool, - valid_from: u32, - valid_until: u32, + time_range: TimeRange, ) -> (Transfer, PackedEthSignature) { let mut stored_nonce = self.nonce.lock().unwrap(); let transfer = Transfer::new_signed( @@ -139,8 +139,7 @@ impl ZkSyncAccount { amount, fee, nonce.unwrap_or_else(|| *stored_nonce), - valid_from, - valid_until, + time_range, &self.private_key, ) .expect("Failed to sign transfer"); diff --git a/core/tests/testkit/src/account_set.rs b/core/tests/testkit/src/account_set.rs index 3dd76e5822..afd732211d 100644 --- a/core/tests/testkit/src/account_set.rs +++ b/core/tests/testkit/src/account_set.rs @@ -7,6 +7,7 @@ use zksync_crypto::rand::Rng; use zksync_types::{AccountId, Address, Nonce, PriorityOp, TokenId, ZkSyncTx}; use crate::types::*; +use zksync_types::tx::TimeRange; /// Account set is used to create transactions using stored account /// in a convenient way @@ -72,8 +73,7 @@ impl AccountSet { amount: BigUint, fee: BigUint, nonce: Option, - valid_from: u32, - valid_until: u32, + time_range: TimeRange, increment_nonce: bool, ) -> ZkSyncTx { let from = &self.zksync_accounts[from.0]; @@ -88,8 +88,7 @@ impl AccountSet { &to.address, nonce, increment_nonce, - valid_from, - valid_until, + time_range, ) .0, )) @@ -107,8 +106,6 @@ impl AccountSet { fee: BigUint, nonce: Option, increment_nonce: bool, - valid_from: u32, - valid_until: u32, rng: &mut impl Rng, ) -> ZkSyncTx { let from = &self.zksync_accounts[from.0]; @@ -124,8 +121,7 @@ impl AccountSet { &to_address, nonce, increment_nonce, - valid_from, - valid_until, + Default::default(), ) .0, )) diff --git a/core/tests/testkit/src/bin/gas_price_test.rs b/core/tests/testkit/src/bin/gas_price_test.rs index 8b7194cf05..60531b9eb6 100644 --- a/core/tests/testkit/src/bin/gas_price_test.rs +++ b/core/tests/testkit/src/bin/gas_price_test.rs @@ -350,8 +350,7 @@ async fn commit_cost_of_transfers( Token(0), tranfers_amount[i].clone(), tranfers_fee[i].clone(), - 0, - u32::MAX, + Default::default(), ) .await; } diff --git a/core/tests/testkit/src/scenarios.rs b/core/tests/testkit/src/scenarios.rs index 3767820426..111a147335 100644 --- a/core/tests/testkit/src/scenarios.rs +++ b/core/tests/testkit/src/scenarios.rs @@ -221,8 +221,7 @@ pub async fn perform_basic_operations( Token(token), &deposit_amount / BigUint::from(8u32), &deposit_amount / BigUint::from(8u32), - 0, - u32::MAX, + Default::default(), ) .await; @@ -234,8 +233,7 @@ pub async fn perform_basic_operations( Token(token), &deposit_amount / BigUint::from(8u32), &deposit_amount / BigUint::from(8u32), - 0, - u32::MAX, + Default::default(), ) .await; @@ -247,8 +245,7 @@ pub async fn perform_basic_operations( deposit_amount.clone(), BigUint::from(0u32), Some(nonce + 1), - 0, - u32::MAX, + Default::default(), false, ); test_setup @@ -263,8 +260,7 @@ pub async fn perform_basic_operations( Token(token), &deposit_amount / BigUint::from(4u32), &deposit_amount / BigUint::from(4u32), - 0, - u32::MAX, + Default::default(), ) .await; diff --git a/core/tests/testkit/src/test_setup.rs b/core/tests/testkit/src/test_setup.rs index 16ad35b38e..ec3977bcb7 100644 --- a/core/tests/testkit/src/test_setup.rs +++ b/core/tests/testkit/src/test_setup.rs @@ -26,6 +26,7 @@ use zksync_crypto::rand::Rng; use crate::account_set::AccountSet; use crate::state_keeper_utils::*; use crate::types::*; +use zksync_types::tx::TimeRange; /// Used to create transactions between accounts and check for their validity. /// Every new block should start with `.start_block()` @@ -412,8 +413,7 @@ impl TestSetup { token: Token, amount: BigUint, fee: BigUint, - valid_from: u32, - valid_until: u32, + time_range: TimeRange, ) { let mut zksync0_old = self .get_expected_zksync_account_balance(from, token.0) @@ -438,17 +438,9 @@ impl TestSetup { .sync_accounts_state .insert((self.accounts.fee_account_id, token.0), zksync0_old); - let transfer = self.accounts.transfer( - from, - to, - token, - amount, - fee, - None, - valid_from, - valid_until, - true, - ); + let transfer = self + .accounts + .transfer(from, to, token, amount, fee, None, time_range, true); self.execute_tx(transfer).await; } @@ -480,17 +472,9 @@ impl TestSetup { .sync_accounts_state .insert((self.accounts.fee_account_id, token.0), zksync0_old); - let transfer = self.accounts.transfer_to_new_random( - from, - token, - amount, - fee, - None, - true, - valid_from, - valid_until, - rng, - ); + let transfer = self + .accounts + .transfer_to_new_random(from, token, amount, fee, None, true, rng); self.execute_tx(transfer).await; } diff --git a/keys/packed/verify-keys-contracts-4-account-32_-balance-11.tar.gz b/keys/packed/verify-keys-contracts-4-account-32_-balance-11.tar.gz index bff504b4f9..382d4b66c2 100644 Binary files a/keys/packed/verify-keys-contracts-4-account-32_-balance-11.tar.gz and b/keys/packed/verify-keys-contracts-4-account-32_-balance-11.tar.gz differ diff --git a/sdk/zksync-rs/src/operations/transfer.rs b/sdk/zksync-rs/src/operations/transfer.rs index ae7cc50815..787d08c9aa 100644 --- a/sdk/zksync-rs/src/operations/transfer.rs +++ b/sdk/zksync-rs/src/operations/transfer.rs @@ -12,6 +12,7 @@ use zksync_types::{ use crate::{ error::ClientError, operations::SyncTransactionHandle, provider::Provider, wallet::Wallet, }; +use zksync_types::tx::TimeRange; #[derive(Debug)] pub struct TransferBuilder<'a, S: EthereumSigner, P: Provider> { @@ -21,8 +22,8 @@ pub struct TransferBuilder<'a, S: EthereumSigner, P: Provider> { fee: Option, to: Option
, nonce: Option, - valid_from: Option, - valid_until: Option, + valid_from: Option, + valid_until: Option, } impl<'a, S, P> TransferBuilder<'a, S, P> @@ -56,7 +57,7 @@ where .to .ok_or_else(|| ClientError::MissingRequiredField("to".into()))?; let valid_from = self.valid_from.unwrap_or(0); - let valid_until = self.valid_until.unwrap_or(u32::MAX); + let valid_until = self.valid_until.unwrap_or(u64::MAX); let nonce = match self.nonce { Some(nonce) => nonce, @@ -84,7 +85,14 @@ where self.wallet .signer - .sign_transfer(token, amount, fee, to, nonce, valid_from, valid_until) + .sign_transfer( + token, + amount, + fee, + to, + nonce, + TimeRange::new(valid_from, valid_until), + ) .await .map(|(tx, signature)| (ZkSyncTx::Transfer(Box::new(tx)), signature)) .map_err(ClientError::SigningError) @@ -171,13 +179,13 @@ where } /// Sets the unix format timestamp of the first moment when transaction execution is valid. - pub fn valid_from(mut self, valid_from: u32) -> Self { + pub fn valid_from(mut self, valid_from: u64) -> Self { self.valid_from = Some(valid_from); self } /// Sets the unix format timestamp of the last moment when transaction execution is valid. - pub fn valid_until(mut self, valid_until: u32) -> Self { + pub fn valid_until(mut self, valid_until: u64) -> Self { self.valid_until = Some(valid_until); self } diff --git a/sdk/zksync-rs/src/signer.rs b/sdk/zksync-rs/src/signer.rs index 901bd5db84..9b228464c3 100644 --- a/sdk/zksync-rs/src/signer.rs +++ b/sdk/zksync-rs/src/signer.rs @@ -2,7 +2,7 @@ use std::fmt; use zksync_eth_signer::error::SignerError; use zksync_eth_signer::EthereumSigner; -use zksync_types::tx::{ChangePubKeyECDSAData, ChangePubKeyEthAuthData, TxEthSignature}; +use zksync_types::tx::{ChangePubKeyECDSAData, ChangePubKeyEthAuthData, TimeRange, TxEthSignature}; // External uses use num::BigUint; // Workspace uses @@ -143,8 +143,7 @@ impl Signer { fee: BigUint, to: Address, nonce: Nonce, - valid_from: u32, - valid_until: u32, + time_range: TimeRange, ) -> Result<(Transfer, Option), SignerError> { let account_id = self.account_id.ok_or(SignerError::NoSigningKey)?; @@ -156,8 +155,7 @@ impl Signer { amount, fee, nonce, - valid_from, - valid_until, + time_range, &self.private_key, ) .map_err(signing_failed_error)?; diff --git a/sdk/zksync-rs/tests/integration.rs b/sdk/zksync-rs/tests/integration.rs index 534b4185f1..1d0a6df1f7 100644 --- a/sdk/zksync-rs/tests/integration.rs +++ b/sdk/zksync-rs/tests/integration.rs @@ -727,8 +727,7 @@ async fn batch_transfer() -> Result<(), anyhow::Error> { fee, recipient, nonce, - 0, - u32::MAX, + Default::default(), ) .await .expect("Transfer signing error"); diff --git a/sdk/zksync-rs/tests/unit.rs b/sdk/zksync-rs/tests/unit.rs index 7d5cff9e34..ad8a39a039 100644 --- a/sdk/zksync-rs/tests/unit.rs +++ b/sdk/zksync-rs/tests/unit.rs @@ -203,8 +203,7 @@ mod signatures_with_vectors { transfer_tx.fee.clone(), sign_data.to, sign_data.nonce, - 0, - u32::MAX, + Default::default(), ) .await .expect("Transfer signing error"); diff --git a/yarn.lock b/yarn.lock index 5feeebd848..2947125a42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1411,10 +1411,10 @@ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.0.tgz#ebab032b3aed03945ea560f56bb67aec56a30cbc" integrity sha512-fIi6XP9PgKqwSNVcLDr6S5hvGlc21PendaLD5eGdXEXc9aYQ0OJX8Mk3evs+p78x7W9n9U3ZcKtTiGc1+YScDw== -"@nomiclabs/hardhat-etherscan@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.0.1.tgz#576c162b0c2b8f5913b3853f4591e98ccc1c2e4d" - integrity sha512-5xPh5xhLXO1tDO0VTc4qlqqgv2m1bL+pXLSFibUVJ2EzzXHKn1C4ioHmYgseIkoNC3iG19cSJ7gRcQz4u54pGQ== +"@nomiclabs/hardhat-etherscan@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.0.tgz#08512c3e602155dc0d2becb193cd2e0155867839" + integrity sha512-YK9/UZI1Ct9TYfqZJnjIERlFC7bFrG0eUS2O0kFrH8RjLdcQXBI0GNpxXGAuDbotBg0t8wRKHibbK50TQu0ybA== dependencies: "@ethersproject/abi" "^5.0.2" "@ethersproject/address" "^5.0.2" @@ -1618,10 +1618,10 @@ resolved "https://registry.yarnpkg.com/@soda/get-current-script/-/get-current-script-1.0.2.tgz#a53515db25d8038374381b73af20bb4f2e508d87" integrity sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w== -"@solidity-parser/parser@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.7.1.tgz#660210130e4237476cb55e2882064809f80f861e" - integrity sha512-5ma2uuwPAEX1TPl2rAPAAuGlBkKnn2oUKQvnhTFlDIB8U/KDWX77FpHtL6Rcz+OwqSCWx9IClxACgyIEJ/GhIw== +"@solidity-parser/parser@^0.11.0": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.11.1.tgz#fa840af64840c930f24a9c82c08d4a092a068add" + integrity sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ== "@solidity-parser/parser@^0.8.2": version "0.8.2" @@ -7367,14 +7367,14 @@ hardhat-typechain@^0.3.3: resolved "https://registry.yarnpkg.com/hardhat-typechain/-/hardhat-typechain-0.3.3.tgz#cef7996d2054aecd5e6b7677130b2f2b1fe9d352" integrity sha512-NrqP7Zng28prV3YT0lXoo1pXtZxoNCMfiZIWkf1HXjjID42JLLfSOTsvlb0okDMpz4tJaEEkgADJO69sKZxw+Q== -hardhat@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.0.3.tgz#35e07060d9854d4182f201aeaa1c05316bd7e4d3" - integrity sha512-mDygAl+1qd5KBdXQBfc3R5XmC/rVdYYbEuOTSQY3rlncVu9gfockZVDsHtAMPw/FiBIRMApLcOceK7D1XQmHRw== +hardhat@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.0.8.tgz#6ec232293dd6b3ca7baeadb095ba4afce4b9b2e0" + integrity sha512-2tDAtOfshrBzP103dx7PQrhTwv2sqjhQStZAPwkkQTic25o2EH6HYE2++LuOG98YwqSjr0WvhvdBvKl3dCSkYA== dependencies: "@nomiclabs/ethereumjs-vm" "^4.1.1" "@sentry/node" "^5.18.1" - "@solidity-parser/parser" "^0.7.1" + "@solidity-parser/parser" "^0.11.0" "@types/bn.js" "^4.11.5" "@types/lru-cache" "^5.1.0" abort-controller "^3.0.0"