Skip to content
This repository has been archived by the owner on Nov 9, 2022. It is now read-only.

Commit

Permalink
feat: remove verification for state_checkpoint_list
Browse files Browse the repository at this point in the history
  • Loading branch information
keroro520 committed Sep 14, 2022
1 parent 6fa577f commit f7c473a
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 231 deletions.
115 changes: 0 additions & 115 deletions c/validator_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
33 changes: 1 addition & 32 deletions contracts/challenge-lock/src/verifications/context.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down Expand Up @@ -137,36 +136,6 @@ pub fn verify_tx_context(input: TxContextInput) -> Result<TxContext, Error> {
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)?;
Expand Down
2 changes: 1 addition & 1 deletion contracts/gw-utils/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub enum Error {
InsufficientInputFinalizedAssets,
InsufficientOutputFinalizedAssets,
SMTKeyMissing,
InvalidStateCheckpoint,
_InvalidStateCheckpoint, // deprecated
InvalidBlock,
InvalidStatus,
InvalidStakeCellUnlock,
Expand Down
87 changes: 4 additions & 83 deletions contracts/state-validator/src/verifications/submit_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*,
};

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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(())
}

Expand Down Expand Up @@ -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)?;

Expand Down Expand Up @@ -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 = {
Expand Down

0 comments on commit f7c473a

Please sign in to comment.