Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cmd/headers/download/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ func (cs *ControlServerImpl) newBlock(ctx context.Context, inreq *proto_sentry.I
} else {
return fmt.Errorf("singleHeaderAsSegment failed: %v", err)
}
cs.bd.AddToPrefetch(request.Block)
outreq := proto_sentry.PeerMinBlockRequest{
PeerId: inreq.PeerId,
MinBlock: request.Block.NumberU64(),
Expand All @@ -503,8 +504,11 @@ func (cs *ControlServerImpl) blockBodies(inreq *proto_sentry.InboundMessage) err
return fmt.Errorf("decode BlockBodies: %v", err)
}
delivered, undelivered := cs.bd.DeliverBodies(request)
// Approximate numbers
cs.bd.DeliverySize(float64(len(inreq.Data))*float64(delivered)/float64(delivered+undelivered), float64(len(inreq.Data))*float64(undelivered)/float64(delivered+undelivered))
total := delivered + undelivered
if total > 0 {
// Approximate numbers
cs.bd.DeliverySize(float64(len(inreq.Data))*float64(delivered)/float64(delivered+undelivered), float64(len(inreq.Data))*float64(undelivered)/float64(delivered+undelivered))
}
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/headers/download/sentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ func runPeer(
TD: gointerfaces.ConvertH256ToUint256Int(protoStatusData.TotalDifficulty).ToBig(),
Head: gointerfaces.ConvertH256ToHash(protoStatusData.BestHash),
Genesis: genesisHash,
ForkID: forkid.NewIDFromForks(protoStatusData.ForkData.Forks, genesisHash),
ForkID: forkid.NewIDFromForks(protoStatusData.ForkData.Forks, genesisHash, protoStatusData.MaxBlock),
}
forkFilter := forkid.NewFilterFromForks(protoStatusData.ForkData.Forks, genesisHash)
forkFilter := forkid.NewFilterFromForks(protoStatusData.ForkData.Forks, genesisHash, protoStatusData.MaxBlock)
networkID := protoStatusData.NetworkId
if err := p2p.Send(rw, eth.StatusMsg, statusData); err != nil {
return fmt.Errorf("handshake to peer %s: %v", peerID, err)
Expand Down
21 changes: 7 additions & 14 deletions core/forkid/forkid.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,16 @@ type Filter func(id ID) error

// NewID calculates the Ethereum fork ID from the chain config, genesis hash, and head.
func NewID(config *params.ChainConfig, genesis common.Hash, head uint64) ID {
return NewIDFromForks(GatherForks(config), genesis, head)
}

func NewIDFromForks(forks []uint64, genesis common.Hash, head uint64) ID {
// Calculate the starting checksum from the genesis hash
hash := crc32.ChecksumIEEE(genesis[:])

// Calculate the current fork checksum and the next fork block
var next uint64
for _, fork := range GatherForks(config) {
for _, fork := range forks {
if fork <= head {
// Fork already passed, checksum the previous hash and the fork number
hash = checksumUpdate(hash, fork)
Expand All @@ -72,17 +76,6 @@ func NewID(config *params.ChainConfig, genesis common.Hash, head uint64) ID {
return ID{Hash: checksumToBytes(hash), Next: next}
}

func NewIDFromForks(forks []uint64, genesis common.Hash) ID {
// Calculate the starting checksum from the genesis hash
hash := crc32.ChecksumIEEE(genesis[:])

// Calculate the current fork checksum and the next fork block
for _, fork := range forks {
hash = checksumUpdate(hash, fork)
}
return ID{Hash: checksumToBytes(hash), Next: 0}
}

// NewFilter creates a filter that returns if a fork ID should be rejected or notI
// based on the local chain's status.
func NewFilter(config *params.ChainConfig, genesis common.Hash, head func() uint64) Filter {
Expand All @@ -94,8 +87,8 @@ func NewFilter(config *params.ChainConfig, genesis common.Hash, head func() uint
)
}

func NewFilterFromForks(forks []uint64, genesis common.Hash) Filter {
head := func() uint64 { return 0 }
func NewFilterFromForks(forks []uint64, genesis common.Hash, headNumber uint64) Filter {
head := func() uint64 { return headNumber }
return newFilter(forks, genesis, head)
}

Expand Down
3 changes: 2 additions & 1 deletion eth/downloader/downloader_stagedsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/ledgerwatch/turbo-geth/eth/stagedsync"
"github.com/ledgerwatch/turbo-geth/log"
"github.com/ledgerwatch/turbo-geth/rlp"
"github.com/ledgerwatch/turbo-geth/turbo/stages/bodydownload"
)

// externsions for downloader needed for staged sync
Expand All @@ -19,7 +20,7 @@ func (d *Downloader) SpawnBodyDownloadStage(
id string,
s *stagedsync.StageState,
u stagedsync.Unwinder,
prefetchedBlocks *stagedsync.PrefetchedBlocks,
prefetchedBlocks *bodydownload.PrefetchedBlocks,
) (bool, error) {
d.bodiesState = s
d.bodiesUnwinder = u
Expand Down
3 changes: 2 additions & 1 deletion eth/stagedsync/stage_bodies.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"fmt"

"github.com/ledgerwatch/turbo-geth/ethdb"
"github.com/ledgerwatch/turbo-geth/turbo/stages/bodydownload"
)

func spawnBodyDownloadStage(s *StageState, u Unwinder, d DownloaderGlue, pid string, pb *PrefetchedBlocks) error {
func spawnBodyDownloadStage(s *StageState, u Unwinder, d DownloaderGlue, pid string, pb *bodydownload.PrefetchedBlocks) error {
logPrefix := s.state.LogPrefix()
cont, err := d.SpawnBodyDownloadStage(logPrefix, pid, s, u, pb)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion eth/stagedsync/stagebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ledgerwatch/turbo-geth/log"
"github.com/ledgerwatch/turbo-geth/params"
"github.com/ledgerwatch/turbo-geth/turbo/shards"
"github.com/ledgerwatch/turbo-geth/turbo/stages/bodydownload"
)

type ChainEventNotifier interface {
Expand Down Expand Up @@ -45,7 +46,7 @@ type StageParameters struct {
headersFetchers []func() error
txPool *core.TxPool
poolStart func() error
prefetchedBlocks *PrefetchedBlocks
prefetchedBlocks *bodydownload.PrefetchedBlocks
stateReaderBuilder StateReaderBuilder
stateWriterBuilder StateWriterBuilder
notifier ChainEventNotifier
Expand Down
5 changes: 3 additions & 2 deletions eth/stagedsync/stagedsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import (
"github.com/ledgerwatch/turbo-geth/ethdb"
"github.com/ledgerwatch/turbo-geth/params"
"github.com/ledgerwatch/turbo-geth/turbo/shards"
"github.com/ledgerwatch/turbo-geth/turbo/stages/bodydownload"
)

const prof = false // whether to profile

type StagedSync struct {
PrefetchedBlocks *PrefetchedBlocks
PrefetchedBlocks *bodydownload.PrefetchedBlocks
stageBuilders StageBuilders
unwindOrder UnwindOrder
params OptionalParameters
Expand All @@ -40,7 +41,7 @@ type OptionalParameters struct {

func New(stages StageBuilders, unwindOrder UnwindOrder, params OptionalParameters) *StagedSync {
return &StagedSync{
PrefetchedBlocks: NewPrefetchedBlocks(),
PrefetchedBlocks: bodydownload.NewPrefetchedBlocks(),
stageBuilders: stages,
unwindOrder: unwindOrder,
params: params,
Expand Down
4 changes: 3 additions & 1 deletion eth/stagedsync/types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package stagedsync

import "github.com/ledgerwatch/turbo-geth/turbo/stages/bodydownload"

type DownloaderGlue interface {
SpawnHeaderDownloadStage([]func() error, *StageState, Unwinder) error
SpawnBodyDownloadStage(string, string, *StageState, Unwinder, *PrefetchedBlocks) (bool, error)
SpawnBodyDownloadStage(string, string, *StageState, Unwinder, *bodydownload.PrefetchedBlocks) (bool, error)
}
29 changes: 23 additions & 6 deletions turbo/stages/bodydownload/body_algos.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,17 @@ func (bd *BodyDownload) RequestMoreBodies(db ethdb.Database, blockNum uint64, cu
log.Error("Could not find canonical header", "block number", blockNum)
}
if header != nil {
bd.deliveries[blockNum-bd.requestedLow] = types.NewBlockWithHeader(header) // Block without uncles and transactions
if header.UncleHash != types.EmptyUncleHash || header.TxHash != types.EmptyRootHash {
var doubleHash DoubleHash
copy(doubleHash[:], header.UncleHash.Bytes())
copy(doubleHash[common.HashLength:], header.TxHash.Bytes())
bd.requestedMap[doubleHash] = blockNum
if block := bd.prefetchedBlocks.Pop(hash); block != nil {
// Block is prefetched, no need to request
bd.deliveries[blockNum-bd.requestedLow] = block
} else {
bd.deliveries[blockNum-bd.requestedLow] = types.NewBlockWithHeader(header) // Block without uncles and transactions
if header.UncleHash != types.EmptyUncleHash || header.TxHash != types.EmptyRootHash {
var doubleHash DoubleHash
copy(doubleHash[:], header.UncleHash.Bytes())
copy(doubleHash[common.HashLength:], header.TxHash.Bytes())
bd.requestedMap[doubleHash] = blockNum
}
}
}
}
Expand Down Expand Up @@ -243,3 +248,15 @@ func (bd *BodyDownload) PrintPeerMap() {
fmt.Printf("---------------------------\n")
bd.peerMap = make(map[string]int)
}

func (bd *BodyDownload) AddToPrefetch(block *types.Block) {
if hash := types.CalcUncleHash(block.Uncles()); hash != block.UncleHash() {
log.Warn("Propagated block has invalid uncles", "have", hash, "exp", block.UncleHash())
return
}
if hash := types.DeriveSha(block.Transactions()); hash != block.TxHash() {
log.Warn("Propagated block has invalid body", "have", hash, "exp", block.TxHash())
return
}
bd.prefetchedBlocks.Add(block)
}
2 changes: 2 additions & 0 deletions turbo/stages/bodydownload/body_data_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type BodyDownload struct {
lowWaitUntil uint64 // Time to wait for before starting the next round request from requestedLow
outstandingLimit uint64 // Limit of number of outstanding blocks for body requests
peerMap map[string]int
prefetchedBlocks *PrefetchedBlocks
}

// BodyRequest is a sketch of the request for block bodies, meaning that access to the database is required to convert it to the actual BlockBodies request (look up hashes of canonical blocks)
Expand All @@ -47,6 +48,7 @@ func NewBodyDownload(outstandingLimit int) *BodyDownload {
deliveries: make([]*types.Block, outstandingLimit+MaxBodiesInRequest),
requests: make([]*BodyRequest, outstandingLimit+MaxBodiesInRequest),
peerMap: make(map[string]int),
prefetchedBlocks: NewPrefetchedBlocks(),
}
return bd
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package stagedsync
package bodydownload

import (
"github.com/ledgerwatch/turbo-geth/common"
Expand Down