mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
Merge 86d05d84aa into b3b110bc95
This commit is contained in:
commit
5a97b89600
5 changed files with 45 additions and 12 deletions
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ type ProtocolManager struct {
|
||||||
|
|
||||||
fastSync bool
|
fastSync bool
|
||||||
txpool txPool
|
txpool txPool
|
||||||
blockchain *core.BlockChain
|
blockchain blockChain
|
||||||
chaindb ethdb.Database
|
chaindb ethdb.Database
|
||||||
|
|
||||||
downloader *downloader.Downloader
|
downloader *downloader.Downloader
|
||||||
|
|
@ -86,7 +86,7 @@ type ProtocolManager struct {
|
||||||
|
|
||||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
// with the ethereum network.
|
// with the ethereum network.
|
||||||
func NewProtocolManager(fastSync bool, networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
func NewProtocolManager(fastSync bool, networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain blockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
||||||
// Figure out whether to allow fast sync or not
|
// Figure out whether to allow fast sync or not
|
||||||
if fastSync && blockchain.CurrentBlock().NumberU64() > 0 {
|
if fastSync && blockchain.CurrentBlock().NumberU64() > 0 {
|
||||||
glog.V(logger.Info).Infof("blockchain not empty, fast sync disabled")
|
glog.V(logger.Info).Infof("blockchain not empty, fast sync disabled")
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,30 @@ type chainManager interface {
|
||||||
Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash)
|
Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// proxy interface to core.BlockChain
|
||||||
|
type blockChain interface {
|
||||||
|
Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash)
|
||||||
|
Genesis() *types.Block
|
||||||
|
CurrentHeader() *types.Header
|
||||||
|
CurrentBlock() *types.Block
|
||||||
|
CurrentFastBlock() *types.Block
|
||||||
|
HasHeader(hash common.Hash) bool
|
||||||
|
HasBlock(hash common.Hash) bool
|
||||||
|
HasBlockAndState(hash common.Hash) bool
|
||||||
|
GetHeader(hash common.Hash) *types.Header
|
||||||
|
GetHeaderByNumber(number uint64) *types.Header
|
||||||
|
GetBlock(hash common.Hash) *types.Block
|
||||||
|
GetBlockByNumber(number uint64) *types.Block
|
||||||
|
GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash
|
||||||
|
GetBodyRLP(hash common.Hash) rlp.RawValue
|
||||||
|
FastSyncCommitHead(hash common.Hash) error
|
||||||
|
GetTd(hash common.Hash) *big.Int
|
||||||
|
InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error)
|
||||||
|
InsertChain(chain types.Blocks) (int, error)
|
||||||
|
InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error)
|
||||||
|
Rollback(chain []common.Hash)
|
||||||
|
}
|
||||||
|
|
||||||
// statusData is the network packet for the status message.
|
// statusData is the network packet for the status message.
|
||||||
type statusData struct {
|
type statusData struct {
|
||||||
ProtocolVersion uint32
|
ProtocolVersion uint32
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue