cmd, consensus, core, miner: instatx clique for --dev (#15323)
* cmd, consensus, core, miner: instatx clique for --dev * cmd, consensus, clique: support configurable --dev block times * cmd, core: allow --dev to use persistent storage too
This commit is contained in:
parent
ea5f2da39a
commit
6d6a5a9337
@ -59,7 +59,7 @@ type SimulatedBackend struct {
|
|||||||
// for testing purposes.
|
// for testing purposes.
|
||||||
func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend {
|
func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend {
|
||||||
database, _ := ethdb.NewMemDatabase()
|
database, _ := ethdb.NewMemDatabase()
|
||||||
genesis := core.Genesis{Config: params.AllProtocolChanges, Alloc: alloc}
|
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, Alloc: alloc}
|
||||||
genesis.MustCommit(database)
|
genesis.MustCommit(database)
|
||||||
blockchain, _ := core.NewBlockChain(database, genesis.Config, ethash.NewFaker(), vm.Config{})
|
blockchain, _ := core.NewBlockChain(database, genesis.Config, ethash.NewFaker(), vm.Config{})
|
||||||
backend := &SimulatedBackend{database: database, blockchain: blockchain, config: genesis.Config}
|
backend := &SimulatedBackend{database: database, blockchain: blockchain, config: genesis.Config}
|
||||||
|
@ -134,7 +134,7 @@ Fatal: could not decrypt key with given passphrase
|
|||||||
func TestUnlockFlag(t *testing.T) {
|
func TestUnlockFlag(t *testing.T) {
|
||||||
datadir := tmpDatadirWithKeystore(t)
|
datadir := tmpDatadirWithKeystore(t)
|
||||||
geth := runGeth(t,
|
geth := runGeth(t,
|
||||||
"--datadir", datadir, "--nat", "none", "--nodiscover", "--dev",
|
"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
|
||||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
|
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
|
||||||
"js", "testdata/empty.js")
|
"js", "testdata/empty.js")
|
||||||
geth.Expect(`
|
geth.Expect(`
|
||||||
@ -158,7 +158,7 @@ Passphrase: {{.InputLine "foobar"}}
|
|||||||
func TestUnlockFlagWrongPassword(t *testing.T) {
|
func TestUnlockFlagWrongPassword(t *testing.T) {
|
||||||
datadir := tmpDatadirWithKeystore(t)
|
datadir := tmpDatadirWithKeystore(t)
|
||||||
geth := runGeth(t,
|
geth := runGeth(t,
|
||||||
"--datadir", datadir, "--nat", "none", "--nodiscover", "--dev",
|
"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
|
||||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
|
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
|
||||||
defer geth.ExpectExit()
|
defer geth.ExpectExit()
|
||||||
geth.Expect(`
|
geth.Expect(`
|
||||||
@ -177,7 +177,7 @@ Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could
|
|||||||
func TestUnlockFlagMultiIndex(t *testing.T) {
|
func TestUnlockFlagMultiIndex(t *testing.T) {
|
||||||
datadir := tmpDatadirWithKeystore(t)
|
datadir := tmpDatadirWithKeystore(t)
|
||||||
geth := runGeth(t,
|
geth := runGeth(t,
|
||||||
"--datadir", datadir, "--nat", "none", "--nodiscover", "--dev",
|
"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
|
||||||
"--unlock", "0,2",
|
"--unlock", "0,2",
|
||||||
"js", "testdata/empty.js")
|
"js", "testdata/empty.js")
|
||||||
geth.Expect(`
|
geth.Expect(`
|
||||||
@ -204,7 +204,7 @@ Passphrase: {{.InputLine "foobar"}}
|
|||||||
func TestUnlockFlagPasswordFile(t *testing.T) {
|
func TestUnlockFlagPasswordFile(t *testing.T) {
|
||||||
datadir := tmpDatadirWithKeystore(t)
|
datadir := tmpDatadirWithKeystore(t)
|
||||||
geth := runGeth(t,
|
geth := runGeth(t,
|
||||||
"--datadir", datadir, "--nat", "none", "--nodiscover", "--dev",
|
"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
|
||||||
"--password", "testdata/passwords.txt", "--unlock", "0,2",
|
"--password", "testdata/passwords.txt", "--unlock", "0,2",
|
||||||
"js", "testdata/empty.js")
|
"js", "testdata/empty.js")
|
||||||
geth.ExpectExit()
|
geth.ExpectExit()
|
||||||
@ -224,7 +224,7 @@ func TestUnlockFlagPasswordFile(t *testing.T) {
|
|||||||
func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
|
func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
|
||||||
datadir := tmpDatadirWithKeystore(t)
|
datadir := tmpDatadirWithKeystore(t)
|
||||||
geth := runGeth(t,
|
geth := runGeth(t,
|
||||||
"--datadir", datadir, "--nat", "none", "--nodiscover", "--dev",
|
"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
|
||||||
"--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
|
"--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
|
||||||
defer geth.ExpectExit()
|
defer geth.ExpectExit()
|
||||||
geth.Expect(`
|
geth.Expect(`
|
||||||
@ -235,7 +235,7 @@ Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase)
|
|||||||
func TestUnlockFlagAmbiguous(t *testing.T) {
|
func TestUnlockFlagAmbiguous(t *testing.T) {
|
||||||
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
||||||
geth := runGeth(t,
|
geth := runGeth(t,
|
||||||
"--keystore", store, "--nat", "none", "--nodiscover", "--dev",
|
"--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
|
||||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
|
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
|
||||||
"js", "testdata/empty.js")
|
"js", "testdata/empty.js")
|
||||||
defer geth.ExpectExit()
|
defer geth.ExpectExit()
|
||||||
@ -273,7 +273,7 @@ In order to avoid this warning, you need to remove the following duplicate key f
|
|||||||
func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
|
func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
|
||||||
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
||||||
geth := runGeth(t,
|
geth := runGeth(t,
|
||||||
"--keystore", store, "--nat", "none", "--nodiscover", "--dev",
|
"--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
|
||||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
|
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
|
||||||
defer geth.ExpectExit()
|
defer geth.ExpectExit()
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
|||||||
|
|
||||||
// Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode
|
// Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode
|
||||||
shhEnabled := enableWhisper(ctx)
|
shhEnabled := enableWhisper(ctx)
|
||||||
shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DevModeFlag.Name)
|
shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name)
|
||||||
if shhEnabled || shhAutoEnabled {
|
if shhEnabled || shhAutoEnabled {
|
||||||
if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) {
|
if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) {
|
||||||
cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name))
|
cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name))
|
||||||
|
@ -99,7 +99,8 @@ var (
|
|||||||
utils.NetrestrictFlag,
|
utils.NetrestrictFlag,
|
||||||
utils.NodeKeyFileFlag,
|
utils.NodeKeyFileFlag,
|
||||||
utils.NodeKeyHexFlag,
|
utils.NodeKeyHexFlag,
|
||||||
utils.DevModeFlag,
|
utils.DeveloperFlag,
|
||||||
|
utils.DeveloperPeriodFlag,
|
||||||
utils.TestnetFlag,
|
utils.TestnetFlag,
|
||||||
utils.RinkebyFlag,
|
utils.RinkebyFlag,
|
||||||
utils.VMEnableDebugFlag,
|
utils.VMEnableDebugFlag,
|
||||||
@ -270,7 +271,7 @@ func startNode(ctx *cli.Context, stack *node.Node) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Start auxiliary services if enabled
|
// Start auxiliary services if enabled
|
||||||
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) {
|
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
|
||||||
// Mining only makes sense if a full Ethereum node is running
|
// Mining only makes sense if a full Ethereum node is running
|
||||||
var ethereum *eth.Ethereum
|
var ethereum *eth.Ethereum
|
||||||
if err := stack.Service(ðereum); err != nil {
|
if err := stack.Service(ðereum); err != nil {
|
||||||
|
@ -72,7 +72,6 @@ var AppHelpFlagGroups = []flagGroup{
|
|||||||
utils.NetworkIdFlag,
|
utils.NetworkIdFlag,
|
||||||
utils.TestnetFlag,
|
utils.TestnetFlag,
|
||||||
utils.RinkebyFlag,
|
utils.RinkebyFlag,
|
||||||
utils.DevModeFlag,
|
|
||||||
utils.SyncModeFlag,
|
utils.SyncModeFlag,
|
||||||
utils.EthStatsURLFlag,
|
utils.EthStatsURLFlag,
|
||||||
utils.IdentityFlag,
|
utils.IdentityFlag,
|
||||||
@ -81,6 +80,12 @@ var AppHelpFlagGroups = []flagGroup{
|
|||||||
utils.LightKDFFlag,
|
utils.LightKDFFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{Name: "DEVELOPER CHAIN",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
utils.DeveloperFlag,
|
||||||
|
utils.DeveloperPeriodFlag,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "ETHASH",
|
Name: "ETHASH",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
|
@ -137,9 +137,13 @@ var (
|
|||||||
Name: "rinkeby",
|
Name: "rinkeby",
|
||||||
Usage: "Rinkeby network: pre-configured proof-of-authority test network",
|
Usage: "Rinkeby network: pre-configured proof-of-authority test network",
|
||||||
}
|
}
|
||||||
DevModeFlag = cli.BoolFlag{
|
DeveloperFlag = cli.BoolFlag{
|
||||||
Name: "dev",
|
Name: "dev",
|
||||||
Usage: "Developer mode: pre-configured private network with several debugging flags",
|
Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled",
|
||||||
|
}
|
||||||
|
DeveloperPeriodFlag = cli.IntFlag{
|
||||||
|
Name: "dev.period",
|
||||||
|
Usage: "Block period to use in developer mode (0 = mine only if transaction pending)",
|
||||||
}
|
}
|
||||||
IdentityFlag = cli.StringFlag{
|
IdentityFlag = cli.StringFlag{
|
||||||
Name: "identity",
|
Name: "identity",
|
||||||
@ -796,7 +800,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
|
|||||||
cfg.NetRestrict = list
|
cfg.NetRestrict = list
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.GlobalBool(DevModeFlag.Name) {
|
if ctx.GlobalBool(DeveloperFlag.Name) {
|
||||||
// --dev mode can't use p2p networking.
|
// --dev mode can't use p2p networking.
|
||||||
cfg.MaxPeers = 0
|
cfg.MaxPeers = 0
|
||||||
cfg.ListenAddr = ":0"
|
cfg.ListenAddr = ":0"
|
||||||
@ -817,8 +821,8 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
|
|||||||
switch {
|
switch {
|
||||||
case ctx.GlobalIsSet(DataDirFlag.Name):
|
case ctx.GlobalIsSet(DataDirFlag.Name):
|
||||||
cfg.DataDir = ctx.GlobalString(DataDirFlag.Name)
|
cfg.DataDir = ctx.GlobalString(DataDirFlag.Name)
|
||||||
case ctx.GlobalBool(DevModeFlag.Name):
|
case ctx.GlobalBool(DeveloperFlag.Name):
|
||||||
cfg.DataDir = filepath.Join(os.TempDir(), "ethereum_dev_mode")
|
cfg.DataDir = "" // unless explicitly requested, use memory databases
|
||||||
case ctx.GlobalBool(TestnetFlag.Name):
|
case ctx.GlobalBool(TestnetFlag.Name):
|
||||||
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "testnet")
|
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "testnet")
|
||||||
case ctx.GlobalBool(RinkebyFlag.Name):
|
case ctx.GlobalBool(RinkebyFlag.Name):
|
||||||
@ -924,7 +928,7 @@ func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
|
|||||||
// SetEthConfig applies eth-related command line flags to the config.
|
// SetEthConfig applies eth-related command line flags to the config.
|
||||||
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
||||||
// Avoid conflicting network flags
|
// Avoid conflicting network flags
|
||||||
checkExclusive(ctx, DevModeFlag, TestnetFlag, RinkebyFlag)
|
checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag)
|
||||||
checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag)
|
checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag)
|
||||||
|
|
||||||
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
||||||
@ -985,14 +989,30 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
|||||||
cfg.NetworkId = 4
|
cfg.NetworkId = 4
|
||||||
}
|
}
|
||||||
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
|
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
|
||||||
case ctx.GlobalBool(DevModeFlag.Name):
|
case ctx.GlobalBool(DeveloperFlag.Name):
|
||||||
cfg.Genesis = core.DevGenesisBlock()
|
// Create new developer account or reuse existing one
|
||||||
if !ctx.GlobalIsSet(GasPriceFlag.Name) {
|
var (
|
||||||
cfg.GasPrice = new(big.Int)
|
developer accounts.Account
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if accs := ks.Accounts(); len(accs) > 0 {
|
||||||
|
developer = ks.Accounts()[0]
|
||||||
|
} else {
|
||||||
|
developer, err = ks.NewAccount("")
|
||||||
|
if err != nil {
|
||||||
|
Fatalf("Failed to create developer account: %v", err)
|
||||||
}
|
}
|
||||||
cfg.PowTest = true
|
|
||||||
}
|
}
|
||||||
|
if err := ks.Unlock(developer, ""); err != nil {
|
||||||
|
Fatalf("Failed to unlock developer account: %v", err)
|
||||||
|
}
|
||||||
|
log.Info("Using developer account", "address", developer.Address)
|
||||||
|
|
||||||
|
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)
|
||||||
|
if !ctx.GlobalIsSet(GasPriceFlag.Name) {
|
||||||
|
cfg.GasPrice = big.NewInt(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO(fjl): move trie cache generations into config
|
// TODO(fjl): move trie cache generations into config
|
||||||
if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 {
|
if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 {
|
||||||
state.MaxTrieCacheGen = uint16(gen)
|
state.MaxTrieCacheGen = uint16(gen)
|
||||||
@ -1077,8 +1097,8 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
|
|||||||
genesis = core.DefaultTestnetGenesisBlock()
|
genesis = core.DefaultTestnetGenesisBlock()
|
||||||
case ctx.GlobalBool(RinkebyFlag.Name):
|
case ctx.GlobalBool(RinkebyFlag.Name):
|
||||||
genesis = core.DefaultRinkebyGenesisBlock()
|
genesis = core.DefaultRinkebyGenesisBlock()
|
||||||
case ctx.GlobalBool(DevModeFlag.Name):
|
case ctx.GlobalBool(DeveloperFlag.Name):
|
||||||
genesis = core.DevGenesisBlock()
|
Fatalf("Developer chains are ephemeral")
|
||||||
}
|
}
|
||||||
return genesis
|
return genesis
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,11 @@ var (
|
|||||||
|
|
||||||
// errUnauthorized is returned if a header is signed by a non-authorized entity.
|
// errUnauthorized is returned if a header is signed by a non-authorized entity.
|
||||||
errUnauthorized = errors.New("unauthorized")
|
errUnauthorized = errors.New("unauthorized")
|
||||||
|
|
||||||
|
// errWaitTransactions is returned if an empty block is attempted to be sealed
|
||||||
|
// on an instant chain (0 second period). It's important to refuse these as the
|
||||||
|
// block reward is zero, so an empty block just bloats the chain... fast.
|
||||||
|
errWaitTransactions = errors.New("waiting for transactions")
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignerFn is a signer callback function to request a hash to be signed by a
|
// SignerFn is a signer callback function to request a hash to be signed by a
|
||||||
@ -211,9 +216,6 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
|
|||||||
if conf.Epoch == 0 {
|
if conf.Epoch == 0 {
|
||||||
conf.Epoch = epochLength
|
conf.Epoch = epochLength
|
||||||
}
|
}
|
||||||
if conf.Period == 0 {
|
|
||||||
conf.Period = blockPeriod
|
|
||||||
}
|
|
||||||
// Allocate the snapshot caches and create the engine
|
// Allocate the snapshot caches and create the engine
|
||||||
recents, _ := lru.NewARC(inmemorySnapshots)
|
recents, _ := lru.NewARC(inmemorySnapshots)
|
||||||
signatures, _ := lru.NewARC(inmemorySignatures)
|
signatures, _ := lru.NewARC(inmemorySignatures)
|
||||||
@ -599,6 +601,10 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch
|
|||||||
if number == 0 {
|
if number == 0 {
|
||||||
return nil, errUnknownBlock
|
return nil, errUnknownBlock
|
||||||
}
|
}
|
||||||
|
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
|
||||||
|
if c.config.Period == 0 && len(block.Transactions()) == 0 {
|
||||||
|
return nil, errWaitTransactions
|
||||||
|
}
|
||||||
// Don't hold the signer fields for the entire sealing procedure
|
// Don't hold the signer fields for the entire sealing procedure
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
signer, signFn := c.signer, c.signFn
|
signer, signFn := c.signer, c.signFn
|
||||||
|
@ -74,7 +74,7 @@ type testerChainReader struct {
|
|||||||
db ethdb.Database
|
db ethdb.Database
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *testerChainReader) Config() *params.ChainConfig { return params.AllProtocolChanges }
|
func (r *testerChainReader) Config() *params.ChainConfig { return params.AllCliqueProtocolChanges }
|
||||||
func (r *testerChainReader) CurrentHeader() *types.Header { panic("not supported") }
|
func (r *testerChainReader) CurrentHeader() *types.Header { panic("not supported") }
|
||||||
func (r *testerChainReader) GetHeader(common.Hash, uint64) *types.Header { panic("not supported") }
|
func (r *testerChainReader) GetHeader(common.Hash, uint64) *types.Header { panic("not supported") }
|
||||||
func (r *testerChainReader) GetBlock(common.Hash, uint64) *types.Block { panic("not supported") }
|
func (r *testerChainReader) GetBlock(common.Hash, uint64) *types.Block { panic("not supported") }
|
||||||
|
@ -94,7 +94,7 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester {
|
|||||||
t.Fatalf("failed to create node: %v", err)
|
t.Fatalf("failed to create node: %v", err)
|
||||||
}
|
}
|
||||||
ethConf := ð.Config{
|
ethConf := ð.Config{
|
||||||
Genesis: core.DevGenesisBlock(),
|
Genesis: core.DeveloperGenesisBlock(15, common.Address{}),
|
||||||
Etherbase: common.HexToAddress(testAddress),
|
Etherbase: common.HexToAddress(testAddress),
|
||||||
PowTest: true,
|
PowTest: true,
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ func newCanonical(n int, full bool) (ethdb.Database, *BlockChain, error) {
|
|||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
|
|
||||||
blockchain, _ := NewBlockChain(db, params.AllProtocolChanges, ethash.NewFaker(), vm.Config{})
|
blockchain, _ := NewBlockChain(db, params.AllEthashProtocolChanges, ethash.NewFaker(), vm.Config{})
|
||||||
// Create and inject the requested chain
|
// Create and inject the requested chain
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return db, blockchain, nil
|
return db, blockchain, nil
|
||||||
|
@ -151,7 +151,7 @@ func (e *GenesisMismatchError) Error() string {
|
|||||||
// The returned chain configuration is never nil.
|
// The returned chain configuration is never nil.
|
||||||
func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
|
func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
|
||||||
if genesis != nil && genesis.Config == nil {
|
if genesis != nil && genesis.Config == nil {
|
||||||
return params.AllProtocolChanges, common.Hash{}, errGenesisNoConfig
|
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just commit the new block if there is no stored genesis block.
|
// Just commit the new block if there is no stored genesis block.
|
||||||
@ -216,7 +216,7 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
|||||||
case ghash == params.TestnetGenesisHash:
|
case ghash == params.TestnetGenesisHash:
|
||||||
return params.TestnetChainConfig
|
return params.TestnetChainConfig
|
||||||
default:
|
default:
|
||||||
return params.AllProtocolChanges
|
return params.AllEthashProtocolChanges
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
|
|||||||
}
|
}
|
||||||
config := g.Config
|
config := g.Config
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = params.AllProtocolChanges
|
config = params.AllEthashProtocolChanges
|
||||||
}
|
}
|
||||||
return block, WriteChainConfig(db, block.Hash(), config)
|
return block, WriteChainConfig(db, block.Hash(), config)
|
||||||
}
|
}
|
||||||
@ -342,14 +342,30 @@ func DefaultRinkebyGenesisBlock() *Genesis {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DevGenesisBlock returns the 'geth --dev' genesis block.
|
// DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must
|
||||||
func DevGenesisBlock() *Genesis {
|
// be seeded with the
|
||||||
|
func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
|
||||||
|
// Override the default period to the user requested one
|
||||||
|
config := *params.AllCliqueProtocolChanges
|
||||||
|
config.Clique.Period = period
|
||||||
|
|
||||||
|
// Assemble and return the genesis with the precompiles and faucet pre-funded
|
||||||
return &Genesis{
|
return &Genesis{
|
||||||
Config: params.AllProtocolChanges,
|
Config: &config,
|
||||||
Nonce: 42,
|
ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...),
|
||||||
GasLimit: 4712388,
|
GasLimit: 6283185,
|
||||||
Difficulty: big.NewInt(131072),
|
Difficulty: big.NewInt(1),
|
||||||
Alloc: decodePrealloc(devAllocData),
|
Alloc: map[common.Address]GenesisAccount{
|
||||||
|
common.BytesToAddress([]byte{1}): GenesisAccount{Balance: big.NewInt(1)}, // ECRecover
|
||||||
|
common.BytesToAddress([]byte{2}): GenesisAccount{Balance: big.NewInt(1)}, // SHA256
|
||||||
|
common.BytesToAddress([]byte{3}): GenesisAccount{Balance: big.NewInt(1)}, // RIPEMD
|
||||||
|
common.BytesToAddress([]byte{4}): GenesisAccount{Balance: big.NewInt(1)}, // Identity
|
||||||
|
common.BytesToAddress([]byte{5}): GenesisAccount{Balance: big.NewInt(1)}, // ModExp
|
||||||
|
common.BytesToAddress([]byte{6}): GenesisAccount{Balance: big.NewInt(1)}, // ECAdd
|
||||||
|
common.BytesToAddress([]byte{7}): GenesisAccount{Balance: big.NewInt(1)}, // ECScalarMul
|
||||||
|
common.BytesToAddress([]byte{8}): GenesisAccount{Balance: big.NewInt(1)}, // ECPairing
|
||||||
|
faucet: GenesisAccount{Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -65,7 +65,7 @@ func TestSetupGenesis(t *testing.T) {
|
|||||||
return SetupGenesisBlock(db, new(Genesis))
|
return SetupGenesisBlock(db, new(Genesis))
|
||||||
},
|
},
|
||||||
wantErr: errGenesisNoConfig,
|
wantErr: errGenesisNoConfig,
|
||||||
wantConfig: params.AllProtocolChanges,
|
wantConfig: params.AllEthashProtocolChanges,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no block in DB, genesis == nil",
|
name: "no block in DB, genesis == nil",
|
||||||
|
@ -269,6 +269,11 @@ func (self *worker) update() {
|
|||||||
|
|
||||||
self.current.commitTransactions(self.mux, txset, self.chain, self.coinbase)
|
self.current.commitTransactions(self.mux, txset, self.chain, self.coinbase)
|
||||||
self.currentMu.Unlock()
|
self.currentMu.Unlock()
|
||||||
|
} else {
|
||||||
|
// If we're mining, but nothing is being processed, wake on new transactions
|
||||||
|
if self.config.Clique != nil && self.config.Clique.Period == 0 {
|
||||||
|
self.commitNewWork()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// System stopped
|
// System stopped
|
||||||
|
@ -77,15 +77,20 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllProtocolChanges contains every protocol change (EIPs)
|
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
// introduced and accepted by the Ethereum core developers.
|
// and accepted by the Ethereum core developers into the Ethash consensus.
|
||||||
//
|
//
|
||||||
// This configuration is intentionally not using keyed fields.
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// This configuration must *always* have all forks enabled, which
|
// adding flags to the config to also have to set these fields.
|
||||||
// means that all fields must be set at all times. This forces
|
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil}
|
||||||
// anyone adding flags to the config to also have to set these
|
|
||||||
// fields.
|
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
AllProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil}
|
// and accepted by the Ethereum core developers into the Clique consensus.
|
||||||
|
//
|
||||||
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
|
// adding flags to the config to also have to set these fields.
|
||||||
|
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}}
|
||||||
|
|
||||||
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil}
|
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil}
|
||||||
TestRules = TestChainConfig.Rules(new(big.Int))
|
TestRules = TestChainConfig.Rules(new(big.Int))
|
||||||
)
|
)
|
||||||
|
@ -29,8 +29,8 @@ func TestCheckCompatible(t *testing.T) {
|
|||||||
wantErr *ConfigCompatError
|
wantErr *ConfigCompatError
|
||||||
}
|
}
|
||||||
tests := []test{
|
tests := []test{
|
||||||
{stored: AllProtocolChanges, new: AllProtocolChanges, head: 0, wantErr: nil},
|
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 0, wantErr: nil},
|
||||||
{stored: AllProtocolChanges, new: AllProtocolChanges, head: 100, wantErr: nil},
|
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 100, wantErr: nil},
|
||||||
{
|
{
|
||||||
stored: &ChainConfig{EIP150Block: big.NewInt(10)},
|
stored: &ChainConfig{EIP150Block: big.NewInt(10)},
|
||||||
new: &ChainConfig{EIP150Block: big.NewInt(20)},
|
new: &ChainConfig{EIP150Block: big.NewInt(20)},
|
||||||
@ -38,7 +38,7 @@ func TestCheckCompatible(t *testing.T) {
|
|||||||
wantErr: nil,
|
wantErr: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
stored: AllProtocolChanges,
|
stored: AllEthashProtocolChanges,
|
||||||
new: &ChainConfig{HomesteadBlock: nil},
|
new: &ChainConfig{HomesteadBlock: nil},
|
||||||
head: 3,
|
head: 3,
|
||||||
wantErr: &ConfigCompatError{
|
wantErr: &ConfigCompatError{
|
||||||
@ -49,7 +49,7 @@ func TestCheckCompatible(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
stored: AllProtocolChanges,
|
stored: AllEthashProtocolChanges,
|
||||||
new: &ChainConfig{HomesteadBlock: big.NewInt(1)},
|
new: &ChainConfig{HomesteadBlock: big.NewInt(1)},
|
||||||
head: 3,
|
head: 3,
|
||||||
wantErr: &ConfigCompatError{
|
wantErr: &ConfigCompatError{
|
||||||
|
Loading…
Reference in New Issue
Block a user