mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-07 03:22:18 +00:00
076dc33232
- Move borfinality out of eth package - Adds nil pointer check in bor_verifier
192 lines
4.6 KiB
Go
192 lines
4.6 KiB
Go
package whitelist
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/common"
|
|
"github.com/ledgerwatch/erigon-lib/kv"
|
|
"github.com/ledgerwatch/erigon/consensus/bor/finality/rawdb"
|
|
"github.com/ledgerwatch/erigon/core/types"
|
|
)
|
|
|
|
var (
|
|
ErrMismatch = errors.New("mismatch error")
|
|
ErrNoRemote = errors.New("remote peer doesn't have a target block number")
|
|
)
|
|
|
|
type Service struct {
|
|
checkpointService
|
|
milestoneService
|
|
}
|
|
|
|
var ws *Service
|
|
|
|
func RegisterService(db kv.RwDB) {
|
|
ws = NewService(db)
|
|
}
|
|
|
|
func GetWhitelistingService() *Service {
|
|
return ws
|
|
}
|
|
|
|
func NewService(db kv.RwDB) *Service {
|
|
var checkpointDoExist = true
|
|
checkpointNumber, checkpointHash, err := rawdb.ReadFinality[*rawdb.Checkpoint](db)
|
|
|
|
if err != nil {
|
|
checkpointDoExist = false
|
|
}
|
|
|
|
var milestoneDoExist = true
|
|
|
|
milestoneNumber, milestoneHash, err := rawdb.ReadFinality[*rawdb.Milestone](db)
|
|
if err != nil {
|
|
milestoneDoExist = false
|
|
}
|
|
|
|
locked, lockedMilestoneNumber, lockedMilestoneHash, lockedMilestoneIDs, err := rawdb.ReadLockField(db)
|
|
if err != nil || !locked {
|
|
locked = false
|
|
lockedMilestoneIDs = make(map[string]struct{})
|
|
}
|
|
|
|
order, list, err := rawdb.ReadFutureMilestoneList(db)
|
|
if err != nil {
|
|
order = make([]uint64, 0)
|
|
list = make(map[uint64]common.Hash)
|
|
}
|
|
|
|
return &Service{
|
|
&checkpoint{
|
|
finality[*rawdb.Checkpoint]{
|
|
doExist: checkpointDoExist,
|
|
Number: checkpointNumber,
|
|
Hash: checkpointHash,
|
|
interval: 256,
|
|
db: db,
|
|
},
|
|
},
|
|
|
|
&milestone{
|
|
finality: finality[*rawdb.Milestone]{
|
|
doExist: milestoneDoExist,
|
|
Number: milestoneNumber,
|
|
Hash: milestoneHash,
|
|
interval: 256,
|
|
db: db,
|
|
},
|
|
|
|
Locked: locked,
|
|
LockedMilestoneNumber: lockedMilestoneNumber,
|
|
LockedMilestoneHash: lockedMilestoneHash,
|
|
LockedMilestoneIDs: lockedMilestoneIDs,
|
|
FutureMilestoneList: list,
|
|
FutureMilestoneOrder: order,
|
|
MaxCapacity: 10,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (s *Service) PurgeWhitelistedCheckpoint() error {
|
|
s.checkpointService.Purge()
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) PurgeWhitelistedMilestone() error {
|
|
s.milestoneService.Purge()
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) GetWhitelistedCheckpoint() (bool, uint64, common.Hash) {
|
|
return s.checkpointService.Get()
|
|
}
|
|
|
|
func (s *Service) GetWhitelistedMilestone() (bool, uint64, common.Hash) {
|
|
return s.milestoneService.Get()
|
|
}
|
|
|
|
func (s *Service) ProcessMilestone(endBlockNum uint64, endBlockHash common.Hash) {
|
|
s.milestoneService.Process(endBlockNum, endBlockHash)
|
|
}
|
|
|
|
func (s *Service) ProcessCheckpoint(endBlockNum uint64, endBlockHash common.Hash) {
|
|
s.checkpointService.Process(endBlockNum, endBlockHash)
|
|
}
|
|
|
|
func (s *Service) IsValidChain(currentHeader uint64, chain []*types.Header) bool {
|
|
checkpointBool := s.checkpointService.IsValidChain(currentHeader, chain)
|
|
if !checkpointBool {
|
|
return checkpointBool
|
|
}
|
|
|
|
milestoneBool := s.milestoneService.IsValidChain(currentHeader, chain)
|
|
if !milestoneBool {
|
|
return milestoneBool
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (s *Service) GetMilestoneIDsList() []string {
|
|
return s.milestoneService.GetMilestoneIDsList()
|
|
}
|
|
|
|
func splitChain(current uint64, chain []*types.Header) ([]*types.Header, []*types.Header) {
|
|
var (
|
|
pastChain []*types.Header
|
|
futureChain []*types.Header
|
|
first = chain[0].Number.Uint64()
|
|
last = chain[len(chain)-1].Number.Uint64()
|
|
)
|
|
|
|
if current >= first {
|
|
if len(chain) == 1 || current >= last {
|
|
pastChain = chain
|
|
} else {
|
|
pastChain = chain[:current-first+1]
|
|
}
|
|
}
|
|
|
|
if current < last {
|
|
if len(chain) == 1 || current < first {
|
|
futureChain = chain
|
|
} else {
|
|
futureChain = chain[current-first+1:]
|
|
}
|
|
}
|
|
|
|
return pastChain, futureChain
|
|
}
|
|
|
|
func isValidChain(currentHeader uint64, chain []*types.Header, doExist bool, number uint64, hash common.Hash, interval uint64) bool {
|
|
// Check if we have milestone to validate incoming chain in memory
|
|
if !doExist {
|
|
// We don't have any entry, no additional validation will be possible
|
|
return true
|
|
}
|
|
|
|
// Check if imported chain is less than whitelisted number
|
|
if chain[len(chain)-1].Number.Uint64() < number {
|
|
if currentHeader >= number { //If current tip of the chain is greater than whitelist number then return false
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
|
|
// Split the chain into past and future chain
|
|
pastChain, _ := splitChain(currentHeader, chain)
|
|
|
|
// Iterate over the chain and validate against the last milestone
|
|
// It will handle all cases when the incoming chain has atleast one milestone
|
|
for i := len(pastChain) - 1; i >= 0; i-- {
|
|
if pastChain[i].Number.Uint64() == number {
|
|
res := pastChain[i].Hash() == hash
|
|
|
|
return res
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|