Skip to content

Improve transactions verification process in WithVerifyBlock dBFT callback #127

@AnnaShaleva

Description

@AnnaShaleva

After #87 there's a proper WithVerifyBlock dBFT callback implemented. During block verification it performs basic transactions correctness checks (while processing transactions states):

receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
if err != nil {
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
}

and
// Apply the transaction to the current state (included in the env).
result, err := ApplyMessage(evm, msg, gp)
if err != nil {
return nil, err
}

and
// ApplyMessage computes the new state by applying the given message
// against the old state within the environment.
//
// ApplyMessage returns the bytes returned by any EVM execution (if it took place),
// the gas used (which includes gas refunds) and an error if it failed. An error always
// indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block.
func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, error) {
return NewStateTransition(evm, msg, gp).TransitionDb()
}

and
// TransitionDb will transition the state by applying the current message and
// returning the evm execution result with following fields.
//
// - used gas: total gas used (including gas being refunded)
// - returndata: the returned data from evm
// - concrete execution error: various EVM errors which abort the execution, e.g.
// ErrOutOfGas, ErrExecutionReverted
//
// However if any consensus issue encountered, return the error directly with
// nil evm execution result.
func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
// First check this message satisfies all consensus rules before
// applying the message. The rules include these clauses
//
// 1. the nonce of the message caller is correct
// 2. caller has enough balance to cover transaction fee(gaslimit * gasprice)
// 3. the amount of gas required is available in the block
// 4. the purchased gas is enough to cover intrinsic usage
// 5. there is no overflow when calculating intrinsic gas
// 6. caller has enough balance to cover asset transfer for **topmost** call
// Check clauses 1-3, buy gas if everything is correct
if err := st.preCheck(); err != nil {

So basic checks for proposed in-block transactions are there and seems that we don't need a separate mempool to verify in-block transactions. But, there should be some policy checks implemented, as @chenquanyu mentioned in #87 (comment).

Metadata

Metadata

Assignees

No one assigned

    Labels

    dBFTEverything related to dBFT module integrationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions