fn handle_run_result<S: State + CodeStore>(
        &self,
        state: &S,
        block_info: &BlockInfo,
        raw_tx: &RawL2Transaction,
        mut run_result: RunResult,
    ) -> Result<RunResult, TransactionError> {
        let sender_id: u32 = raw_tx.from_id().unpack();
        let nonce_raw_key = build_account_field_key(sender_id, GW_ACCOUNT_NONCE_TYPE);
        let nonce_before = state.get_nonce(sender_id)?;

        if 0 == run_result.exit_code {
            // check sender's nonce is increased by backends
            let nonce_after = {
                let value = run_result
                    .write
                    .write_values
                    .get(&nonce_raw_key)
                    .ok_or(TransactionError::BackendMustIncreaseNonce)?;
                value.to_u32()
            };
            if nonce_after <= nonce_before {
                log::error!(
                    "nonce should increased by backends nonce before: {}, nonce after: {}",
                    nonce_before,
                    nonce_after
                );
                return Err(TransactionError::BackendMustIncreaseNonce);
            }
        } else {
            // revert tx
            let last_run_result_log = run_result.write.logs.pop();
            run_result.revert_write();

            // sender address
            let payer = {
                let script_hash = state.get_script_hash(sender_id)?;
                state
                    .get_registry_address_by_script_hash(ETH_REGISTRY_ACCOUNT_ID, &script_hash)?
                    .ok_or(TransactionError::ScriptHashNotFound)?
            };

            // block producer address
            let block_producer =
                RegistryAddress::from_slice(&block_info.block_producer().raw_data())
                    .unwrap_or_default();

            // add charging fee key-values into run result
            {
                let sender_sudt_key = {
                    let sudt_key = build_sudt_key(SUDT_KEY_FLAG_BALANCE, &payer);
                    build_account_key(CKB_SUDT_ACCOUNT_ID, &sudt_key)
                };
                let block_producer_sudt_key = {
                    let sudt_key = build_sudt_key(SUDT_KEY_FLAG_BALANCE, &block_producer);
                    build_account_key(CKB_SUDT_ACCOUNT_ID, &sudt_key)
                };
                let total_supply_key =
                    build_account_key(CKB_SUDT_ACCOUNT_ID, &SUDT_TOTAL_SUPPLY_KEY);
                for raw_key in [sender_sudt_key, block_producer_sudt_key, total_supply_key] {
                    let raw_value = state.get_raw(&raw_key)?;
                    run_result.read_values.entry(raw_key).or_insert(raw_value);
                }
            }

            // handle tx fee
            let tx_type = get_tx_type(self.rollup_context(), state, raw_tx)?;
            let typed_tx = TypedRawTransaction::from_tx(raw_tx.to_owned(), tx_type)
                .expect("Unknown type of tx");
            let tx_fee = match typed_tx {
                TypedRawTransaction::EthAddrReg(tx) => tx.consumed(),
                TypedRawTransaction::Meta(tx) => tx.consumed(),
                TypedRawTransaction::SimpleUDT(tx) => tx.consumed(),
                TypedRawTransaction::Polyjuice(ref tx) => {
                    // push polyjuice system log back to run_result
                    if let Some(log) = last_run_result_log
                        .filter(|log| log.service_flag() == GW_LOG_POLYJUICE_SYSTEM.into())
                    {
                        run_result.write.logs.push(log);
                    }
                    let args = tx.extract_tx_args().ok_or(TransactionError::NoCost)?;
                    let gas_used = match read_polyjuice_gas_used(&run_result) {
                        Some(gas_used) => gas_used,
                        None => {
                            log::warn!(
                                "[gw-generator] failed to parse gas_used, use gas_limit instead"
                            );
                            args.gas_limit
                        }
                    };
                    gw_types::U256::from(gas_used).checked_mul(args.gas_price.into())
                }
            }
            .ok_or(TransactionError::NoCost)?;

            let mut run_result_state = RunResultState(&mut run_result);

            run_result_state
                .pay_fee(&payer, &block_producer, CKB_SUDT_ACCOUNT_ID, tx_fee)
                .map_err(|err| {
                    log::error!(
                        "[gw-generator] failed to pay fee for failure tx, err: {}",
                        err
                    );
                    TransactionError::InsufficientBalance
                })?;

            // increase sender's nonce
            let nonce = nonce_before
                .checked_add(1)
                .ok_or(TransactionError::NonceOverflow)?;
            run_result
                .write
                .write_values
                .insert(nonce_raw_key, H256::from_u32(nonce));
        }

        // check write data bytes
        if let Some(data) = run_result
            .write
            .write_data
            .values()
            .find(|data| data.len() > MAX_WRITE_DATA_BYTES_LIMIT)
        {
            return Err(TransactionError::ExceededMaxWriteData {
                max_bytes: MAX_WRITE_DATA_BYTES_LIMIT,
                used_bytes: data.len(),
            });
        }
        // check read data bytes
        let read_data_bytes: usize = run_result.read_data.values().map(Bytes::len).sum();
        if read_data_bytes > MAX_READ_DATA_BYTES_LIMIT {
            return Err(TransactionError::ExceededMaxReadData {
                max_bytes: MAX_READ_DATA_BYTES_LIMIT,
                used_bytes: read_data_bytes,
            });
        }

        Ok(run_result)
    }
