|
|
@@ -48,6 +48,8 @@ type BlockGen struct {
|
|
|
engine consensus.Engine
|
|
|
}
|
|
|
|
|
|
+type headerGenFn func(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header
|
|
|
+
|
|
|
// SetCoinbase sets the coinbase of the generated block.
|
|
|
// It can be called at most once.
|
|
|
func (b *BlockGen) SetCoinbase(addr common.Address) {
|
|
|
@@ -170,6 +172,10 @@ func (b *BlockGen) OffsetTime(seconds int64) {
|
|
|
// values. Inserting them into BlockChain requires use of FakePow or
|
|
|
// a similar non-validating proof of work implementation.
|
|
|
func GenerateChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) {
|
|
|
+ return generateChain(config, parent, engine, db, n, gen, makeHeader)
|
|
|
+}
|
|
|
+
|
|
|
+func generateChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen), headerGen headerGenFn) ([]*types.Block, []types.Receipts) {
|
|
|
if config == nil {
|
|
|
config = params.TestChainConfig
|
|
|
}
|
|
|
@@ -177,7 +183,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|
|
chainreader := &fakeChainReader{config: config}
|
|
|
genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
|
|
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
|
|
|
- b.header = makeHeader(chainreader, parent, statedb, b.engine)
|
|
|
+ //b.header = makeHeader(chainreader, parent, statedb, b.engine)
|
|
|
+ b.header = headerGen(chainreader, parent, statedb, b.engine)
|
|
|
|
|
|
// Mutate the state and block according to any hard-fork specs
|
|
|
if daoBlock := config.DAOForkBlock; daoBlock != nil {
|
|
|
@@ -248,6 +255,54 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func makeHeaderWithLargeDifficulty(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
|
|
|
+ var time *big.Int
|
|
|
+ if parent.Time() == nil {
|
|
|
+ time = big.NewInt(1)
|
|
|
+ } else {
|
|
|
+ time = new(big.Int).Add(parent.Time(), big.NewInt(1)) // block time is fixed at 10 seconds
|
|
|
+ }
|
|
|
+
|
|
|
+ return &types.Header{
|
|
|
+ Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())),
|
|
|
+ ParentHash: parent.Hash(),
|
|
|
+ Coinbase: parent.Coinbase(),
|
|
|
+ Difficulty: engine.CalcDifficulty(chain, time.Uint64(), &types.Header{
|
|
|
+ Number: parent.Number(),
|
|
|
+ Time: new(big.Int).Sub(time, big.NewInt(1)),
|
|
|
+ Difficulty: parent.Difficulty(),
|
|
|
+ UncleHash: parent.UncleHash(),
|
|
|
+ }),
|
|
|
+ GasLimit: CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()),
|
|
|
+ Number: new(big.Int).Add(parent.Number(), common.Big1),
|
|
|
+ Time: time,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func makeHeaderWithSmallDifficulty(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
|
|
|
+ var time *big.Int
|
|
|
+ if parent.Time() == nil {
|
|
|
+ time = big.NewInt(30)
|
|
|
+ } else {
|
|
|
+ time = new(big.Int).Add(parent.Time(), big.NewInt(30)) // block time is fixed at 10 seconds
|
|
|
+ }
|
|
|
+
|
|
|
+ return &types.Header{
|
|
|
+ Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())),
|
|
|
+ ParentHash: parent.Hash(),
|
|
|
+ Coinbase: parent.Coinbase(),
|
|
|
+ Difficulty: engine.CalcDifficulty(chain, time.Uint64(), &types.Header{
|
|
|
+ Number: parent.Number(),
|
|
|
+ Time: new(big.Int).Sub(time, big.NewInt(30)),
|
|
|
+ Difficulty: parent.Difficulty(),
|
|
|
+ UncleHash: parent.UncleHash(),
|
|
|
+ }),
|
|
|
+ GasLimit: CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()),
|
|
|
+ Number: new(big.Int).Add(parent.Number(), common.Big1),
|
|
|
+ Time: time,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// makeHeaderChain creates a deterministic chain of headers rooted at parent.
|
|
|
func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header {
|
|
|
blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed)
|