mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
whisper: add light mode check to handshake
This commit is contained in:
parent
7beccb29be
commit
ee39b589b5
4 changed files with 79 additions and 10 deletions
|
|
@ -192,17 +192,17 @@ func (api *PublicWhisperAPI) DeleteSymKey(ctx context.Context, id string) bool {
|
|||
return api.w.DeleteSymKey(id)
|
||||
}
|
||||
|
||||
// MakeLightClient turns the node into light client, which does not forward
|
||||
// MakeLightClient turns the node into pure light client, which does not forward
|
||||
// any incoming messages, and sends only messages originated in this node.
|
||||
func (api *PublicWhisperAPI) MakeLightClient(ctx context.Context) bool {
|
||||
api.w.lightClient = true
|
||||
return api.w.lightClient
|
||||
api.w.SetLightClientMode(true)
|
||||
return true
|
||||
}
|
||||
|
||||
// CancelLightClient cancels light client mode.
|
||||
// CancelLightClient cancels pure light client mode.
|
||||
func (api *PublicWhisperAPI) CancelLightClient(ctx context.Context) bool {
|
||||
api.w.lightClient = false
|
||||
return !api.w.lightClient
|
||||
api.w.SetLightClientMode(false)
|
||||
return true
|
||||
}
|
||||
|
||||
//go:generate gencodec -type NewMessage -field-override newMessageOverride -out gen_newmessage_json.go
|
||||
|
|
|
|||
|
|
@ -79,11 +79,13 @@ func (peer *Peer) stop() {
|
|||
func (peer *Peer) handshake() error {
|
||||
// Send the handshake status message asynchronously
|
||||
errc := make(chan error, 1)
|
||||
isLightNode := peer.host.LightClientMode()
|
||||
go func() {
|
||||
pow := peer.host.MinPow()
|
||||
powConverted := math.Float64bits(pow)
|
||||
bloom := peer.host.BloomFilter()
|
||||
errc <- p2p.SendItems(peer.ws, statusCode, ProtocolVersion, powConverted, bloom)
|
||||
|
||||
errc <- p2p.SendItems(peer.ws, statusCode, ProtocolVersion, powConverted, bloom, isLightNode)
|
||||
}()
|
||||
|
||||
// Fetch the remote status packet and verify protocol match
|
||||
|
|
@ -127,6 +129,11 @@ func (peer *Peer) handshake() error {
|
|||
}
|
||||
}
|
||||
|
||||
b, err := s.Bool()
|
||||
if b && isLightNode {
|
||||
return fmt.Errorf("peer [%x]: useless peer: two pure light node communication", peer.ID())
|
||||
}
|
||||
|
||||
if err := <-errc; err != nil {
|
||||
return fmt.Errorf("peer [%x] failed to send status packet: %v", peer.ID(), err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
var keys = []string{
|
||||
|
|
@ -512,3 +513,47 @@ func waitForServersToStart(t *testing.T) {
|
|||
}
|
||||
t.Fatalf("Failed to start all the servers, running: %d", started)
|
||||
}
|
||||
|
||||
func TestPureLightPeerHandshake(t *testing.T) {
|
||||
w1 := Whisper{}
|
||||
p1 := newPeer(&w1, p2p.NewPeer(discover.NodeID{}, "test", []p2p.Cap{}), &rwStub{[]interface{}{ProtocolVersion, uint64(123), make([]byte, BloomFilterSize), false}})
|
||||
err := p1.handshake()
|
||||
if err != nil {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
func TestPureLightPeerHandshakeWithOldVersion(t *testing.T) {
|
||||
w1 := Whisper{}
|
||||
p1 := newPeer(&w1, p2p.NewPeer(discover.NodeID{}, "test", []p2p.Cap{}), &rwStub{[]interface{}{ProtocolVersion, uint64(123), make([]byte, BloomFilterSize)}})
|
||||
err := p1.handshake()
|
||||
if err != nil {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
func TestPureLightPeerHandshakeError(t *testing.T) {
|
||||
w1 := Whisper{}
|
||||
w1.SetLightClientMode(true)
|
||||
p1 := newPeer(&w1, p2p.NewPeer(discover.NodeID{}, "test", []p2p.Cap{}), &rwStub{[]interface{}{ProtocolVersion, uint64(123), make([]byte, BloomFilterSize), true}})
|
||||
err := p1.handshake()
|
||||
if err == nil {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
type rwStub struct {
|
||||
payload []interface{}
|
||||
}
|
||||
|
||||
func (stub *rwStub) ReadMsg() (p2p.Msg, error) {
|
||||
size, r, err := rlp.EncodeToReader(stub.payload)
|
||||
if err != nil {
|
||||
return p2p.Msg{}, err
|
||||
}
|
||||
return p2p.Msg{Code: statusCode, Size: uint32(size), Payload: r}, nil
|
||||
}
|
||||
|
||||
func (stub *rwStub) WriteMsg(m p2p.Msg) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ const (
|
|||
minPowToleranceIdx // Minimal PoW tolerated by the whisper node for a limited time
|
||||
bloomFilterIdx // Bloom filter for topics of interest for this node
|
||||
bloomFilterToleranceIdx // Bloom filter tolerated by the whisper node for a limited time
|
||||
lightClientModeIdx // Pure light client mode. (does not forward any messages)
|
||||
)
|
||||
|
||||
// Whisper represents a dark communication interface through the Ethereum
|
||||
|
|
@ -82,8 +83,6 @@ type Whisper struct {
|
|||
|
||||
syncAllowance int // maximum time in seconds allowed to process the whisper-related messages
|
||||
|
||||
lightClient bool // indicates is this node is pure light client (does not forward any messages)
|
||||
|
||||
statsMu sync.Mutex // guard stats
|
||||
stats Statistics // Statistics of whisper node
|
||||
|
||||
|
|
@ -276,6 +275,24 @@ func (whisper *Whisper) SetMinimumPowTest(val float64) {
|
|||
whisper.settings.Store(minPowToleranceIdx, val)
|
||||
}
|
||||
|
||||
//SetLightClientMode makes node pure light client (does not forward any messages)
|
||||
func (whisper *Whisper) SetLightClientMode(v bool) {
|
||||
whisper.settings.Store(lightClientModeIdx, v)
|
||||
}
|
||||
|
||||
//LightClientMode indicates is this node is pure light client (does not forward any messages)
|
||||
func (whisper *Whisper) LightClientMode() bool {
|
||||
val, exist := whisper.settings.Load(lightClientModeIdx)
|
||||
if !exist || val == nil {
|
||||
return false
|
||||
}
|
||||
v, ok := val.(bool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (whisper *Whisper) notifyPeersAboutPowRequirementChange(pow float64) {
|
||||
arr := whisper.getPeers()
|
||||
for _, p := range arr {
|
||||
|
|
@ -672,7 +689,7 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
|||
|
||||
trouble := false
|
||||
for _, env := range envelopes {
|
||||
cached, err := whisper.add(env, whisper.lightClient)
|
||||
cached, err := whisper.add(env, whisper.LightClientMode())
|
||||
if err != nil {
|
||||
trouble = true
|
||||
log.Error("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err)
|
||||
|
|
|
|||
Loading…
Reference in a new issue