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 != "" {
|
if cfg.Ethstats.URL != "" {
|
||||||
utils.RegisterEthStatsService(stack, backend, cfg.Ethstats.URL)
|
utils.RegisterEthStatsService(stack, backend, cfg.Ethstats.URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure full-sync tester service if requested
|
// Configure full-sync tester service if requested
|
||||||
if ctx.IsSet(utils.SyncTargetFlag.Name) {
|
if ctx.IsSet(utils.SyncTargetFlag.Name) {
|
||||||
hex := hexutil.MustDecode(ctx.String(utils.SyncTargetFlag.Name))
|
hex := hexutil.MustDecode(ctx.String(utils.SyncTargetFlag.Name))
|
||||||
if len(hex) != common.HashLength {
|
if len(hex) != common.HashLength {
|
||||||
utils.Fatalf("invalid sync target length: have %d, want %d", 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) {
|
if ctx.IsSet(utils.DeveloperFlag.Name) {
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"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/ethconfig"
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||||
|
|
@ -1997,12 +1996,6 @@ func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconf
|
||||||
return filterSystem
|
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.
|
// SetupMetrics configures the metrics system.
|
||||||
func SetupMetrics(cfg *metrics.Config) {
|
func SetupMetrics(cfg *metrics.Config) {
|
||||||
if !cfg.Enabled {
|
if !cfg.Enabled {
|
||||||
|
|
|
||||||
|
|
@ -443,3 +443,8 @@ func (api *DebugAPI) GetTrieFlushInterval() (string, error) {
|
||||||
}
|
}
|
||||||
return api.eth.blockchain.GetTrieFlushInterval().String(), nil
|
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)
|
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
|
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),
|
// 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),
|
discmix: enode.NewFairMix(discmixTimeout),
|
||||||
shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb),
|
shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb),
|
||||||
}
|
}
|
||||||
|
eth.syncOverride = SyncOverride{
|
||||||
|
stack: stack,
|
||||||
|
backend: eth,
|
||||||
|
closed: make(chan struct{}),
|
||||||
|
}
|
||||||
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
|
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
|
||||||
var dbVer = "<nil>"
|
var dbVer = "<nil>"
|
||||||
if bcVersion != nil {
|
if bcVersion != nil {
|
||||||
|
|
@ -576,6 +583,8 @@ func (s *Ethereum) Stop() error {
|
||||||
s.chainDb.Close()
|
s.chainDb.Close()
|
||||||
s.eventMux.Stop()
|
s.eventMux.Stop()
|
||||||
|
|
||||||
|
s.syncOverride.Stop()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -604,3 +613,9 @@ func (s *Ethereum) SyncMode() ethconfig.SyncMode {
|
||||||
// Nope, we're really full syncing
|
// Nope, we're really full syncing
|
||||||
return ethconfig.FullSync
|
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
|
// 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/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package catalyst
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
|
||||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"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
|
// alone without consensus-layer attached. Users must specify a valid block hash
|
||||||
// as the sync target.
|
// as the sync target.
|
||||||
//
|
//
|
||||||
// This tester can be applied to different networks, no matter it's pre-merge or
|
// This tester can be applied to different networks, no matter it's pre-merge or
|
||||||
// post-merge, but only for full-sync.
|
// post-merge, but only for full-sync.
|
||||||
type FullSyncTester struct {
|
type SyncOverride struct {
|
||||||
stack *node.Node
|
stack *node.Node
|
||||||
backend *eth.Ethereum
|
backend *Ethereum
|
||||||
target common.Hash
|
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
wg sync.WaitGroup
|
|
||||||
exitWhenSynced bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterFullSyncTester registers the full-sync tester service into the node
|
// SyncTarget sets the target of the client sync to the given block hash
|
||||||
// stack for launching and stopping the service controlled by node.
|
func (f *SyncOverride) SyncTarget(target common.Hash, exitWhenSynced bool) {
|
||||||
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)
|
|
||||||
go func() {
|
go func() {
|
||||||
defer tester.wg.Done()
|
|
||||||
|
|
||||||
// Trigger beacon sync with the provided block hash as trusted
|
// Trigger beacon sync with the provided block hash as trusted
|
||||||
// chain head.
|
// 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 {
|
if err != nil {
|
||||||
log.Info("Failed to trigger beacon sync", "err", err)
|
log.Info("Failed to trigger beacon sync", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -76,28 +54,25 @@ func (tester *FullSyncTester) Start() error {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
// Stop in case the target block is already stored locally.
|
// 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())
|
log.Info("Full-sync target reached", "number", block.NumberU64(), "hash", block.Hash())
|
||||||
|
if exitWhenSynced {
|
||||||
if tester.exitWhenSynced {
|
log.Info("Terminating node")
|
||||||
go tester.stack.Close() // async since we need to close ourselves
|
f.stack.Close()
|
||||||
log.Info("Terminating the node")
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-tester.closed:
|
case <-f.closed:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the full-sync tester to stop all background activities.
|
// Stop stops the full-sync tester to stop all background activities.
|
||||||
// This function can only be called for one time.
|
// This function can only be called for one time.
|
||||||
func (tester *FullSyncTester) Stop() error {
|
func (f *SyncOverride) Stop() error {
|
||||||
close(tester.closed)
|
close(f.closed)
|
||||||
tester.wg.Wait()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -468,6 +468,11 @@ web3._extend({
|
||||||
call: 'debug_getTrieFlushInterval',
|
call: 'debug_getTrieFlushInterval',
|
||||||
params: 0
|
params: 0
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'syncTarget',
|
||||||
|
call: 'debug_syncTarget',
|
||||||
|
params: 1
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
properties: []
|
properties: []
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue