Skip to content

Commit

Permalink
progpow, eth, ethash, puppeth, consensus: implement v0.9.2 + parity c…
Browse files Browse the repository at this point in the history
…hain spec + reuse cdag
  • Loading branch information
holiman committed Oct 5, 2020
1 parent d8cf225 commit 74bcf0b
Show file tree
Hide file tree
Showing 13 changed files with 296 additions and 3,732 deletions.
6 changes: 6 additions & 0 deletions cmd/puppeth/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ type parityChainSpec struct {
DifficultyBombDelays map[string]string `json:"difficultyBombDelays"`
HomesteadTransition hexutil.Uint64 `json:"homesteadTransition"`
EIP100bTransition hexutil.Uint64 `json:"eip100bTransition"`
ProgpowTransition *hexutil.Uint64 `json:"progpowTransition,omitempty"`
} `json:"params"`
} `json:"Ethash"`
} `json:"engine"`
Expand Down Expand Up @@ -412,6 +413,11 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
if num := genesis.Config.IstanbulBlock; num != nil {
spec.setIstanbul(num)
}
// Progpow
if num := genesis.Config.ProgpowBlock; num != nil {
hexnum := hexutil.Uint64(num.Uint64())
spec.Engine.Ethash.Params.ProgpowTransition = &hexnum
}
spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
spec.Params.GasLimitBoundDivisor = (math2.HexOrDecimal64)(params.GasLimitBoundDivisor)
Expand Down
2 changes: 1 addition & 1 deletion cmd/puppeth/module_dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da
"Byzantium": conf.Genesis.Config.ByzantiumBlock,
"Constantinople": conf.Genesis.Config.ConstantinopleBlock,
"ConstantinopleFix": conf.Genesis.Config.PetersburgBlock,
"ProgPow": conf.Genesis.Config.ProgpowBlock,
"ProgPoW": conf.Genesis.Config.ProgpowBlock,
})
files[filepath.Join(workdir, "index.html")] = indexfile.Bytes()

Expand Down
8 changes: 5 additions & 3 deletions cmd/puppeth/wizard_genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,11 @@ func (w *wizard) manageGenesis() {
fmt.Printf("Which block should YOLOv1 come into effect? (default = %v)\n", w.conf.Genesis.Config.YoloV1Block)
w.conf.Genesis.Config.YoloV1Block = w.readDefaultBigInt(w.conf.Genesis.Config.YoloV1Block)

fmt.Println()
fmt.Printf("Which block should ProgPow come into effect? (default = %v)\n", w.conf.Genesis.Config.ProgpowBlock)
w.conf.Genesis.Config.ProgpowBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ProgpowBlock)
if w.conf.Genesis.Config.Clique == nil {
fmt.Println()
fmt.Printf("Which block should ProgPow come into effect? (default = %v)\n", w.conf.Genesis.Config.ProgpowBlock)
w.conf.Genesis.Config.ProgpowBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ProgpowBlock)
}

