Merge pull request #664 from maticnetwork/master

Merge 'master' into qa
This commit is contained in:
SHIVAM SHARMA 2023-01-13 13:42:23 +05:30 committed by GitHub
commit 66c23d1eeb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 77 additions and 54 deletions

View file

@ -15,14 +15,17 @@
"londonBlock": 23850000, "londonBlock": 23850000,
"bor": { "bor": {
"jaipurBlock": 23850000, "jaipurBlock": 23850000,
"delhiBlock": 38189056,
"period": { "period": {
"0": 2 "0": 2
}, },
"producerDelay": { "producerDelay": {
"0": 6 "0": 6,
"38189056": 4
}, },
"sprint": { "sprint": {
"0": 64 "0": 64,
"38189056": 16
}, },
"backupMultiplier": { "backupMultiplier": {
"0": 2 "0": 2

View file

@ -68,6 +68,7 @@ var (
snapshotStorageReadTimer = metrics.NewRegisteredTimer("chain/snapshot/storage/reads", nil) snapshotStorageReadTimer = metrics.NewRegisteredTimer("chain/snapshot/storage/reads", nil)
snapshotCommitTimer = metrics.NewRegisteredTimer("chain/snapshot/commits", nil) snapshotCommitTimer = metrics.NewRegisteredTimer("chain/snapshot/commits", nil)
blockImportTimer = metrics.NewRegisteredMeter("chain/imports", nil)
blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil)
blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil) blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil)
blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil) blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil)
@ -1518,6 +1519,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
it := newInsertIterator(chain, results, bc.validator) it := newInsertIterator(chain, results, bc.validator)
block, err := it.next() block, err := it.next()
// Update the block import meter; it will just record chains we've received
// from other peers. (Note that the actual chain which gets imported would be
// quite low).
blockImportTimer.Mark(int64(len(headers)))
// Check the validity of incoming chain // Check the validity of incoming chain
isValid, err1 := bc.forker.ValidateReorg(bc.CurrentBlock().Header(), headers) isValid, err1 := bc.forker.ValidateReorg(bc.CurrentBlock().Header(), headers)
if err1 != nil { if err1 != nil {

View file

@ -114,9 +114,7 @@ func (f *ForkChoice) ReorgNeeded(current *types.Header, header *types.Header) (b
func (f *ForkChoice) ValidateReorg(current *types.Header, chain []*types.Header) (bool, error) { func (f *ForkChoice) ValidateReorg(current *types.Header, chain []*types.Header) (bool, error) {
// Call the bor chain validator service // Call the bor chain validator service
if f.validator != nil { if f.validator != nil {
if isValid := f.validator.IsValidChain(current, chain); !isValid { return f.validator.IsValidChain(current, chain)
return false, nil
}
} }
return true, nil return true, nil

View file

@ -13,7 +13,7 @@ import (
// chainValidatorFake is a mock for the chain validator service // chainValidatorFake is a mock for the chain validator service
type chainValidatorFake struct { type chainValidatorFake struct {
validate func(currentHeader *types.Header, chain []*types.Header) bool validate func(currentHeader *types.Header, chain []*types.Header) (bool, error)
} }
// chainReaderFake is a mock for the chain reader service // chainReaderFake is a mock for the chain reader service
@ -21,7 +21,7 @@ type chainReaderFake struct {
getTd func(hash common.Hash, number uint64) *big.Int getTd func(hash common.Hash, number uint64) *big.Int
} }
func newChainValidatorFake(validate func(currentHeader *types.Header, chain []*types.Header) bool) *chainValidatorFake { func newChainValidatorFake(validate func(currentHeader *types.Header, chain []*types.Header) (bool, error)) *chainValidatorFake {
return &chainValidatorFake{validate: validate} return &chainValidatorFake{validate: validate}
} }
@ -46,18 +46,18 @@ func TestPastChainInsert(t *testing.T) {
getTd := func(hash common.Hash, number uint64) *big.Int { getTd := func(hash common.Hash, number uint64) *big.Int {
return big.NewInt(int64(number)) return big.NewInt(int64(number))
} }
validate := func(currentHeader *types.Header, chain []*types.Header) bool { validate := func(currentHeader *types.Header, chain []*types.Header) (bool, error) {
// Put all explicit conditions here // Put all explicit conditions here
// If canonical chain is empty and we're importing a chain of 64 blocks // If canonical chain is empty and we're importing a chain of 64 blocks
if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 { if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 {
return true return true, nil
} }
// If canonical chain is of len 64 and we're importing a past chain from 54-64, then accept it // If canonical chain is of len 64 and we're importing a past chain from 54-64, then accept it
if currentHeader.Number.Uint64() == uint64(64) && chain[0].Number.Uint64() == 55 && len(chain) == 10 { if currentHeader.Number.Uint64() == uint64(64) && chain[0].Number.Uint64() == 55 && len(chain) == 10 {
return true return true, nil
} }
return false return false, nil
} }
mockChainReader := newChainReaderFake(getTd) mockChainReader := newChainReaderFake(getTd)
mockChainValidator := newChainValidatorFake(validate) mockChainValidator := newChainValidatorFake(validate)
@ -116,18 +116,18 @@ func TestFutureChainInsert(t *testing.T) {
getTd := func(hash common.Hash, number uint64) *big.Int { getTd := func(hash common.Hash, number uint64) *big.Int {
return big.NewInt(int64(number)) return big.NewInt(int64(number))
} }
validate := func(currentHeader *types.Header, chain []*types.Header) bool { validate := func(currentHeader *types.Header, chain []*types.Header) (bool, error) {
// Put all explicit conditions here // Put all explicit conditions here
// If canonical chain is empty and we're importing a chain of 64 blocks // If canonical chain is empty and we're importing a chain of 64 blocks
if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 { if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 {
return true return true, nil
} }
// If length of future chains > some value, they should not be accepted // If length of future chains > some value, they should not be accepted
if currentHeader.Number.Uint64() == uint64(64) && len(chain) <= 10 { if currentHeader.Number.Uint64() == uint64(64) && len(chain) <= 10 {
return true return true, nil
} }
return false return false, nil
} }
mockChainReader := newChainReaderFake(getTd) mockChainReader := newChainReaderFake(getTd)
mockChainValidator := newChainValidatorFake(validate) mockChainValidator := newChainValidatorFake(validate)
@ -174,18 +174,18 @@ func TestOverlappingChainInsert(t *testing.T) {
getTd := func(hash common.Hash, number uint64) *big.Int { getTd := func(hash common.Hash, number uint64) *big.Int {
return big.NewInt(int64(number)) return big.NewInt(int64(number))
} }
validate := func(currentHeader *types.Header, chain []*types.Header) bool { validate := func(currentHeader *types.Header, chain []*types.Header) (bool, error) {
// Put all explicit conditions here // Put all explicit conditions here
// If canonical chain is empty and we're importing a chain of 64 blocks // If canonical chain is empty and we're importing a chain of 64 blocks
if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 { if currentHeader.Number.Uint64() == uint64(0) && len(chain) == 64 {
return true return true, nil
} }
// If length of chain is > some fixed value then don't accept it // If length of chain is > some fixed value then don't accept it
if currentHeader.Number.Uint64() == uint64(64) && len(chain) <= 20 { if currentHeader.Number.Uint64() == uint64(64) && len(chain) <= 20 {
return true return true, nil
} }
return false return false, nil
} }
mockChainReader := newChainReaderFake(getTd) mockChainReader := newChainReaderFake(getTd)
mockChainValidator := newChainValidatorFake(validate) mockChainValidator := newChainValidatorFake(validate)
@ -227,7 +227,7 @@ func (c *chainReaderFake) GetTd(hash common.Hash, number uint64) *big.Int {
func (w *chainValidatorFake) IsValidPeer(remoteHeader *types.Header, fetchHeadersByNumber func(number uint64, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error)) (bool, error) { func (w *chainValidatorFake) IsValidPeer(remoteHeader *types.Header, fetchHeadersByNumber func(number uint64, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error)) (bool, error) {
return true, nil return true, nil
} }
func (w *chainValidatorFake) IsValidChain(current *types.Header, headers []*types.Header) bool { func (w *chainValidatorFake) IsValidChain(current *types.Header, headers []*types.Header) (bool, error) {
return w.validate(current, headers) return w.validate(current, headers)
} }
func (w *chainValidatorFake) ProcessCheckpoint(endBlockNum uint64, endBlockHash common.Hash) {} func (w *chainValidatorFake) ProcessCheckpoint(endBlockNum uint64, endBlockHash common.Hash) {}

View file

@ -357,10 +357,6 @@ func (d *Downloader) LegacySync(id string, head common.Hash, td, ttd *big.Int, m
return err // This is an expected fault, don't keep printing it in a spin-loop return err // This is an expected fault, don't keep printing it in a spin-loop
} }
if errors.Is(err, whitelist.ErrNoRemoteCheckoint) {
log.Warn("Doesn't have remote checkpoint yet", "peer", id, "err", err)
}
log.Warn("Synchronisation failed, retrying", "peer", id, "err", err) log.Warn("Synchronisation failed, retrying", "peer", id, "err", err)
return err return err
@ -1581,6 +1577,13 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error {
// of the blocks delivered from the downloader, and the indexing will be off. // of the blocks delivered from the downloader, and the indexing will be off.
log.Debug("Downloaded item processing failed on sidechain import", "index", index, "err", err) log.Debug("Downloaded item processing failed on sidechain import", "index", index, "err", err)
} }
// If we've received too long future chain error (from whitelisting service),
// return that as the root error and `errInvalidChain` as context.
if errors.Is(err, whitelist.ErrLongFutureChain) {
return fmt.Errorf("%v: %w", errInvalidChain, err)
}
return fmt.Errorf("%w: %v", errInvalidChain, err) return fmt.Errorf("%w: %v", errInvalidChain, err)
} }
return nil return nil

View file

@ -1426,8 +1426,8 @@ func (w *whitelistFake) IsValidPeer(_ *types.Header, _ func(number uint64, amoun
return w.validate(w.count) return w.validate(w.count)
} }
func (w *whitelistFake) IsValidChain(current *types.Header, headers []*types.Header) bool { func (w *whitelistFake) IsValidChain(current *types.Header, headers []*types.Header) (bool, error) {
return true return true, nil
} }
func (w *whitelistFake) ProcessCheckpoint(_ uint64, _ common.Hash) {} func (w *whitelistFake) ProcessCheckpoint(_ uint64, _ common.Hash) {}

View file

@ -30,6 +30,7 @@ func NewService(maxCapacity uint) *Service {
var ( var (
ErrCheckpointMismatch = errors.New("checkpoint mismatch") ErrCheckpointMismatch = errors.New("checkpoint mismatch")
ErrLongFutureChain = errors.New("received future chain of unacceptable length")
ErrNoRemoteCheckoint = errors.New("remote peer doesn't have a checkoint") ErrNoRemoteCheckoint = errors.New("remote peer doesn't have a checkoint")
) )
@ -74,16 +75,16 @@ func (w *Service) IsValidPeer(remoteHeader *types.Header, fetchHeadersByNumber f
// IsValidChain checks the validity of chain by comparing it // IsValidChain checks the validity of chain by comparing it
// against the local checkpoint entries // against the local checkpoint entries
func (w *Service) IsValidChain(currentHeader *types.Header, chain []*types.Header) bool { func (w *Service) IsValidChain(currentHeader *types.Header, chain []*types.Header) (bool, error) {
// Check if we have checkpoints to validate incoming chain in memory // Check if we have checkpoints to validate incoming chain in memory
if len(w.checkpointWhitelist) == 0 { if len(w.checkpointWhitelist) == 0 {
// We don't have any entries, no additional validation will be possible // We don't have any entries, no additional validation will be possible
return true return true, nil
} }
// Return if we've received empty chain // Return if we've received empty chain
if len(chain) == 0 { if len(chain) == 0 {
return false return false, nil
} }
var ( var (
@ -95,7 +96,7 @@ func (w *Service) IsValidChain(currentHeader *types.Header, chain []*types.Heade
if chain[len(chain)-1].Number.Uint64() < oldestCheckpointNumber { if chain[len(chain)-1].Number.Uint64() < oldestCheckpointNumber {
// We have future whitelisted entries, so no additional validation will be possible // We have future whitelisted entries, so no additional validation will be possible
// This case will occur when bor is in middle of sync, but heimdall is ahead/fully synced. // This case will occur when bor is in middle of sync, but heimdall is ahead/fully synced.
return true return true, nil
} }
// Split the chain into past and future chain // Split the chain into past and future chain
@ -109,18 +110,18 @@ func (w *Service) IsValidChain(currentHeader *types.Header, chain []*types.Heade
// Don't accept future chain of unacceptable length (from current block) // Don't accept future chain of unacceptable length (from current block)
if len(futureChain)+offset > int(w.checkpointInterval) { if len(futureChain)+offset > int(w.checkpointInterval) {
return false return false, ErrLongFutureChain
} }
// Iterate over the chain and validate against the last checkpoint // Iterate over the chain and validate against the last checkpoint
// It will handle all cases where the incoming chain has atleast one checkpoint // It will handle all cases where the incoming chain has atleast one checkpoint
for i := len(pastChain) - 1; i >= 0; i-- { for i := len(pastChain) - 1; i >= 0; i-- {
if _, ok := w.checkpointWhitelist[pastChain[i].Number.Uint64()]; ok { if _, ok := w.checkpointWhitelist[pastChain[i].Number.Uint64()]; ok {
return pastChain[i].Hash() == w.checkpointWhitelist[pastChain[i].Number.Uint64()] return pastChain[i].Hash() == w.checkpointWhitelist[pastChain[i].Number.Uint64()], nil
} }
} }
return true return true, nil
} }
func splitChain(current uint64, chain []*types.Header) ([]*types.Header, []*types.Header) { func splitChain(current uint64, chain []*types.Header) ([]*types.Header, []*types.Header) {

View file

@ -119,8 +119,9 @@ func TestIsValidChain(t *testing.T) {
s := NewMockService(10, 10) s := NewMockService(10, 10)
chainA := createMockChain(1, 20) // A1->A2...A19->A20 chainA := createMockChain(1, 20) // A1->A2...A19->A20
// case1: no checkpoint whitelist, should consider the chain as valid // case1: no checkpoint whitelist, should consider the chain as valid
res := s.IsValidChain(nil, chainA) res, err := s.IsValidChain(nil, chainA)
require.Equal(t, res, true, "expected chain to be valid") require.Equal(t, res, true, "expected chain to be valid")
require.Equal(t, err, nil, "expected error to be nil")
tempChain := createMockChain(21, 22) // A21->A22 tempChain := createMockChain(21, 22) // A21->A22
@ -132,8 +133,9 @@ func TestIsValidChain(t *testing.T) {
// case2: We're behind the oldest whitelisted block entry, should consider // case2: We're behind the oldest whitelisted block entry, should consider
// the chain as valid as we're still far behind the latest blocks // the chain as valid as we're still far behind the latest blocks
res = s.IsValidChain(chainA[len(chainA)-1], chainA) res, err = s.IsValidChain(chainA[len(chainA)-1], chainA)
require.Equal(t, res, true, "expected chain to be valid") require.Equal(t, res, true, "expected chain to be valid")
require.Equal(t, err, nil, "expected error to be nil")
// Clear checkpoint whitelist and add blocks A5 and A15 in whitelist // Clear checkpoint whitelist and add blocks A5 and A15 in whitelist
s.PurgeCheckpointWhitelist() s.PurgeCheckpointWhitelist()
@ -144,8 +146,9 @@ func TestIsValidChain(t *testing.T) {
// case3: Try importing a past chain having valid checkpoint, should // case3: Try importing a past chain having valid checkpoint, should
// consider the chain as valid // consider the chain as valid
res = s.IsValidChain(chainA[len(chainA)-1], chainA) res, err = s.IsValidChain(chainA[len(chainA)-1], chainA)
require.Equal(t, res, true, "expected chain to be valid") require.Equal(t, res, true, "expected chain to be valid")
require.Equal(t, err, nil, "expected error to be nil")
// Clear checkpoint whitelist and mock blocks in whitelist // Clear checkpoint whitelist and mock blocks in whitelist
tempChain = createMockChain(20, 20) // A20 tempChain = createMockChain(20, 20) // A20
@ -156,22 +159,25 @@ func TestIsValidChain(t *testing.T) {
require.Equal(t, s.length(), 1, "expected 1 items in whitelist") require.Equal(t, s.length(), 1, "expected 1 items in whitelist")
// case4: Try importing a past chain having invalid checkpoint // case4: Try importing a past chain having invalid checkpoint
res = s.IsValidChain(chainA[len(chainA)-1], chainA) res, _ = s.IsValidChain(chainA[len(chainA)-1], chainA)
require.Equal(t, res, false, "expected chain to be invalid") require.Equal(t, res, false, "expected chain to be invalid")
// Not checking error here because we return nil in case of checkpoint mismatch
// create a future chain to be imported of length <= `checkpointInterval` // create a future chain to be imported of length <= `checkpointInterval`
chainB := createMockChain(21, 30) // B21->B22...B29->B30 chainB := createMockChain(21, 30) // B21->B22...B29->B30
// case5: Try importing a future chain of acceptable length // case5: Try importing a future chain of acceptable length
res = s.IsValidChain(chainA[len(chainA)-1], chainB) res, err = s.IsValidChain(chainA[len(chainA)-1], chainB)
require.Equal(t, res, true, "expected chain to be valid") require.Equal(t, res, true, "expected chain to be valid")
require.Equal(t, err, nil, "expected error to be nil")
// create a future chain to be imported of length > `checkpointInterval` // create a future chain to be imported of length > `checkpointInterval`
chainB = createMockChain(21, 40) // C21->C22...C39->C40 chainB = createMockChain(21, 40) // C21->C22...C39->C40
// case5: Try importing a future chain of unacceptable length // case5: Try importing a future chain of unacceptable length
res = s.IsValidChain(chainA[len(chainA)-1], chainB) res, err = s.IsValidChain(chainA[len(chainA)-1], chainB)
require.Equal(t, res, false, "expected chain to be invalid") require.Equal(t, res, false, "expected chain to be invalid")
require.Equal(t, err, ErrLongFutureChain, "expected error")
} }
func TestSplitChain(t *testing.T) { func TestSplitChain(t *testing.T) {

View file

@ -242,7 +242,7 @@ type StateSyncFilter struct {
// interface for whitelist service // interface for whitelist service
type ChainValidator interface { type ChainValidator interface {
IsValidPeer(remoteHeader *types.Header, fetchHeadersByNumber func(number uint64, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error)) (bool, error) IsValidPeer(remoteHeader *types.Header, fetchHeadersByNumber func(number uint64, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error)) (bool, error)
IsValidChain(currentHeader *types.Header, chain []*types.Header) bool IsValidChain(currentHeader *types.Header, chain []*types.Header) (bool, error)
ProcessCheckpoint(endBlockNum uint64, endBlockHash common.Hash) ProcessCheckpoint(endBlockNum uint64, endBlockHash common.Hash)
GetCheckpointWhitelist() map[uint64]common.Hash GetCheckpointWhitelist() map[uint64]common.Hash
PurgeCheckpointWhitelist() PurgeCheckpointWhitelist()

View file

@ -30,14 +30,17 @@ var mainnetBor = &Chain{
LondonBlock: big.NewInt(23850000), LondonBlock: big.NewInt(23850000),
Bor: &params.BorConfig{ Bor: &params.BorConfig{
JaipurBlock: big.NewInt(23850000), JaipurBlock: big.NewInt(23850000),
DelhiBlock: big.NewInt(38189056),
Period: map[string]uint64{ Period: map[string]uint64{
"0": 2, "0": 2,
}, },
ProducerDelay: map[string]uint64{ ProducerDelay: map[string]uint64{
"0": 6, "0": 6,
"38189056": 4,
}, },
Sprint: map[string]uint64{ Sprint: map[string]uint64{
"0": 64, "0": 64,
"38189056": 16,
}, },
BackupMultiplier: map[string]uint64{ BackupMultiplier: map[string]uint64{
"0": 2, "0": 2,

View file

@ -1,5 +1,5 @@
Source: bor Source: bor
Version: 0.3.2 Version: 0.3.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor Source: bor
Version: 0.3.2 Version: 0.3.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 0.3.2 Version: 0.3.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 0.3.2 Version: 0.3.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 0.3.2 Version: 0.3.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 0.3.2 Version: 0.3.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -404,14 +404,17 @@ var (
LondonBlock: big.NewInt(23850000), LondonBlock: big.NewInt(23850000),
Bor: &BorConfig{ Bor: &BorConfig{
JaipurBlock: big.NewInt(23850000), JaipurBlock: big.NewInt(23850000),
DelhiBlock: big.NewInt(38189056),
Period: map[string]uint64{ Period: map[string]uint64{
"0": 2, "0": 2,
}, },
ProducerDelay: map[string]uint64{ ProducerDelay: map[string]uint64{
"0": 6, "0": 6,
"38189056": 4,
}, },
Sprint: map[string]uint64{ Sprint: map[string]uint64{
"0": 64, "0": 64,
"38189056": 16,
}, },
BackupMultiplier: map[string]uint64{ BackupMultiplier: map[string]uint64{
"0": 2, "0": 2,

View file

@ -21,10 +21,10 @@ import (
) )
const ( const (
VersionMajor = 0 // Major version component of the current release VersionMajor = 0 // Major version component of the current release
VersionMinor = 3 // Minor version component of the current release VersionMinor = 3 // Minor version component of the current release
VersionPatch = 2 // Patch version component of the current release VersionPatch = 3 // Patch version component of the current release
VersionMeta = "beta" // Version metadata to append to the version string VersionMeta = "stable" // Version metadata to append to the version string
) )
// Version holds the textual version string. // Version holds the textual version string.