les: implement ultralight client (#16904)
For more information about this light client mode, read https://hackmd.io/s/HJy7jjZpm
This commit is contained in:
@ -33,6 +33,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"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/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
@ -119,12 +120,29 @@ type ProtocolManager struct {
|
||||
|
||||
// wait group is used for graceful shutdowns during downloading
|
||||
// and processing
|
||||
wg *sync.WaitGroup
|
||||
wg *sync.WaitGroup
|
||||
ulc *ulc
|
||||
}
|
||||
|
||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||
// with the ethereum network.
|
||||
func NewProtocolManager(chainConfig *params.ChainConfig, indexerConfig *light.IndexerConfig, lightSync bool, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, serverPool *serverPool, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) {
|
||||
func NewProtocolManager(
|
||||
chainConfig *params.ChainConfig,
|
||||
indexerConfig *light.IndexerConfig,
|
||||
lightSync bool,
|
||||
networkId uint64,
|
||||
mux *event.TypeMux,
|
||||
engine consensus.Engine,
|
||||
peers *peerSet,
|
||||
blockchain BlockChain,
|
||||
txpool txPool,
|
||||
chainDb ethdb.Database,
|
||||
odr *LesOdr,
|
||||
txrelay *LesTxRelay,
|
||||
serverPool *serverPool,
|
||||
quitSync chan struct{},
|
||||
wg *sync.WaitGroup,
|
||||
ulcConfig *eth.ULCConfig) (*ProtocolManager, error) {
|
||||
// Create the protocol manager with the base fields
|
||||
manager := &ProtocolManager{
|
||||
lightSync: lightSync,
|
||||
@ -149,6 +167,10 @@ func NewProtocolManager(chainConfig *params.ChainConfig, indexerConfig *light.In
|
||||
manager.reqDist = odr.retriever.dist
|
||||
}
|
||||
|
||||
if ulcConfig != nil {
|
||||
manager.ulc = newULC(ulcConfig)
|
||||
}
|
||||
|
||||
removePeer := manager.removePeer
|
||||
if disableClientRemovePeer {
|
||||
removePeer = func(id string) {}
|
||||
@ -234,7 +256,11 @@ func (pm *ProtocolManager) runPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWrit
|
||||
}
|
||||
|
||||
func (pm *ProtocolManager) newPeer(pv int, nv uint64, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
|
||||
return newPeer(pv, nv, p, newMeteredMsgWriter(rw))
|
||||
var isTrusted bool
|
||||
if pm.isULCEnabled() {
|
||||
isTrusted = pm.ulc.isTrusted(p.ID())
|
||||
}
|
||||
return newPeer(pv, nv, isTrusted, p, newMeteredMsgWriter(rw))
|
||||
}
|
||||
|
||||
// handle is the callback invoked to manage the life cycle of a les peer. When
|
||||
@ -276,6 +302,7 @@ func (pm *ProtocolManager) handle(p *peer) error {
|
||||
if rw, ok := p.rw.(*meteredMsgReadWriter); ok {
|
||||
rw.Init(p.version)
|
||||
}
|
||||
|
||||
// Register the peer locally
|
||||
if err := pm.peers.Register(p); err != nil {
|
||||
p.Log().Error("Light Ethereum peer registration failed", "err", err)
|
||||
@ -287,6 +314,7 @@ func (pm *ProtocolManager) handle(p *peer) error {
|
||||
}
|
||||
pm.removePeer(p.id)
|
||||
}()
|
||||
|
||||
// Register the peer in the downloader. If the downloader considers it banned, we disconnect
|
||||
if pm.lightSync {
|
||||
p.lock.Lock()
|
||||
@ -371,16 +399,15 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||
// Block header query, collect the requested headers and reply
|
||||
case AnnounceMsg:
|
||||
p.Log().Trace("Received announce message")
|
||||
if p.requestAnnounceType == announceTypeNone {
|
||||
if p.announceType == announceTypeNone {
|
||||
return errResp(ErrUnexpectedResponse, "")
|
||||
}
|
||||
|
||||
var req announceData
|
||||
if err := msg.Decode(&req); err != nil {
|
||||
return errResp(ErrDecode, "%v: %v", msg, err)
|
||||
}
|
||||
|
||||
if p.requestAnnounceType == announceTypeSigned {
|
||||
if p.announceType == announceTypeSigned {
|
||||
if err := req.checkSignature(p.ID()); err != nil {
|
||||
p.Log().Trace("Invalid announcement signature", "err", err)
|
||||
return err
|
||||
@ -1175,6 +1202,14 @@ func (pm *ProtocolManager) txStatus(hashes []common.Hash) []txStatus {
|
||||
return stats
|
||||
}
|
||||
|
||||
// isULCEnabled returns true if we can use ULC
|
||||
func (pm *ProtocolManager) isULCEnabled() bool {
|
||||
if pm.ulc == nil || len(pm.ulc.trustedKeys) == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// downloaderPeerNotify implements peerSetNotify
|
||||
type downloaderPeerNotify ProtocolManager
|
||||
|
||||
|
Reference in New Issue
Block a user