|
|
|
package consensus
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
|
|
|
"github.com/ethereum/go-ethereum/params"
|
|
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
|
|
"github.com/harmony-one/harmony/core/state"
|
|
|
|
"github.com/harmony-one/harmony/core/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Bft struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewFaker() *Bft {
|
|
|
|
return &Bft{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Author implements Engine, returning the header's coinbase as the
|
|
|
|
// proof-of-work verified author of the block.
|
|
|
|
func (bft *Bft) Author(header *types.Header) (common.Address, error) {
|
|
|
|
return header.Coinbase, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// VerifyHeader checks whether a header conforms to the consensus rules of the
|
|
|
|
// stock Ethereum bft engine.
|
|
|
|
func (bft *Bft) VerifyHeader(chain ChainReader, header *types.Header, seal bool) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
|
|
|
|
// concurrently. The method returns a quit channel to abort the operations and
|
|
|
|
// a results channel to retrieve the async verifications.
|
|
|
|
func (bft *Bft) VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
|
|
|
|
abort, results := make(chan struct{}), make(chan error, len(headers))
|
|
|
|
for i := 0; i < len(headers); i++ {
|
|
|
|
results <- nil
|
|
|
|
}
|
|
|
|
return abort, results
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bft *Bft) verifyHeaderWorker(chain ChainReader, headers []*types.Header, seals []bool, index int) error {
|
|
|
|
var parent *types.Header
|
|
|
|
if index == 0 {
|
|
|
|
parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
|
|
|
|
} else if headers[index-1].Hash() == headers[index].ParentHash {
|
|
|
|
parent = headers[index-1]
|
|
|
|
}
|
|
|
|
if parent == nil {
|
|
|
|
return ErrUnknownAncestor
|
|
|
|
}
|
|
|
|
if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
|
|
|
|
return nil // known block
|
|
|
|
}
|
|
|
|
return bft.verifyHeader(chain, headers[index], parent, false, seals[index])
|
|
|
|
}
|
|
|
|
|
|
|
|
// verifyHeader checks whether a header conforms to the consensus rules of the
|
|
|
|
// stock Ethereum bft engine.
|
|
|
|
// See YP section 4.3.4. "Block Header Validity"
|
|
|
|
func (bft *Bft) verifyHeader(chain ChainReader, header, parent *types.Header, uncle bool, seal bool) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// VerifySeal implements consensus.Engine, checking whether the given block satisfies
|
|
|
|
// the PoW difficulty requirements.
|
|
|
|
func (bft *Bft) VerifySeal(chain ChainReader, header *types.Header) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prepare implements consensus.Engine, initializing the difficulty field of a
|
|
|
|
// header to conform to the ethash protocol. The changes are done inline.
|
|
|
|
func (bft *Bft) Prepare(chain ChainReader, header *types.Header) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
|
|
|
|
// setting the final state and assembling the block.
|
|
|
|
func (bft *Bft) Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, receipts []*types.Receipt) (*types.Block, error) {
|
|
|
|
// Accumulate any block and uncle rewards and commit the final state root
|
|
|
|
// Header seems complete, assemble into a block and return
|
|
|
|
accumulateRewards(chain.Config(), state, header)
|
|
|
|
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
|
|
|
return types.NewBlock(header, txs, receipts), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// SealHash returns the hash of a block prior to it being sealed.
|
|
|
|
func (bft *Bft) SealHash(header *types.Header) (hash common.Hash) {
|
|
|
|
hasher := sha3.NewKeccak256()
|
|
|
|
|
|
|
|
rlp.Encode(hasher, []interface{}{
|
|
|
|
header.ParentHash,
|
|
|
|
header.UncleHash,
|
|
|
|
header.Coinbase,
|
|
|
|
header.Root,
|
|
|
|
header.TxHash,
|
|
|
|
header.ReceiptHash,
|
|
|
|
header.Bloom,
|
|
|
|
header.Difficulty,
|
|
|
|
header.Number,
|
|
|
|
header.GasLimit,
|
|
|
|
header.GasUsed,
|
|
|
|
header.Time,
|
|
|
|
header.Extra,
|
|
|
|
})
|
|
|
|
hasher.Sum(hash[:0])
|
|
|
|
return hash
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bft *Bft) Seal(chain ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// AccumulateRewards credits the coinbase of the given block with the mining
|
|
|
|
// reward. The total reward consists of the static block reward and rewards for
|
|
|
|
// included uncles. The coinbase of each uncle block is also rewarded.
|
|
|
|
func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header) {
|
|
|
|
|
|
|
|
}
|