This repository has been archived by the owner on Oct 4, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 166
Block processing
beholder0x2a edited this page Aug 27, 2016
·
1 revision
This is a brief description on how block processing works (e.g., block 20 => block 21 => etc)
Block processing starts in the ChainManager
(https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/chain_manager.go)
- Block(s) are inserted using
InsertChain(...)
(https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/chain_manager.go#L324) - Each block is then processed by the
Processor
which in our case is always theBlockManager
https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/chain_manager.go#L326- Block validation and processing all happens with the
BlockManager
https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go - Checked if the block already's in storage (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L171)
- Check if we have the parent (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L175)
- Validate the easy, less intensive tasks first (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L189)
- Calculate the difficulty and compare it to the parent's difficulty (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L272)
- Verify the proof of work (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L290)
- Transition the state (e.g., apply transactions) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L193)
- Set the gas limit. Transactions will use the gasPool to "buy" gas from the coinbase (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L87)
- Attempt to transition the state using the current message (transaction) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L116)
- All transactional state changes happen within the
StateTransition
object and start at theTransitionState
method (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L150) - Check the tx nonce:
tx.nonce == account.nonce
(https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L138) - Check if we can buy the gas of the coin base (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L110)
- Use TxGas (500) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L169)
- Create a contract if len(address) == 0 (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L189)
- Run init code (see
Create VmEnv
) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L190) - Charge additional gas for creation bytes (i.e.,
len(ret) * createByteGas
) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L193) - Set the return data as contract code (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L196)
- Run init code (see
- Or run the code if the recipient has any code to execute (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/state_transition.go#L200)
- Use the
VmEnv
and call eitherCreate
orCall
(depending on the address). TheVmEnv
will instantiate a newExecution
handler which will take care of starting the virtual machine. TheVmEnv
will be used to throughout the entire process. The virtual machine itself has access to the VmEnv and will this object to call in to other contracts or create new accounts. (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/vm_env.go#L46) - Execute given code (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/execution.go#L34)
- Make sure we haven't reached max depth (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/execution.go#L38)
- Transfer value (err is set incase of insufficient funds) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/execution.go#L46)
- Snapshot the state for rollback feature (value transfers happen regardless of errors) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/execution.go#L55)
- Execute code given (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/execution.go#L69)
- Enter VM run loop (https://github.com/ethereumproject/go-ethereum/blob/docbranch/vm/vm_debug.go#L40)
- Create a new
Context
which holds the code, gas and information about the caller (https://github.com/ethereumproject/go-ethereum/blob/docbranch/vm/vm_debug.go#L50) - Check for precompiled contract (https://github.com/ethereumproject/go-ethereum/blob/docbranch/vm/vm_debug.go#L68) see (https://github.com/ethereumproject/go-ethereum/blob/docbranch/vm/address.go#L23) for all pre compiled contracts and run it if there's a contract at that address (https://github.com/ethereumproject/go-ethereum/blob/docbranch/vm/vm_debug.go#L935)
- Analyse valid jump positions (https://github.com/ethereumproject/go-ethereum/blob/docbranch/vm/vm_debug.go#L75). It's worth noting that
jump
(https://github.com/ethereumproject/go-ethereum/blob/docbranch/vm/vm_debug.go#L83) uses the jump positions in order to determine whether theJUMP(I)
landed on a valid position. Valid positions for jump are: anyJUMPDEST
(0x5c
) which is not part of aPUSH
instruction (e.g.PUSH 0x5c
would be an invalid jump position). - .... Run code .... (evaluation of code is a different topic)
- Eventually the execution will end, be it a success or a failure (stack err, OOG, depth level, etc) and return a value and whether it was successful.
- Use the
- All transactional state changes happen within the
- Evaluate outcome and set the code accordingly (if action was create)
- Update the state changes made during the state transition (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L138)
- Create a new receipt. Receipts are checked for validity at the end of the transaction processing (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L141).
- Validate the block's bloom by concatenating the receipts log and run it through the bloom filter (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L200 & https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/types/bloom9.go#L11)
- Validate the transaction hash (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L206)
- Validate the receipt hash (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L212)
- Accumulate the reward for the miner (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L219)
- Validate the uncle's parent (must be in chain) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L312)
- Validate the uncle's block number (not greater than 6) (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L317)
- Validate the uncle's not includes multiple times (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L321)
- Reward miner (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L339)
- Update the state with all changes and validate the merkle root (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L223)
- Calculate the total difficulty of the block (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L231)
- Sync the state to the db (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L233)
- Return the total difficulty if the process was a success (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/block_manager.go#L242)
- Block validation and processing all happens with the
- Write block to the database (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/chain_manager.go#L242)
- Compare the total difficulty of the process block to our current known TD (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/chain_manager.go#L244) if greater than:
- Set new TD (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/chain_manager.go#L288)
- Insert in to the canonical chain by setting it as current block (https://github.com/ethereumproject/go-ethereum/blob/docbranch/core/chain_manager.go#L211)
❤️ Stay Classy