mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
wshiper: broadcast received hashes to peers
Signed-off-by: Dmitry Shulyak <yashulyak@gmail.com>
This commit is contained in:
parent
b007412db1
commit
f0de0f2230
3 changed files with 70 additions and 11 deletions
|
|
@ -44,6 +44,7 @@ const (
|
||||||
messagesCode = 1 // normal whisper message
|
messagesCode = 1 // normal whisper message
|
||||||
p2pCode = 2 // peer-to-peer message (to be consumed by the peer, but not forwarded any further)
|
p2pCode = 2 // peer-to-peer message (to be consumed by the peer, but not forwarded any further)
|
||||||
p2pRequestCode = 3 // peer-to-peer message, used by Dapp protocol
|
p2pRequestCode = 3 // peer-to-peer message, used by Dapp protocol
|
||||||
|
hashesCode = 4 // code used to populate known hashes of the peer
|
||||||
NumberOfMessageCodes = 64
|
NumberOfMessageCodes = 64
|
||||||
|
|
||||||
paddingMask = byte(3)
|
paddingMask = byte(3)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ type Peer struct {
|
||||||
trusted bool
|
trusted bool
|
||||||
|
|
||||||
known *set.Set // Messages already known by the peer to avoid wasting bandwidth
|
known *set.Set // Messages already known by the peer to avoid wasting bandwidth
|
||||||
|
advertised map[common.Hash]struct{}
|
||||||
|
hashes chan common.Hash
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,6 +48,8 @@ func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer {
|
||||||
ws: rw,
|
ws: rw,
|
||||||
trusted: false,
|
trusted: false,
|
||||||
known: set.New(),
|
known: set.New(),
|
||||||
|
advertised: make(map[common.Hash]struct{}),
|
||||||
|
hashes: make(chan common.Hash, 20),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +104,8 @@ func (p *Peer) update() {
|
||||||
// Start the tickers for the updates
|
// Start the tickers for the updates
|
||||||
expire := time.NewTicker(expirationCycle)
|
expire := time.NewTicker(expirationCycle)
|
||||||
transmit := time.NewTicker(transmissionCycle)
|
transmit := time.NewTicker(transmissionCycle)
|
||||||
|
hashesTransmit := time.NewTicker(100 * time.Millisecond)
|
||||||
|
hashes := make([]common.Hash, 0, 10)
|
||||||
// Loop and transmit until termination is requested
|
// Loop and transmit until termination is requested
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|
@ -113,7 +117,27 @@ func (p *Peer) update() {
|
||||||
log.Trace("broadcast failed", "reason", err, "peer", p.ID())
|
log.Trace("broadcast failed", "reason", err, "peer", p.ID())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case <-hashesTransmit.C:
|
||||||
|
if err := p.broadcastHashes(hashes); err != nil {
|
||||||
|
log.Trace("broadcast of hashes failed", err, "peer", p.ID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hashes = hashes[:0]
|
||||||
|
case hash := <-p.hashes:
|
||||||
|
if _, ok := p.advertised[hash]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if p.known.Has(hash) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hashes = append(hashes, hash)
|
||||||
|
if len(hashes) == cap(hashes) {
|
||||||
|
if err := p.broadcastHashes(hashes); err != nil {
|
||||||
|
log.Trace("broadcast of hashes failed", err, "peer", p.ID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hashes = hashes[:0]
|
||||||
|
}
|
||||||
case <-p.quit:
|
case <-p.quit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -146,6 +170,10 @@ func (peer *Peer) expire() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Peer) addHash(hash common.Hash) {
|
||||||
|
p.hashes <- hash
|
||||||
|
}
|
||||||
|
|
||||||
// broadcast iterates over the collection of envelopes and transmits yet unknown
|
// broadcast iterates over the collection of envelopes and transmits yet unknown
|
||||||
// ones over the network.
|
// ones over the network.
|
||||||
func (p *Peer) broadcast() error {
|
func (p *Peer) broadcast() error {
|
||||||
|
|
@ -168,6 +196,20 @@ func (p *Peer) broadcast() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Peer) broadcastHashes(hashes []common.Hash) error {
|
||||||
|
if len(hashes) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
log.Trace("broadcast", "hashes", hashes)
|
||||||
|
if err := p2p.Send(p.ws, hashesCode, hashes); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, hash := range hashes {
|
||||||
|
p.advertised[hash] = struct{}{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Peer) ID() []byte {
|
func (p *Peer) ID() []byte {
|
||||||
id := p.peer.ID()
|
id := p.peer.ID()
|
||||||
return id[:]
|
return id[:]
|
||||||
|
|
|
||||||
|
|
@ -511,6 +511,15 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
case statusCode:
|
case statusCode:
|
||||||
// this should not happen, but no need to panic; just ignore this message.
|
// this should not happen, but no need to panic; just ignore this message.
|
||||||
log.Warn("unxepected status message received", "peer", p.peer.ID())
|
log.Warn("unxepected status message received", "peer", p.peer.ID())
|
||||||
|
case hashesCode:
|
||||||
|
var hashes []common.Hash
|
||||||
|
err := packet.Decode(&hashes)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("invalid haashes")
|
||||||
|
}
|
||||||
|
for _, hash := range hashes {
|
||||||
|
p.known.Add(hash)
|
||||||
|
}
|
||||||
case messagesCode:
|
case messagesCode:
|
||||||
// decode the contained envelopes
|
// decode the contained envelopes
|
||||||
var envelope Envelope
|
var envelope Envelope
|
||||||
|
|
@ -617,6 +626,13 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wh.poolMu.Unlock()
|
wh.poolMu.Unlock()
|
||||||
|
wh.peerMu.RLock()
|
||||||
|
if !alreadyCached {
|
||||||
|
for p := range wh.peers {
|
||||||
|
p.addHash(hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wh.peerMu.RUnlock()
|
||||||
|
|
||||||
if alreadyCached {
|
if alreadyCached {
|
||||||
log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex())
|
log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex())
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue