aboutsummaryrefslogtreecommitdiffstats
path: root/consensus
diff options
context:
space:
mode:
Diffstat (limited to 'consensus')
-rw-r--r--consensus/clique/clique.go5
-rw-r--r--consensus/consensus.go3
-rw-r--r--consensus/ethash/consensus.go29
-rw-r--r--consensus/ethash/ethash_test.go11
-rw-r--r--consensus/ethash/sealer.go4
-rw-r--r--consensus/ethash/sealer_test.go2
6 files changed, 45 insertions, 9 deletions
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go
index 085944701..3730c91f6 100644
--- a/consensus/clique/clique.go
+++ b/consensus/clique/clique.go
@@ -673,6 +673,11 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
return new(big.Int).Set(diffNoTurn)
}
+// SealHash returns the hash of a block prior to it being sealed.
+func (c *Clique) SealHash(header *types.Header) common.Hash {
+ return sigHash(header)
+}
+
// Close implements consensus.Engine. It's a noop for clique as there is are no background threads.
func (c *Clique) Close() error {
return nil
diff --git a/consensus/consensus.go b/consensus/consensus.go
index 827175444..27799f13c 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -90,6 +90,9 @@ type Engine interface {
// seal place on top.
Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error)
+ // SealHash returns the hash of a block prior to it being sealed.
+ SealHash(header *types.Header) common.Hash
+
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
// that a new block should have.
CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int
diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go
index 86fd997ae..259cc5056 100644
--- a/consensus/ethash/consensus.go
+++ b/consensus/ethash/consensus.go
@@ -31,7 +31,9 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/rlp"
)
// Ethash proof-of-work protocol constants.
@@ -495,7 +497,7 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainReader, header *types.Head
if fulldag {
dataset := ethash.dataset(number, true)
if dataset.generated() {
- digest, result = hashimotoFull(dataset.dataset, header.HashNoNonce().Bytes(), header.Nonce.Uint64())
+ digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
// Datasets are unmapped in a finalizer. Ensure that the dataset stays alive
// until after the call to hashimotoFull so it's not unmapped while being used.
@@ -513,7 +515,7 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainReader, header *types.Head
if ethash.config.PowMode == ModeTest {
size = 32 * 1024
}
- digest, result = hashimotoLight(size, cache.cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64())
+ digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())
// Caches are unmapped in a finalizer. Ensure that the cache stays alive
// until after the call to hashimotoLight so it's not unmapped while being used.
@@ -552,6 +554,29 @@ func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header
return types.NewBlock(header, txs, uncles, receipts), nil
}
+// SealHash returns the hash of a block prior to it being sealed.
+func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
+ hasher := sha3.NewKeccak256()
+
+ rlp.Encode(hasher, []interface{}{
+ header.ParentHash,
+ header.UncleHash,
+ header.Coinbase,
+ header.Root,
+ header.TxHash,
+ header.ReceiptHash,
+ header.Bloom,
+ header.Difficulty,
+ header.Number,
+ header.GasLimit,
+ header.GasUsed,
+ header.Time,
+ header.Extra,
+ })
+ hasher.Sum(hash[:0])
+ return hash
+}
+
// Some weird constants to avoid constant memory allocs for them.
var (
big8 = big.NewInt(8)
diff --git a/consensus/ethash/ethash_test.go b/consensus/ethash/ethash_test.go
index 87ac17c2b..b190d63d6 100644
--- a/consensus/ethash/ethash_test.go
+++ b/consensus/ethash/ethash_test.go
@@ -94,6 +94,7 @@ func TestRemoteSealer(t *testing.T) {
}
header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)}
block := types.NewBlockWithHeader(header)
+ sealhash := ethash.SealHash(header)
// Push new work.
ethash.Seal(nil, block, nil)
@@ -102,27 +103,29 @@ func TestRemoteSealer(t *testing.T) {
work [3]string
err error
)
- if work, err = api.GetWork(); err != nil || work[0] != block.HashNoNonce().Hex() {
+ if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() {
t.Error("expect to return a mining work has same hash")
}
- if res := api.SubmitWork(types.BlockNonce{}, block.HashNoNonce(), common.Hash{}); res {
+ if res := api.SubmitWork(types.BlockNonce{}, sealhash, common.Hash{}); res {
t.Error("expect to return false when submit a fake solution")
}
// Push new block with same block number to replace the original one.
header = &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(1000)}
block = types.NewBlockWithHeader(header)
+ sealhash = ethash.SealHash(header)
ethash.Seal(nil, block, nil)
- if work, err = api.GetWork(); err != nil || work[0] != block.HashNoNonce().Hex() {
+ if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() {
t.Error("expect to return the latest pushed work")
}
// Push block with higher block number.
newHead := &types.Header{Number: big.NewInt(2), Difficulty: big.NewInt(100)}
newBlock := types.NewBlockWithHeader(newHead)
+ newSealhash := ethash.SealHash(newHead)
ethash.Seal(nil, newBlock, nil)
- if res := api.SubmitWork(types.BlockNonce{}, block.HashNoNonce(), common.Hash{}); res {
+ if res := api.SubmitWork(types.BlockNonce{}, newSealhash, common.Hash{}); res {
t.Error("expect to return false when submit a stale solution")
}
}
diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go
index c3b2c86d1..a458c60f6 100644
--- a/consensus/ethash/sealer.go
+++ b/consensus/ethash/sealer.go
@@ -111,7 +111,7 @@ func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan s
// Extract some data from the header
var (
header = block.Header()
- hash = header.HashNoNonce().Bytes()
+ hash = ethash.SealHash(header).Bytes()
target = new(big.Int).Div(two256, header.Difficulty)
number = header.Number.Uint64()
dataset = ethash.dataset(number, false)
@@ -213,7 +213,7 @@ func (ethash *Ethash) remote(notify []string) {
// result[1], 32 bytes hex encoded seed hash used for DAG
// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
makeWork := func(block *types.Block) {
- hash := block.HashNoNonce()
+ hash := ethash.SealHash(block.Header())
currentWork[0] = hash.Hex()
currentWork[1] = common.BytesToHash(SeedHash(block.NumberU64())).Hex()
diff --git a/consensus/ethash/sealer_test.go b/consensus/ethash/sealer_test.go
index 6c7157a5a..d1b66f9cf 100644
--- a/consensus/ethash/sealer_test.go
+++ b/consensus/ethash/sealer_test.go
@@ -51,7 +51,7 @@ func TestRemoteNotify(t *testing.T) {
ethash.Seal(nil, block, nil)
select {
case work := <-sink:
- if want := header.HashNoNonce().Hex(); work[0] != want {
+ if want := ethash.SealHash(header).Hex(); work[0] != want {
t.Errorf("work packet hash mismatch: have %s, want %s", work[0], want)
}
if want := common.BytesToHash(SeedHash(header.Number.Uint64())).Hex(); work[1] != want {