Skip to content

Commit 0f6835f

Browse files
committed
consensus, params, metadium: replaced dag-based digest with simple sha256 hash
1 parent c8aad64 commit 0f6835f

File tree

5 files changed

+77
-38
lines changed

5 files changed

+77
-38
lines changed

consensus/ethash/algorithm.go

+11
Original file line numberDiff line numberDiff line change
@@ -1150,3 +1150,14 @@ var cacheSizes = [maxEpoch]uint64{
11501150
283377344, 283508416, 283639744, 283770304, 283901504, 284032576,
11511151
284163136, 284294848, 284426176, 284556992, 284687296, 284819264,
11521152
284950208, 285081536}
1153+
1154+
// a simple sha256 hash from seed & nonce
1155+
func hashimeta(hash []byte, nonce uint64) ([]byte, []byte) {
1156+
// Combine header+nonce into a 64 byte seed
1157+
seed := make([]byte, 40)
1158+
copy(seed, hash)
1159+
binary.LittleEndian.PutUint64(seed[32:], nonce)
1160+
1161+
result := crypto.Keccak256(seed)
1162+
return result, result
1163+
}

consensus/ethash/consensus.go

+28-24
Original file line numberDiff line numberDiff line change
@@ -548,33 +548,37 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *type
548548
digest []byte
549549
result []byte
550550
)
551-
// If fast-but-heavy PoW verification was requested, use an ethash dataset
552-
if fulldag {
553-
dataset := ethash.dataset(number, true)
554-
if dataset.generated() {
555-
digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
556-
557-
// Datasets are unmapped in a finalizer. Ensure that the dataset stays alive
558-
// until after the call to hashimotoFull so it's not unmapped while being used.
559-
runtime.KeepAlive(dataset)
560-
} else {
561-
// Dataset not yet generated, don't hang, use a cache instead
562-
fulldag = false
551+
if chain.Config().IsAvocado(header.Number) {
552+
digest, result = hashimeta(ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
553+
} else {
554+
// If fast-but-heavy PoW verification was requested, use an ethash dataset
555+
if fulldag {
556+
dataset := ethash.dataset(number, true)
557+
if dataset.generated() {
558+
digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
559+
560+
// Datasets are unmapped in a finalizer. Ensure that the dataset stays alive
561+
// until after the call to hashimotoFull so it's not unmapped while being used.
562+
runtime.KeepAlive(dataset)
563+
} else {
564+
// Dataset not yet generated, don't hang, use a cache instead
565+
fulldag = false
566+
}
563567
}
564-
}
565-
// If slow-but-light PoW verification was requested (or DAG not yet ready), use an ethash cache
566-
if !fulldag {
567-
cache := ethash.cache(number)
568+
// If slow-but-light PoW verification was requested (or DAG not yet ready), use an ethash cache
569+
if !fulldag {
570+
cache := ethash.cache(number)
568571

569-
size := datasetSize(number)
570-
if ethash.config.PowMode == ModeTest {
571-
size = 32 * 1024
572-
}
573-
digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
572+
size := datasetSize(number)
573+
if ethash.config.PowMode == ModeTest {
574+
size = 32 * 1024
575+
}
576+
digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
574577

575-
// Caches are unmapped in a finalizer. Ensure that the cache stays alive
576-
// until after the call to hashimotoLight so it's not unmapped while being used.
577-
runtime.KeepAlive(cache)
578+
// Caches are unmapped in a finalizer. Ensure that the cache stays alive
579+
// until after the call to hashimotoLight so it's not unmapped while being used.
580+
runtime.KeepAlive(cache)
581+
}
578582
}
579583
// Verify the calculated values against the ones provided in the header
580584
if !bytes.Equal(header.MixDigest[:], digest) {

consensus/ethash/sealer.go

+22-10
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block
6464
ethash.lock.Unlock()
6565
abort := make(chan struct{})
6666
found := make(chan *types.Block)
67-
go ethash.mine(block, 0, uint64(ethash.rand.Int63()), abort, found)
67+
go ethash.mine(block, 0, uint64(ethash.rand.Int63()), abort, found, chain.Config().IsAvocado(block.Number()))
6868
result := <-found
6969
select {
7070
case results <- result:
@@ -121,7 +121,7 @@ func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block
121121
pend.Add(1)
122122
go func(id int, nonce uint64) {
123123
defer pend.Done()
124-
ethash.mine(block, id, nonce, abort, locals)
124+
ethash.mine(block, id, nonce, abort, locals, chain.Config().IsAvocado(block.Number()))
125125
}(i, uint64(ethash.rand.Int63()))
126126
}
127127
// Wait until sealing is terminated or a nonce is found
@@ -154,14 +154,15 @@ func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block
154154

155155
// mine is the actual proof-of-work miner that searches for a nonce starting from
156156
// seed that results in correct final block difficulty.
157-
func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block) {
157+
func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block, nodag bool) {
158158
// Extract some data from the header
159159
var (
160-
header = block.Header()
161-
hash = ethash.SealHash(header).Bytes()
162-
target = new(big.Int).Div(two256, header.Difficulty)
163-
number = header.Number.Uint64()
164-
dataset = ethash.dataset(number, false)
160+
header = block.Header()
161+
hash = ethash.SealHash(header).Bytes()
162+
target = new(big.Int).Div(two256, header.Difficulty)
163+
number = header.Number.Uint64()
164+
cache *cache
165+
size uint64
165166
)
166167
// Start generating random nonces until we abort or find a good one
167168
var (
@@ -188,7 +189,16 @@ search:
188189
attempts = 0
189190
}
190191
// Compute the PoW value of this nonce
191-
digest, result := hashimotoFull(dataset.dataset, hash, nonce)
192+
var digest, result []byte
193+
if !nodag {
194+
if cache == nil {
195+
cache = ethash.cache(number)
196+
size = datasetSize(number)
197+
}
198+
digest, result = hashimotoLight(size, cache.cache, hash, nonce)
199+
} else {
200+
digest, result = hashimeta(hash, nonce)
201+
}
192202
if powBuffer.SetBytes(result).Cmp(target) <= 0 {
193203
// Correct nonce found, create a new header with it
194204
header = types.CopyHeader(header)
@@ -209,7 +219,9 @@ search:
209219
}
210220
// Datasets are unmapped in a finalizer. Ensure that the dataset stays live
211221
// during sealing so it's not unmapped while being read.
212-
runtime.KeepAlive(dataset)
222+
if cache != nil {
223+
runtime.KeepAlive(cache)
224+
}
213225
}
214226

215227
// This is the timeout for HTTP requests to notify external miners.

metadium/scripts/genesis-template.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"constantinopleBlock": 0,
2727
"istanbulBlock": 0,
2828
"londonBlock": 0,
29-
"muirGlacierBlock": 0
29+
"muirGlacierBlock": 0,
30+
"avocadoBlock": 0
3031
}
3132
}

params/config.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ var (
7474
BerlinBlock: big.NewInt(12_244_000),
7575
LondonBlock: big.NewInt(12_965_000),
7676
ArrowGlacierBlock: big.NewInt(13_773_000),
77+
AvocadoBlock: big.NewInt(1_000_000_000_000),
7778
Ethash: new(EthashConfig),
7879
}
7980

@@ -155,6 +156,7 @@ var (
155156
MuirGlacierBlock: big.NewInt(11441000),
156157
BerlinBlock: big.NewInt(51960000),
157158
LondonBlock: big.NewInt(51960000),
159+
AvocadoBlock: big.NewInt(1_000_000_000_000),
158160
Ethash: new(EthashConfig),
159161
}
160162

@@ -174,6 +176,7 @@ var (
174176
MuirGlacierBlock: big.NewInt(5623000),
175177
BerlinBlock: big.NewInt(38067000),
176178
LondonBlock: big.NewInt(38067000),
179+
AvocadoBlock: big.NewInt(1_000_000_000_000),
177180
Ethash: new(EthashConfig),
178181
}
179182

@@ -297,16 +300,16 @@ var (
297300
//
298301
// This configuration is intentionally not using keyed fields to force anyone
299302
// adding flags to the config to also have to set these fields.
300-
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil}
303+
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil}
301304

