core, eth, rpc: split out block validator and state processor
This removes the burden on a single object to take care of all validation and state processing. Now instead the validation is done by the `core.BlockValidator` (`types.Validator`) that takes care of both header and uncle validation through the `ValidateBlock` method and state validation through the `ValidateState` method. The state processing is done by a new object `core.StateProcessor` (`types.Processor`) and accepts a new state as input and uses that to process the given block's transactions (and uncles for rewords) to calculate the state root for the next block (P_n + 1).
This commit is contained in:
@ -100,7 +100,7 @@ type worker struct {
|
||||
|
||||
eth core.Backend
|
||||
chain *core.BlockChain
|
||||
proc *core.BlockProcessor
|
||||
proc core.Validator
|
||||
chainDb ethdb.Database
|
||||
|
||||
coinbase common.Address
|
||||
@ -131,7 +131,7 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
|
||||
recv: make(chan *Result, resultQueueSize),
|
||||
gasPrice: new(big.Int),
|
||||
chain: eth.BlockChain(),
|
||||
proc: eth.BlockProcessor(),
|
||||
proc: eth.BlockChain().Validator(),
|
||||
possibleUncles: make(map[common.Hash]*types.Block),
|
||||
coinbase: coinbase,
|
||||
txQueue: make(map[common.Hash]*types.Transaction),
|
||||
@ -244,7 +244,7 @@ func (self *worker) update() {
|
||||
// Apply transaction to the pending state if we're not mining
|
||||
if atomic.LoadInt32(&self.mining) == 0 {
|
||||
self.currentMu.Lock()
|
||||
self.current.commitTransactions(types.Transactions{ev.Tx}, self.gasPrice, self.proc)
|
||||
self.current.commitTransactions(types.Transactions{ev.Tx}, self.gasPrice, self.chain)
|
||||
self.currentMu.Unlock()
|
||||
}
|
||||
}
|
||||
@ -290,7 +290,9 @@ func (self *worker) wait() {
|
||||
glog.V(logger.Error).Infoln("Invalid block found during mining")
|
||||
continue
|
||||
}
|
||||
if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent.Header(), true, false); err != nil && err != core.BlockFutureErr {
|
||||
|
||||
auxValidator := self.eth.BlockChain().AuxValidator()
|
||||
if err := core.ValidateHeader(auxValidator, block.Header(), parent.Header(), true, false); err != nil && err != core.BlockFutureErr {
|
||||
glog.V(logger.Error).Infoln("Invalid header on mined block:", err)
|
||||
continue
|
||||
}
|
||||
@ -516,7 +518,7 @@ func (self *worker) commitNewWork() {
|
||||
transactions := append(singleTxOwner, multiTxOwner...)
|
||||
*/
|
||||
|
||||
work.commitTransactions(transactions, self.gasPrice, self.proc)
|
||||
work.commitTransactions(transactions, self.gasPrice, self.chain)
|
||||
self.eth.TxPool().RemoveTransactions(work.lowGasTxs)
|
||||
|
||||
// compute uncles for the new block.
|
||||
@ -575,9 +577,8 @@ func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (env *Work) commitTransactions(transactions types.Transactions, gasPrice *big.Int, proc *core.BlockProcessor) {
|
||||
func (env *Work) commitTransactions(transactions types.Transactions, gasPrice *big.Int, bc *core.BlockChain) {
|
||||
gp := new(core.GasPool).AddGas(env.header.GasLimit)
|
||||
|
||||
for _, tx := range transactions {
|
||||
// We can skip err. It has already been validated in the tx pool
|
||||
from, _ := tx.From()
|
||||
@ -615,7 +616,7 @@ func (env *Work) commitTransactions(transactions types.Transactions, gasPrice *b
|
||||
|
||||
env.state.StartRecord(tx.Hash(), common.Hash{}, 0)
|
||||
|
||||
err := env.commitTransaction(tx, proc, gp)
|
||||
err := env.commitTransaction(tx, bc, gp)
|
||||
switch {
|
||||
case core.IsGasLimitErr(err):
|
||||
// ignore the transactor so no nonce errors will be thrown for this account
|
||||
@ -635,9 +636,9 @@ func (env *Work) commitTransactions(transactions types.Transactions, gasPrice *b
|
||||
}
|
||||
}
|
||||
|
||||
func (env *Work) commitTransaction(tx *types.Transaction, proc *core.BlockProcessor, gp *core.GasPool) error {
|
||||
func (env *Work) commitTransaction(tx *types.Transaction, bc *core.BlockChain, gp *core.GasPool) error {
|
||||
snap := env.state.Copy()
|
||||
receipt, _, err := proc.ApplyTransaction(gp, env.state, env.header, tx, env.header.GasUsed, true)
|
||||
receipt, _, _, err := core.ApplyTransaction(bc, gp, env.state, env.header, tx, env.header.GasUsed)
|
||||
if err != nil {
|
||||
env.state.Set(snap)
|
||||
return err
|
||||
|
Reference in New Issue
Block a user