out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ")
fmt.Printf("Chain configuration updated:\n\n%s\n", out)
Expand Down
18 changes: 9 additions & 9 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1814,15 +1814,15 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readOnly bool) (chain *core.B
engine = ethash.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) {
engine = ethash.New(ethash.Config{
CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir),
CachesInMem: eth.DefaultConfig.Ethash.CachesInMem,
CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk,
CachesLockMmap: eth.DefaultConfig.Ethash.CachesLockMmap,
DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir),
DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem,
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
DatasetsLockMmap: eth.DefaultConfig.Ethash.DatasetsLockMmap,
ProgpowBlockNumber: config.ProgpowBlock,
CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir),
CachesInMem: eth.DefaultConfig.Ethash.CachesInMem,
CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk,
CachesLockMmap: eth.DefaultConfig.Ethash.CachesLockMmap,
DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir),
DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem,
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
DatasetsLockMmap: eth.DefaultConfig.Ethash.DatasetsLockMmap,
ProgpowBlock: config.ProgpowBlock,
}, nil, false)
}
}
Expand Down
14 changes: 7 additions & 7 deletions consensus/ethash/algorithm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) {

go func(idx int) {
defer pend.Done()
ethash := New(Config{cachedir, 0, 1, false, "", 0, 0, false, ModeNormal, nil}, nil, false)
ethash := New(Config{cachedir, 0, 1, false, "", 0, 0, false, ModeNormal, nil, nil}, nil, false)
defer ethash.Close()
if err := ethash.VerifySeal(nil, block.Header()); err != nil {
t.Errorf("proc %d: block verification failed: %v", idx, err)
Expand All @@ -739,15 +739,15 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) {
pend.Wait()
}

// Benchmarks the cache generation performance.
// BenchmarkCacheGeneration benchmarks the cache generation performance.
func BenchmarkCacheGeneration(b *testing.B) {
for i := 0; i < b.N; i++ {
cache := make([]uint32, cacheSize(1)/4)
generateCache(cache, 0, make([]byte, 32))
}
}

// Benchmarks the dataset (small) generation performance.
// BenchmarkSmallDatasetGeneration benchmarks the dataset (small) generation performance.
func BenchmarkSmallDatasetGeneration(b *testing.B) {
cache := make([]uint32, 65536/4)
generateCache(cache, 0, make([]byte, 32))
Expand All @@ -759,7 +759,7 @@ func BenchmarkSmallDatasetGeneration(b *testing.B) {
}
}

// Benchmarks the light verification performance.
// BenchmarkHashimotoLight benchmarks the light verification performance.
func BenchmarkHashimotoLight(b *testing.B) {
cache := make([]uint32, cacheSize(1)/4)
generateCache(cache, 0, make([]byte, 32))
Expand All @@ -772,7 +772,7 @@ func BenchmarkHashimotoLight(b *testing.B) {
}
}

// BenchmarkProgpowLight Benchmarks the light verification performance (not counting cDag generation).
// BenchmarkProgpowLight benchmarks the light verification performance (not counting cDag generation).
func BenchmarkProgpowLight(b *testing.B) {
cache := make([]uint32, cacheSize(1)/4)
generateCache(cache, 0, make([]byte, 32))
Expand All @@ -787,7 +787,7 @@ func BenchmarkProgpowLight(b *testing.B) {
}
}

// Benchmarks the full (small) verification performance.
// BenchmarkHashimotoFullSmall benchmarks the full (small) verification performance.
func BenchmarkHashimotoFullSmall(b *testing.B) {
cache := make([]uint32, 65536/4)
generateCache(cache, 0, make([]byte, 32))
Expand Down Expand Up @@ -828,7 +828,7 @@ func BenchmarkHashimotoFullMmap(b *testing.B) {
benchmarkHashimotoFullMmap(b, "WithoutLock", false)
}

// Benchmarks the full (small) verification performance.
// BenchmarkProgpowFullSmall benchmarks the full (small) verification performance.
func BenchmarkProgpowFullSmall(b *testing.B) {
cache := make([]uint32, 65536/4)
generateCache(cache, 0, make([]byte, 32))
Expand Down
2 changes: 1 addition & 1 deletion consensus/ethash/consensus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func TestCalcDifficulty(t *testing.T) {
// DatasetDir: "",
// DatasetsInMem: 1,
// DatasetsOnDisk: 1,
// ProgpowBlockNumber: config.ProgpowBlock,
// ProgpowBlock: config.ProgpowBlock,
// }, nil, false)
// bc, err := core.NewBlockChain(db, nil, config, engine, vm.Config{}, nil)
// //fmt.Printf("Genesis hash %x\n", bc.Genesis().Hash())
Expand Down
63 changes: 42 additions & 21 deletions consensus/ethash/ethash.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package ethash

import (
"encoding/binary"
"errors"
"fmt"
"math"
Expand Down Expand Up @@ -47,9 +48,9 @@ var (
// two256 is a big integer representing 2^256
two256 = 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 *Ethash
ethashMu sync.Mutex // lock for initializing sharedEthash
// sharedEngines contains ethash instances which are mapped by progpow blocknumber
sharedEngines map[uint64]*Ethash
ethashMu sync.Mutex // lock for modifying sharedEngines

// algorithmRevision is the data structure version used for file naming.
algorithmRevision = 23
Expand Down Expand Up @@ -409,16 +410,16 @@ const (

// Config are the configuration parameters of the ethash.
type Config struct {
CacheDir string
CachesInMem int
CachesOnDisk int
CachesLockMmap bool
DatasetDir string
DatasetsInMem int
DatasetsOnDisk int
DatasetsLockMmap bool
PowMode Mode
ProgpowBlockNumber *big.Int // Block number at which to use progpow instead of hashimoto
CacheDir string
CachesInMem int
CachesOnDisk int
CachesLockMmap bool
DatasetDir string
DatasetsInMem int
DatasetsOnDisk int
DatasetsLockMmap bool
PowMode Mode
ProgpowBlock *big.Int // Block number at which to use progpow instead of hashimoto

Log log.Logger `toml:"-"`
}
Expand Down Expand Up @@ -542,11 +543,16 @@ func NewFullFaker() *Ethash {
// in the same process.
func NewShared(progpowNumber *big.Int) *Ethash {
ethashMu.Lock()
if sharedEthash == nil {
sharedEthash = New(Config{"", 3, 0, false, "", 1, 0, false, ModeNormal, progpowNumber, nil}, nil, false)
if progpowNumber == nil {
progpowNumber = new(big.Int).SetUint64(uint64(math.MaxUint64))
}
sharedEngine, exist := sharedEngines[progpowNumber.Uint64()]
if !exist {
sharedEngine = New(Config{"", 3, 0, false, "", 1, 0, false, ModeNormal, progpowNumber, nil}, nil, false)
sharedEngines[progpowNumber.Uint64()] = sharedEngine
}
ethashMu.Unlock()
return &Ethash{shared: sharedEthash}
return &Ethash{shared: sharedEngine}
}

// Close closes the exit channel to notify all backend threads exiting.
Expand Down Expand Up @@ -700,8 +706,24 @@ type powLight func(size uint64, cache []uint32, hash []byte, nonce, number uint6

// fullPow returns either hashimoto or progpow full checker depending on number
func (ethash *Ethash) fullPow(number *big.Int) powFull {
if progpowNumber := ethash.config.ProgpowBlockNumber; progpowNumber != nil && progpowNumber.Cmp(number) <= 0 {
return progpowFull
if progpowNumber := ethash.config.ProgpowBlock; progpowNumber != nil && progpowNumber.Cmp(number) <= 0 {
ethashCache := ethash.cache(number.Uint64())
if ethashCache.cDag == nil {
log.Warn("cDag is nil, suboptimal performance")
cDag := make([]uint32, progpowCacheWords)
generateCDag(cDag, ethashCache.cache, number.Uint64()/epochLength)
ethashCache.cDag = cDag
}
mix := make([]byte, hashBytes)
return func(dataset []uint32, hash []byte, nonce, number uint64) ([]byte, []byte) {
lookup := func(index uint32) []byte {
for i := uint32(0); i < hashWords; i++ {
binary.LittleEndian.PutUint32(mix[i*4:], dataset[index+i])
}
return mix
}
return progpow(hash, nonce, uint64(len(dataset))*4, number, ethashCache.cDag, lookup)
}
}
return func(dataset []uint32, hash []byte, nonce uint64, number uint64) ([]byte, []byte) {
return hashimotoFull(dataset, hash, nonce)
Expand All @@ -710,13 +732,12 @@ func (ethash *Ethash) fullPow(number *big.Int) powFull {

// lightPow returns either hashimoto or progpow depending on number
func (ethash *Ethash) lightPow(number *big.Int) powLight {
if progpowNumber := ethash.config.ProgpowBlockNumber; progpowNumber != nil && progpowNumber.Cmp(number) <= 0 {
if progpowNumber := ethash.config.ProgpowBlock; progpowNumber != nil && progpowNumber.Cmp(number) <= 0 {
return func(size uint64, cache []uint32, hash []byte, nonce uint64, blockNumber uint64) ([]byte, []byte) {
ethashCache := ethash.cache(blockNumber)
if ethashCache.cDag == nil {
log.Warn("cDag is nil, suboptimal performance")
var cDag []uint32
cDag = make([]uint32, progpowCacheWords)
cDag := make([]uint32, progpowCacheWords)
generateCDag(cDag, ethashCache.cache, blockNumber/epochLength)
ethashCache.cDag = cDag
}
Expand Down
Loading

0 comments on commit 74bcf0b

Please sign in to comment.