mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-21 19:20:39 +00:00
polygon/sync: move PeersWithBlockNumInfo and mocks, refactor bor.GetRootHash (#9232)
This commit is contained in:
parent
c5b75d00ca
commit
fb0226d293
@ -1392,12 +1392,23 @@ func (c *Bor) GetRootHash(ctx context.Context, tx kv.Tx, start, end uint64) (str
|
||||
if start > end || end > currentHeaderNumber {
|
||||
return "", &valset.InvalidStartEndBlockError{Start: start, End: end, CurrentHeader: currentHeaderNumber}
|
||||
}
|
||||
blockHeaders := make([]*types.Header, end-start+1)
|
||||
blockHeaders := make([]*types.Header, length)
|
||||
for number := start; number <= end; number++ {
|
||||
blockHeaders[number-start], _ = c.getHeaderByNumber(ctx, tx, number)
|
||||
}
|
||||
|
||||
headers := make([][32]byte, NextPowerOfTwo(length))
|
||||
hash, err := ComputeHeadersRootHash(blockHeaders)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hashStr := hex.EncodeToString(hash)
|
||||
c.rootHashCache.Add(cacheKey, hashStr)
|
||||
return hashStr, nil
|
||||
}
|
||||
|
||||
func ComputeHeadersRootHash(blockHeaders []*types.Header) ([]byte, error) {
|
||||
headers := make([][32]byte, NextPowerOfTwo(uint64(len(blockHeaders))))
|
||||
for i := 0; i < len(blockHeaders); i++ {
|
||||
blockHeader := blockHeaders[i]
|
||||
header := crypto.Keccak256(AppendBytes32(
|
||||
@ -1413,13 +1424,10 @@ func (c *Bor) GetRootHash(ctx context.Context, tx kv.Tx, start, end uint64) (str
|
||||
}
|
||||
tree := merkle.NewTreeWithOpts(merkle.TreeOptions{EnableHashSorting: false, DisableHashLeaves: true})
|
||||
if err := tree.Generate(Convert(headers), sha3.NewLegacyKeccak256()); err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
root := hex.EncodeToString(tree.Root().Hash)
|
||||
|
||||
c.rootHashCache.Add(cacheKey, root)
|
||||
|
||||
return root, nil
|
||||
return tree.Root().Hash, nil
|
||||
}
|
||||
|
||||
func (c *Bor) getHeaderByNumber(ctx context.Context, tx kv.Tx, number uint64) (*types.Header, error) {
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon/polygon/bor"
|
||||
)
|
||||
|
||||
//go:generate mockgen -destination=./mock/canonical_chain_builder_mock.go -package=mock . CanonicalChainBuilder
|
||||
//go:generate mockgen -destination=./canonical_chain_builder_mock.go -package=sync . CanonicalChainBuilder
|
||||
type CanonicalChainBuilder interface {
|
||||
Reset(root *types.Header)
|
||||
ContainsHash(hash libcommon.Hash) bool
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/ledgerwatch/erigon/polygon/sync (interfaces: CanonicalChainBuilder)
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
// Package sync is a generated GoMock package.
|
||||
package sync
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
@ -2,7 +2,7 @@ package sync
|
||||
|
||||
import "github.com/ledgerwatch/erigon/core/types"
|
||||
|
||||
//go:generate mockgen -destination=./mock/db_mock.go -package=mock . DB
|
||||
//go:generate mockgen -destination=./db_mock.go -package=sync . DB
|
||||
type DB interface {
|
||||
WriteHeaders(headers []*types.Header) error
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/ledgerwatch/erigon/polygon/sync (interfaces: DB)
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
// Package sync is a generated GoMock package.
|
||||
package sync
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
@ -13,12 +13,11 @@ import (
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/polygon/sync/peerinfo"
|
||||
)
|
||||
|
||||
const headerDownloaderLogPrefix = "HeaderDownloader"
|
||||
|
||||
func NewHeaderDownloader(logger log.Logger, sentry Sentry, db DB, heimdall Heimdall, verify HeaderVerifier) *HeaderDownloader {
|
||||
func NewHeaderDownloader(logger log.Logger, sentry Sentry, db DB, heimdall Heimdall, verify StatePointHeadersVerifier) *HeaderDownloader {
|
||||
statePointHeadersMemo, err := lru.New[common.Hash, []*types.Header](sentry.MaxPeers())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -39,7 +38,7 @@ type HeaderDownloader struct {
|
||||
sentry Sentry
|
||||
db DB
|
||||
heimdall Heimdall
|
||||
verify HeaderVerifier
|
||||
verify StatePointHeadersVerifier
|
||||
statePointHeadersMemo *lru.Cache[common.Hash, []*types.Header] // statePoint.rootHash->[headers part of state point]
|
||||
}
|
||||
|
||||
@ -194,9 +193,9 @@ func (hd *HeaderDownloader) downloadUsingStatePoints(ctx context.Context, stateP
|
||||
}
|
||||
|
||||
// choosePeers assumes peers are sorted in ascending order based on block num
|
||||
func (hd *HeaderDownloader) choosePeers(peers peerinfo.PeersWithBlockNumInfo, statePoints statePoints) peerinfo.PeersWithBlockNumInfo {
|
||||
func (hd *HeaderDownloader) choosePeers(peers PeersWithBlockNumInfo, statePoints statePoints) PeersWithBlockNumInfo {
|
||||
var peersIdx int
|
||||
chosenPeers := make(peerinfo.PeersWithBlockNumInfo, 0, len(peers))
|
||||
chosenPeers := make(PeersWithBlockNumInfo, 0, len(peers))
|
||||
for _, statePoint := range statePoints {
|
||||
if peersIdx >= len(peers) {
|
||||
break
|
||||
|
@ -12,13 +12,10 @@ import (
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint"
|
||||
"github.com/ledgerwatch/erigon/polygon/heimdall/milestone"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/polygon/sync/mock"
|
||||
"github.com/ledgerwatch/erigon/polygon/sync/peerinfo"
|
||||
"github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint"
|
||||
"github.com/ledgerwatch/erigon/polygon/heimdall/milestone"
|
||||
"github.com/ledgerwatch/erigon/turbo/testlog"
|
||||
)
|
||||
|
||||
@ -28,10 +25,10 @@ func newHeaderDownloaderTest(t *testing.T) *headerDownloaderTest {
|
||||
|
||||
func newHeaderDownloaderTestWithOpts(t *testing.T, opts headerDownloaderTestOpts) *headerDownloaderTest {
|
||||
ctrl := gomock.NewController(t)
|
||||
heimdall := mock.NewMockHeimdall(ctrl)
|
||||
sentry := mock.NewMockSentry(ctrl)
|
||||
heimdall := NewMockHeimdall(ctrl)
|
||||
sentry := NewMockSentry(ctrl)
|
||||
sentry.EXPECT().MaxPeers().Return(100).Times(1)
|
||||
db := mock.NewMockDB(ctrl)
|
||||
db := NewMockDB(ctrl)
|
||||
logger := testlog.Logger(t, log.LvlDebug)
|
||||
headerVerifier := opts.getOrCreateDefaultHeaderVerifier()
|
||||
headerDownloader := NewHeaderDownloader(logger, sentry, db, heimdall, headerVerifier)
|
||||
@ -44,10 +41,10 @@ func newHeaderDownloaderTestWithOpts(t *testing.T, opts headerDownloaderTestOpts
|
||||
}
|
||||
|
||||
type headerDownloaderTestOpts struct {
|
||||
headerVerifier HeaderVerifier
|
||||
headerVerifier StatePointHeadersVerifier
|
||||
}
|
||||
|
||||
func (opts headerDownloaderTestOpts) getOrCreateDefaultHeaderVerifier() HeaderVerifier {
|
||||
func (opts headerDownloaderTestOpts) getOrCreateDefaultHeaderVerifier() StatePointHeadersVerifier {
|
||||
if opts.headerVerifier == nil {
|
||||
return func(_ *statePoint, _ []*types.Header) error {
|
||||
return nil
|
||||
@ -58,14 +55,14 @@ func (opts headerDownloaderTestOpts) getOrCreateDefaultHeaderVerifier() HeaderVe
|
||||
}
|
||||
|
||||
type headerDownloaderTest struct {
|
||||
heimdall *mock.MockHeimdall
|
||||
sentry *mock.MockSentry
|
||||
db *mock.MockDB
|
||||
heimdall *MockHeimdall
|
||||
sentry *MockSentry
|
||||
db *MockDB
|
||||
headerDownloader *HeaderDownloader
|
||||
}
|
||||
|
||||
func (hdt headerDownloaderTest) fakePeers(count int, blockNums ...*big.Int) peerinfo.PeersWithBlockNumInfo {
|
||||
peers := make(peerinfo.PeersWithBlockNumInfo, count)
|
||||
func (hdt headerDownloaderTest) fakePeers(count int, blockNums ...*big.Int) PeersWithBlockNumInfo {
|
||||
peers := make(PeersWithBlockNumInfo, count)
|
||||
for i := range peers {
|
||||
var blockNum *big.Int
|
||||
if i < len(blockNums) {
|
||||
@ -74,7 +71,7 @@ func (hdt headerDownloaderTest) fakePeers(count int, blockNums ...*big.Int) peer
|
||||
blockNum = new(big.Int).SetUint64(math.MaxUint64)
|
||||
}
|
||||
|
||||
peers[i] = &peerinfo.PeerWithBlockNumInfo{
|
||||
peers[i] = &PeerWithBlockNumInfo{
|
||||
ID: fmt.Sprintf("peer%d", i+1),
|
||||
BlockNum: blockNum,
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
package sync
|
||||
|
||||
import "github.com/ledgerwatch/erigon/core/types"
|
||||
|
||||
type HeaderVerifier func(statePoint *statePoint, headers []*types.Header) error
|
@ -18,7 +18,7 @@ import (
|
||||
|
||||
// Heimdall is a wrapper of Heimdall HTTP API
|
||||
//
|
||||
//go:generate mockgen -destination=./mock/heimdall_mock.go -package=mock . Heimdall
|
||||
//go:generate mockgen -destination=./heimdall_mock.go -package=sync . Heimdall
|
||||
type Heimdall interface {
|
||||
FetchCheckpoints(ctx context.Context, start uint64) ([]*checkpoint.Checkpoint, error)
|
||||
FetchMilestones(ctx context.Context, start uint64) ([]*milestone.Milestone, error)
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/ledgerwatch/erigon/polygon/sync (interfaces: Heimdall)
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
// Package sync is a generated GoMock package.
|
||||
package sync
|
||||
|
||||
import (
|
||||
context "context"
|
@ -1,4 +1,4 @@
|
||||
package peerinfo
|
||||
package sync
|
||||
|
||||
import "math/big"
|
||||
|
@ -5,13 +5,12 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/polygon/sync/peerinfo"
|
||||
)
|
||||
|
||||
//go:generate mockgen -destination=./mock/sentry_mock.go -package=mock . Sentry
|
||||
//go:generate mockgen -destination=./sentry_mock.go -package=sync . Sentry
|
||||
type Sentry interface {
|
||||
MaxPeers() int
|
||||
PeersWithBlockNumInfo() peerinfo.PeersWithBlockNumInfo
|
||||
PeersWithBlockNumInfo() PeersWithBlockNumInfo
|
||||
DownloadHeaders(ctx context.Context, start *big.Int, end *big.Int, peerID string) ([]*types.Header, error)
|
||||
Penalize(peerID string)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/ledgerwatch/erigon/polygon/sync (interfaces: Sentry)
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
// Package sync is a generated GoMock package.
|
||||
package sync
|
||||
|
||||
import (
|
||||
context "context"
|
||||
@ -11,7 +11,6 @@ import (
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
types "github.com/ledgerwatch/erigon/core/types"
|
||||
peerinfo "github.com/ledgerwatch/erigon/polygon/sync/peerinfo"
|
||||
)
|
||||
|
||||
// MockSentry is a mock of Sentry interface.
|
||||
@ -67,10 +66,10 @@ func (mr *MockSentryMockRecorder) MaxPeers() *gomock.Call {
|
||||
}
|
||||
|
||||
// PeersWithBlockNumInfo mocks base method.
|
||||
func (m *MockSentry) PeersWithBlockNumInfo() peerinfo.PeersWithBlockNumInfo {
|
||||
func (m *MockSentry) PeersWithBlockNumInfo() PeersWithBlockNumInfo {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PeersWithBlockNumInfo")
|
||||
ret0, _ := ret[0].(peerinfo.PeersWithBlockNumInfo)
|
||||
ret0, _ := ret[0].(PeersWithBlockNumInfo)
|
||||
return ret0
|
||||
}
|
||||
|
22
polygon/sync/state_point_headers_verifier.go
Normal file
22
polygon/sync/state_point_headers_verifier.go
Normal file
@ -0,0 +1,22 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/polygon/bor"
|
||||
)
|
||||
|
||||
type StatePointHeadersVerifier func(statePoint *statePoint, headers []*types.Header) error
|
||||
|
||||
func VerifyStatePointHeaders(statePoint *statePoint, headers []*types.Header) error {
|
||||
rootHash, err := bor.ComputeHeadersRootHash(headers)
|
||||
if err != nil {
|
||||
return fmt.Errorf("VerifyStatePointHeaders: failed to compute headers root hash %w", err)
|
||||
}
|
||||
if !bytes.Equal(rootHash, statePoint.rootHash[:]) {
|
||||
return fmt.Errorf("VerifyStatePointHeaders: bad headers root hash")
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user