diff options
author | gary rong <garyrong0905@gmail.com> | 2017-12-22 20:37:50 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2017-12-22 20:37:50 +0800 |
commit | 5f8888e11606296c9582496974c0f6b96a882146 (patch) | |
tree | ef8139ff20ae33eb5a236290d5107dd808e34340 /consensus | |
parent | 9dbb8ef4aadb8e40aef8b681cf86acd20789abdc (diff) | |
download | dexon-5f8888e11606296c9582496974c0f6b96a882146.tar dexon-5f8888e11606296c9582496974c0f6b96a882146.tar.gz dexon-5f8888e11606296c9582496974c0f6b96a882146.tar.bz2 dexon-5f8888e11606296c9582496974c0f6b96a882146.tar.lz dexon-5f8888e11606296c9582496974c0f6b96a882146.tar.xz dexon-5f8888e11606296c9582496974c0f6b96a882146.tar.zst dexon-5f8888e11606296c9582496974c0f6b96a882146.zip |
accounts, consensus, core, eth: make chain maker consensus agnostic (#15497)
* accounts, consensus, core, eth: make chain maker consensus agnostic
* consensus, core: move CalcDifficulty to Engine interface
* consensus: add docs for calcDifficulty function
* consensus, core: minor comment fixups
Diffstat (limited to 'consensus')
-rw-r--r-- | consensus/clique/clique.go | 28 | ||||
-rw-r--r-- | consensus/consensus.go | 5 | ||||
-rw-r--r-- | consensus/ethash/consensus.go | 19 | ||||
-rw-r--r-- | consensus/ethash/consensus_test.go | 1 |
4 files changed, 41 insertions, 12 deletions
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index a98058141..2bdad9092 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -510,7 +510,6 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro header.Nonce = types.BlockNonce{} number := header.Number.Uint64() - // Assemble the voting snapshot to check which votes make sense snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) if err != nil { @@ -538,10 +537,8 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro c.lock.RUnlock() } // Set the correct difficulty - header.Difficulty = diffNoTurn - if snap.inturn(header.Number.Uint64(), c.signer) { - header.Difficulty = diffInTurn - } + header.Difficulty = CalcDifficulty(snap, c.signer) + // Ensure the extra data has all it's components if len(header.Extra) < extraVanity { header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) @@ -655,6 +652,27 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch return block.WithSeal(header), nil } +// 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 { + snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil) + if err != nil { + return nil + } + return CalcDifficulty(snap, c.signer) +} + +// 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 CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int { + if snap.inturn(snap.Number+1, signer) { + return new(big.Int).Set(diffInTurn) + } + return new(big.Int).Set(diffNoTurn) +} + // 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 { diff --git a/consensus/consensus.go b/consensus/consensus.go index 865238cee..be5e661c1 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "math/big" ) // ChainReader defines a small collection of methods needed to access the local @@ -88,6 +89,10 @@ type Engine interface { // seal place on top. Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) + // 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 + // APIs returns the RPC APIs this consensus engine provides. APIs(chain ChainReader) []rpc.API } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 2bdb18677..5fe67c851 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -240,7 +240,8 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent * return errZeroBlockTime } // Verify the block's difficulty based in it's timestamp and parent's difficulty - expected := CalcDifficulty(chain.Config(), header.Time.Uint64(), parent) + expected := ethash.CalcDifficulty(chain, header.Time.Uint64(), parent) + if expected.Cmp(header.Difficulty) != 0 { return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected) } @@ -287,7 +288,13 @@ func (ethash *Ethash) 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. -// TODO (karalabe): Move the chain maker into this package and make this private! +func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { + return CalcDifficulty(chain.Config(), time, 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 CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int { next := new(big.Int).Add(parent.Number, big1) switch { @@ -502,8 +509,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) if parent == nil { return consensus.ErrUnknownAncestor } - header.Difficulty = CalcDifficulty(chain.Config(), header.Time.Uint64(), parent) - + header.Difficulty = ethash.CalcDifficulty(chain, header.Time.Uint64(), parent) return nil } @@ -511,7 +517,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) // setting the final state and assembling the block. func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { // Accumulate any block and uncle rewards and commit the final state root - AccumulateRewards(chain.Config(), state, header, uncles) + accumulateRewards(chain.Config(), state, header, uncles) header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) // Header seems complete, assemble into a block and return @@ -527,8 +533,7 @@ var ( // 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. -// TODO (karalabe): Move the chain maker into this package and make this private! -func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { +func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { // Select the correct block reward based on chain progression blockReward := FrontierBlockReward if config.IsByzantium(header.Number) { diff --git a/consensus/ethash/consensus_test.go b/consensus/ethash/consensus_test.go index a58d220ef..438a99dd6 100644 --- a/consensus/ethash/consensus_test.go +++ b/consensus/ethash/consensus_test.go @@ -71,6 +71,7 @@ func TestCalcDifficulty(t *testing.T) { } config := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(1150000)} + for name, test := range tests { number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1)) diff := CalcDifficulty(config, test.CurrentTimestamp, &types.Header{ |