swarm/pss: new version of pss.forward proposed by Viktor

This commit is contained in:
Vlad 2018-12-09 20:36:40 +04:00
parent f48a3f3e2f
commit af44980e7f

View file

@ -926,49 +926,29 @@ func (p *Pss) trySend(sp *network.Peer, msg *PssMsg) bool {
// successfully forwarded to at least one peer. // successfully forwarded to at least one peer.
func (p *Pss) forward(msg *PssMsg) error { func (p *Pss) forward(msg *PssMsg) error {
metrics.GetOrRegisterCounter("pss.forward", nil).Inc(1) metrics.GetOrRegisterCounter("pss.forward", nil).Inc(1)
sent := 0 // number of successful sends sent := 0 // number of successful sends
var isDstInProxBin bool // is destination address within the neighbourhood depth of the forwarding peer
to := make([]byte, addressLength) to := make([]byte, addressLength)
copy(to[:len(msg.To)], msg.To) copy(to[:len(msg.To)], msg.To)
neighbourhoodDepth := p.Kademlia.NeighbourhoodDepth() neighbourhoodDepth := p.Kademlia.NeighbourhoodDepth()
// luminosity is the opposite of darkness. the more bytes are removed from the address, the higher is darkness, // luminosity is the opposite of darkness. the more bytes are removed from the address, the higher is darkness,
// but the luminosity is less. here luminosity equals the number of bits present in the destination address. // but the luminosity is less. here luminosity equals the number of bits present in the destination address.
luminousRadius := len(msg.To) * 8 luminosityRadius := len(msg.To) * 8
if luminousRadius >= neighbourhoodDepth { pof := pot.DefaultPof(neighbourhoodDepth) // pof function matching up to neighbourhoodDepth bits (pof <= neighbourhoodDepth)
pof := pot.DefaultPof(neighbourhoodDepth) depth, _ := pof(to, p.BaseAddr(), 0)
_, isDstInProxBin = pof(to, p.BaseAddr(), 0) if depth > luminosityRadius {
depth = luminosityRadius
} }
if isDstInProxBin { p.Kademlia.EachConn(to, addressLength*8, func(sp *network.Peer, po int, _ bool) bool {
// forward to all the nearest neighbours of the forwarding node if po < depth && sent > 0 {
p.Kademlia.EachConn(nil, addressLength*8, func(sp *network.Peer, po int, _ bool) bool { return false // stop iterating
isPeerInProxBin := (po >= neighbourhoodDepth) }
if isPeerInProxBin { if p.trySend(sp, msg) {
if p.trySend(sp, msg) { sent++
sent++ }
} return true // continue
} })
mustContinue := isPeerInProxBin
return mustContinue
})
}
if !isDstInProxBin || sent == 0 {
// in case of partial address, msg should be forwarded to all the peers matching the partial
// address, if there are any; otherwise only to one peer, closest to the recipient address.
// in any case, msg must be sent to at least one peer.
p.Kademlia.EachConn(to, addressLength*8, func(sp *network.Peer, po int, _ bool) bool {
isAddrMatch := (po >= luminousRadius)
if isAddrMatch || sent == 0 {
if p.trySend(sp, msg) {
sent++
}
}
mustContinue := (isAddrMatch || sent == 0)
return mustContinue
})
}
// if we failed to send to anyone, re-insert message in the send-queue // if we failed to send to anyone, re-insert message in the send-queue
if sent == 0 { if sent == 0 {