From b55fcac50e404ad9dc394ebb808074cf14b23e02 Mon Sep 17 00:00:00 2001 From: Hussam Date: Mon, 14 Oct 2024 17:56:29 -0500 Subject: [PATCH] Safeguard efficiency score calculation --- consensus/blake3pow/consensus.go | 5 ++++- consensus/consensus.go | 2 +- consensus/progpow/consensus.go | 5 ++++- core/core.go | 2 +- core/headerchain.go | 12 ++++++++++-- core/worker.go | 5 ++++- quai/api_backend.go | 2 +- 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/consensus/blake3pow/consensus.go b/consensus/blake3pow/consensus.go index 8ac7ec9c7a..681c252267 100644 --- a/consensus/blake3pow/consensus.go +++ b/consensus/blake3pow/consensus.go @@ -361,7 +361,10 @@ func (blake3pow *Blake3pow) verifyHeader(chain consensus.ChainHeaderReader, head return fmt.Errorf("invalid threshold count: have %v, want %v", header.ThresholdCount(), 0) } } else { - expectedEfficiencyScore := chain.ComputeEfficiencyScore(parent) + expectedEfficiencyScore, err := chain.ComputeEfficiencyScore(parent) + if err != nil { + return err + } if header.EfficiencyScore() != expectedEfficiencyScore { return fmt.Errorf("invalid efficiency score: have %v, want %v", header.EfficiencyScore(), expectedEfficiencyScore) } diff --git a/consensus/consensus.go b/consensus/consensus.go index 0d6a1a888e..5d4e211786 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -93,7 +93,7 @@ type ChainHeaderReader interface { ProcessingState() bool // ComputeEfficiencyScore returns the efficiency score computed at each prime block - ComputeEfficiencyScore(header *types.WorkObject) uint16 + ComputeEfficiencyScore(header *types.WorkObject) (uint16, error) // ComputeExpansionNumber returns the expansion number of the block ComputeExpansionNumber(parent *types.WorkObject) (uint8, error) diff --git a/consensus/progpow/consensus.go b/consensus/progpow/consensus.go index 02915998df..72e2ab1748 100644 --- a/consensus/progpow/consensus.go +++ b/consensus/progpow/consensus.go @@ -357,7 +357,10 @@ func (progpow *Progpow) verifyHeader(chain consensus.ChainHeaderReader, header, return fmt.Errorf("invalid threshold count: have %v, want %v", header.ThresholdCount(), 0) } } else { - expectedEfficiencyScore := chain.ComputeEfficiencyScore(parent) + expectedEfficiencyScore, err := chain.ComputeEfficiencyScore(parent) + if err != nil { + return err + } if header.EfficiencyScore() != expectedEfficiencyScore { return fmt.Errorf("invalid efficiency score: have %v, want %v", header.EfficiencyScore(), expectedEfficiencyScore) } diff --git a/core/core.go b/core/core.go index 9ed2a26576..7f6f82bd70 100644 --- a/core/core.go +++ b/core/core.go @@ -998,7 +998,7 @@ func (c *Core) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscript // ComputeEfficiencyScore computes the efficiency score for the given prime // block This data is is only valid if called from Prime context, otherwise // there is no guarantee for this data to be accurate -func (c *Core) ComputeEfficiencyScore(header *types.WorkObject) uint16 { +func (c *Core) ComputeEfficiencyScore(header *types.WorkObject) (uint16, error) { return c.sl.hc.ComputeEfficiencyScore(header) } diff --git a/core/headerchain.go b/core/headerchain.go index 2e49c378fb..720d1edf2c 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -35,6 +35,10 @@ const ( c_calcOrderCacheLimit = 10000 ) +var ( + errInvalidEfficiencyScore = errors.New("unable to compute efficiency score") +) + type calcOrderResponse struct { intrinsicEntropy *big.Int order int @@ -1225,17 +1229,21 @@ func (hc *HeaderChain) ComputeExpansionNumber(parent *types.WorkObject) (uint8, } // ComputeEfficiencyScore calculates the efficiency score for the given header -func (hc *HeaderChain) ComputeEfficiencyScore(parent *types.WorkObject) uint16 { +func (hc *HeaderChain) ComputeEfficiencyScore(parent *types.WorkObject) (uint16, error) { deltaEntropy := new(big.Int).Add(parent.ParentDeltaEntropy(common.REGION_CTX), parent.ParentDeltaEntropy(common.ZONE_CTX)) uncledDeltaEntropy := new(big.Int).Add(parent.ParentUncledDeltaEntropy(common.REGION_CTX), parent.ParentUncledDeltaEntropy(common.ZONE_CTX)) // Take the ratio of deltaEntropy to the uncledDeltaEntropy in percentage efficiencyScore := uncledDeltaEntropy.Mul(uncledDeltaEntropy, big.NewInt(100)) + if deltaEntropy.Cmp(common.Big0) == 0 { + hc.logger.Error(errInvalidEfficiencyScore) + return 0, errInvalidEfficiencyScore + } efficiencyScore.Div(efficiencyScore, deltaEntropy) // Calculate the exponential moving average ewma := (uint16(efficiencyScore.Uint64()) + parent.EfficiencyScore()*params.TREE_EXPANSION_FILTER_ALPHA) / 10 - return ewma + return ewma, nil } // UpdateEtxEligibleSlices returns the updated etx eligible slices field diff --git a/core/worker.go b/core/worker.go index 17e51f0f2e..06fc6c9e2a 100644 --- a/core/worker.go +++ b/core/worker.go @@ -1461,7 +1461,10 @@ func (w *worker) prepareWork(genParams *generateParams, wo *types.WorkObject) (* newWo.Header().SetThresholdCount(0) } else { // compute the efficiency score at each prime block - efficiencyScore := w.hc.ComputeEfficiencyScore(parent) + efficiencyScore, err := w.hc.ComputeEfficiencyScore(parent) + if err != nil { + return nil, err + } newWo.Header().SetEfficiencyScore(efficiencyScore) // If the threshold count is zero we have not started considering for the diff --git a/quai/api_backend.go b/quai/api_backend.go index a140c2cc6c..b6bed5f97d 100644 --- a/quai/api_backend.go +++ b/quai/api_backend.go @@ -629,7 +629,7 @@ func (b *QuaiAPIBackend) IsBlockHashABadHash(hash common.Hash) bool { return b.quai.core.IsBlockHashABadHash(hash) } -func (b *QuaiAPIBackend) ComputeEfficiencyScore(header *types.WorkObject) uint16 { +func (b *QuaiAPIBackend) ComputeEfficiencyScore(header *types.WorkObject) (uint16, error) { return b.quai.core.ComputeEfficiencyScore(header) }