From 68a24ca1db811ed16acae23117d992ff6a3574a1 Mon Sep 17 00:00:00 2001 From: asyukii Date: Mon, 6 Nov 2023 10:49:13 +0800 Subject: [PATCH] feat: remoteDb only delay syncs for specified peers change logic --- cmd/utils/flags.go | 7 +++++++ core/types/state_expiry.go | 28 +++++++++++++++++----------- eth/downloader/downloader.go | 2 +- eth/fetcher/block_fetcher.go | 2 +- p2p/server.go | 4 ++++ 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index de013fbe5a..9b13e1012a 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1994,6 +1994,13 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if err != nil { Fatalf("%v", err) } + seCfg.AllowedPeerList = make([]string, 0) + for _, seNode := range stack.Config().P2P.StateExpiryAllowedNodes { + seCfg.AllowedPeerList = append(seCfg.AllowedPeerList, seNode.ID().String()) + } + if len(seCfg.AllowedPeerList) == 0 && seCfg.EnableRemoteMode { + log.Warn("State expiry remote mode is enabled but no allowed peers are specified.") + } cfg.StateExpiryCfg = seCfg chaindb.Close() diff --git a/core/types/state_expiry.go b/core/types/state_expiry.go index bb83a31f2c..7ae6870bba 100644 --- a/core/types/state_expiry.go +++ b/core/types/state_expiry.go @@ -23,7 +23,8 @@ type StateExpiryConfig struct { StateEpoch2Block uint64 StateEpochPeriod uint64 EnableLocalRevive bool - EnableRemoteMode bool `rlp:"optional"` // when enable remoteDB mode, it will register specific RPC for partial proof and keep sync behind for safety proof + EnableRemoteMode bool `rlp:"optional"` // when enable remoteDB mode, it will register specific RPC for partial proof and keep sync behind for safety proof + AllowedPeerList []string `rlp:"optional"` // when enable remoteDB mode, it will only delay its sync for the peers in the list } // EnableExpiry when enable remote mode, it just check param @@ -75,7 +76,7 @@ func (s *StateExpiryConfig) CheckCompatible(newCfg *StateExpiryConfig) error { return errors.New("disable state expiry is dangerous after enabled, expired state may pruned") } if s.EnableRemoteMode && !newCfg.EnableRemoteMode { - return errors.New("disable state expiry EnableRemoteMode is dangerous after enabled") + return errors.New("disable state expiry EnableRemoteMode is dangerous after enabled") } if err := s.CheckStateEpochCompatible(newCfg.StateEpoch1Block, newCfg.StateEpoch2Block, newCfg.StateEpochPeriod); err != nil { @@ -115,21 +116,25 @@ func (s *StateExpiryConfig) String() string { if s.Enable && s.EnableRemoteMode { return "State Expiry Enable in RemoteMode, it will not expired any state." } - return fmt.Sprintf("Enable State Expiry, RemoteEndpoint: %v, StateEpoch: [%v|%v|%v], StateScheme: %v, PruneLevel: %v, EnableLocalRevive: %v.", - s.FullStateEndpoint, s.StateEpoch1Block, s.StateEpoch2Block, s.StateEpochPeriod, s.StateScheme, s.PruneLevel, s.EnableLocalRevive) + return fmt.Sprintf("Enable State Expiry, RemoteEndpoint: %v, StateEpoch: [%v|%v|%v], StateScheme: %v, PruneLevel: %v, EnableLocalRevive: %v, AllowedPeerList: %v.", + s.FullStateEndpoint, s.StateEpoch1Block, s.StateEpoch2Block, s.StateEpochPeriod, s.StateScheme, s.PruneLevel, s.EnableLocalRevive, s.AllowedPeerList) } // ShouldKeep1EpochBehind when enable state expiry, keep remoteDB behind the latest only 1 epoch blocks -func (s *StateExpiryConfig) ShouldKeep1EpochBehind(remote uint64, local uint64) (bool, uint64) { - if !s.EnableRemoteMode { - return false, remote - } - if remote <= local { +func (s *StateExpiryConfig) ShouldKeep1EpochBehind(remote uint64, local uint64, peerId string) (bool, uint64) { + + if !s.EnableRemoteMode || remote <= local || remote < s.StateEpoch1Block { return false, remote } - // if in epoch0, just sync - if remote < s.StateEpoch1Block { + allowed := false + for _, allowPeer := range s.AllowedPeerList { + if allowPeer == peerId { + allowed = true + break + } + } + if !allowed { return false, remote } @@ -145,5 +150,6 @@ func (s *StateExpiryConfig) ShouldKeep1EpochBehind(remote uint64, local uint64) if remote-s.StateEpochPeriod <= local { return true, 0 } + return false, remote - s.StateEpochPeriod } diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 0c388dd9c8..f82bc7e346 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -527,7 +527,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd * if d.expiryConfig.EnableRemote() { var keep bool - keep, remoteHeight = d.expiryConfig.ShouldKeep1EpochBehind(remoteHeight, localHeight) + keep, remoteHeight = d.expiryConfig.ShouldKeep1EpochBehind(remoteHeight, localHeight, p.id) log.Debug("EnableRemote wait remote more blocks", "remoteHeight", remoteHeader.Number, "request", remoteHeight, "localHeight", localHeight, "keep", keep, "config", d.expiryConfig) if keep { return errCanceled diff --git a/eth/fetcher/block_fetcher.go b/eth/fetcher/block_fetcher.go index 652fa3c5b5..5d94395f3d 100644 --- a/eth/fetcher/block_fetcher.go +++ b/eth/fetcher/block_fetcher.go @@ -388,7 +388,7 @@ func (f *BlockFetcher) loop() { } if f.expiryConfig.EnableRemote() { - if keep, _ := f.expiryConfig.ShouldKeep1EpochBehind(number, height); keep { + if keep, _ := f.expiryConfig.ShouldKeep1EpochBehind(number, height, op.origin); keep { log.Debug("BlockFetcher EnableRemote wait remote more blocks", "remoteHeight", number, "localHeight", height, "config", f.expiryConfig) break } diff --git a/p2p/server.go b/p2p/server.go index 0c6e0b7ee0..cd076692a4 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -134,6 +134,10 @@ type Config struct { // allowed to connect, even above the peer limit. TrustedNodes []*enode.Node + // StateExpiryAllowedNodes are used to ensure that the state expiry remoteDb + // will only delay its sync for the peers in the list. + StateExpiryAllowedNodes []*enode.Node + // Connectivity can be restricted to certain IP networks. // If this option is set to a non-nil value, only hosts which match one of the // IP networks contained in the list are considered.