Skip to content

Commit

Permalink
Merge pull request ethereum#243 from etclabscore/feat/dev-mode-ethash
Browse files Browse the repository at this point in the history
Add an Ethash Fake sealing option for `—dev` mode, using `—dev.ethash`
  • Loading branch information
ziogaschr authored Dec 4, 2020
2 parents 774bf52 + 190920d commit 028e166
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 19 deletions.
13 changes: 11 additions & 2 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ var (
utils.EthProtocolsFlag,
utils.DeveloperFlag,
utils.DeveloperPeriodFlag,
utils.DeveloperPoWFlag,
utils.ClassicFlag,
utils.MordorFlag,
utils.SocialFlag,
Expand All @@ -160,6 +161,7 @@ var (
utils.NetworkIdFlag,
utils.EthStatsURLFlag,
utils.FakePoWFlag,
utils.FakePoWPoissonFlag,
utils.NoCompactionFlag,
utils.GpoBlocksFlag,
utils.LegacyGpoBlocksFlag,
Expand Down Expand Up @@ -311,7 +313,10 @@ func checkMainnet(ctx *cli.Context) bool {
log.Info("Starting Geth on Görli testnet...")

case ctx.GlobalIsSet(utils.DeveloperFlag.Name):
log.Info("Starting Geth in ephemeral dev mode...")
log.Info("Starting Geth in ephemeral proof-of-authority network dev mode...")

case ctx.GlobalIsSet(utils.DeveloperPoWFlag.Name):
log.Info("Starting Geth in ephemeral proof-of-work network dev mode...")

case ctx.GlobalIsSet(utils.ClassicFlag.Name):
log.Info("Starting Geth on Ethereum Classic...")
Expand Down Expand Up @@ -488,7 +493,8 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) {
}

// Start auxiliary services if enabled
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
isDeveloperMode := ctx.GlobalBool(utils.DeveloperFlag.Name) || ctx.GlobalBool(utils.DeveloperPoWFlag.Name)
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || isDeveloperMode {
// Mining only makes sense if a full Ethereum node is running
if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {
utils.Fatalf("Light clients do not support mining")
Expand All @@ -510,6 +516,9 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) {
threads = ctx.GlobalInt(utils.LegacyMinerThreadsFlag.Name)
log.Warn("The flag --minerthreads is deprecated and will be removed in the future, please use --miner.threads")
}
if isDeveloperMode && !ctx.GlobalIsSet(utils.MinerThreadsFlag.Name) && !ctx.GlobalIsSet(utils.LegacyMinerThreadsFlag.Name) {
threads = 1
}
if err := ethBackend.StartMining(threads); err != nil {
utils.Fatalf("Failed to start mining: %v", err)
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
Flags: []cli.Flag{
utils.DeveloperFlag,
utils.DeveloperPeriodFlag,
utils.DeveloperPoWFlag,
},
},
{
Expand Down Expand Up @@ -214,6 +215,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
Name: "LOGGING AND DEBUGGING",
Flags: append([]cli.Flag{
utils.FakePoWFlag,
utils.FakePoWPoissonFlag,
utils.NoCompactionFlag,
}, debug.Flags...),
},
Expand Down
33 changes: 24 additions & 9 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,11 @@ var (
}
DeveloperPeriodFlag = cli.IntFlag{
Name: "dev.period",
Usage: "Block period to use in developer mode (0 = mine only if transaction pending)",
Usage: "Block period for proof-of-authority network to use in developer mode (0 = mine only if transaction pending)",
}
DeveloperPoWFlag = cli.BoolFlag{
Name: "dev.pow",
Usage: "Ephemeral proof-of-work network with a pre-funded developer account, mining enabled",
}
IdentityFlag = cli.StringFlag{
Name: "identity",
Expand Down Expand Up @@ -517,6 +521,10 @@ var (
Name: "fakepow",
Usage: "Disables proof-of-work verification",
}
FakePoWPoissonFlag = cli.BoolFlag{
Name: "fakepow.poisson",
Usage: "Disables proof-of-work verification and adds mining delay (Poisson) based on --miner.threads",
}
NoCompactionFlag = cli.BoolFlag{
Name: "nocompaction",
Usage: "Disables db compaction after import",
Expand Down Expand Up @@ -1252,7 +1260,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
cfg.NetRestrict = list
}

if ctx.GlobalBool(DeveloperFlag.Name) {
if ctx.GlobalBool(DeveloperFlag.Name) || ctx.GlobalBool(DeveloperPoWFlag.Name) {
// --dev mode can't use p2p networking.
cfg.MaxPeers = 0
cfg.ListenAddr = ":0"
Expand Down Expand Up @@ -1341,7 +1349,7 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) {
case ctx.GlobalIsSet(DataDirFlag.Name):
cfg.DataDir = ctx.GlobalString(DataDirFlag.Name)

case ctx.GlobalBool(DeveloperFlag.Name):
case ctx.GlobalBool(DeveloperFlag.Name) || ctx.GlobalBool(DeveloperPoWFlag.Name):
cfg.DataDir = "" // unless explicitly requested, use memory databases

case (ctx.GlobalBool(LegacyTestnetFlag.Name) || ctx.GlobalBool(RopstenFlag.Name)) && cfg.DataDir == node.DefaultDataDir():
Expand Down Expand Up @@ -1478,6 +1486,9 @@ func setEthash(ctx *cli.Context, cfg *eth.Config) {
setEthashCacheDir(ctx, cfg)
setEthashDatasetDir(ctx, cfg)

if ctx.GlobalBool(FakePoWPoissonFlag.Name) {
cfg.Ethash.PowMode = ethash.ModePoissonFake
}
if ctx.GlobalIsSet(EthashCachesInMemoryFlag.Name) {
cfg.Ethash.CachesInMem = ctx.GlobalInt(EthashCachesInMemoryFlag.Name)
}
Expand Down Expand Up @@ -1611,16 +1622,18 @@ func SetShhConfig(ctx *cli.Context, stack *node.Node) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
// Avoid conflicting network flags
CheckExclusive(ctx, DeveloperFlag, LegacyTestnetFlag, RopstenFlag, RinkebyFlag, GoerliFlag, YoloV1Flag, ClassicFlag, KottiFlag, MordorFlag, EthersocialFlag, SocialFlag)
CheckExclusive(ctx, DeveloperFlag, DeveloperPoWFlag, LegacyTestnetFlag, RopstenFlag, RinkebyFlag, GoerliFlag, YoloV1Flag, ClassicFlag, KottiFlag, MordorFlag, EthersocialFlag, SocialFlag)
CheckExclusive(ctx, LegacyLightServFlag, LightServeFlag, SyncModeFlag, "light")
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
CheckExclusive(ctx, DeveloperFlag, DeveloperPoWFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
CheckExclusive(ctx, GCModeFlag, "archive", TxLookupLimitFlag)
// todo(rjl493456442) make it available for les server
// Ancient tx indices pruning is not available for les server now
// since light client relies on the server for transaction status query.
CheckExclusive(ctx, LegacyLightServFlag, LightServeFlag, TxLookupLimitFlag)

CheckExclusive(ctx, AncientFlag, AncientRPCFlag)
CheckExclusive(ctx, DeveloperPoWFlag, DeveloperPeriodFlag, FakePoWFlag)
CheckExclusive(ctx, FakePoWFlag, FakePoWPoissonFlag)

var ks *keystore.KeyStore
if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
Expand Down Expand Up @@ -1790,7 +1803,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
}
}

if ctx.GlobalBool(DeveloperFlag.Name) {
if ctx.GlobalBool(DeveloperFlag.Name) || ctx.GlobalBool(DeveloperPoWFlag.Name) {
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337
}
Expand Down Expand Up @@ -1824,7 +1837,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
log.Info("Using developer account", "address", developer.Address)

// Create a new developer genesis block or reuse existing one
cfg.Genesis = params.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)
cfg.Genesis = params.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address, ctx.GlobalBool(DeveloperPoWFlag.Name))
if ctx.GlobalIsSet(DataDirFlag.Name) {
// Check if we have an already initialized chain and fall back to
// that if so. Otherwise we need to generate a new genesis spec.
Expand Down Expand Up @@ -2007,7 +2020,7 @@ func genesisForCtxChainConfig(ctx *cli.Context) *genesisT.Genesis {
}

func MakeGenesis(ctx *cli.Context) *genesisT.Genesis {
if ctx.GlobalBool(DeveloperFlag.Name) {
if ctx.GlobalBool(DeveloperFlag.Name) || ctx.GlobalBool(DeveloperPoWFlag.Name) {
Fatalf("Developer chains are ephemeral")
}
return genesisForCtxChainConfig(ctx)
Expand All @@ -2029,7 +2042,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readOnly bool) (chain *core.B
}, chainDb)
} else {
engine = ethash.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) {
if ctx.GlobalBool(FakePoWPoissonFlag.Name) {
engine = ethash.NewPoissonFaker()
} else if !ctx.GlobalBool(FakePoWFlag.Name) {
engine = ethash.New(ethash.Config{
CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir),
CachesInMem: eth.DefaultConfig.Ethash.CachesInMem,
Expand Down
12 changes: 12 additions & 0 deletions consensus/ethash/ethash.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,18 @@ func NewFakeDelayer(delay time.Duration) *Ethash {
}
}

// NewPoissonFaker creates a ethash consensus engine with a fake PoW scheme that
// accepts all blocks as valid, but delays mining by some time based on miner.threads, though
// they still have to conform to the Ethereum consensus rules.
func NewPoissonFaker() *Ethash {
return &Ethash{
config: Config{
PowMode: ModePoissonFake,
Log: log.Root(),
},
}
}

// NewFullFaker creates an ethash consensus engine with a full fake scheme that
// accepts all blocks as valid, without checking any consensus rules whatsoever.
func NewFullFaker() *Ethash {
Expand Down
2 changes: 1 addition & 1 deletion console/console_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester {
t.Fatalf("failed to create node: %v", err)
}
ethConf := &eth.Config{
Genesis: params.DeveloperGenesisBlock(15, common.Address{}),
Genesis: params.DeveloperGenesisBlock(15, common.Address{}, false),
Miner: miner.Config{
Etherbase: common.HexToAddress(testAddress),
},
Expand Down
3 changes: 3 additions & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ func CreateConsensusEngine(stack *node.Node, chainConfig ctypes.ChainConfigurato
case ethash.ModeFake:
log.Warn("Ethash used in fake mode")
return ethash.NewFaker()
case ethash.ModePoissonFake:
log.Warn("Ethash used in fake Poisson mode")
return ethash.NewPoissonFaker()
case ethash.ModeTest:
log.Warn("Ethash used in test mode")
return ethash.NewTester(nil, noverify)
Expand Down
2 changes: 1 addition & 1 deletion miner/miner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux) {
// Create chainConfig
memdb := memorydb.New()
chainDB := rawdb.NewDatabase(memdb)
genesis := params.DeveloperGenesisBlock(15, common.HexToAddress("12345"))
genesis := params.DeveloperGenesisBlock(15, common.HexToAddress("12345"), false)
chainConfig, _, err := core.SetupGenesisBlock(chainDB, genesis)
if err != nil {
t.Fatalf("can't create new chain config: %v", err)
Expand Down
84 changes: 78 additions & 6 deletions params/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params/types/coregeth"
"github.com/ethereum/go-ethereum/params/types/ctypes"
"github.com/ethereum/go-ethereum/params/types/genesisT"
"github.com/ethereum/go-ethereum/params/types/goethereum"
"github.com/ethereum/go-ethereum/params/vars"
)

// DefaultGenesisBlock returns the Ethereum main net genesis block.
Expand Down Expand Up @@ -86,17 +90,85 @@ func DefaultYoloV1GenesisBlock() *genesisT.Genesis {

// DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must
// be seeded with the
func DeveloperGenesisBlock(period uint64, faucet common.Address) *genesisT.Genesis {
// Override the default period to the user requested one
config := *AllCliqueProtocolChanges
config.Clique.Period = period
func DeveloperGenesisBlock(period uint64, faucet common.Address, useEthash bool) *genesisT.Genesis {
if !useEthash {
// Make a copy to avoid unpredicted contamination.
config := &goethereum.ChainConfig{}
*config = *AllCliqueProtocolChanges

// Override the default period to the user requested one
config.Clique.Period = period
// Assemble and return the genesis with the precompiles and faucet pre-funded
return &genesisT.Genesis{
Config: config,
ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
GasLimit: 6283185,
Difficulty: big.NewInt(1),
Alloc: map[common.Address]genesisT.GenesisAccount{
common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
},
}
}

// Use an ETC equivalent of AllEthashProtocolChanges.
// This will allow initial permanent disposal of the difficulty bomb,
// and we'll override the monetary policy block reward schedule to be a non-occurring.
//
// This was originally intended to be as follows, but import cycles prevent it.
// Leaving here to show provenance of initial configuration value.
// config := &coregeth.CoreGethChainConfig{}
// *config = *tests.Forks["ETC_Phoenix"].(*coregeth.CoreGethChainConfig)
config := &coregeth.CoreGethChainConfig{
NetworkID: AllCliqueProtocolChanges.GetChainID().Uint64(), // Use network and chain IDs equivalent to Clique configuration, ie 1337.
Ethash: new(ctypes.EthashConfig),
ChainID: AllCliqueProtocolChanges.GetChainID(),
EIP2FBlock: big.NewInt(0),
EIP7FBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP160FBlock: big.NewInt(0),
EIP161FBlock: big.NewInt(0),
EIP170FBlock: big.NewInt(0),
EIP100FBlock: big.NewInt(0),
EIP140FBlock: big.NewInt(0),
EIP198FBlock: big.NewInt(0),
EIP211FBlock: big.NewInt(0),
EIP212FBlock: big.NewInt(0),
EIP213FBlock: big.NewInt(0),
EIP214FBlock: big.NewInt(0),
EIP658FBlock: big.NewInt(0),
EIP145FBlock: big.NewInt(0),
EIP1014FBlock: big.NewInt(0),
EIP1052FBlock: big.NewInt(0),
EIP1283FBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
EIP152FBlock: big.NewInt(0),
EIP1108FBlock: big.NewInt(0),
EIP1344FBlock: big.NewInt(0),
EIP1884FBlock: big.NewInt(0),
EIP2028FBlock: big.NewInt(0),
EIP2200FBlock: big.NewInt(0),
DisposalBlock: big.NewInt(0),
ECIP1017FBlock: nil, // disable block reward disinflation
ECIP1017EraRounds: nil, // ^
ECIP1010PauseBlock: nil, // no need for difficulty bomb delay (see disposal block)
ECIP1010Length: nil, // ^
}

// Assemble and return the genesis with the precompiles and faucet pre-funded
return &genesisT.Genesis{
Config: &config,
Config: config,
ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
GasLimit: 6283185,
Difficulty: big.NewInt(1),
Difficulty: vars.MinimumDifficulty,
Alloc: map[common.Address]genesisT.GenesisAccount{
common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
Expand Down

0 comments on commit 028e166

Please sign in to comment.