engines/engine_v2: refactor verifyQC by errgroup, close XFN-09 (#1740)

This commit is contained in:
Daniel Liu 2025-11-15 19:12:15 +08:00 committed by GitHub
parent fc9ca96104
commit 60868c9045
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,12 +1,14 @@
package engine_v2 package engine_v2
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -25,6 +27,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/XinFinOrg/XDPoSChain/trie" "github.com/XinFinOrg/XDPoSChain/trie"
"golang.org/x/sync/errgroup"
) )
type XDPoS_v2 struct { type XDPoS_v2 struct {
@ -756,34 +759,36 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *
} }
start := time.Now() start := time.Now()
var wg sync.WaitGroup eg, ctx := errgroup.WithContext(context.Background())
wg.Add(len(signatures)) eg.SetLimit(runtime.NumCPU())
sigErrChan := make(chan error, len(signatures)) for _, sig := range signatures {
eg.Go(func() error {
for _, signature := range signatures { select {
go func(sig types.Signature) { case <-ctx.Done():
defer wg.Done() return ctx.Err()
default:
verified, _, err := x.verifyMsgSignature(types.VoteSigHash(&types.VoteForSign{ verified, _, err := x.verifyMsgSignature(types.VoteSigHash(&types.VoteForSign{
ProposedBlockInfo: quorumCert.ProposedBlockInfo, ProposedBlockInfo: quorumCert.ProposedBlockInfo,
GapNumber: quorumCert.GapNumber, GapNumber: quorumCert.GapNumber,
}), sig, epochInfo.Masternodes) }), sig, epochInfo.Masternodes)
if err != nil { if err != nil {
log.Error("[verifyQC] Error while verfying QC message signatures", "Error", err) log.Error("[verifyQC] Error while verfying QC message signatures", "Error", err)
sigErrChan <- errors.New("error while verfying QC message signatures") return errors.New("error while verfying QC message signatures")
return
} }
if !verified { if !verified {
log.Warn("[verifyQC] Signature not verified doing QC verification", "QC", quorumCert) log.Warn("[verifyQC] Signature not verified doing QC verification", "QC", quorumCert)
sigErrChan <- errors.New("fail to verify QC due to signature mis-match") return errors.New("fail to verify QC due to signature mis-match")
return
} }
}(signature) return nil
} }
wg.Wait() })
}
err = eg.Wait()
elapsed := time.Since(start) elapsed := time.Since(start)
log.Debug("[verifyQC] time verify message signatures of qc", "elapsed", elapsed) log.Debug("[verifyQC] time verify message signatures of qc", "elapsed", elapsed)
if len(sigErrChan) > 0 { if err != nil {
return <-sigErrChan return err
} }
epochSwitchNumber := epochInfo.EpochSwitchBlockInfo.Number.Uint64() epochSwitchNumber := epochInfo.EpochSwitchBlockInfo.Number.Uint64()
gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch