Skip to content

Commit

Permalink
Revert "cmd, eth: switch the dev synctarget to hash from block (ether…
Browse files Browse the repository at this point in the history
…eum#28209)"

This reverts commit f754753.
  • Loading branch information
devopsbo3 authored Nov 10, 2023
1 parent d533f72 commit fd1b65c
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 126 deletions.
13 changes: 5 additions & 8 deletions cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import (
"github.com/ethereum/go-ethereum/accounts/scwallet"
"github.com/ethereum/go-ethereum/accounts/usbwallet"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/eth/catalyst"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/ethconfig"
Expand Down Expand Up @@ -201,18 +199,17 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
if ctx.IsSet(utils.GraphQLEnabledFlag.Name) {
utils.RegisterGraphQLService(stack, backend, filterSystem, &cfg.Node)
}

// Add the Ethereum Stats daemon if requested.
if cfg.Ethstats.URL != "" {
utils.RegisterEthStatsService(stack, backend, cfg.Ethstats.URL)
}

// Configure full-sync tester service if requested
if ctx.IsSet(utils.SyncTargetFlag.Name) {
hex := hexutil.MustDecode(ctx.String(utils.SyncTargetFlag.Name))
if len(hex) != common.HashLength {
utils.Fatalf("invalid sync target length: have %d, want %d", len(hex), common.HashLength)
}
utils.RegisterFullSyncTester(stack, eth, common.BytesToHash(hex))
if ctx.IsSet(utils.SyncTargetFlag.Name) && cfg.Eth.SyncMode == downloader.FullSync {
utils.RegisterFullSyncTester(stack, eth, ctx.Path(utils.SyncTargetFlag.Name))
}

// Start the dev mode if requested, or launch the engine API for
// interacting with external consensus client.
if ctx.IsSet(utils.DeveloperFlag.Name) {
Expand Down
30 changes: 22 additions & 8 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package utils

import (
"bytes"
"context"
"crypto/ecdsa"
"encoding/hex"
Expand All @@ -38,9 +39,11 @@ import (
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/fdlimit"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
Expand Down Expand Up @@ -69,6 +72,7 @@ import (
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/p2p/netutil"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/triedb/hashdb"
Expand Down Expand Up @@ -591,9 +595,9 @@ var (
}

// MISC settings
SyncTargetFlag = &cli.StringFlag{
SyncTargetFlag = &cli.PathFlag{
Name: "synctarget",
Usage: `Hash of the block to full sync to (dev testing feature)`,
Usage: `File for containing the hex-encoded block-rlp as sync target(dev feature)`,
TakesFile: true,
Category: flags.MiscCategory,
}
Expand Down Expand Up @@ -1687,9 +1691,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
godebug.SetGCPercent(int(gogc))

if ctx.IsSet(SyncTargetFlag.Name) {
cfg.SyncMode = downloader.FullSync // dev sync target forces full sync
} else if ctx.IsSet(SyncModeFlag.Name) {
if ctx.IsSet(SyncModeFlag.Name) {
cfg.SyncMode = *flags.GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
}
if ctx.IsSet(NetworkIdFlag.Name) {
Expand Down Expand Up @@ -1974,9 +1976,21 @@ func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconf
}

// RegisterFullSyncTester adds the full-sync tester service into node.
func RegisterFullSyncTester(stack *node.Node, eth *eth.Ethereum, target common.Hash) {
catalyst.RegisterFullSyncTester(stack, eth, target)
log.Info("Registered full-sync tester", "hash", target)
func RegisterFullSyncTester(stack *node.Node, eth *eth.Ethereum, path string) {
blob, err := os.ReadFile(path)
if err != nil {
Fatalf("Failed to read block file: %v", err)
}
rlpBlob, err := hexutil.Decode(string(bytes.TrimRight(blob, "\r\n")))
if err != nil {
Fatalf("Failed to decode block blob: %v", err)
}
var block types.Block
if err := rlp.DecodeBytes(rlpBlob, &block); err != nil {
Fatalf("Failed to decode block: %v", err)
}
catalyst.RegisterFullSyncTester(stack, eth, &block)
log.Info("Registered full-sync tester", "number", block.NumberU64(), "hash", block.Hash())
}

func SetupMetrics(ctx *cli.Context) {
Expand Down
54 changes: 27 additions & 27 deletions eth/catalyst/tester.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,31 @@ import (
"sync"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
)

// FullSyncTester is an auxiliary service that allows Geth to perform full sync
// alone without consensus-layer attached. Users must specify a valid block hash
// as the sync target.
//
// This tester can be applied to different networks, no matter it's pre-merge or
// post-merge, but only for full-sync.
// alone without consensus-layer attached. Users must specify a valid block as
// the sync target. This tester can be applied to different networks, no matter
// it's pre-merge or post-merge, but only for full-sync.
type FullSyncTester struct {
stack *node.Node
backend *eth.Ethereum
target common.Hash
closed chan struct{}
wg sync.WaitGroup
api *ConsensusAPI
block *types.Block
closed chan struct{}
wg sync.WaitGroup
}

// RegisterFullSyncTester registers the full-sync tester service into the node
// stack for launching and stopping the service controlled by node.
func RegisterFullSyncTester(stack *node.Node, backend *eth.Ethereum, target common.Hash) (*FullSyncTester, error) {
func RegisterFullSyncTester(stack *node.Node, backend *eth.Ethereum, block *types.Block) (*FullSyncTester, error) {
cl := &FullSyncTester{
stack: stack,
backend: backend,
target: target,
closed: make(chan struct{}),
api: newConsensusAPIWithoutHeartbeat(backend),
block: block,
closed: make(chan struct{}),
}
stack.RegisterLifecycle(cl)
return cl, nil
Expand All @@ -60,25 +56,29 @@ func (tester *FullSyncTester) Start() error {
go func() {
defer tester.wg.Done()

// Trigger beacon sync with the provided block hash as trusted
// chain head.
err := tester.backend.Downloader().BeaconDevSync(downloader.FullSync, tester.target, tester.closed)
if err != nil {
log.Info("Failed to trigger beacon sync", "err", err)
}

ticker := time.NewTicker(time.Second * 5)
defer ticker.Stop()

for {
select {
case <-ticker.C:
// Stop in case the target block is already stored locally.
if block := tester.backend.BlockChain().GetBlockByHash(tester.target); block != nil {
log.Info("Full-sync target reached", "number", block.NumberU64(), "hash", block.Hash())
go tester.stack.Close() // async since we need to close ourselves
// Don't bother downloader in case it's already syncing.
if tester.api.eth.Downloader().Synchronising() {
continue
}
// Short circuit in case the target block is already stored
// locally. TODO(somehow terminate the node stack if target
// is reached).
if tester.api.eth.BlockChain().HasBlock(tester.block.Hash(), tester.block.NumberU64()) {
log.Info("Full-sync target reached", "number", tester.block.NumberU64(), "hash", tester.block.Hash())
return
}
// Trigger beacon sync with the provided block header as
// trusted chain head.
err := tester.api.eth.Downloader().BeaconSync(downloader.FullSync, tester.block.Header(), tester.block.Header())
if err != nil {
log.Info("Failed to beacon sync", "err", err)
}

case <-tester.closed:
return
Expand Down
81 changes: 0 additions & 81 deletions eth/downloader/beacondevsync.go

This file was deleted.

10 changes: 10 additions & 0 deletions eth/downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ func (d *Downloader) Progress() ethereum.SyncProgress {
}
}

// Synchronising returns whether the downloader is currently retrieving blocks.
func (d *Downloader) Synchronising() bool {
return d.synchronising.Load()
}

// RegisterPeer injects a new download peer into the set of block source to be
// used for fetching hashes and blocks from.
func (d *Downloader) RegisterPeer(id string, version uint, peer Peer) error {
Expand All @@ -304,6 +309,11 @@ func (d *Downloader) RegisterPeer(id string, version uint, peer Peer) error {
return nil
}

// RegisterLightPeer injects a light client peer, wrapping it so it appears as a regular peer.
func (d *Downloader) RegisterLightPeer(id string, version uint, peer LightPeer) error {
return d.RegisterPeer(id, version, &lightPeerWrapper{peer})
}

// UnregisterPeer remove a peer from the known list, preventing any action from
// the specified peer. An effort is also made to return any pending fetches into
// the queue.
Expand Down
27 changes: 25 additions & 2 deletions eth/downloader/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,39 @@ type peerConnection struct {
lock sync.RWMutex
}

// Peer encapsulates the methods required to synchronise with a remote full peer.
type Peer interface {
// LightPeer encapsulates the methods required to synchronise with a remote light peer.
type LightPeer interface {
Head() (common.Hash, *big.Int)
RequestHeadersByHash(common.Hash, int, int, bool, chan *eth.Response) (*eth.Request, error)
RequestHeadersByNumber(uint64, int, int, bool, chan *eth.Response) (*eth.Request, error)
}

// Peer encapsulates the methods required to synchronise with a remote full peer.
type Peer interface {
LightPeer
RequestBodies([]common.Hash, chan *eth.Response) (*eth.Request, error)
RequestReceipts([]common.Hash, chan *eth.Response) (*eth.Request, error)
}

// lightPeerWrapper wraps a LightPeer struct, stubbing out the Peer-only methods.
type lightPeerWrapper struct {
peer LightPeer
}

func (w *lightPeerWrapper) Head() (common.Hash, *big.Int) { return w.peer.Head() }
func (w *lightPeerWrapper) RequestHeadersByHash(h common.Hash, amount int, skip int, reverse bool, sink chan *eth.Response) (*eth.Request, error) {
return w.peer.RequestHeadersByHash(h, amount, skip, reverse, sink)
}
func (w *lightPeerWrapper) RequestHeadersByNumber(i uint64, amount int, skip int, reverse bool, sink chan *eth.Response) (*eth.Request, error) {
return w.peer.RequestHeadersByNumber(i, amount, skip, reverse, sink)
}
func (w *lightPeerWrapper) RequestBodies([]common.Hash, chan *eth.Response) (*eth.Request, error) {
panic("RequestBodies not supported in light client mode sync")
}
func (w *lightPeerWrapper) RequestReceipts([]common.Hash, chan *eth.Response) (*eth.Request, error) {
panic("RequestReceipts not supported in light client mode sync")
}

// newPeerConnection creates a new downloader peer.
func newPeerConnection(id string, version uint, peer Peer, logger log.Logger) *peerConnection {
return &peerConnection{
Expand Down

0 comments on commit fd1b65c

Please sign in to comment.