eth, les: reject light client connection is server is not synced (#19616)
* eth, les: reject light client connection is server is not synced * eth, les: rename function and variables * les: format
This commit is contained in:
parent
922e757f19
commit
4e0c1a1a6b
@ -480,6 +480,7 @@ func (s *Ethereum) IsListening() bool { return true } // Always
|
|||||||
func (s *Ethereum) EthVersion() int { return int(s.protocolManager.SubProtocols[0].Version) }
|
func (s *Ethereum) EthVersion() int { return int(s.protocolManager.SubProtocols[0].Version) }
|
||||||
func (s *Ethereum) NetVersion() uint64 { return s.networkID }
|
func (s *Ethereum) NetVersion() uint64 { return s.networkID }
|
||||||
func (s *Ethereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader }
|
func (s *Ethereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader }
|
||||||
|
func (s *Ethereum) Synced() bool { return atomic.LoadUint32(&s.protocolManager.acceptTxs) == 1 }
|
||||||
|
|
||||||
// Protocols implements node.Service, returning all the currently configured
|
// Protocols implements node.Service, returning all the currently configured
|
||||||
// network protocols to start.
|
// network protocols to start.
|
||||||
|
@ -158,7 +158,8 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
|
|||||||
leth.serverPool,
|
leth.serverPool,
|
||||||
quitSync,
|
quitSync,
|
||||||
&leth.wg,
|
&leth.wg,
|
||||||
config.ULC); err != nil {
|
config.ULC,
|
||||||
|
nil); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,12 +87,16 @@ type txPool interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ProtocolManager struct {
|
type ProtocolManager struct {
|
||||||
lightSync bool
|
// Configs
|
||||||
|
chainConfig *params.ChainConfig
|
||||||
|
iConfig *light.IndexerConfig
|
||||||
|
|
||||||
|
client bool // The indicator whether the node is light client
|
||||||
|
maxPeers int // The maximum number peers allowed to connect.
|
||||||
|
networkId uint64 // The identity of network.
|
||||||
|
|
||||||
txpool txPool
|
txpool txPool
|
||||||
txrelay *LesTxRelay
|
txrelay *LesTxRelay
|
||||||
networkId uint64
|
|
||||||
chainConfig *params.ChainConfig
|
|
||||||
iConfig *light.IndexerConfig
|
|
||||||
blockchain BlockChain
|
blockchain BlockChain
|
||||||
chainDb ethdb.Database
|
chainDb ethdb.Database
|
||||||
odr *LesOdr
|
odr *LesOdr
|
||||||
@ -102,23 +106,21 @@ type ProtocolManager struct {
|
|||||||
reqDist *requestDistributor
|
reqDist *requestDistributor
|
||||||
retriever *retrieveManager
|
retriever *retrieveManager
|
||||||
servingQueue *servingQueue
|
servingQueue *servingQueue
|
||||||
|
downloader *downloader.Downloader
|
||||||
downloader *downloader.Downloader
|
fetcher *lightFetcher
|
||||||
fetcher *lightFetcher
|
ulc *ulc
|
||||||
peers *peerSet
|
peers *peerSet
|
||||||
maxPeers int
|
|
||||||
|
|
||||||
eventMux *event.TypeMux
|
|
||||||
|
|
||||||
// channels for fetcher, syncer, txsyncLoop
|
// channels for fetcher, syncer, txsyncLoop
|
||||||
newPeerCh chan *peer
|
newPeerCh chan *peer
|
||||||
quitSync chan struct{}
|
quitSync chan struct{}
|
||||||
noMorePeers chan struct{}
|
noMorePeers chan struct{}
|
||||||
|
|
||||||
// wait group is used for graceful shutdowns during downloading
|
wg *sync.WaitGroup
|
||||||
// and processing
|
eventMux *event.TypeMux
|
||||||
wg *sync.WaitGroup
|
|
||||||
ulc *ulc
|
// Callbacks
|
||||||
|
synced func() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
@ -126,7 +128,7 @@ type ProtocolManager struct {
|
|||||||
func NewProtocolManager(
|
func NewProtocolManager(
|
||||||
chainConfig *params.ChainConfig,
|
chainConfig *params.ChainConfig,
|
||||||
indexerConfig *light.IndexerConfig,
|
indexerConfig *light.IndexerConfig,
|
||||||
lightSync bool,
|
client bool,
|
||||||
networkId uint64,
|
networkId uint64,
|
||||||
mux *event.TypeMux,
|
mux *event.TypeMux,
|
||||||
engine consensus.Engine,
|
engine consensus.Engine,
|
||||||
@ -139,10 +141,10 @@ func NewProtocolManager(
|
|||||||
serverPool *serverPool,
|
serverPool *serverPool,
|
||||||
quitSync chan struct{},
|
quitSync chan struct{},
|
||||||
wg *sync.WaitGroup,
|
wg *sync.WaitGroup,
|
||||||
ulcConfig *eth.ULCConfig) (*ProtocolManager, error) {
|
ulcConfig *eth.ULCConfig, synced func() bool) (*ProtocolManager, error) {
|
||||||
// Create the protocol manager with the base fields
|
// Create the protocol manager with the base fields
|
||||||
manager := &ProtocolManager{
|
manager := &ProtocolManager{
|
||||||
lightSync: lightSync,
|
client: client,
|
||||||
eventMux: mux,
|
eventMux: mux,
|
||||||
blockchain: blockchain,
|
blockchain: blockchain,
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
@ -158,6 +160,7 @@ func NewProtocolManager(
|
|||||||
quitSync: quitSync,
|
quitSync: quitSync,
|
||||||
wg: wg,
|
wg: wg,
|
||||||
noMorePeers: make(chan struct{}),
|
noMorePeers: make(chan struct{}),
|
||||||
|
synced: synced,
|
||||||
}
|
}
|
||||||
if odr != nil {
|
if odr != nil {
|
||||||
manager.retriever = odr.retriever
|
manager.retriever = odr.retriever
|
||||||
@ -174,7 +177,7 @@ func NewProtocolManager(
|
|||||||
if disableClientRemovePeer {
|
if disableClientRemovePeer {
|
||||||
removePeer = func(id string) {}
|
removePeer = func(id string) {}
|
||||||
}
|
}
|
||||||
if lightSync {
|
if client {
|
||||||
var checkpoint uint64
|
var checkpoint uint64
|
||||||
if cht, ok := params.TrustedCheckpoints[blockchain.Genesis().Hash()]; ok {
|
if cht, ok := params.TrustedCheckpoints[blockchain.Genesis().Hash()]; ok {
|
||||||
checkpoint = (cht.SectionIndex+1)*params.CHTFrequency - 1
|
checkpoint = (cht.SectionIndex+1)*params.CHTFrequency - 1
|
||||||
@ -193,7 +196,7 @@ func (pm *ProtocolManager) removePeer(id string) {
|
|||||||
|
|
||||||
func (pm *ProtocolManager) Start(maxPeers int) {
|
func (pm *ProtocolManager) Start(maxPeers int) {
|
||||||
pm.maxPeers = maxPeers
|
pm.maxPeers = maxPeers
|
||||||
if pm.lightSync {
|
if pm.client {
|
||||||
go pm.syncer()
|
go pm.syncer()
|
||||||
} else {
|
} else {
|
||||||
go func() {
|
go func() {
|
||||||
@ -268,10 +271,13 @@ func (pm *ProtocolManager) newPeer(pv int, nv uint64, p *p2p.Peer, rw p2p.MsgRea
|
|||||||
func (pm *ProtocolManager) handle(p *peer) error {
|
func (pm *ProtocolManager) handle(p *peer) error {
|
||||||
// Ignore maxPeers if this is a trusted peer
|
// Ignore maxPeers if this is a trusted peer
|
||||||
// In server mode we try to check into the client pool after handshake
|
// In server mode we try to check into the client pool after handshake
|
||||||
if pm.lightSync && pm.peers.Len() >= pm.maxPeers && !p.Peer.Info().Network.Trusted {
|
if pm.client && pm.peers.Len() >= pm.maxPeers && !p.Peer.Info().Network.Trusted {
|
||||||
return p2p.DiscTooManyPeers
|
return p2p.DiscTooManyPeers
|
||||||
}
|
}
|
||||||
|
// Reject light clients if server is not synced.
|
||||||
|
if !pm.client && !pm.synced() {
|
||||||
|
return p2p.DiscRequested
|
||||||
|
}
|
||||||
p.Log().Debug("Light Ethereum peer connected", "name", p.Name())
|
p.Log().Debug("Light Ethereum peer connected", "name", p.Name())
|
||||||
|
|
||||||
// Execute the LES handshake
|
// Execute the LES handshake
|
||||||
@ -304,7 +310,7 @@ func (pm *ProtocolManager) handle(p *peer) error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// Register the peer in the downloader. If the downloader considers it banned, we disconnect
|
// Register the peer in the downloader. If the downloader considers it banned, we disconnect
|
||||||
if pm.lightSync {
|
if pm.client {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
head := p.headInfo
|
head := p.headInfo
|
||||||
p.lock.Unlock()
|
p.lock.Unlock()
|
||||||
|
@ -170,7 +170,7 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
|
|||||||
if lightSync {
|
if lightSync {
|
||||||
indexConfig = light.TestClientIndexerConfig
|
indexConfig = light.TestClientIndexerConfig
|
||||||
}
|
}
|
||||||
pm, err := NewProtocolManager(gspec.Config, indexConfig, lightSync, NetworkId, evmux, engine, peers, chain, pool, db, odr, nil, nil, make(chan struct{}), new(sync.WaitGroup), ulcConfig)
|
pm, err := NewProtocolManager(gspec.Config, indexConfig, lightSync, NetworkId, evmux, engine, peers, chain, pool, db, odr, nil, nil, make(chan struct{}), new(sync.WaitGroup), ulcConfig, func() bool { return true })
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
|
|||||||
nil,
|
nil,
|
||||||
quitSync,
|
quitSync,
|
||||||
new(sync.WaitGroup),
|
new(sync.WaitGroup),
|
||||||
config.ULC)
|
config.ULC, eth.Synced)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -243,6 +243,7 @@ func (s *LesServer) Stop() {
|
|||||||
s.protocolManager.Stop()
|
s.protocolManager.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo(rjl493456442) separate client and server implementation.
|
||||||
func (pm *ProtocolManager) blockLoop() {
|
func (pm *ProtocolManager) blockLoop() {
|
||||||
pm.wg.Add(1)
|
pm.wg.Add(1)
|
||||||
headCh := make(chan core.ChainHeadEvent, 10)
|
headCh := make(chan core.ChainHeadEvent, 10)
|
||||||
|
0
les/transactions.rlp
Executable file
0
les/transactions.rlp
Executable file
25
les/ulc.go
25
les/ulc.go
@ -1,9 +1,24 @@
|
|||||||
|
// Copyright 2019 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// 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 les
|
package les
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -12,24 +27,24 @@ type ulc struct {
|
|||||||
minTrustedFraction int
|
minTrustedFraction int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newULC creates and returns a ultra light client instance.
|
||||||
func newULC(ulcConfig *eth.ULCConfig) *ulc {
|
func newULC(ulcConfig *eth.ULCConfig) *ulc {
|
||||||
if ulcConfig == nil {
|
if ulcConfig == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
m := make(map[string]struct{}, len(ulcConfig.TrustedServers))
|
m := make(map[string]struct{}, len(ulcConfig.TrustedServers))
|
||||||
for _, id := range ulcConfig.TrustedServers {
|
for _, id := range ulcConfig.TrustedServers {
|
||||||
node, err := enode.ParseV4(id)
|
node, err := enode.ParseV4(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("node:", id, " err:", err)
|
log.Debug("Failed to parse trusted server", "id", id, "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
m[node.ID().String()] = struct{}{}
|
m[node.ID().String()] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ulc{m, ulcConfig.MinTrustedFraction}
|
return &ulc{m, ulcConfig.MinTrustedFraction}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isTrusted return an indicator that whether the specified peer is trusted.
|
||||||
func (u *ulc) isTrusted(p enode.ID) bool {
|
func (u *ulc) isTrusted(p enode.ID) bool {
|
||||||
if u.trustedKeys == nil {
|
if u.trustedKeys == nil {
|
||||||
return false
|
return false
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
// Copyright 2019 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// 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 les
|
package les
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
Loading…
Reference in New Issue
Block a user