// check and handle run_result before return
check and handle run_result before return
check and handle run_result before return
fn handle_run_result<S: State + CodeStore>(
        &self,
        state: &S,
        block_info: &BlockInfo,
        raw_tx: &RawL2Transaction,
        mut run_result: RunResult,
    ) -> Result<RunResult, TransactionError> {
        let sender_id: u32 = raw_tx.from_id().unpack();
        let nonce_raw_key = build_account_field_key(sender_id, GW_ACCOUNT_NONCE_TYPE);
        let nonce_before = state.get_nonce(sender_id)?;
        if 0 == run_result.exit_code {
            // check sender's nonce is increased by backends
            let nonce_after = {
                let value = run_result
                    .write
                    .write_values
                    .get(&nonce_raw_key)
                    .ok_or(TransactionError::BackendMustIncreaseNonce)?;
                value.to_u32()
            };
            if nonce_after <= nonce_before {
                log::error!(
                    "nonce should increased by backends nonce before: {}, nonce after: {}",
                    nonce_before,
                    nonce_after
                );
                return Err(TransactionError::BackendMustIncreaseNonce);
            }
        } else {
            // revert tx
            let last_run_result_log = run_result.write.logs.pop();
            run_result.revert_write();
            // sender address
            let payer = {
                let script_hash = state.get_script_hash(sender_id)?;
                state
                    .get_registry_address_by_script_hash(ETH_REGISTRY_ACCOUNT_ID, &script_hash)?
                    .ok_or(TransactionError::ScriptHashNotFound)?
            };
            // block producer address
            let block_producer =
                RegistryAddress::from_slice(&block_info.block_producer().raw_data())
                    .unwrap_or_default();
            // add charging fee key-values into run result
            {
                let sender_sudt_key = {
                    let sudt_key = build_sudt_key(SUDT_KEY_FLAG_BALANCE, &payer);
                    build_account_key(CKB_SUDT_ACCOUNT_ID, &sudt_key)
                };
                let block_producer_sudt_key = {
                    let sudt_key = build_sudt_key(SUDT_KEY_FLAG_BALANCE, &block_producer);
                    build_account_key(CKB_SUDT_ACCOUNT_ID, &sudt_key)
                };
                let total_supply_key =
                    build_account_key(CKB_SUDT_ACCOUNT_ID, &SUDT_TOTAL_SUPPLY_KEY);
                for raw_key in [sender_sudt_key, block_producer_sudt_key, total_supply_key] {
                    let raw_value = state.get_raw(&raw_key)?;
                    run_result.read_values.entry(raw_key).or_insert(raw_value);
                }
            }
            // handle tx fee
            let tx_type = get_tx_type(self.rollup_context(), state, raw_tx)?;
            let typed_tx = TypedRawTransaction::from_tx(raw_tx.to_owned(), tx_type)
                .expect("Unknown type of tx");
            let tx_fee = match typed_tx {
                TypedRawTransaction::EthAddrReg(tx) => tx.consumed(),
                TypedRawTransaction::Meta(tx) => tx.consumed(),
                TypedRawTransaction::SimpleUDT(tx) => tx.consumed(),
                TypedRawTransaction::Polyjuice(ref tx) => {
                    // push polyjuice system log back to run_result
                    if let Some(log) = last_run_result_log
                        .filter(|log| log.service_flag() == GW_LOG_POLYJUICE_SYSTEM.into())
                    {
                        run_result.write.logs.push(log);
                    }
                    let args = tx.extract_tx_args().ok_or(TransactionError::NoCost)?;
                    let gas_used = match read_polyjuice_gas_used(&run_result) {
                        Some(gas_used) => gas_used,
                        None => {
                            log::warn!(
                                "[gw-generator] failed to parse gas_used, use gas_limit instead"
                            );
                            args.gas_limit
                        }
                    };
                    gw_types::U256::from(gas_used).checked_mul(args.gas_price.into())
                }
            }
            .ok_or(TransactionError::NoCost)?;
            let mut run_result_state = RunResultState(&mut run_result);
            run_result_state
                .pay_fee(&payer, &block_producer, CKB_SUDT_ACCOUNT_ID, tx_fee)
                .map_err(|err| {
                    log::error!(
                        "[gw-generator] failed to pay fee for failure tx, err: {}",
                        err
                    );
                    TransactionError::InsufficientBalance
                })?;
            // increase sender's nonce
            let nonce = nonce_before
                .checked_add(1)
                .ok_or(TransactionError::NonceOverflow)?;
            run_result
                .write
                .write_values
                .insert(nonce_raw_key, H256::from_u32(nonce));
        }
        // check write data bytes
        if let Some(data) = run_result
            .write
            .write_data
            .values()
            .find(|data| data.len() > MAX_WRITE_DATA_BYTES_LIMIT)
        {
            return Err(TransactionError::ExceededMaxWriteData {
                max_bytes: MAX_WRITE_DATA_BYTES_LIMIT,
                used_bytes: data.len(),
            });
        }
        // check read data bytes
        let read_data_bytes: usize = run_result.read_data.values().map(Bytes::len).sum();
        if read_data_bytes > MAX_READ_DATA_BYTES_LIMIT {
            return Err(TransactionError::ExceededMaxReadData {
                max_bytes: MAX_READ_DATA_BYTES_LIMIT,
                used_bytes: read_data_bytes,
            });
        }
        Ok(run_result)
    }
