Converted direct reference to the BlockChain to an interface in vm env, state processor and block validator.

This commit is contained in:
Matthieu Riou 2016-03-14 21:33:18 -07:00
parent dc98fecbec
commit 86d05d84aa
3 changed files with 19 additions and 10 deletions

View file

@ -84,7 +84,8 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
return err return err
} }
// verify the uncles are correctly rewarded // verify the uncles are correctly rewarded
if err := v.VerifyUncles(block, parent); err != nil { ancestors := v.bc.GetBlocksFromHash(block.ParentHash(), 7)
if err := VerifyUncles(v.Pow, block, parent, ancestors); err != nil {
return err return err
} }
@ -109,6 +110,10 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
// itself. ValidateState returns a database batch if the validation was a success // itself. ValidateState returns a database batch if the validation was a success
// otherwise nil and an error is returned. // otherwise nil and an error is returned.
func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas *big.Int) (err error) { func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas *big.Int) (err error) {
return ValidateState(block, parent, statedb, receipts, usedGas)
}
func ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas *big.Int) (err error) {
header := block.Header() header := block.Header()
if block.GasUsed().Cmp(usedGas) != 0 { if block.GasUsed().Cmp(usedGas) != 0 {
return ValidationError(fmt.Sprintf("gas used error (%v / %v)", block.GasUsed(), usedGas)) return ValidationError(fmt.Sprintf("gas used error (%v / %v)", block.GasUsed(), usedGas))
@ -136,7 +141,7 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
// consensus rules to the various block headers included; it will return an // consensus rules to the various block headers included; it will return an
// error if any of the included uncle headers were invalid. It returns an error // error if any of the included uncle headers were invalid. It returns an error
// if the validation failed. // if the validation failed.
func (v *BlockValidator) VerifyUncles(block, parent *types.Block) error { func VerifyUncles(pow pow.PoW, block, parent *types.Block, ancestorList []*types.Block) error {
// validate that there at most 2 uncles included in this block // validate that there at most 2 uncles included in this block
if len(block.Uncles()) > 2 { if len(block.Uncles()) > 2 {
return ValidationError("Block can only contain maximum 2 uncles (contained %v)", len(block.Uncles())) return ValidationError("Block can only contain maximum 2 uncles (contained %v)", len(block.Uncles()))
@ -144,7 +149,7 @@ func (v *BlockValidator) VerifyUncles(block, parent *types.Block) error {
uncles := set.New() uncles := set.New()
ancestors := make(map[common.Hash]*types.Block) ancestors := make(map[common.Hash]*types.Block)
for _, ancestor := range v.bc.GetBlocksFromHash(block.ParentHash(), 7) { for _, ancestor := range ancestorList {
ancestors[ancestor.Hash()] = ancestor ancestors[ancestor.Hash()] = ancestor
// Include ancestors uncles in the uncle set. Uncles must be unique. // Include ancestors uncles in the uncle set. Uncles must be unique.
for _, uncle := range ancestor.Uncles() { for _, uncle := range ancestor.Uncles() {
@ -175,7 +180,7 @@ func (v *BlockValidator) VerifyUncles(block, parent *types.Block) error {
return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4]) return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4])
} }
if err := ValidateHeader(v.Pow, uncle, ancestors[uncle.ParentHash].Header(), true, true); err != nil { if err := ValidateHeader(pow, uncle, ancestors[uncle.ParentHash].Header(), true, true); err != nil {
return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err)) return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err))
} }
} }

View file

@ -17,10 +17,10 @@ var (
) )
type StateProcessor struct { type StateProcessor struct {
bc *BlockChain bc blockGetter
} }
func NewStateProcessor(bc *BlockChain) *StateProcessor { func NewStateProcessor(bc blockGetter) *StateProcessor {
return &StateProcessor{bc} return &StateProcessor{bc}
} }
@ -60,7 +60,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB) (ty
// //
// ApplyTransactions returns the generated receipts and vm logs during the // ApplyTransactions returns the generated receipts and vm logs during the
// execution of the state transition phase. // execution of the state transition phase.
func ApplyTransaction(bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int) (*types.Receipt, vm.Logs, *big.Int, error) { func ApplyTransaction(bc blockGetter, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int) (*types.Receipt, vm.Logs, *big.Int, error) {
_, gas, err := ApplyMessage(NewEnv(statedb, bc, tx, header), tx, gp) _, gas, err := ApplyMessage(NewEnv(statedb, bc, tx, header), tx, gp)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err

View file

@ -25,10 +25,14 @@ import (
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
) )
type blockGetter interface {
GetBlock(common.Hash) *types.Block
}
// GetHashFn returns a function for which the VM env can query block hashes through // GetHashFn returns a function for which the VM env can query block hashes through
// up to the limit defined by the Yellow Paper and uses the given block chain // up to the limit defined by the Yellow Paper and uses the given block chain
// to query for information. // to query for information.
func GetHashFn(ref common.Hash, chain *BlockChain) func(n uint64) common.Hash { func GetHashFn(ref common.Hash, chain blockGetter) func(n uint64) common.Hash {
return func(n uint64) common.Hash { return func(n uint64) common.Hash {
for block := chain.GetBlock(ref); block != nil; block = chain.GetBlock(block.ParentHash()) { for block := chain.GetBlock(ref); block != nil; block = chain.GetBlock(block.ParentHash()) {
if block.NumberU64() == n { if block.NumberU64() == n {
@ -45,7 +49,7 @@ type VMEnv struct {
header *types.Header header *types.Header
msg Message msg Message
depth int depth int
chain *BlockChain chain blockGetter
typ vm.Type typ vm.Type
getHashFn func(uint64) common.Hash getHashFn func(uint64) common.Hash
@ -53,7 +57,7 @@ type VMEnv struct {
logs []vm.StructLog logs []vm.StructLog
} }
func NewEnv(state *state.StateDB, chain *BlockChain, msg Message, header *types.Header) *VMEnv { func NewEnv(state *state.StateDB, chain blockGetter, msg Message, header *types.Header) *VMEnv {
return &VMEnv{ return &VMEnv{
chain: chain, chain: chain,
state: state, state: state,