forked from ethereum/go-ethereum
-
Notifications
You must be signed in to change notification settings - Fork 7
Block processing
obscuren edited this page Jan 3, 2015
·
4 revisions
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/ethereum/go-ethereum/blob/docbranch/core/chain_manager.go)
- Block(s) are inserted using
InsertChain(...)(https://github.com/ethereum/go-ethereum/blob/docbranch/core/chain_manager.go#L324) - Each block is then processed by the
Processorwhich in our case is always theBlockManagerhttps://github.com/ethereum/go-ethereum/blob/docbranch/core/chain_manager.go#L326- Block validation and processing all happens with the
BlockManagerhttps://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go - Checked if the block already's in storage (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L171)
- Check if we have the parent (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L175)
- Validate the easy, less intensive tasks first (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L189)
- Calculate the difficulty and compare it to the parent's difficulty (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L272)
- Verify the proof of work (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L290)
- Transition the state (e.g., apply transactions) (https://github.com/ethereum/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/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L87)
- Attempt to transition the state using the current message (transaction) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L116)
- All transactional state changes happen within the
StateTransitionobject and start at theTransitionStatemethod (https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L150) - Check the tx nonce:
tx.nonce == account.nonce(https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L138) - Check if we can buy the gas of the coin base (https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L110)
- Use TxGas (500) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L169)
- Create a contract if len(address) == 0 (https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L189)
- Run init code (see
Create VmEnv) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L190) - Charge additional gas for creation bytes (i.e.,
len(ret) * createByteGas) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L193) - Set the return data as contract code (https://github.com/ethereum/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/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L200)
- Use the
VmEnvand call eitherCreateorRun(depending on the address). TheVmEnvwill instantiate a newExecutionhandler which will take care of starting the virtual machine. TheVmEnvwill 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/ethereum/go-ethereum/blob/docbranch/core/vm_env.go#L46) - Create
VmEnvand use that as the Virtual machine's environment for creating or executing now contracts (https://github.com/ethereum/go-ethereum/blob/docbranch/core/vm_env.go) - Create
Executionobject which takes care of the actual Vm instantiation (https://github.com/ethereum/go-ethereum/blob/docbranch/core/execution.go#L35)- Get the recipient and sender (https://github.com/ethereum/go-ethereum/blob/docbranch/core/execution.go#L39)
- Transfer value (err is set incase of insufficient funds) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/execution.go#L42)
- Snapshot the state for rollback feature (https://github.com/ethereum/go-ethereum/blob/docbranch/core/execution.go#L51)
-
deferchecking for depth and oog errors so that we may rollback to the previous snapshot (https://github.com/ethereum/go-ethereum/blob/docbranch/core/execution.go#L52) - Check for precompiled contract (https://github.com/ethereum/go-ethereum/blob/docbranch/core/execution.go#L61) see (https://github.com/ethereum/go-ethereum/blob/docbranch/vm/address.go#L23) for all pre compiled contracts.
- Execute code given (https://github.com/ethereum/go-ethereum/blob/docbranch/core/execution.go#L69)
- Enter VM run loop (https://github.com/ethereum/go-ethereum/blob/docbranch/vm/vm_debug.go#L39)
- Create a new closure which holds the code, gas and information about the caller (https://github.com/ethereum/go-ethereum/blob/docbranch/vm/vm_debug.go#L49)
- Analyse valid jump positions (https://github.com/ethereum/go-ethereum/blob/docbranch/vm/vm_debug.go#L75)
- it's worth noting that
jump(https://github.com/ethereum/go-ethereum/blob/docbranch/vm/vm_debug.go#L88) uses the jump positions in order to determine whether theJUMPlanded on a valid 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) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/state_transition.go#L178)
- Update the state changes made during the state transition (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L140)
- Create a new receipt for validity checks at the end of the transaction processing (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L143)
- Validate the receipts by creating a new bloom filter out of it and compare it against the received block's bloom (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L204)
- Validate the transaction hash (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L210)
- Validate the receipt hash (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L216)
- Accumulate the reward for the miner (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L222)
- Validate the uncle's parent (must be in chain) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L311)
- Validate the uncle's block number (not greater than 6) (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L316)
- Validate the uncle's not includes multiple times (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L320)
- Reward miner (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L338)
- Update the state with all changes and validate the merkle root (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L228)
- Calculate the total difficulty of the block (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L234)
- Sync the state to the db (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L236)
- Return the total difficulty if the process was a success (https://github.com/ethereum/go-ethereum/blob/docbranch/core/block_manager.go#L245)
- Block validation and processing all happens with the
- Write block to the database (https://github.com/ethereum/go-ethereum/blob/docbranch/core/chain_manager.go#L292)
- Compare the total difficulty of the process block to our current known TD (https://github.com/ethereum/go-ethereum/blob/docbranch/core/chain_manager.go#L293) if greater than:
- Set new TD (https://github.com/ethereum/go-ethereum/blob/docbranch/core/chain_manager.go#L298)
- Insert in to the canonical chain by setting it as current block (https://github.com/ethereum/go-ethereum/blob/docbranch/core/chain_manager.go#L292)