302305
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
303306
// and accepted by the Ethereum core developers into the Clique consensus.
304307
//
305308
// This configuration is intentionally not using keyed fields to force anyone
306309
// adding flags to the config to also have to set these fields.
307-
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
310+
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
308311

309-
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil}
312+
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil}
310313
TestRules = TestChainConfig.Rules(new(big.Int), false)
311314
)
312315

@@ -387,6 +390,7 @@ type ChainConfig struct {
387390
LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london)
388391
ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated)
389392
MergeForkBlock *big.Int `json:"mergeForkBlock,omitempty"` // EIP-3675 (TheMerge) switch block (nil = no fork, 0 = already in merge proceedings)
393+
AvocadoBlock *big.Int `json:"avocadoBlock,omitempty"` // Avocado switch block (nil = no fork, 0 = already on avocado)
390394

391395
// TerminalTotalDifficulty is the amount of total difficulty reached by
392396
// the network that triggers the consensus upgrade.
@@ -515,6 +519,11 @@ func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool {
515519
return isForked(c.ArrowGlacierBlock, num)
516520
}
517521

522+
// IsAvocado returns whether num is either equal to the Avocado fork block or greater.
523+
func (c *ChainConfig) IsAvocado(num *big.Int) bool {
524+
return isForked(c.AvocadoBlock, num)
525+
}
526+
518527
// IsTerminalPoWBlock returns whether the given block is the last block of PoW stage.
519528
func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool {
520529
if c.TerminalTotalDifficulty == nil {
@@ -714,6 +723,7 @@ type Rules struct {
714723
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
715724
IsBerlin, IsLondon bool
716725
IsMerge bool
726+
IsAvocado bool
717727
}
718728

719729
// Rules ensures c's ChainID is not nil.
@@ -735,5 +745,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules {
735745
IsBerlin: c.IsBerlin(num),
736746
IsLondon: c.IsLondon(num),
737747
IsMerge: isMerge,
748+
IsAvocado: c.IsAvocado(num),
738749
}
739750
}

0 commit comments

Comments
 (0)