diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index 66e3e02a4e..3ea22ccfab 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -134,7 +134,7 @@ Fatal: could not decrypt key with given passphrase func TestUnlockFlag(t *testing.T) { datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, - "--datadir", datadir, "--nat", "none", "--nodiscover", "--dev", + "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js") geth.Expect(` @@ -158,7 +158,7 @@ Passphrase: {{.InputLine "foobar"}} func TestUnlockFlagWrongPassword(t *testing.T) { datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, - "--datadir", datadir, "--nat", "none", "--nodiscover", "--dev", + "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a") defer geth.ExpectExit() geth.Expect(` @@ -177,7 +177,7 @@ Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could func TestUnlockFlagMultiIndex(t *testing.T) { datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, - "--datadir", datadir, "--nat", "none", "--nodiscover", "--dev", + "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "0,2", "js", "testdata/empty.js") geth.Expect(` @@ -204,7 +204,7 @@ Passphrase: {{.InputLine "foobar"}} func TestUnlockFlagPasswordFile(t *testing.T) { datadir := tmpDatadirWithKeystore(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", "js", "testdata/empty.js") geth.ExpectExit() @@ -224,7 +224,7 @@ func TestUnlockFlagPasswordFile(t *testing.T) { func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { datadir := tmpDatadirWithKeystore(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") defer geth.ExpectExit() geth.Expect(` @@ -235,7 +235,7 @@ Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase) func TestUnlockFlagAmbiguous(t *testing.T) { store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") geth := runGeth(t, - "--keystore", store, "--nat", "none", "--nodiscover", "--dev", + "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js") 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) { store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") geth := runGeth(t, - "--keystore", store, "--nat", "none", "--nodiscover", "--dev", + "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a") defer geth.ExpectExit() diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 018fa8b71c..8bd27b5c6a 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -100,6 +100,7 @@ var ( utils.NodeKeyFileFlag, utils.NodeKeyHexFlag, utils.DeveloperFlag, + utils.DeveloperPeriodFlag, utils.TestnetFlag, utils.RinkebyFlag, utils.VMEnableDebugFlag, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 7e2038f660..5bb2255f3b 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -72,7 +72,6 @@ var AppHelpFlagGroups = []flagGroup{ utils.NetworkIdFlag, utils.TestnetFlag, utils.RinkebyFlag, - utils.DeveloperFlag, utils.SyncModeFlag, utils.EthStatsURLFlag, utils.IdentityFlag, @@ -81,6 +80,12 @@ var AppHelpFlagGroups = []flagGroup{ utils.LightKDFFlag, }, }, + {Name: "DEVELOPER CHAIN", + Flags: []cli.Flag{ + utils.DeveloperFlag, + utils.DeveloperPeriodFlag, + }, + }, { Name: "ETHASH", Flags: []cli.Flag{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 5317c80ae5..3af625a6ac 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -139,7 +139,11 @@ var ( } DeveloperFlag = cli.BoolFlag{ 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{ Name: "identity", @@ -995,7 +999,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { } log.Info("Created developer account", "address", faucet.Address) - cfg.Genesis = core.DefaultDeveloperGenesisBlock(faucet.Address) + cfg.Genesis = core.DefaultDeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), faucet.Address) if !ctx.GlobalIsSet(GasPriceFlag.Name) { cfg.GasPrice = big.NewInt(1) } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index ae9f91582b..6892d83906 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -126,10 +126,10 @@ var ( // errUnauthorized is returned if a header is signed by a non-authorized entity. errUnauthorized = errors.New("unauthorized") - // errEmptyInstantBlock is returned if an empty block is attempted to be sealed + // 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. - errEmptyInstantBlock = errors.New("empty instant block") + errWaitTransactions = errors.New("waiting for transactions") ) // SignerFn is a signer callback function to request a hash to be signed by a @@ -603,7 +603,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch } // 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, errEmptyInstantBlock + return nil, errWaitTransactions } // Don't hold the signer fields for the entire sealing procedure c.lock.RLock() diff --git a/console/console_test.go b/console/console_test.go index 8ac499bd12..0bc3d436e5 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -94,7 +94,7 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { t.Fatalf("failed to create node: %v", err) } ethConf := ð.Config{ - Genesis: core.DevGenesisBlock(), + Genesis: core.DefaultDeveloperGenesisBlock(15, common.Address{}), Etherbase: common.HexToAddress(testAddress), PowTest: true, } diff --git a/core/genesis.go b/core/genesis.go index ee99da5686..01ae8e9088 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -344,9 +344,14 @@ func DefaultRinkebyGenesisBlock() *Genesis { // DefaultDeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this // must be seeded with the -func DefaultDeveloperGenesisBlock(faucet common.Address) *Genesis { +func DefaultDeveloperGenesisBlock(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{ - Config: params.AllCliqueProtocolChanges, + Config: &config, ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...), GasLimit: 4712388, Difficulty: big.NewInt(1), @@ -359,7 +364,7 @@ func DefaultDeveloperGenesisBlock(faucet common.Address) *Genesis { common.Address{6}: GenesisAccount{Balance: big.NewInt(1)}, // ECAdd common.Address{7}: GenesisAccount{Balance: big.NewInt(1)}, // ECScalarMul common.Address{8}: GenesisAccount{Balance: big.NewInt(1)}, // ECPairing - faucet: GenesisAccount{Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))}, + faucet: GenesisAccount{Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(8))}, }, } }