metrics: add doublesign counter (#2419)

This commit is contained in:
Satyajit Das 2024-04-29 07:12:43 +05:30 committed by GitHub
parent 9e170972f4
commit 9d8df917b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -48,8 +48,9 @@ import (
) )
const ( const (
inMemorySnapshots = 256 // Number of recent snapshots to keep in memory inMemorySnapshots = 256 // Number of recent snapshots to keep in memory
inMemorySignatures = 4096 // Number of recent block signatures to keep in memory inMemorySignatures = 4096 // Number of recent block signatures to keep in memory
inMemoryHeaders = 86400 // Number of recent headers to keep in memory for double sign detection
checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database
defaultEpochLength = uint64(100) // Default number of blocks of checkpoint to update validatorSet from contract defaultEpochLength = uint64(100) // Default number of blocks of checkpoint to update validatorSet from contract
@ -80,6 +81,7 @@ var (
verifyVoteAttestationErrorCounter = metrics.NewRegisteredCounter("parlia/verifyVoteAttestation/error", nil) verifyVoteAttestationErrorCounter = metrics.NewRegisteredCounter("parlia/verifyVoteAttestation/error", nil)
updateAttestationErrorCounter = metrics.NewRegisteredCounter("parlia/updateAttestation/error", nil) updateAttestationErrorCounter = metrics.NewRegisteredCounter("parlia/updateAttestation/error", nil)
validVotesfromSelfCounter = metrics.NewRegisteredCounter("parlia/VerifyVote/self", nil) validVotesfromSelfCounter = metrics.NewRegisteredCounter("parlia/VerifyVote/self", nil)
doubleSignCounter = metrics.NewRegisteredCounter("parlia/doublesign", nil)
systemContracts = map[common.Address]bool{ systemContracts = map[common.Address]bool{
common.HexToAddress(systemcontracts.ValidatorContract): true, common.HexToAddress(systemcontracts.ValidatorContract): true,
@ -216,8 +218,11 @@ type Parlia struct {
genesisHash common.Hash genesisHash common.Hash
db ethdb.Database // Database to store and retrieve snapshot checkpoints db ethdb.Database // Database to store and retrieve snapshot checkpoints
recentSnaps *lru.ARCCache // Snapshots for recent block to speed up recentSnaps *lru.ARCCache // Snapshots for recent block to speed up
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
recentHeaders *lru.ARCCache //
// Recent headers to check for double signing: key includes block number and miner. value is the block header
// If same key's value already exists for different block header roots then double sign is detected
signer types.Signer signer types.Signer
@ -263,6 +268,10 @@ func New(
if err != nil { if err != nil {
panic(err) panic(err)
} }
recentHeaders, err := lru.NewARC(inMemoryHeaders)
if err != nil {
panic(err)
}
vABIBeforeLuban, err := abi.JSON(strings.NewReader(validatorSetABIBeforeLuban)) vABIBeforeLuban, err := abi.JSON(strings.NewReader(validatorSetABIBeforeLuban))
if err != nil { if err != nil {
panic(err) panic(err)
@ -286,6 +295,7 @@ func New(
db: db, db: db,
ethAPI: ethAPI, ethAPI: ethAPI,
recentSnaps: recentSnaps, recentSnaps: recentSnaps,
recentHeaders: recentHeaders,
signatures: signatures, signatures: signatures,
validatorSetABIBeforeLuban: vABIBeforeLuban, validatorSetABIBeforeLuban: vABIBeforeLuban,
validatorSetABI: vABI, validatorSetABI: vABI,
@ -813,6 +823,16 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea
return errUnauthorizedValidator(signer.String()) return errUnauthorizedValidator(signer.String())
} }
// check for double sign & add to cache
key := proposalKey(*header)
value, ok := p.recentHeaders.Get(key)
if ok {
doubleSignCounter.Inc(1)
} else {
p.recentHeaders.Add(key, value)
}
if snap.SignRecently(signer) { if snap.SignRecently(signer) {
return errRecentlySigned return errRecentlySigned
} }
@ -2011,3 +2031,8 @@ func applyMessage(
} }
return msg.Gas() - returnGas, err return msg.Gas() - returnGas, err
} }
// proposalKey build a key which is a combination of the block number and the proposer address.
func proposalKey(header types.Header) string {
return header.ParentHash.String() + header.Coinbase.String()
}