Skip to content

accounts, consensus, core, eth: make chain maker consensus agnostic#15497

Merged
karalabe merged 4 commits into
ethereum:masterfrom
rjl493456442:improve_chain_marker
Dec 22, 2017
Merged

accounts, consensus, core, eth: make chain maker consensus agnostic#15497
karalabe merged 4 commits into
ethereum:masterfrom
rjl493456442:improve_chain_marker

Conversation

@rjl493456442
Copy link
Copy Markdown
Member

@rjl493456442 rjl493456442 commented Nov 16, 2017

Implements #15488

Comment thread core/chain_makers.go Outdated
b.header.Difficulty = ethash.CalcDifficulty(b.config, b.header.Time.Uint64(), b.parent.Header())
if pow, ok := b.engine.(consensus.PoW); ok {
b.header.Difficulty = pow.CalcDifficulty(b.config, b.header.Time.Uint64(), b.parent.Header())
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take care, the difficulty should work for all consensus engines, not just for PoW based ones. Clique has its own notion of difficulty too.

Comment thread consensus/consensus.go Outdated
// 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.
AccumulateRewards(*params.ChainConfig, *state.StateDB, *types.Header, []*types.Header)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think consensus.Engine.Finalize already contains the reward accumulation within. I'm not sure you need an external method for it.

Comment thread consensus/consensus.go Outdated

// CalcDifficulty returns the difficulty that a new block should have when created at time
// given the parent block's time and difficulty.
CalcDifficulty(*params.ChainConfig, uint64, *types.Header) *big.Int
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we perhaps similarly use consensus.Engine.Prepare to calculate the difficulty? Maybe some code needs the raw difficulty, just asking. Ether way, it should probably land in the Engine interface, not in PoW only.

@rjl493456442 rjl493456442 force-pushed the improve_chain_marker branch 2 times, most recently from 86c8ccc to b05355e Compare November 19, 2017 06:22
@rjl493456442
Copy link
Copy Markdown
Member Author

@karalabe Updated

Copy link
Copy Markdown
Member

@karalabe karalabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost perfect :) I've written up some suggestions, plus 1 open question remains.

Comment thread tests/difficulty_test_util.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This became a bit convoluted. I think it's fine to retain the global method ethash.CalcDifficulty, and just wrap it with the engine.CalcDifficulty.

Comment thread consensus/ethash/consensus.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we completely move CalcDifficulty inside the ethash engine, then outside code that wants to work with ethash will always need an engine. I think the best would be to leave this method as a plain global, and also to wrap it within the engine. That way we have an engine agnostic way to calculate a difficulty, but it can be done without requiring an engine object too.

Comment thread consensus/ethash/consensus_test.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you retain the global ethash.CalcDifficulty method too, you won't need either the NewFaker, nor the emphemeral chain here.

Comment thread consensus/clique/clique.go Outdated
Copy link
Copy Markdown
Member

@karalabe karalabe Dec 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling CalcDifficulty here is a bit expensive as it needs to regenerate the snapsot internally. Imho it would be better to leave this code as is and calculate the difficulty directly.

Alternatively, you can add a global clique.CalcDifficulty method the same was as in ethash.CalcDifficulty, that would contain just the essence and operate on a snapshot:

func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
	if snap.inturn(snap.Number+1, c.signer) {
		return new(big.Int).Set(diffInTurn)
	}
	return new(big.Int).Set(diffNoTurn)
}

And you can call this function directly here, and also wrap it with engine.CalcDifficulty.

Comment thread core/chain_makers.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonus point if we can figure out a way to get rid of this ephemeral blockchain here. I'm also unsure if it is correct in the case of Clique (i.e. does this chain contain any data, or will it just blow up when invoked for clique)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason to construct an ephemeral blockchain here is we need to use it to calculate the new difficulty for the new block.
As for clique, chainReader is necessary for difficulty calculation. So we'd better keep it.

@karalabe karalabe added this to the 1.8.0 milestone Dec 21, 2017
return CalcDifficulty(snap, c.signer)
}

func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to have a doc here ;)

return CalcDifficulty(chain.Config(), time, parent)
}

func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to have a doc here ;)

Copy link
Copy Markdown
Member

@karalabe karalabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@karalabe karalabe merged commit 5f8888e into ethereum:master Dec 22, 2017
mariameda pushed a commit to NiluPlatform/go-nilu that referenced this pull request Aug 23, 2018
…thereum#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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants