From f7c473a49132c5683d8e8c2a2aa19051c79317c6 Mon Sep 17 00:00:00 2001 From: keroro Date: Wed, 14 Sep 2022 14:02:57 +0800 Subject: [PATCH] feat: remove verification for state_checkpoint_list --- c/validator_utils.h | 115 ------------------ .../src/verifications/context.rs | 33 +---- contracts/gw-utils/src/error.rs | 2 +- .../src/verifications/submit_block.rs | 87 +------------ 4 files changed, 6 insertions(+), 231 deletions(-) diff --git a/c/validator_utils.h b/c/validator_utils.h index f6a857c2..7a5c06ac 100644 --- a/c/validator_utils.h +++ b/c/validator_utils.h @@ -88,10 +88,6 @@ typedef struct gw_context_t { /* sender's original nonce */ uint32_t original_sender_nonce; - /* tx check point */ - uint8_t prev_tx_checkpoint[32]; - uint8_t post_tx_checkpoint[32]; - /* kv state */ smt_state_t kv_state; smt_pair_t kv_pairs[GW_MAX_KV_PAIRS]; @@ -1011,59 +1007,6 @@ int _gw_verify_cbmt_tx_proof(mol_seg_t *proof_seg, mol_seg_t *root_seg, return memcmp(root_seg->ptr, leaf_hash, 32); } -/* - * Load transaction checkpoints - */ -int _load_tx_checkpoint(mol_seg_t *raw_l2block_seg, uint32_t tx_index, - uint8_t prev_tx_checkpoint[32], - uint8_t post_tx_checkpoint[32]) { - mol_seg_t submit_withdrawals_seg = - MolReader_RawL2Block_get_submit_withdrawals(raw_l2block_seg); - mol_seg_t withdrawals_count_seg = - MolReader_SubmitWithdrawals_get_withdrawal_count(&submit_withdrawals_seg); - uint32_t withdrawals_count = 0; - _gw_fast_memcpy((uint8_t *)(&withdrawals_count), withdrawals_count_seg.ptr, - sizeof(uint32_t)); - - mol_seg_t checkpoint_list_seg = - MolReader_RawL2Block_get_state_checkpoint_list(raw_l2block_seg); - - // load prev tx checkpoint - if (0 == tx_index) { - mol_seg_t submit_txs_seg = - MolReader_RawL2Block_get_submit_transactions(raw_l2block_seg); - mol_seg_t prev_state_checkpoint_seg = - MolReader_SubmitTransactions_get_prev_state_checkpoint(&submit_txs_seg); - if (32 != prev_state_checkpoint_seg.size) { - printf("invalid prev state checkpoint"); - return GW_FATAL_INVALID_DATA; - } - _gw_fast_memcpy(prev_tx_checkpoint, prev_state_checkpoint_seg.ptr, 32); - } else { - uint32_t prev_tx_checkpoint_index = withdrawals_count + tx_index - 1; - - mol_seg_res_t checkpoint_res = - MolReader_Byte32Vec_get(&checkpoint_list_seg, prev_tx_checkpoint_index); - if (MOL_OK != checkpoint_res.errno || 32 != checkpoint_res.seg.size) { - printf("invalid prev tx checkpoint"); - return GW_FATAL_INVALID_DATA; - } - _gw_fast_memcpy(prev_tx_checkpoint, checkpoint_res.seg.ptr, 32); - } - - // load post tx checkpoint - uint32_t post_tx_checkpoint_index = withdrawals_count + tx_index; - - mol_seg_res_t checkpoint_res = - MolReader_Byte32Vec_get(&checkpoint_list_seg, post_tx_checkpoint_index); - if (MOL_OK != checkpoint_res.errno || 32 != checkpoint_res.seg.size) { - printf("invalid post tx checkpoint"); - return GW_FATAL_INVALID_DATA; - } - _gw_fast_memcpy(post_tx_checkpoint, checkpoint_res.seg.ptr, 32); - return 0; -} - /* Load verify transaction witness */ int _load_verify_transaction_witness(uint8_t rollup_script_hash[32], @@ -1260,13 +1203,6 @@ int _load_verify_transaction_witness(uint8_t rollup_script_hash[32], kv_state_proof_bytes_seg.size); ctx->kv_state_proof_size = kv_state_proof_bytes_seg.size; - /* load tx checkpoint */ - ret = _load_tx_checkpoint(&raw_l2block_seg, tx_index, ctx->prev_tx_checkpoint, - ctx->post_tx_checkpoint); - if (ret != 0) { - return ret; - } - mol_seg_t account_count_seg = MolReader_CCTransactionWitness_get_account_count(&cc_tx_witness_seg); _gw_fast_memcpy((uint8_t *)(&ctx->account_count), account_count_seg.ptr, @@ -1537,43 +1473,6 @@ int _check_owner_lock_hash() { return GW_ERROR_NOT_FOUND; } -int _gw_calculate_state_checkpoint(uint8_t buffer[32], const smt_state_t *state, - const uint8_t *proof, uint32_t proof_length, - uint32_t account_count) { - uint8_t root[32]; - int ret = smt_calculate_root(root, state, proof, proof_length); - if (0 != ret) { - printf( - "_gw_calculate_state_check_point: failed to calculate kv state " - "root ret: %d", - ret); - return GW_FATAL_SMT_CALCULATE_ROOT; - } - - blake2b_state blake2b_ctx; - blake2b_init(&blake2b_ctx, 32); - blake2b_update(&blake2b_ctx, root, 32); - blake2b_update(&blake2b_ctx, &account_count, sizeof(uint32_t)); - blake2b_final(&blake2b_ctx, buffer, 32); - - return 0; -} - -int _gw_verify_checkpoint(const uint8_t checkpoint[32], - const smt_state_t *state, const uint8_t *proof, - uint32_t proof_length, uint32_t account_count) { - uint8_t proof_checkpoint[32]; - int ret = _gw_calculate_state_checkpoint(proof_checkpoint, state, proof, - proof_length, account_count); - if (0 != ret) { - return ret; - } - if (0 != memcmp(proof_checkpoint, checkpoint, 32)) { - return GW_FATAL_INVALID_CHECK_POINT; - } - return 0; -} - int gw_context_init(gw_context_t *ctx) { /* check owner lock */ int ret = _check_owner_lock_hash(); @@ -1650,13 +1549,6 @@ int gw_context_init(gw_context_t *ctx) { /* verify kv_state merkle proof */ smt_state_normalize(&ctx->kv_state); - ret = _gw_verify_checkpoint(ctx->prev_tx_checkpoint, &ctx->kv_state, - ctx->kv_state_proof, ctx->kv_state_proof_size, - ctx->account_count); - if (ret != 0) { - printf("failed to merkle verify prev tx checkpoint"); - return ret; - } /* init original sender nonce */ ret = _load_sender_nonce(ctx, &ctx->original_sender_nonce); @@ -1688,13 +1580,6 @@ int gw_finalize(gw_context_t *ctx) { } smt_state_normalize(&ctx->kv_state); - ret = _gw_verify_checkpoint(ctx->post_tx_checkpoint, &ctx->kv_state, - ctx->kv_state_proof, ctx->kv_state_proof_size, - ctx->account_count); - if (ret != 0) { - printf("failed to merkle verify post tx checkpoint"); - return ret; - } return 0; } diff --git a/contracts/challenge-lock/src/verifications/context.rs b/contracts/challenge-lock/src/verifications/context.rs index 83ee5bf4..12c6b95d 100644 --- a/contracts/challenge-lock/src/verifications/context.rs +++ b/contracts/challenge-lock/src/verifications/context.rs @@ -1,7 +1,6 @@ use core::result::Result; use gw_common::{ - builtins::ETH_REGISTRY_ACCOUNT_ID, merkle_utils::calculate_state_checkpoint, - registry_address::RegistryAddress, state::State, H256, + builtins::ETH_REGISTRY_ACCOUNT_ID, registry_address::RegistryAddress, state::State, H256, }; use gw_state::kv_state::KVState; use gw_types::{ @@ -137,36 +136,6 @@ pub fn verify_tx_context(input: TxContextInput) -> Result { return Err(Error::MerkleProof); } - // verify kv-state merkle proof (prev state root) - let prev_state_checkpoint: H256 = match tx_index.checked_sub(1) { - Some(tx_prev_state_checkpoint_index) => { - // skip withdrawal state checkpoints - let offset: u32 = raw_block.submit_withdrawals().withdrawal_count().unpack(); - raw_block - .state_checkpoint_list() - .get((offset + tx_prev_state_checkpoint_index) as usize) - .ok_or(Error::InvalidStateCheckpoint)? - .unpack() - } - None => raw_block - .submit_transactions() - .prev_state_checkpoint() - .unpack(), - }; - let state_root = kv_state.calculate_root().map_err(|_err| { - debug!("verify_tx_context, calculate merkle root error: {:?}", _err); - Error::MerkleProof - })?; - let account_count = kv_state.get_account_count()?; - let calculated_state_checkpoint: H256 = calculate_state_checkpoint(&state_root, account_count); - if prev_state_checkpoint != calculated_state_checkpoint { - debug!( - "TxContext mismatch prev_state_checkpoint: {:?}, calculated_state_checkpoint: {:?}", - prev_state_checkpoint, calculated_state_checkpoint - ); - return Err(Error::MerkleProof); - } - let sender_address = kv_state .get_registry_address_by_script_hash(ETH_REGISTRY_ACCOUNT_ID, &sender_script_hash)? .ok_or(Error::RegistryAddressNotFound)?; diff --git a/contracts/gw-utils/src/error.rs b/contracts/gw-utils/src/error.rs index e0b79128..dd89521d 100644 --- a/contracts/gw-utils/src/error.rs +++ b/contracts/gw-utils/src/error.rs @@ -25,7 +25,7 @@ pub enum Error { InsufficientInputFinalizedAssets, InsufficientOutputFinalizedAssets, SMTKeyMissing, - InvalidStateCheckpoint, + _InvalidStateCheckpoint, // deprecated InvalidBlock, InvalidStatus, InvalidStakeCellUnlock, diff --git a/contracts/state-validator/src/verifications/submit_block.rs b/contracts/state-validator/src/verifications/submit_block.rs index 469acf83..0b67f020 100644 --- a/contracts/state-validator/src/verifications/submit_block.rs +++ b/contracts/state-validator/src/verifications/submit_block.rs @@ -36,14 +36,14 @@ use gw_common::{ builtins::CKB_SUDT_ACCOUNT_ID, error::Error as StateError, h256_ext::H256Ext, - merkle_utils::{calculate_ckb_merkle_root, calculate_state_checkpoint, ckb_merkle_leaf_hash}, + merkle_utils::{calculate_ckb_merkle_root, ckb_merkle_leaf_hash}, state::State, CKB_SUDT_SCRIPT_ARGS, H256, }; use gw_types::{ bytes::Bytes, core::{ScriptHashType, Status}, - packed::{Byte32, GlobalState, RawL2Block, RollupConfig}, + packed::{GlobalState, RawL2Block, RollupConfig}, prelude::*, }; @@ -530,53 +530,7 @@ fn verify_block_producer( Ok(()) } -fn check_state_checkpoints(block: &L2BlockReader) -> Result<(), Error> { - let raw_block = block.raw(); - let checkpoint_list = raw_block.state_checkpoint_list(); - - let transactions = block.transactions(); - let withdrawals = block.withdrawals(); - - if checkpoint_list.len() != withdrawals.len() + transactions.len() { - debug!( - "Wrong checkpoint length, checkpoints_list: {}, withdrawals: {} transactions: {}", - checkpoint_list.len(), - withdrawals.len(), - transactions.len() - ); - return Err(Error::InvalidStateCheckpoint); - } - - // check post state - let last_state_checkpoint = if transactions.is_empty() { - raw_block.submit_transactions().prev_state_checkpoint() - } else { - // return last transaction state checkpoint - checkpoint_list - .iter() - .last() - .ok_or(Error::InvalidStateCheckpoint)? - }; - let block_state_checkpoint: Byte32 = { - let post_account_state = raw_block.post_account(); - calculate_state_checkpoint( - &post_account_state.merkle_root().unpack(), - post_account_state.count().unpack(), - ) - .pack() - }; - if last_state_checkpoint.as_slice() != block_state_checkpoint.as_slice() { - debug!( - "Mismatch last_state_checkpoint: {:?}, block_state_checkpoint: {:?}", - last_state_checkpoint, block_state_checkpoint - ); - return Err(Error::InvalidStateCheckpoint); - } - - Ok(()) -} - -fn check_block_transactions(block: &L2BlockReader, kv_state: &KVState) -> Result<(), Error> { +fn check_block_transactions(block: &L2BlockReader) -> Result<(), Error> { // check tx_witness_root let raw_block = block.raw(); @@ -605,36 +559,6 @@ fn check_block_transactions(block: &L2BlockReader, kv_state: &KVState) -> Result return Err(Error::MerkleProof); } - // check current account tree state - let prev_state_checkpoint: H256 = submit_transactions.prev_state_checkpoint().unpack(); - if kv_state.calculate_state_checkpoint()? != prev_state_checkpoint { - debug!("submit_transactions.prev_state_checkpoint isn't equals to the state checkpoint calculated from context"); - return Err(Error::InvalidStateCheckpoint); - } - - // check post account tree state - let last_checkpoint_root = if block.transactions().is_empty() { - prev_state_checkpoint - } else { - raw_block - .state_checkpoint_list() - .iter() - .last() - .map(|checkpoint| checkpoint.unpack()) - .ok_or(Error::InvalidStateCheckpoint)? - }; - let block_post_state_root = { - let account = raw_block.post_account(); - calculate_state_checkpoint(&account.merkle_root().unpack(), account.count().unpack()) - }; - if last_checkpoint_root != block_post_state_root { - debug!( - "Invalid post state, last_checkpoint_root: {:?}, block_post_state_root: {:?}", - last_checkpoint_root, block_post_state_root - ); - return Err(Error::InvalidStateCheckpoint); - } - Ok(()) } @@ -738,9 +662,6 @@ pub fn verify( ) -> Result<(), Error> { check_status(prev_global_state, Status::Running)?; - // check checkpoints - check_state_checkpoints(block)?; - // Check withdrawals root check_block_withdrawals(block)?; @@ -786,7 +707,7 @@ pub fn verify( // Mint token: deposit requests -> layer2 SUDT check_layer2_deposit(&rollup_type_hash, config, &mut kv_state, &deposit_cells)?; // Check transactions - check_block_transactions(block, &kv_state)?; + check_block_transactions(block)?; // Verify Post state let actual_post_global_state = {