Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion consensus/clique/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
// API is a user facing RPC API to allow controlling the signer and voting
// mechanisms of the proof-of-authority scheme.
type API struct {
chain consensus.ChainReader
chain consensus.ChainHeaderReader
clique *Clique
}

Expand Down
34 changes: 21 additions & 13 deletions consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ func (c *Clique) Author(header *types.Header) (common.Address, error) {
}

// VerifyHeader checks whether a header conforms to the consensus rules.
func (c *Clique) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
func (c *Clique) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error {
return c.verifyHeader(chain, header, nil)
}

// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
// method returns a quit channel to abort the operations and a results channel to
// retrieve the async verifications (the order is that of the input slice).
func (c *Clique) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
func (c *Clique) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
abort := make(chan struct{})
results := make(chan error, len(headers))

Expand All @@ -278,7 +278,7 @@ func (c *Clique) VerifyHeaders(chain consensus.ChainReader, headers []*types.Hea
// caller may optionally pass in a batch of parents (ascending order) to avoid
// looking those up from the database. This is useful for concurrently verifying
// a batch of new headers.
func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
if header.Number == nil {
return errUnknownBlock
}
Expand Down Expand Up @@ -341,7 +341,7 @@ func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header,
// rather depend on a batch of previous headers. The caller may optionally pass
// in a batch of parents (ascending order) to avoid looking those up from the
// database. This is useful for concurrently verifying a batch of new headers.
func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
// The genesis block is the always valid dead-end
number := header.Number.Uint64()
if number == 0 {
Expand Down Expand Up @@ -381,7 +381,7 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *type
}

// snapshot retrieves the authorization snapshot at a given point in time.
func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
func (c *Clique) snapshot(chain consensus.ChainHeaderReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
// Search for a snapshot in memory or on disk for checkpoints
var (
headers []*types.Header
Expand Down Expand Up @@ -469,15 +469,15 @@ func (c *Clique) VerifyUncles(chain consensus.ChainReader, block *types.Block) e

// VerifySeal implements consensus.Engine, checking whether the signature contained
// in the header satisfies the consensus protocol requirements.
func (c *Clique) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
func (c *Clique) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error {
return c.verifySeal(chain, header, nil)
}

// verifySeal checks whether the signature contained in the header satisfies the
// consensus protocol requirements. The method accepts an optional list of parent
// headers that aren't yet part of the local blockchain to generate the snapshots
// from.
func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
func (c *Clique) verifySeal(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
// Verifying the genesis block is not supported
number := header.Number.Uint64()
if number == 0 {
Expand Down Expand Up @@ -520,7 +520,7 @@ func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, p

// Prepare implements consensus.Engine, preparing all the consensus fields of the
// header for running the transactions on top.
func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) error {
func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
// If the block isn't a checkpoint, cast a random vote (good enough for now)
header.Coinbase = common.Address{}
header.Nonce = types.BlockNonce{}
Expand Down Expand Up @@ -584,11 +584,19 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
}

// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given, and returns the final block.
func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// rewards given.
func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) error {
// No block rewards in PoA, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil)
return nil
}

// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
// nor block rewards given, and returns the final block.
func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// Finalize block
c.Finalize(chain, header, state, txs, uncles)

// Assemble and return the final block for sealing
return types.NewBlock(header, txs, nil, receipts, new(trie.Trie)), nil
Expand Down Expand Up @@ -617,7 +625,7 @@ func (c *Clique) Authorize(signer common.Address, signFn SignerFn) {

// Seal implements consensus.Engine, attempting to create a sealed block using
// the local signing credentials.
func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
header := block.Header()

// Sealing the genesis block is not supported
Expand Down Expand Up @@ -690,7 +698,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results c
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
// that a new block should have based on the previous blocks in the chain and the
// current signer.
func (c *Clique) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
func (c *Clique) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil)
if err != nil {
return nil
Expand Down Expand Up @@ -748,7 +756,7 @@ func (c *Clique) Close() error {

// APIs implements consensus.Engine, returning the user facing RPC API to allow
// controlling the signer voting.
func (c *Clique) APIs(chain consensus.ChainReader) []rpc.API {
func (c *Clique) APIs(chain consensus.ChainHeaderReader) []rpc.API {
return []rpc.API{{
Namespace: "clique",
Version: "1.0",
Expand Down
26 changes: 16 additions & 10 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

// ChainReader defines a small collection of methods needed to access the local
// blockchain during header and/or uncle verification.
type ChainReader interface {
type ChainHeaderReader interface {
// Config retrieves the blockchain's chain configuration.
Config() *params.ChainConfig

Expand All @@ -44,6 +44,12 @@ type ChainReader interface {

// GetHeaderByHash retrieves a block header from the database by its hash.
GetHeaderByHash(hash common.Hash) *types.Header
}

// ChainReader defines a small collection of methods needed to access the local
// blockchain during header and/or uncle verification.
type ChainReader interface {
ChainHeaderReader

// GetBlock retrieves a block from the database by hash and number.
GetBlock(hash common.Hash, number uint64) *types.Block
Expand All @@ -59,32 +65,32 @@ type Engine interface {
// VerifyHeader checks whether a header conforms to the consensus rules of a
// given engine. Verifying the seal may be done optionally here, or explicitly
// via the VerifySeal method.
VerifyHeader(chain ChainReader, header *types.Header, seal bool) error
VerifyHeader(chain ChainHeaderReader, header *types.Header, seal bool) error

// 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 (the order is that of
// the input slice).
VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error)
VerifyHeaders(chain ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error)

// VerifyUncles verifies that the given block's uncles conform to the consensus
// rules of a given engine.
VerifyUncles(chain ChainReader, block *types.Block) error

// VerifySeal checks whether the crypto seal on a header is valid according to
// the consensus rules of the given engine.
VerifySeal(chain ChainReader, header *types.Header) error
VerifySeal(chain ChainHeaderReader, header *types.Header) error

// Prepare initializes the consensus fields of a block header according to the
// rules of a particular engine. The changes are executed inline.
Prepare(chain ChainReader, header *types.Header) error
Prepare(chain ChainHeaderReader, header *types.Header) error

Finalize(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) error
// Finalize runs any post-transaction state modifications (e.g. block rewards)
// and assembles the final block.
// Note: The block header and state database might be updated to reflect any
// consensus rules that happen at finalization (e.g. block rewards).
Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)
FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)

FinalizeWithoutParent(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)
Expand All @@ -93,17 +99,17 @@ type Engine interface {
//
// Note, the method returns immediately and will send the result async. More
// than one result may also be returned depending on the consensus algorithm.
Seal(chain ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error
Seal(chain ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error

// SealHash returns the hash of a block prior to it being sealed.
SealHash(header *types.Header) common.Hash

// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
// that a new block should have.
CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int
CalcDifficulty(chain ChainHeaderReader, time uint64, parent *types.Header) *big.Int

// APIs returns the RPC APIs this consensus engine provides.
APIs(chain ChainReader) []rpc.API
APIs(chain ChainHeaderReader) []rpc.API

// Close terminates any background threads maintained by the consensus engine.
Close() error
Expand Down
35 changes: 23 additions & 12 deletions consensus/cuckoo/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (cuckoo *Cuckoo) Author(header *types.Header) (common.Address, error) {

// VerifyHeader checks whether a header conforms to the consensus rules of the
// stock Cortex cuckoo engine.
func (cuckoo *Cuckoo) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
func (cuckoo *Cuckoo) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error {
// If we're running a full engine faking, accept any input as valid
if cuckoo.config.PowMode == ModeFullFake {
return nil
Expand All @@ -113,7 +113,7 @@ func (cuckoo *Cuckoo) VerifyHeader(chain consensus.ChainReader, header *types.He
// 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 (cuckoo *Cuckoo) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
func (cuckoo *Cuckoo) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
// If we're running a full engine faking, accept any input as valid
if cuckoo.config.PowMode == ModeFullFake || len(headers) == 0 {
abort, results := make(chan struct{}), make(chan error, len(headers))
Expand Down Expand Up @@ -175,7 +175,7 @@ func (cuckoo *Cuckoo) VerifyHeaders(chain consensus.ChainReader, headers []*type
return abort, errorsOut
}

func (cuckoo *Cuckoo) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error {
func (cuckoo *Cuckoo) verifyHeaderWorker(chain consensus.ChainHeaderReader, 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)
Expand Down Expand Up @@ -250,7 +250,7 @@ func (cuckoo *Cuckoo) VerifyUncles(chain consensus.ChainReader, block *types.Blo
// verifyHeader checks whether a header conforms to the consensus rules of the
// stock Cortex cuckoo engine.
// See YP section 4.3.4. "Block Header Validity"
func (cuckoo *Cuckoo) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle, seal bool) error {
func (cuckoo *Cuckoo) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header, uncle, seal bool) error {
// Ensure that the header's extra-data section is of a reasonable size
if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
Expand Down Expand Up @@ -345,7 +345,7 @@ func (cuckoo *Cuckoo) verifyHeader(chain consensus.ChainReader, header, parent *
// CalcDifficulty is the difficulty adjustment algorithm. It returns
// the difficulty that a new block should have when created at time
// given the parent block's time and difficulty.
func (cuckoo *Cuckoo) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
func (cuckoo *Cuckoo) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
return CalcDifficulty(chain.Config(), time, parent)
}

Expand Down Expand Up @@ -648,7 +648,7 @@ func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int {
// VerifySeal implements consensus.Engine, checking whether the given block satisfies
// the PoW difficulty requirements.

func (cuckoo *Cuckoo) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
func (cuckoo *Cuckoo) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error {
// If we're running a fake PoW, accept any seal as valid
if cuckoo.config.PowMode == ModeFake || cuckoo.config.PowMode == ModeFullFake {
time.Sleep(cuckoo.fakeDelay)
Expand Down Expand Up @@ -687,7 +687,7 @@ func (cuckoo *Cuckoo) VerifySeal(chain consensus.ChainReader, header *types.Head

// Prepare implements consensus.Engine, initializing the difficulty field of a
// header to conform to the cuckoo protocol. The changes are done inline.
func (cuckoo *Cuckoo) Prepare(chain consensus.ChainReader, header *types.Header) error {
func (cuckoo *Cuckoo) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
if parent == nil {
return consensus.ErrUnknownAncestor
Expand All @@ -703,17 +703,28 @@ func (cuckoo *Cuckoo) Prepare(chain consensus.ChainReader, header *types.Header)
}

// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
// setting the final state and assembling the block.
func (cuckoo *Cuckoo) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
//log.Info(fmt.Sprintf("parent: %v, current: %v, number: %v, total: %v, epoch: %v", header.ParentHash, header.Supply, header.Number, params.CTXC_TOP, params.CortexBlockRewardPeriod))
// setting the final state on the header
func (cuckoo *Cuckoo) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) error {
// Always need parent to caculate the reward of current block
parent := chain.GetHeaderByHash(header.ParentHash)
if parent == nil {
return nil, consensus.ErrUnknownAncestor
return consensus.ErrUnknownAncestor
}
//log.Info(fmt.Sprintf("parent: %v, current: %v, number: %v, total: %v, epoch: %v", parent.Number, header.Hash(), header.Number, params.CTXC_TOP, params.CortexBlockRewardPeriod))
// Accumulate any block and uncle rewards and commit the final state root
accumulateRewards(chain.Config(), state, header, parent, uncles)
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
return nil
}

// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
// setting the final state and assembling the block.
func (cuckoo *Cuckoo) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
//log.Info(fmt.Sprintf("parent: %v, current: %v, number: %v, total: %v, epoch: %v", parent.Number, header.Hash(), header.Number, params.CTXC_TOP, params.CortexBlockRewardPeriod))
// Accumulate any block and uncle rewards and commit the final state root
err := cuckoo.Finalize(chain, header, state, txs, uncles)
if err != nil {
return nil, err
}

// Header seems complete, assemble into a block and return
return types.NewBlock(header, txs, uncles, receipts, new(trie.Trie)), nil
Expand Down
2 changes: 1 addition & 1 deletion consensus/cuckoo/cuckoo.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func (cuckoo *Cuckoo) Hashrate() float64 {
return cuckoo.hashrate.Rate1()
}

func (cuckoo *Cuckoo) APIs(chain consensus.ChainReader) []rpc.API {
func (cuckoo *Cuckoo) APIs(chain consensus.ChainHeaderReader) []rpc.API {
// In order to ensure backward compatibility, we exposes cuckoo RPC APIs
// to both ctxc and cuckoo namespaces.
return []rpc.API{
Expand Down
Loading