fn handle_run_result < S : State + CodeStore > ( & self , state : & S , block_info : & BlockInfo , raw_tx : & RawL2Transaction , mut run_result : RunResult , ) -> Result < RunResult , TransactionError > { let sender_id : u32 = raw_tx . from_id ( ) . unpack ( ) ; let nonce_raw_key = build_account_field_key ( sender_id , GW_ACCOUNT_NONCE_TYPE ) ; let nonce_before = state . get_nonce ( sender_id ) ? ; if 0 == run_result . exit_code { // check sender's nonce is increased by backends let nonce_after = { let value = run_result . write . write_values . get ( & nonce_raw_key ) . ok_or ( TransactionError :: BackendMustIncreaseNonce ) ? ; value . to_u32 ( ) } ; if nonce_after <= nonce_before { log :: error ! ( " " nonce_before nonce_after ) ; return Err ( TransactionError :: BackendMustIncreaseNonce ) ; } } else { // revert tx let last_run_result_log = run_result . write . logs . pop ( ) ; run_result . revert_write ( ) ; // sender address let payer = { let script_hash = state . get_script_hash ( sender_id ) ? ; state . get_registry_address_by_script_hash ( ETH_REGISTRY_ACCOUNT_ID , & script_hash ) ? . ok_or ( TransactionError :: ScriptHashNotFound ) ? } ; // block producer address let block_producer = RegistryAddress :: from_slice ( & block_info . block_producer ( ) . raw_data ( ) ) . unwrap_or_default ( ) ; // add charging fee key-values into run result { let sender_sudt_key = { let sudt_key = build_sudt_key ( SUDT_KEY_FLAG_BALANCE , & payer ) ; build_account_key ( CKB_SUDT_ACCOUNT_ID , & sudt_key ) } ; let block_producer_sudt_key = { let sudt_key = build_sudt_key ( SUDT_KEY_FLAG_BALANCE , & block_producer ) ; build_account_key ( CKB_SUDT_ACCOUNT_ID , & sudt_key ) } ; let total_supply_key = build_account_key ( CKB_SUDT_ACCOUNT_ID , & SUDT_TOTAL_SUPPLY_KEY ) ; for raw_key in [ sender_sudt_key , block_producer_sudt_key , total_supply_key ] { let raw_value = state . get_raw ( & raw_key ) ? ; run_result . read_values . entry ( raw_key ) . or_insert ( raw_value ) ; } } // handle tx fee let tx_type = get_tx_type ( self . rollup_context ( ) , state , raw_tx ) ? ; let typed_tx = TypedRawTransaction :: from_tx ( raw_tx . to_owned ( ) , tx_type ) . expect ( " " ) ; let tx_fee = match typed_tx { TypedRawTransaction :: EthAddrReg ( tx ) => tx . consumed ( ) , TypedRawTransaction :: Meta ( tx ) => tx . consumed ( ) , TypedRawTransaction :: SimpleUDT ( tx ) => tx . consumed ( ) , TypedRawTransaction :: Polyjuice ( ref tx ) => { // push polyjuice system log back to run_result if let Some ( log ) = last_run_result_log . filter ( | log | log . service_flag ( ) == GW_LOG_POLYJUICE_SYSTEM . into ( ) ) { run_result . write . logs . push ( log ) ; } let args = tx . extract_tx_args ( ) . ok_or ( TransactionError :: NoCost ) ? ; let gas_used = match read_polyjuice_gas_used ( & run_result ) { Some ( gas_used ) => gas_used , None => { log :: warn ! ( " " ) ; args . gas_limit } } ; gw_types :: U256 :: from ( gas_used ) . checked_mul ( args . gas_price . into ( ) ) } } . ok_or ( TransactionError :: NoCost ) ? ; let mut run_result_state = RunResultState ( & mut run_result ) ; run_result_state . pay_fee ( & payer , & block_producer , CKB_SUDT_ACCOUNT_ID , tx_fee ) . map_err ( | err | { log :: error ! ( " " err ) ; TransactionError :: InsufficientBalance } ) ? ; // increase sender's nonce let nonce = nonce_before . checked_add ( 1 ) . ok_or ( TransactionError :: NonceOverflow ) ? ; run_result . write . write_values . insert ( nonce_raw_key , H256 :: from_u32 ( nonce ) ) ; } // check write data bytes if let Some ( data ) = run_result . write . write_data . values ( ) . find ( | data | data . len ( ) > MAX_WRITE_DATA_BYTES_LIMIT ) { return Err ( TransactionError :: ExceededMaxWriteData { max_bytes : MAX_WRITE_DATA_BYTES_LIMIT , used_bytes : data . len ( ) , } ) ; } // check read data bytes let read_data_bytes : usize = run_result . read_data . values ( ) . map ( Bytes :: len ) . sum ( ) ; if read_data_bytes > MAX_READ_DATA_BYTES_LIMIT { return Err ( TransactionError :: ExceededMaxReadData { max_bytes : MAX_READ_DATA_BYTES_LIMIT , used_bytes : read_data_bytes , } ) ; } Ok ( run_result ) }
check and handle run_result before return
check and handle run_result before return
&self
state
&S
block_info
&BlockInfo
raw_tx
&RawL2Transaction
run_result
RunResult
&self
state
&S
block_info
&BlockInfo
raw_tx
&RawL2Transaction
run_result
RunResult