From 533e03ea23e1400b3da5dd1e035f063f658552e4 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 16 Nov 2017 20:29:45 +0800 Subject: [PATCH 1/4] cmd, consensus, eth: split ethash related config to it own --- cmd/utils/flags.go | 26 +++++++------- consensus/ethash/ethash.go | 70 +++++++++++++++++++++++--------------- console/console_test.go | 5 ++- eth/backend.go | 10 +++--- eth/config.go | 39 +++++++++------------ eth/gen_config.go | 36 ++++++++++---------- 6 files changed, 99 insertions(+), 87 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 5c29292685cd..46c9adc12bc0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -217,27 +217,27 @@ var ( EthashCachesInMemoryFlag = cli.IntFlag{ Name: "ethash.cachesinmem", Usage: "Number of recent ethash caches to keep in memory (16MB each)", - Value: eth.DefaultConfig.EthashCachesInMem, + Value: eth.DefaultConfig.Ethash.CachesInMem, } EthashCachesOnDiskFlag = cli.IntFlag{ Name: "ethash.cachesondisk", Usage: "Number of recent ethash caches to keep on disk (16MB each)", - Value: eth.DefaultConfig.EthashCachesOnDisk, + Value: eth.DefaultConfig.Ethash.CachesOnDisk, } EthashDatasetDirFlag = DirectoryFlag{ Name: "ethash.dagdir", Usage: "Directory to store the ethash mining DAGs (default = inside home folder)", - Value: DirectoryString{eth.DefaultConfig.EthashDatasetDir}, + Value: DirectoryString{eth.DefaultConfig.Ethash.DatasetDir}, } EthashDatasetsInMemoryFlag = cli.IntFlag{ Name: "ethash.dagsinmem", Usage: "Number of recent ethash mining DAGs to keep in memory (1+GB each)", - Value: eth.DefaultConfig.EthashDatasetsInMem, + Value: eth.DefaultConfig.Ethash.DatasetsInMem, } EthashDatasetsOnDiskFlag = cli.IntFlag{ Name: "ethash.dagsondisk", Usage: "Number of recent ethash mining DAGs to keep on disk (1+GB each)", - Value: eth.DefaultConfig.EthashDatasetsOnDisk, + Value: eth.DefaultConfig.Ethash.DatasetsOnDisk, } // Transaction pool settings TxPoolNoLocalsFlag = cli.BoolFlag{ @@ -910,22 +910,22 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { func setEthash(ctx *cli.Context, cfg *eth.Config) { if ctx.GlobalIsSet(EthashCacheDirFlag.Name) { - cfg.EthashCacheDir = ctx.GlobalString(EthashCacheDirFlag.Name) + cfg.Ethash.CacheDir = ctx.GlobalString(EthashCacheDirFlag.Name) } if ctx.GlobalIsSet(EthashDatasetDirFlag.Name) { - cfg.EthashDatasetDir = ctx.GlobalString(EthashDatasetDirFlag.Name) + cfg.Ethash.DatasetDir = ctx.GlobalString(EthashDatasetDirFlag.Name) } if ctx.GlobalIsSet(EthashCachesInMemoryFlag.Name) { - cfg.EthashCachesInMem = ctx.GlobalInt(EthashCachesInMemoryFlag.Name) + cfg.Ethash.CachesInMem = ctx.GlobalInt(EthashCachesInMemoryFlag.Name) } if ctx.GlobalIsSet(EthashCachesOnDiskFlag.Name) { - cfg.EthashCachesOnDisk = ctx.GlobalInt(EthashCachesOnDiskFlag.Name) + cfg.Ethash.CachesOnDisk = ctx.GlobalInt(EthashCachesOnDiskFlag.Name) } if ctx.GlobalIsSet(EthashDatasetsInMemoryFlag.Name) { - cfg.EthashDatasetsInMem = ctx.GlobalInt(EthashDatasetsInMemoryFlag.Name) + cfg.Ethash.DatasetsInMem = ctx.GlobalInt(EthashDatasetsInMemoryFlag.Name) } if ctx.GlobalIsSet(EthashDatasetsOnDiskFlag.Name) { - cfg.EthashDatasetsOnDisk = ctx.GlobalInt(EthashDatasetsOnDiskFlag.Name) + cfg.Ethash.DatasetsOnDisk = ctx.GlobalInt(EthashDatasetsOnDiskFlag.Name) } } @@ -1160,8 +1160,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai engine = ethash.NewFaker() if !ctx.GlobalBool(FakePoWFlag.Name) { engine = ethash.New( - stack.ResolvePath(eth.DefaultConfig.EthashCacheDir), eth.DefaultConfig.EthashCachesInMem, eth.DefaultConfig.EthashCachesOnDisk, - stack.ResolvePath(eth.DefaultConfig.EthashDatasetDir), eth.DefaultConfig.EthashDatasetsInMem, eth.DefaultConfig.EthashDatasetsOnDisk, + stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir), eth.DefaultConfig.Ethash.CachesInMem, eth.DefaultConfig.Ethash.CachesOnDisk, + stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir), eth.DefaultConfig.Ethash.DatasetsInMem, eth.DefaultConfig.Ethash.DatasetsOnDisk, ) } } diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index dd61470728e3..d21544fe6fa4 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -320,15 +320,25 @@ func MakeDataset(block uint64, dir string) { d.release() } +// EthashConfig are the configuration parameters of the ethash. +type EthashConfig struct { + CacheDir string + CachesInMem int + CachesOnDisk int + DatasetDir string + DatasetsInMem int + DatasetsOnDisk int + + // Miscellaneous options + PowFake bool + PowTest bool + PowShared bool +} + // Ethash is a consensus engine based on proot-of-work implementing the ethash // algorithm. type Ethash struct { - cachedir string // Data directory to store the verification caches - cachesinmem int // Number of caches to keep in memory - cachesondisk int // Number of caches to keep on disk - dagdir string // Data directory to store full mining datasets - dagsinmem int // Number of mining datasets to keep in memory - dagsondisk int // Number of mining datasets to keep on disk + EthashConfig caches map[uint64]*cache // In memory caches to avoid regenerating too often fcache *cache // Pre-generated cache for the estimated future epoch @@ -365,16 +375,18 @@ func New(cachedir string, cachesinmem, cachesondisk int, dagdir string, dagsinme log.Info("Disk storage enabled for ethash DAGs", "dir", dagdir, "count", dagsondisk) } return &Ethash{ - cachedir: cachedir, - cachesinmem: cachesinmem, - cachesondisk: cachesondisk, - dagdir: dagdir, - dagsinmem: dagsinmem, - dagsondisk: dagsondisk, - caches: make(map[uint64]*cache), - datasets: make(map[uint64]*dataset), - update: make(chan struct{}), - hashrate: metrics.NewMeter(), + EthashConfig: EthashConfig{ + CacheDir: cachedir, + CachesInMem: cachesinmem, + CachesOnDisk: cachesondisk, + DatasetDir: dagdir, + DatasetsInMem: dagsinmem, + DatasetsOnDisk: dagsondisk, + }, + caches: make(map[uint64]*cache), + datasets: make(map[uint64]*dataset), + update: make(chan struct{}), + hashrate: metrics.NewMeter(), } } @@ -382,12 +394,14 @@ func New(cachedir string, cachesinmem, cachesondisk int, dagdir string, dagsinme // purposes. func NewTester() *Ethash { return &Ethash{ - cachesinmem: 1, - caches: make(map[uint64]*cache), - datasets: make(map[uint64]*dataset), - tester: true, - update: make(chan struct{}), - hashrate: metrics.NewMeter(), + EthashConfig: EthashConfig{ + CachesInMem: 1, + }, + caches: make(map[uint64]*cache), + datasets: make(map[uint64]*dataset), + tester: true, + update: make(chan struct{}), + hashrate: metrics.NewMeter(), } } @@ -436,7 +450,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { current, future := ethash.caches[epoch], (*cache)(nil) if current == nil { // No in-memory cache, evict the oldest if the cache limit was reached - for len(ethash.caches) > 0 && len(ethash.caches) >= ethash.cachesinmem { + for len(ethash.caches) > 0 && len(ethash.caches) >= ethash.CachesInMem { var evict *cache for _, cache := range ethash.caches { if evict == nil || evict.used.After(cache.used) { @@ -473,7 +487,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.cachedir, ethash.cachesondisk, ethash.tester) + current.generate(ethash.CacheDir, ethash.CachesOnDisk, ethash.tester) current.lock.Lock() current.used = time.Now() @@ -481,7 +495,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { // If we exhausted the future cache, now's a good time to regenerate it if future != nil { - go future.generate(ethash.cachedir, ethash.cachesondisk, ethash.tester) + go future.generate(ethash.CacheDir, ethash.CachesOnDisk, ethash.tester) } return current.cache } @@ -498,7 +512,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { current, future := ethash.datasets[epoch], (*dataset)(nil) if current == nil { // No in-memory dataset, evict the oldest if the dataset limit was reached - for len(ethash.datasets) > 0 && len(ethash.datasets) >= ethash.dagsinmem { + for len(ethash.datasets) > 0 && len(ethash.datasets) >= ethash.DatasetsInMem { var evict *dataset for _, dataset := range ethash.datasets { if evict == nil || evict.used.After(dataset.used) { @@ -536,7 +550,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.dagdir, ethash.dagsondisk, ethash.tester) + current.generate(ethash.DatasetDir, ethash.DatasetsOnDisk, ethash.tester) current.lock.Lock() current.used = time.Now() @@ -544,7 +558,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { // If we exhausted the future dataset, now's a good time to regenerate it if future != nil { - go future.generate(ethash.dagdir, ethash.dagsondisk, ethash.tester) + go future.generate(ethash.DatasetDir, ethash.DatasetsOnDisk, ethash.tester) } return current.dataset } diff --git a/console/console_test.go b/console/console_test.go index a159b62bbf8c..a97a4372753a 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -27,6 +27,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/internal/jsre" @@ -96,7 +97,9 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { ethConf := ð.Config{ Genesis: core.DeveloperGenesisBlock(15, common.Address{}), Etherbase: common.HexToAddress(testAddress), - PowTest: true, + Ethash: ethash.EthashConfig{ + PowTest: true, + }, } if confOverride != nil { confOverride(ethConf) diff --git a/eth/backend.go b/eth/backend.go index 1cd9e8fffa3e..55373daec070 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -216,18 +216,18 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *Config, chainConfig } // Otherwise assume proof-of-work switch { - case config.PowFake: + case config.Ethash.PowFake: log.Warn("Ethash used in fake mode") return ethash.NewFaker() - case config.PowTest: + case config.Ethash.PowTest: log.Warn("Ethash used in test mode") return ethash.NewTester() - case config.PowShared: + case config.Ethash.PowShared: log.Warn("Ethash used in shared mode") return ethash.NewShared() default: - engine := ethash.New(ctx.ResolvePath(config.EthashCacheDir), config.EthashCachesInMem, config.EthashCachesOnDisk, - config.EthashDatasetDir, config.EthashDatasetsInMem, config.EthashDatasetsOnDisk) + engine := ethash.New(ctx.ResolvePath(config.Ethash.CacheDir), config.Ethash.CachesInMem, config.Ethash.CachesOnDisk, + config.Ethash.DatasetDir, config.Ethash.DatasetsInMem, config.Ethash.DatasetsOnDisk) engine.SetThreads(-1) // Disable CPU mining return engine } diff --git a/eth/config.go b/eth/config.go index 7bcfd403ea1e..efc326deb2b6 100644 --- a/eth/config.go +++ b/eth/config.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -33,16 +34,18 @@ import ( // DefaultConfig contains default settings for use on the Ethereum main net. var DefaultConfig = Config{ - SyncMode: downloader.FastSync, - EthashCacheDir: "ethash", - EthashCachesInMem: 2, - EthashCachesOnDisk: 3, - EthashDatasetsInMem: 1, - EthashDatasetsOnDisk: 2, - NetworkId: 1, - LightPeers: 20, - DatabaseCache: 128, - GasPrice: big.NewInt(18 * params.Shannon), + SyncMode: downloader.FastSync, + Ethash: ethash.EthashConfig{ + CacheDir: "ethash", + CachesInMem: 2, + CachesOnDisk: 3, + DatasetsInMem: 1, + DatasetsOnDisk: 2, + }, + NetworkId: 1, + LightPeers: 20, + DatabaseCache: 128, + GasPrice: big.NewInt(18 * params.Shannon), TxPool: core.DefaultTxPoolConfig, GPO: gasprice.Config{ @@ -59,9 +62,9 @@ func init() { } } if runtime.GOOS == "windows" { - DefaultConfig.EthashDatasetDir = filepath.Join(home, "AppData", "Ethash") + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "AppData", "Ethash") } else { - DefaultConfig.EthashDatasetDir = filepath.Join(home, ".ethash") + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, ".ethash") } } @@ -92,12 +95,7 @@ type Config struct { GasPrice *big.Int // Ethash options - EthashCacheDir string - EthashCachesInMem int - EthashCachesOnDisk int - EthashDatasetDir string - EthashDatasetsInMem int - EthashDatasetsOnDisk int + Ethash ethash.EthashConfig // Transaction pool options TxPool core.TxPoolConfig @@ -109,10 +107,7 @@ type Config struct { EnablePreimageRecording bool // Miscellaneous options - DocRoot string `toml:"-"` - PowFake bool `toml:"-"` - PowTest bool `toml:"-"` - PowShared bool `toml:"-"` + DocRoot string `toml:"-"` } type configMarshaling struct { diff --git a/eth/gen_config.go b/eth/gen_config.go index 4a4cd7b9c506..2c703af119ed 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -54,19 +54,19 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.MinerThreads = c.MinerThreads enc.ExtraData = c.ExtraData enc.GasPrice = c.GasPrice - enc.EthashCacheDir = c.EthashCacheDir - enc.EthashCachesInMem = c.EthashCachesInMem - enc.EthashCachesOnDisk = c.EthashCachesOnDisk - enc.EthashDatasetDir = c.EthashDatasetDir - enc.EthashDatasetsInMem = c.EthashDatasetsInMem - enc.EthashDatasetsOnDisk = c.EthashDatasetsOnDisk + enc.EthashCacheDir = c.Ethash.CacheDir + enc.EthashCachesInMem = c.Ethash.CachesInMem + enc.EthashCachesOnDisk = c.Ethash.CachesOnDisk + enc.EthashDatasetDir = c.Ethash.DatasetDir + enc.EthashDatasetsInMem = c.Ethash.DatasetsInMem + enc.EthashDatasetsOnDisk = c.Ethash.DatasetsOnDisk enc.TxPool = c.TxPool enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot - enc.PowFake = c.PowFake - enc.PowTest = c.PowTest - enc.PowShared = c.PowShared + enc.PowFake = c.Ethash.PowFake + enc.PowTest = c.Ethash.PowTest + enc.PowShared = c.Ethash.PowShared return &enc, nil } @@ -140,22 +140,22 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { c.GasPrice = dec.GasPrice } if dec.EthashCacheDir != nil { - c.EthashCacheDir = *dec.EthashCacheDir + c.Ethash.CacheDir = *dec.EthashCacheDir } if dec.EthashCachesInMem != nil { - c.EthashCachesInMem = *dec.EthashCachesInMem + c.Ethash.CachesInMem = *dec.EthashCachesInMem } if dec.EthashCachesOnDisk != nil { - c.EthashCachesOnDisk = *dec.EthashCachesOnDisk + c.Ethash.CachesOnDisk = *dec.EthashCachesOnDisk } if dec.EthashDatasetDir != nil { - c.EthashDatasetDir = *dec.EthashDatasetDir + c.Ethash.DatasetDir = *dec.EthashDatasetDir } if dec.EthashDatasetsInMem != nil { - c.EthashDatasetsInMem = *dec.EthashDatasetsInMem + c.Ethash.DatasetsInMem = *dec.EthashDatasetsInMem } if dec.EthashDatasetsOnDisk != nil { - c.EthashDatasetsOnDisk = *dec.EthashDatasetsOnDisk + c.Ethash.DatasetsOnDisk = *dec.EthashDatasetsOnDisk } if dec.TxPool != nil { c.TxPool = *dec.TxPool @@ -170,13 +170,13 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { c.DocRoot = *dec.DocRoot } if dec.PowFake != nil { - c.PowFake = *dec.PowFake + c.Ethash.PowFake = *dec.PowFake } if dec.PowTest != nil { - c.PowTest = *dec.PowTest + c.Ethash.PowTest = *dec.PowTest } if dec.PowShared != nil { - c.PowShared = *dec.PowShared + c.Ethash.PowShared = *dec.PowShared } return nil } From 8913f67f8e4928ef4fb71be25459be1cbb8da29a Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 23 Nov 2017 21:37:10 +0800 Subject: [PATCH 2/4] eth, consensus: minor polish --- cmd/utils/flags.go | 12 ++-- consensus/ethash/algorithm_test.go | 3 +- consensus/ethash/consensus.go | 10 ++-- consensus/ethash/ethash.go | 88 +++++++++++++++++------------- consensus/ethash/sealer.go | 2 +- console/console_test.go | 4 +- eth/backend.go | 20 ++++--- eth/config.go | 4 +- eth/gen_config.go | 12 ++-- les/backend.go | 2 +- 10 files changed, 88 insertions(+), 69 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 46c9adc12bc0..9fbad8daba2c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1159,10 +1159,14 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai } else { engine = ethash.NewFaker() if !ctx.GlobalBool(FakePoWFlag.Name) { - engine = ethash.New( - stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir), eth.DefaultConfig.Ethash.CachesInMem, eth.DefaultConfig.Ethash.CachesOnDisk, - stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir), eth.DefaultConfig.Ethash.DatasetsInMem, eth.DefaultConfig.Ethash.DatasetsOnDisk, - ) + engine = ethash.New(ethash.Config{ + CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir), + CachesInMem: eth.DefaultConfig.Ethash.CachesInMem, + CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk, + DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir), + DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem, + DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk, + }) } } vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)} diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go index 7e4307a74a69..ca17ae019cc4 100644 --- a/consensus/ethash/algorithm_test.go +++ b/consensus/ethash/algorithm_test.go @@ -703,8 +703,7 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) { go func(idx int) { defer pend.Done() - - ethash := New(cachedir, 0, 1, "", 0, 0) + ethash := New(Config{cachedir, 0, 1, "", 0, 0, false, false, false, false}) if err := ethash.VerifySeal(nil, block.Header()); err != nil { t.Errorf("proc %d: block verification failed: %v", idx, err) } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 6a19d449f346..684f470764af 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -68,7 +68,7 @@ func (ethash *Ethash) Author(header *types.Header) (common.Address, error) { // stock Ethereum ethash engine. func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { // If we're running a full engine faking, accept any input as valid - if ethash.fakeFull { + if ethash.config.FullFake { return nil } // Short circuit if the header is known, or it's parent not @@ -89,7 +89,7 @@ func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.He // a results channel to retrieve the async verifications. func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { // If we're running a full engine faking, accept any input as valid - if ethash.fakeFull || len(headers) == 0 { + if ethash.config.FullFake || len(headers) == 0 { abort, results := make(chan struct{}), make(chan error, len(headers)) for i := 0; i < len(headers); i++ { results <- nil @@ -169,7 +169,7 @@ func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers [] // rules of the stock Ethereum ethash engine. func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { // If we're running a full engine faking, accept any input as valid - if ethash.fakeFull { + if ethash.config.FullFake { return nil } // Verify that there are at most 2 uncles included in this block @@ -455,7 +455,7 @@ func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int { // the PoW difficulty requirements. func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error { // If we're running a fake PoW, accept any seal as valid - if ethash.fakeMode { + if ethash.config.Fake { time.Sleep(ethash.fakeDelay) if ethash.fakeFail == header.Number.Uint64() { return errInvalidPoW @@ -480,7 +480,7 @@ func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Head cache := ethash.cache(number) size := datasetSize(number) - if ethash.tester { + if ethash.config.Test { size = 32 * 1024 } digest, result := hashimotoLight(size, cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64()) diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index d21544fe6fa4..b3d4b2b4b66f 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -45,7 +45,7 @@ var ( maxUint256 = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0)) // sharedEthash is a full instance that can be shared between multiple users. - sharedEthash = New("", 3, 0, "", 1, 0) + sharedEthash = New(Config{"", 3, 0, "", 1, 0, false, false, false, false}) // algorithmRevision is the data structure version used for file naming. algorithmRevision = 23 @@ -320,8 +320,8 @@ func MakeDataset(block uint64, dir string) { d.release() } -// EthashConfig are the configuration parameters of the ethash. -type EthashConfig struct { +// Config are the configuration parameters of the ethash. +type Config struct { CacheDir string CachesInMem int CachesOnDisk int @@ -329,16 +329,17 @@ type EthashConfig struct { DatasetsInMem int DatasetsOnDisk int - // Miscellaneous options - PowFake bool - PowTest bool - PowShared bool + // The fields below are configurations for testing + Fake bool + FullFake bool + Test bool + Shared bool } // Ethash is a consensus engine based on proot-of-work implementing the ethash // algorithm. type Ethash struct { - EthashConfig + config Config caches map[uint64]*cache // In memory caches to avoid regenerating too often fcache *cache // Pre-generated cache for the estimated future epoch @@ -352,10 +353,7 @@ type Ethash struct { hashrate metrics.Meter // Meter tracking the average hashrate // The fields below are hooks for testing - tester bool // Flag whether to use a smaller test dataset shared *Ethash // Shared PoW verifier to avoid cache regeneration - fakeMode bool // Flag whether to disable PoW checking - fakeFull bool // Flag whether to disable all consensus rules fakeFail uint64 // Block number which fails PoW check even in fake mode fakeDelay time.Duration // Time delay to sleep for before returning from verify @@ -363,26 +361,19 @@ type Ethash struct { } // New creates a full sized ethash PoW scheme. -func New(cachedir string, cachesinmem, cachesondisk int, dagdir string, dagsinmem, dagsondisk int) *Ethash { - if cachesinmem <= 0 { - log.Warn("One ethash cache must always be in memory", "requested", cachesinmem) - cachesinmem = 1 +func New(config Config) *Ethash { + if config.CachesInMem <= 0 { + log.Warn("One ethash cache must always be in memory", "requested", config.CachesInMem) + config.CachesInMem = 1 } - if cachedir != "" && cachesondisk > 0 { - log.Info("Disk storage enabled for ethash caches", "dir", cachedir, "count", cachesondisk) + if config.CacheDir != "" && config.CachesOnDisk > 0 { + log.Info("Disk storage enabled for ethash caches", "dir", config.CacheDir, "count", config.CachesOnDisk) } - if dagdir != "" && dagsondisk > 0 { - log.Info("Disk storage enabled for ethash DAGs", "dir", dagdir, "count", dagsondisk) + if config.DatasetDir != "" && config.DatasetsOnDisk > 0 { + log.Info("Disk storage enabled for ethash DAGs", "dir", config.DatasetDir, "count", config.DatasetsOnDisk) } return &Ethash{ - EthashConfig: EthashConfig{ - CacheDir: cachedir, - CachesInMem: cachesinmem, - CachesOnDisk: cachesondisk, - DatasetDir: dagdir, - DatasetsInMem: dagsinmem, - DatasetsOnDisk: dagsondisk, - }, + config: config, caches: make(map[uint64]*cache), datasets: make(map[uint64]*dataset), update: make(chan struct{}), @@ -394,12 +385,12 @@ func New(cachedir string, cachesinmem, cachesondisk int, dagdir string, dagsinme // purposes. func NewTester() *Ethash { return &Ethash{ - EthashConfig: EthashConfig{ + config: Config{ CachesInMem: 1, + Test: true, }, caches: make(map[uint64]*cache), datasets: make(map[uint64]*dataset), - tester: true, update: make(chan struct{}), hashrate: metrics.NewMeter(), } @@ -409,27 +400,46 @@ func NewTester() *Ethash { // all blocks' seal as valid, though they still have to conform to the Ethereum // consensus rules. func NewFaker() *Ethash { - return &Ethash{fakeMode: true} + return &Ethash{ + config: Config{ + Fake: true, + }, + } } // NewFakeFailer creates a ethash consensus engine with a fake PoW scheme that // accepts all blocks as valid apart from the single one specified, though they // still have to conform to the Ethereum consensus rules. func NewFakeFailer(fail uint64) *Ethash { - return &Ethash{fakeMode: true, fakeFail: fail} + return &Ethash{ + config: Config{ + Fake: true, + }, + fakeFail: fail, + } } // NewFakeDelayer creates a ethash consensus engine with a fake PoW scheme that // accepts all blocks as valid, but delays verifications by some time, though // they still have to conform to the Ethereum consensus rules. func NewFakeDelayer(delay time.Duration) *Ethash { - return &Ethash{fakeMode: true, fakeDelay: delay} + return &Ethash{ + config: Config{ + Fake: true, + }, + fakeDelay: delay, + } } // 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 { - return &Ethash{fakeMode: true, fakeFull: true} + return &Ethash{ + config: Config{ + Fake: true, + FullFake: true, + }, + } } // NewShared creates a full sized ethash PoW shared between all requesters running @@ -450,7 +460,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { current, future := ethash.caches[epoch], (*cache)(nil) if current == nil { // No in-memory cache, evict the oldest if the cache limit was reached - for len(ethash.caches) > 0 && len(ethash.caches) >= ethash.CachesInMem { + for len(ethash.caches) > 0 && len(ethash.caches) >= ethash.config.CachesInMem { var evict *cache for _, cache := range ethash.caches { if evict == nil || evict.used.After(cache.used) { @@ -487,7 +497,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.CacheDir, ethash.CachesOnDisk, ethash.tester) + current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.Test) current.lock.Lock() current.used = time.Now() @@ -495,7 +505,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { // If we exhausted the future cache, now's a good time to regenerate it if future != nil { - go future.generate(ethash.CacheDir, ethash.CachesOnDisk, ethash.tester) + go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.Test) } return current.cache } @@ -512,7 +522,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { current, future := ethash.datasets[epoch], (*dataset)(nil) if current == nil { // No in-memory dataset, evict the oldest if the dataset limit was reached - for len(ethash.datasets) > 0 && len(ethash.datasets) >= ethash.DatasetsInMem { + for len(ethash.datasets) > 0 && len(ethash.datasets) >= ethash.config.DatasetsInMem { var evict *dataset for _, dataset := range ethash.datasets { if evict == nil || evict.used.After(dataset.used) { @@ -550,7 +560,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.DatasetDir, ethash.DatasetsOnDisk, ethash.tester) + current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.Test) current.lock.Lock() current.used = time.Now() @@ -558,7 +568,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { // If we exhausted the future dataset, now's a good time to regenerate it if future != nil { - go future.generate(ethash.DatasetDir, ethash.DatasetsOnDisk, ethash.tester) + go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.Test) } return current.dataset } diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go index 784e8f6491f2..62d056dd098a 100644 --- a/consensus/ethash/sealer.go +++ b/consensus/ethash/sealer.go @@ -34,7 +34,7 @@ import ( // the block's difficulty requirements. func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) { // If we're running a fake PoW, simply return a 0 nonce immediately - if ethash.fakeMode { + if ethash.config.Fake { header := block.Header() header.Nonce, header.MixDigest = types.BlockNonce{}, common.Hash{} return block.WithSeal(header), nil diff --git a/console/console_test.go b/console/console_test.go index a97a4372753a..492a55733f03 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -97,8 +97,8 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { ethConf := ð.Config{ Genesis: core.DeveloperGenesisBlock(15, common.Address{}), Etherbase: common.HexToAddress(testAddress), - Ethash: ethash.EthashConfig{ - PowTest: true, + Ethash: ethash.Config{ + Test: true, }, } if confOverride != nil { diff --git a/eth/backend.go b/eth/backend.go index 55373daec070..1104e8909e64 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -125,7 +125,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { chainConfig: chainConfig, eventMux: ctx.EventMux, accountManager: ctx.AccountManager, - engine: CreateConsensusEngine(ctx, config, chainConfig, chainDb), + engine: CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb), shutdownChan: make(chan bool), stopDbUpgrade: stopDbUpgrade, networkId: config.NetworkId, @@ -209,25 +209,31 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data } // CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service -func CreateConsensusEngine(ctx *node.ServiceContext, config *Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine { +func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine { // If proof-of-authority is requested, set it up if chainConfig.Clique != nil { return clique.New(chainConfig.Clique, db) } // Otherwise assume proof-of-work switch { - case config.Ethash.PowFake: + case config.Fake: log.Warn("Ethash used in fake mode") return ethash.NewFaker() - case config.Ethash.PowTest: + case config.Test: log.Warn("Ethash used in test mode") return ethash.NewTester() - case config.Ethash.PowShared: + case config.Shared: log.Warn("Ethash used in shared mode") return ethash.NewShared() default: - engine := ethash.New(ctx.ResolvePath(config.Ethash.CacheDir), config.Ethash.CachesInMem, config.Ethash.CachesOnDisk, - config.Ethash.DatasetDir, config.Ethash.DatasetsInMem, config.Ethash.DatasetsOnDisk) + engine := ethash.New(ethash.Config{ + CacheDir: ctx.ResolvePath(config.CacheDir), + CachesInMem: config.CachesInMem, + CachesOnDisk: config.CachesOnDisk, + DatasetDir: config.DatasetDir, + DatasetsInMem: config.DatasetsInMem, + DatasetsOnDisk: config.DatasetsOnDisk, + }) engine.SetThreads(-1) // Disable CPU mining return engine } diff --git a/eth/config.go b/eth/config.go index efc326deb2b6..383cd6783c12 100644 --- a/eth/config.go +++ b/eth/config.go @@ -35,7 +35,7 @@ import ( // DefaultConfig contains default settings for use on the Ethereum main net. var DefaultConfig = Config{ SyncMode: downloader.FastSync, - Ethash: ethash.EthashConfig{ + Ethash: ethash.Config{ CacheDir: "ethash", CachesInMem: 2, CachesOnDisk: 3, @@ -95,7 +95,7 @@ type Config struct { GasPrice *big.Int // Ethash options - Ethash ethash.EthashConfig + Ethash ethash.Config // Transaction pool options TxPool core.TxPoolConfig diff --git a/eth/gen_config.go b/eth/gen_config.go index 2c703af119ed..134fae7465b8 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -64,9 +64,9 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot - enc.PowFake = c.Ethash.PowFake - enc.PowTest = c.Ethash.PowTest - enc.PowShared = c.Ethash.PowShared + enc.PowFake = c.Ethash.Fake + enc.PowTest = c.Ethash.Test + enc.PowShared = c.Ethash.Shared return &enc, nil } @@ -170,13 +170,13 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { c.DocRoot = *dec.DocRoot } if dec.PowFake != nil { - c.Ethash.PowFake = *dec.PowFake + c.Ethash.Fake = *dec.PowFake } if dec.PowTest != nil { - c.Ethash.PowTest = *dec.PowTest + c.Ethash.Test = *dec.PowTest } if dec.PowShared != nil { - c.Ethash.PowShared = *dec.PowShared + c.Ethash.Shared = *dec.PowShared } return nil } diff --git a/les/backend.go b/les/backend.go index 333df920e0f3..7180b81d768b 100644 --- a/les/backend.go +++ b/les/backend.go @@ -98,7 +98,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { peers: peers, reqDist: newRequestDistributor(peers, quitSync), accountManager: ctx.AccountManager, - engine: eth.CreateConsensusEngine(ctx, config, chainConfig, chainDb), + engine: eth.CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb), shutdownChan: make(chan bool), networkId: config.NetworkId, bloomRequests: make(chan chan *bloombits.Retrieval), From 2a0d4a6b96e2a04a89cc933cf3cfc9afbc8af482 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 23 Nov 2017 21:58:21 +0800 Subject: [PATCH 3/4] eth, consenus, console: compress pow testing config field to single one --- consensus/ethash/algorithm_test.go | 2 +- consensus/ethash/consensus.go | 10 ++++---- consensus/ethash/ethash.go | 38 +++++++++++++++++------------- consensus/ethash/sealer.go | 2 +- console/console_test.go | 2 +- eth/backend.go | 6 ++--- eth/gen_config.go | 27 +++++++-------------- 7 files changed, 40 insertions(+), 47 deletions(-) diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go index ca17ae019cc4..38477f0f715e 100644 --- a/consensus/ethash/algorithm_test.go +++ b/consensus/ethash/algorithm_test.go @@ -703,7 +703,7 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) { go func(idx int) { defer pend.Done() - ethash := New(Config{cachedir, 0, 1, "", 0, 0, false, false, false, false}) + ethash := New(Config{cachedir, 0, 1, "", 0, 0, Normal}) if err := ethash.VerifySeal(nil, block.Header()); err != nil { t.Errorf("proc %d: block verification failed: %v", idx, err) } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 684f470764af..7a598e8e8101 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -68,7 +68,7 @@ func (ethash *Ethash) Author(header *types.Header) (common.Address, error) { // stock Ethereum ethash engine. func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { // If we're running a full engine faking, accept any input as valid - if ethash.config.FullFake { + if ethash.config.PowMode == FullFake { return nil } // Short circuit if the header is known, or it's parent not @@ -89,7 +89,7 @@ func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.He // a results channel to retrieve the async verifications. func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { // If we're running a full engine faking, accept any input as valid - if ethash.config.FullFake || len(headers) == 0 { + if ethash.config.PowMode == FullFake || len(headers) == 0 { abort, results := make(chan struct{}), make(chan error, len(headers)) for i := 0; i < len(headers); i++ { results <- nil @@ -169,7 +169,7 @@ func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers [] // rules of the stock Ethereum ethash engine. func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { // If we're running a full engine faking, accept any input as valid - if ethash.config.FullFake { + if ethash.config.PowMode == FullFake { return nil } // Verify that there are at most 2 uncles included in this block @@ -455,7 +455,7 @@ func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int { // the PoW difficulty requirements. func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error { // If we're running a fake PoW, accept any seal as valid - if ethash.config.Fake { + if ethash.config.PowMode == Fake || ethash.config.PowMode == FullFake { time.Sleep(ethash.fakeDelay) if ethash.fakeFail == header.Number.Uint64() { return errInvalidPoW @@ -480,7 +480,7 @@ func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Head cache := ethash.cache(number) size := datasetSize(number) - if ethash.config.Test { + if ethash.config.PowMode == Test { size = 32 * 1024 } digest, result := hashimotoLight(size, cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64()) diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index b3d4b2b4b66f..78efae1d488a 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -45,7 +45,7 @@ var ( maxUint256 = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0)) // sharedEthash is a full instance that can be shared between multiple users. - sharedEthash = New(Config{"", 3, 0, "", 1, 0, false, false, false, false}) + sharedEthash = New(Config{"", 3, 0, "", 1, 0, Normal}) // algorithmRevision is the data structure version used for file naming. algorithmRevision = 23 @@ -320,6 +320,16 @@ func MakeDataset(block uint64, dir string) { d.release() } +type Mode uint + +const ( + Normal Mode = iota + Shared + Test + Fake + FullFake +) + // Config are the configuration parameters of the ethash. type Config struct { CacheDir string @@ -328,12 +338,7 @@ type Config struct { DatasetDir string DatasetsInMem int DatasetsOnDisk int - - // The fields below are configurations for testing - Fake bool - FullFake bool - Test bool - Shared bool + PowMode Mode } // Ethash is a consensus engine based on proot-of-work implementing the ethash @@ -387,7 +392,7 @@ func NewTester() *Ethash { return &Ethash{ config: Config{ CachesInMem: 1, - Test: true, + PowMode: Test, }, caches: make(map[uint64]*cache), datasets: make(map[uint64]*dataset), @@ -402,7 +407,7 @@ func NewTester() *Ethash { func NewFaker() *Ethash { return &Ethash{ config: Config{ - Fake: true, + PowMode: Fake, }, } } @@ -413,7 +418,7 @@ func NewFaker() *Ethash { func NewFakeFailer(fail uint64) *Ethash { return &Ethash{ config: Config{ - Fake: true, + PowMode: Fake, }, fakeFail: fail, } @@ -425,7 +430,7 @@ func NewFakeFailer(fail uint64) *Ethash { func NewFakeDelayer(delay time.Duration) *Ethash { return &Ethash{ config: Config{ - Fake: true, + PowMode: Fake, }, fakeDelay: delay, } @@ -436,8 +441,7 @@ func NewFakeDelayer(delay time.Duration) *Ethash { func NewFullFaker() *Ethash { return &Ethash{ config: Config{ - Fake: true, - FullFake: true, + PowMode: FullFake, }, } } @@ -497,7 +501,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.Test) + current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == Test) current.lock.Lock() current.used = time.Now() @@ -505,7 +509,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { // If we exhausted the future cache, now's a good time to regenerate it if future != nil { - go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.Test) + go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == Test) } return current.cache } @@ -560,7 +564,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.Test) + current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == Test) current.lock.Lock() current.used = time.Now() @@ -568,7 +572,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { // If we exhausted the future dataset, now's a good time to regenerate it if future != nil { - go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.Test) + go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == Test) } return current.dataset } diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go index 62d056dd098a..d7cceb11d44f 100644 --- a/consensus/ethash/sealer.go +++ b/consensus/ethash/sealer.go @@ -34,7 +34,7 @@ import ( // the block's difficulty requirements. func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) { // If we're running a fake PoW, simply return a 0 nonce immediately - if ethash.config.Fake { + if ethash.config.PowMode == Fake || ethash.config.PowMode == FullFake { header := block.Header() header.Nonce, header.MixDigest = types.BlockNonce{}, common.Hash{} return block.WithSeal(header), nil diff --git a/console/console_test.go b/console/console_test.go index 492a55733f03..98d0feddacac 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -98,7 +98,7 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { Genesis: core.DeveloperGenesisBlock(15, common.Address{}), Etherbase: common.HexToAddress(testAddress), Ethash: ethash.Config{ - Test: true, + PowMode: ethash.Test, }, } if confOverride != nil { diff --git a/eth/backend.go b/eth/backend.go index 1104e8909e64..8d08feca60b4 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -216,13 +216,13 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chai } // Otherwise assume proof-of-work switch { - case config.Fake: + case config.PowMode == ethash.Fake: log.Warn("Ethash used in fake mode") return ethash.NewFaker() - case config.Test: + case config.PowMode == ethash.Test: log.Warn("Ethash used in test mode") return ethash.NewTester() - case config.Shared: + case config.PowMode == ethash.Shared: log.Warn("Ethash used in shared mode") return ethash.NewShared() default: diff --git a/eth/gen_config.go b/eth/gen_config.go index 134fae7465b8..e2d50e1f6628 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -36,10 +37,8 @@ func (c Config) MarshalTOML() (interface{}, error) { TxPool core.TxPoolConfig GPO gasprice.Config EnablePreimageRecording bool - DocRoot string `toml:"-"` - PowFake bool `toml:"-"` - PowTest bool `toml:"-"` - PowShared bool `toml:"-"` + DocRoot string `toml:"-"` + PowMode ethash.Mode `toml:"-"` } var enc Config enc.Genesis = c.Genesis @@ -64,9 +63,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot - enc.PowFake = c.Ethash.Fake - enc.PowTest = c.Ethash.Test - enc.PowShared = c.Ethash.Shared + enc.PowMode = c.Ethash.PowMode return &enc, nil } @@ -94,10 +91,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { TxPool *core.TxPoolConfig GPO *gasprice.Config EnablePreimageRecording *bool - DocRoot *string `toml:"-"` - PowFake *bool `toml:"-"` - PowTest *bool `toml:"-"` - PowShared *bool `toml:"-"` + DocRoot *string `toml:"-"` + PowMode *ethash.Mode `toml:"-"` } var dec Config if err := unmarshal(&dec); err != nil { @@ -169,14 +164,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.DocRoot != nil { c.DocRoot = *dec.DocRoot } - if dec.PowFake != nil { - c.Ethash.Fake = *dec.PowFake - } - if dec.PowTest != nil { - c.Ethash.Test = *dec.PowTest - } - if dec.PowShared != nil { - c.Ethash.Shared = *dec.PowShared + if dec.PowMode != nil { + c.Ethash.PowMode = *dec.PowMode } return nil } From ac6908d71ffdaeaed444fcc33f32703a6283ebfc Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 24 Nov 2017 21:23:42 +0800 Subject: [PATCH 4/4] consensus, eth: document pow mode --- consensus/ethash/algorithm_test.go | 2 +- consensus/ethash/consensus.go | 10 +++++----- consensus/ethash/ethash.go | 31 +++++++++++++++--------------- consensus/ethash/sealer.go | 2 +- console/console_test.go | 2 +- eth/backend.go | 6 +++--- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go index 38477f0f715e..7765ff9fe68e 100644 --- a/consensus/ethash/algorithm_test.go +++ b/consensus/ethash/algorithm_test.go @@ -703,7 +703,7 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) { go func(idx int) { defer pend.Done() - ethash := New(Config{cachedir, 0, 1, "", 0, 0, Normal}) + ethash := New(Config{cachedir, 0, 1, "", 0, 0, ModeNormal}) if err := ethash.VerifySeal(nil, block.Header()); err != nil { t.Errorf("proc %d: block verification failed: %v", idx, err) } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 7a598e8e8101..51bdd9e731e5 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -68,7 +68,7 @@ func (ethash *Ethash) Author(header *types.Header) (common.Address, error) { // stock Ethereum ethash engine. func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { // If we're running a full engine faking, accept any input as valid - if ethash.config.PowMode == FullFake { + if ethash.config.PowMode == ModeFullFake { return nil } // Short circuit if the header is known, or it's parent not @@ -89,7 +89,7 @@ func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.He // a results channel to retrieve the async verifications. func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { // If we're running a full engine faking, accept any input as valid - if ethash.config.PowMode == FullFake || len(headers) == 0 { + if ethash.config.PowMode == ModeFullFake || len(headers) == 0 { abort, results := make(chan struct{}), make(chan error, len(headers)) for i := 0; i < len(headers); i++ { results <- nil @@ -169,7 +169,7 @@ func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers [] // rules of the stock Ethereum ethash engine. func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { // If we're running a full engine faking, accept any input as valid - if ethash.config.PowMode == FullFake { + if ethash.config.PowMode == ModeFullFake { return nil } // Verify that there are at most 2 uncles included in this block @@ -455,7 +455,7 @@ func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int { // the PoW difficulty requirements. func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error { // If we're running a fake PoW, accept any seal as valid - if ethash.config.PowMode == Fake || ethash.config.PowMode == FullFake { + if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { time.Sleep(ethash.fakeDelay) if ethash.fakeFail == header.Number.Uint64() { return errInvalidPoW @@ -480,7 +480,7 @@ func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Head cache := ethash.cache(number) size := datasetSize(number) - if ethash.config.PowMode == Test { + if ethash.config.PowMode == ModeTest { size = 32 * 1024 } digest, result := hashimotoLight(size, cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64()) diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index 78efae1d488a..a78b3a895d39 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -45,7 +45,7 @@ var ( maxUint256 = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0)) // sharedEthash is a full instance that can be shared between multiple users. - sharedEthash = New(Config{"", 3, 0, "", 1, 0, Normal}) + sharedEthash = New(Config{"", 3, 0, "", 1, 0, ModeNormal}) // algorithmRevision is the data structure version used for file naming. algorithmRevision = 23 @@ -320,14 +320,15 @@ func MakeDataset(block uint64, dir string) { d.release() } +// Mode defines the type and amount of PoW verification an ethash engine makes. type Mode uint const ( - Normal Mode = iota - Shared - Test - Fake - FullFake + ModeNormal Mode = iota + ModeShared + ModeTest + ModeFake + ModeFullFake ) // Config are the configuration parameters of the ethash. @@ -392,7 +393,7 @@ func NewTester() *Ethash { return &Ethash{ config: Config{ CachesInMem: 1, - PowMode: Test, + PowMode: ModeTest, }, caches: make(map[uint64]*cache), datasets: make(map[uint64]*dataset), @@ -407,7 +408,7 @@ func NewTester() *Ethash { func NewFaker() *Ethash { return &Ethash{ config: Config{ - PowMode: Fake, + PowMode: ModeFake, }, } } @@ -418,7 +419,7 @@ func NewFaker() *Ethash { func NewFakeFailer(fail uint64) *Ethash { return &Ethash{ config: Config{ - PowMode: Fake, + PowMode: ModeFake, }, fakeFail: fail, } @@ -430,7 +431,7 @@ func NewFakeFailer(fail uint64) *Ethash { func NewFakeDelayer(delay time.Duration) *Ethash { return &Ethash{ config: Config{ - PowMode: Fake, + PowMode: ModeFake, }, fakeDelay: delay, } @@ -441,7 +442,7 @@ func NewFakeDelayer(delay time.Duration) *Ethash { func NewFullFaker() *Ethash { return &Ethash{ config: Config{ - PowMode: FullFake, + PowMode: ModeFullFake, }, } } @@ -501,7 +502,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == Test) + current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest) current.lock.Lock() current.used = time.Now() @@ -509,7 +510,7 @@ func (ethash *Ethash) cache(block uint64) []uint32 { // If we exhausted the future cache, now's a good time to regenerate it if future != nil { - go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == Test) + go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest) } return current.cache } @@ -564,7 +565,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { ethash.lock.Unlock() // Wait for generation finish, bump the timestamp and finalize the cache - current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == Test) + current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest) current.lock.Lock() current.used = time.Now() @@ -572,7 +573,7 @@ func (ethash *Ethash) dataset(block uint64) []uint32 { // If we exhausted the future dataset, now's a good time to regenerate it if future != nil { - go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == Test) + go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest) } return current.dataset } diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go index d7cceb11d44f..c2447e473060 100644 --- a/consensus/ethash/sealer.go +++ b/consensus/ethash/sealer.go @@ -34,7 +34,7 @@ import ( // the block's difficulty requirements. func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) { // If we're running a fake PoW, simply return a 0 nonce immediately - if ethash.config.PowMode == Fake || ethash.config.PowMode == FullFake { + if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { header := block.Header() header.Nonce, header.MixDigest = types.BlockNonce{}, common.Hash{} return block.WithSeal(header), nil diff --git a/console/console_test.go b/console/console_test.go index 98d0feddacac..d29680785449 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -98,7 +98,7 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { Genesis: core.DeveloperGenesisBlock(15, common.Address{}), Etherbase: common.HexToAddress(testAddress), Ethash: ethash.Config{ - PowMode: ethash.Test, + PowMode: ethash.ModeTest, }, } if confOverride != nil { diff --git a/eth/backend.go b/eth/backend.go index 8d08feca60b4..e7f0f57dd48e 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -216,13 +216,13 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chai } // Otherwise assume proof-of-work switch { - case config.PowMode == ethash.Fake: + case config.PowMode == ethash.ModeFake: log.Warn("Ethash used in fake mode") return ethash.NewFaker() - case config.PowMode == ethash.Test: + case config.PowMode == ethash.ModeTest: log.Warn("Ethash used in test mode") return ethash.NewTester() - case config.PowMode == ethash.Shared: + case config.PowMode == ethash.ModeShared: log.Warn("Ethash used in shared mode") return ethash.NewShared() default: