Skip to content

Commit

Permalink
consortium/v2: make SealHash return unchanged hash after Shillin (axi…
Browse files Browse the repository at this point in the history
…einfinity#332)

As we delay assembling finality vote until Seal function, it means the seal hash
can be updated after the FinalizeAndAssemble. This breaks the worker which uses
seal hash to store and look up seal tasks between FinalizeAndAssemble and Seal
function. Worker uses SealHash function to get the header hash and this function
is used by worker only not by any other parts in the consensus. So in this
commit, we make this function returns a hash of header without the finality
vote. This is not the real hash used for sealing but it remains unchanged after
FinalizeAndAssemble which meet the requirement of the worker.
  • Loading branch information
minh-bq committed Sep 7, 2023
1 parent ab7efcc commit c59e820
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions consensus/consortium/v2/consortium.go
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ func (c *Consortium) Seal(chain consensus.ChainHeaderReader, block *types.Block,
select {
case results <- block.WithSeal(header):
default:
log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header, c.chainConfig.ChainID))
log.Warn("Sealing result is not read by miner", "sealhash", calculateSealHash(header, c.chainConfig.ChainID))
}
}()

Expand All @@ -1020,7 +1020,24 @@ func (c *Consortium) Seal(chain consensus.ChainHeaderReader, block *types.Block,

// SealHash returns the hash of a block prior to it being sealed.
func (c *Consortium) SealHash(header *types.Header) common.Hash {
return SealHash(header, c.chainConfig.ChainID)
isShillin := c.chainConfig.IsShillin(header.Number)
if isShillin {
// After Shillin, this consensus.SealHash function does not
// return the real hash used for sealing because the real
// hash changes after the FinalizeAndAssemble call. As this
// function is used by worker only to store and look up the
// sealing tasks, we just return the hash of header without
// the finality vote, so this hash remains unchanged after
// FinalizeAndAssemble call.
copyHeader := types.CopyHeader(header)

extraData, _ := finality.DecodeExtra(copyHeader.Extra, true)
extraData.HasFinalityVote = 0
copyHeader.Extra = extraData.Encode(true)
return calculateSealHash(copyHeader, c.chainConfig.ChainID)
} else {
return calculateSealHash(header, c.chainConfig.ChainID)
}
}

// Close implements consensus.Engine. It's a noop for Consortium as there are no background threads.
Expand Down Expand Up @@ -1305,7 +1322,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache, chainId *big.Int) (
signature := header.Extra[len(header.Extra)-consortiumCommon.ExtraSeal:]

// Recover the public key and the Ethereum address
pubkey, err := crypto.Ecrecover(SealHash(header, chainId).Bytes(), signature)
pubkey, err := crypto.Ecrecover(calculateSealHash(header, chainId).Bytes(), signature)
if err != nil {
return common.Address{}, err
}
Expand All @@ -1316,8 +1333,8 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache, chainId *big.Int) (
return signer, nil
}

// SealHash returns the hash of a block prior to it being sealed.
func SealHash(header *types.Header, chainId *big.Int) (hash common.Hash) {
// calculateSealHash returns the hash of a block prior to it being sealed.
func calculateSealHash(header *types.Header, chainId *big.Int) (hash common.Hash) {
hasher := sha3.NewLegacyKeccak256()
encodeSigHeader(hasher, header, chainId)
hasher.Sum(hash[:0])
Expand Down

0 comments on commit c59e820

Please sign in to comment.