mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
all: add debug_syncTarget as an API method
This commit is contained in:
parent
e71487b033
commit
cc7bc75829
6 changed files with 43 additions and 49 deletions
|
|
@ -262,13 +262,14 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
|||
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), ctx.Bool(utils.ExitWhenSyncedFlag.Name))
|
||||
eth.SyncOverride().SyncTarget(common.BytesToHash(hex), ctx.Bool(utils.ExitWhenSyncedFlag.Name))
|
||||
}
|
||||
|
||||
if ctx.IsSet(utils.DeveloperFlag.Name) {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||
|
|
@ -1997,12 +1996,6 @@ func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconf
|
|||
return filterSystem
|
||||
}
|
||||
|
||||
// RegisterFullSyncTester adds the full-sync tester service into node.
|
||||
func RegisterFullSyncTester(stack *node.Node, eth *eth.Ethereum, target common.Hash, exitWhenSynced bool) {
|
||||
catalyst.RegisterFullSyncTester(stack, eth, target, exitWhenSynced)
|
||||
log.Info("Registered full-sync tester", "hash", target, "exitWhenSynced", exitWhenSynced)
|
||||
}
|
||||
|
||||
// SetupMetrics configures the metrics system.
|
||||
func SetupMetrics(cfg *metrics.Config) {
|
||||
if !cfg.Enabled {
|
||||
|
|
|
|||
|
|
@ -443,3 +443,8 @@ func (api *DebugAPI) GetTrieFlushInterval() (string, error) {
|
|||
}
|
||||
return api.eth.blockchain.GetTrieFlushInterval().String(), nil
|
||||
}
|
||||
|
||||
// SetSyncTarget initiates a full-sync to the target block hash
|
||||
func (api *DebugAPI) SyncTarget(target common.Hash) {
|
||||
api.eth.SyncOverride().SyncTarget(target, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ type Ethereum struct {
|
|||
lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
|
||||
|
||||
shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully
|
||||
|
||||
syncOverride SyncOverride // allows the sync target to be overridden
|
||||
}
|
||||
|
||||
// New creates a new Ethereum object (including the initialisation of the common Ethereum object),
|
||||
|
|
@ -202,6 +204,11 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
|||
discmix: enode.NewFairMix(discmixTimeout),
|
||||
shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb),
|
||||
}
|
||||
eth.syncOverride = SyncOverride{
|
||||
stack: stack,
|
||||
backend: eth,
|
||||
closed: make(chan struct{}),
|
||||
}
|
||||
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
|
||||
var dbVer = "<nil>"
|
||||
if bcVersion != nil {
|
||||
|
|
@ -576,6 +583,8 @@ func (s *Ethereum) Stop() error {
|
|||
s.chainDb.Close()
|
||||
s.eventMux.Stop()
|
||||
|
||||
s.syncOverride.Stop()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -604,3 +613,9 @@ func (s *Ethereum) SyncMode() ethconfig.SyncMode {
|
|||
// Nope, we're really full syncing
|
||||
return ethconfig.FullSync
|
||||
}
|
||||
|
||||
// SyncOverride returns a SyncOverride instance which is used to force the node
|
||||
// to sync to a target block hash.
|
||||
func (s *Ethereum) SyncOverride() *SyncOverride {
|
||||
return &s.syncOverride
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,57 +14,35 @@
|
|||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package catalyst
|
||||
package eth
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
)
|
||||
|
||||
// FullSyncTester is an auxiliary service that allows Geth to perform full sync
|
||||
// SyncOverride 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.
|
||||
type FullSyncTester struct {
|
||||
type SyncOverride struct {
|
||||
stack *node.Node
|
||||
backend *eth.Ethereum
|
||||
target common.Hash
|
||||
backend *Ethereum
|
||||
closed chan struct{}
|
||||
wg sync.WaitGroup
|
||||
exitWhenSynced bool
|
||||
}
|
||||
|
||||
// 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, exitWhenSynced bool) (*FullSyncTester, error) {
|
||||
cl := &FullSyncTester{
|
||||
stack: stack,
|
||||
backend: backend,
|
||||
target: target,
|
||||
closed: make(chan struct{}),
|
||||
exitWhenSynced: exitWhenSynced,
|
||||
}
|
||||
stack.RegisterLifecycle(cl)
|
||||
return cl, nil
|
||||
}
|
||||
|
||||
// Start launches the beacon sync with provided sync target.
|
||||
func (tester *FullSyncTester) Start() error {
|
||||
tester.wg.Add(1)
|
||||
// SyncTarget sets the target of the client sync to the given block hash
|
||||
func (f *SyncOverride) SyncTarget(target common.Hash, exitWhenSynced bool) {
|
||||
go func() {
|
||||
defer tester.wg.Done()
|
||||
|
||||
// Trigger beacon sync with the provided block hash as trusted
|
||||
// chain head.
|
||||
err := tester.backend.Downloader().BeaconDevSync(ethconfig.FullSync, tester.target, tester.closed)
|
||||
err := f.backend.Downloader().BeaconDevSync(ethconfig.FullSync, target, f.closed)
|
||||
if err != nil {
|
||||
log.Info("Failed to trigger beacon sync", "err", err)
|
||||
}
|
||||
|
|
@ -76,28 +54,25 @@ func (tester *FullSyncTester) Start() error {
|
|||
select {
|
||||
case <-ticker.C:
|
||||
// Stop in case the target block is already stored locally.
|
||||
if block := tester.backend.BlockChain().GetBlockByHash(tester.target); block != nil {
|
||||
if block := f.backend.BlockChain().GetBlockByHash(target); block != nil {
|
||||
log.Info("Full-sync target reached", "number", block.NumberU64(), "hash", block.Hash())
|
||||
|
||||
if tester.exitWhenSynced {
|
||||
go tester.stack.Close() // async since we need to close ourselves
|
||||
log.Info("Terminating the node")
|
||||
if exitWhenSynced {
|
||||
log.Info("Terminating node")
|
||||
f.stack.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
case <-tester.closed:
|
||||
case <-f.closed:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops the full-sync tester to stop all background activities.
|
||||
// This function can only be called for one time.
|
||||
func (tester *FullSyncTester) Stop() error {
|
||||
close(tester.closed)
|
||||
tester.wg.Wait()
|
||||
func (f *SyncOverride) Stop() error {
|
||||
close(f.closed)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -468,6 +468,11 @@ web3._extend({
|
|||
call: 'debug_getTrieFlushInterval',
|
||||
params: 0
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'syncTarget',
|
||||
call: 'debug_syncTarget',
|
||||
params: 1
|
||||
}),
|
||||
],
|
||||
properties: []
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue