mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
swarm/pss: Exorcise evil bitwise logic and revert kad consts
This commit is contained in:
parent
3e6d23eb4f
commit
b13b05c297
5 changed files with 89 additions and 70 deletions
|
|
@ -29,16 +29,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/swarm/pot"
|
"github.com/ethereum/go-ethereum/swarm/pot"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
defaultMaxProxDisplay = 16
|
|
||||||
defaultMinProxBinSize = 2
|
|
||||||
defaultMinBinSize = 2
|
|
||||||
defaultMaxBinSize = 4
|
|
||||||
defaultRetryInterval = 4200000000 // 4.2 sec
|
|
||||||
defaultMaxRetries = 42
|
|
||||||
defaultRetryExponent = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Taking the proximity order relative to a fix point x classifies the points in
|
Taking the proximity order relative to a fix point x classifies the points in
|
||||||
|
|
@ -78,13 +68,13 @@ type KadParams struct {
|
||||||
// NewKadParams returns a params struct with default values
|
// NewKadParams returns a params struct with default values
|
||||||
func NewKadParams() *KadParams {
|
func NewKadParams() *KadParams {
|
||||||
return &KadParams{
|
return &KadParams{
|
||||||
MaxProxDisplay: defaultMaxProxDisplay,
|
MaxProxDisplay: 16,
|
||||||
MinProxBinSize: defaultMinProxBinSize,
|
MinProxBinSize: 2,
|
||||||
MinBinSize: defaultMinBinSize,
|
MinBinSize: 2,
|
||||||
MaxBinSize: defaultMaxBinSize,
|
MaxBinSize: 4,
|
||||||
RetryInterval: defaultRetryInterval,
|
RetryInterval: 4200000000, // 4.2 sec
|
||||||
MaxRetries: defaultMaxRetries,
|
MaxRetries: 42,
|
||||||
RetryExponent: defaultRetryExponent,
|
RetryExponent: 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,7 @@ func (pssapi *API) Receive(ctx context.Context, topic Topic, raw bool, prox bool
|
||||||
|
|
||||||
psssub := notifier.CreateSubscription()
|
psssub := notifier.CreateSubscription()
|
||||||
|
|
||||||
hndlr := &handler{
|
hndlr := NewHandler(func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
|
||||||
f: func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
|
|
||||||
apimsg := &APIMsg{
|
apimsg := &APIMsg{
|
||||||
Msg: hexutil.Bytes(msg),
|
Msg: hexutil.Bytes(msg),
|
||||||
Asymmetric: asymmetric,
|
Asymmetric: asymmetric,
|
||||||
|
|
@ -70,13 +69,12 @@ func (pssapi *API) Receive(ctx context.Context, topic Topic, raw bool, prox bool
|
||||||
log.Warn(fmt.Sprintf("notification on pss sub topic rpc (sub %v) msg %v failed!", psssub.ID, msg))
|
log.Warn(fmt.Sprintf("notification on pss sub topic rpc (sub %v) msg %v failed!", psssub.ID, msg))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
})
|
||||||
}
|
|
||||||
if raw {
|
if raw {
|
||||||
hndlr.caps |= handlerCapRaw
|
hndlr.caps.raw = true
|
||||||
}
|
}
|
||||||
if prox {
|
if prox {
|
||||||
hndlr.caps |= handlerCapProx
|
hndlr.caps.prox = true
|
||||||
}
|
}
|
||||||
|
|
||||||
deregf := pssapi.Register(&topic, hndlr)
|
deregf := pssapi.Register(&topic, hndlr)
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ type Pss struct {
|
||||||
handlers map[Topic]map[*handler]bool // topic and version based pss payload handlers. See pss.Handle()
|
handlers map[Topic]map[*handler]bool // topic and version based pss payload handlers. See pss.Handle()
|
||||||
handlersMu sync.RWMutex
|
handlersMu sync.RWMutex
|
||||||
hashPool sync.Pool
|
hashPool sync.Pool
|
||||||
topicHandlerCaps map[Topic]byte // caches capabilities of each topic's handlers (see handlerCap* consts in types.go)
|
topicHandlerCaps map[Topic]*handlerCaps // caches capabilities of each topic's handlers (see handlerCap* consts in types.go)
|
||||||
|
|
||||||
// process
|
// process
|
||||||
quitC chan struct{}
|
quitC chan struct{}
|
||||||
|
|
@ -183,7 +183,8 @@ func NewPss(k *network.Kademlia, params *PssParams) (*Pss, error) {
|
||||||
symKeyDecryptCacheCapacity: params.SymKeyCacheCapacity,
|
symKeyDecryptCacheCapacity: params.SymKeyCacheCapacity,
|
||||||
|
|
||||||
handlers: make(map[Topic]map[*handler]bool),
|
handlers: make(map[Topic]map[*handler]bool),
|
||||||
topicHandlerCaps: make(map[Topic]byte),
|
topicHandlerCaps: make(map[Topic]*handlerCaps),
|
||||||
|
|
||||||
hashPool: sync.Pool{
|
hashPool: sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
return sha3.NewKeccak256()
|
return sha3.NewKeccak256()
|
||||||
|
|
@ -324,20 +325,36 @@ func (p *Pss) Register(topic *Topic, hndlr *handler) func() {
|
||||||
p.handlers[*topic] = handlers
|
p.handlers[*topic] = handlers
|
||||||
log.Debug("registered handler", "caps", hndlr.caps)
|
log.Debug("registered handler", "caps", hndlr.caps)
|
||||||
}
|
}
|
||||||
|
if hndlr.caps == nil {
|
||||||
|
hndlr.caps = &handlerCaps{}
|
||||||
|
}
|
||||||
handlers[hndlr] = true
|
handlers[hndlr] = true
|
||||||
p.topicHandlerCaps[*topic] |= hndlr.caps
|
if _, ok := p.topicHandlerCaps[*topic]; !ok {
|
||||||
|
p.topicHandlerCaps[*topic] = &handlerCaps{}
|
||||||
|
}
|
||||||
|
if !p.topicHandlerCaps[*topic].raw && hndlr.caps.raw {
|
||||||
|
p.topicHandlerCaps[*topic].raw = true
|
||||||
|
}
|
||||||
|
if !p.topicHandlerCaps[*topic].prox && hndlr.caps.prox {
|
||||||
|
p.topicHandlerCaps[*topic].prox = true
|
||||||
|
}
|
||||||
return func() { p.deregister(topic, hndlr) }
|
return func() { p.deregister(topic, hndlr) }
|
||||||
}
|
}
|
||||||
func (p *Pss) deregister(topic *Topic, hndlr *handler) {
|
func (p *Pss) deregister(topic *Topic, hndlr *handler) {
|
||||||
p.handlersMu.Lock()
|
p.handlersMu.Lock()
|
||||||
defer p.handlersMu.Unlock()
|
defer p.handlersMu.Unlock()
|
||||||
handlers := p.handlers[*topic]
|
handlers := p.handlers[*topic]
|
||||||
if len(handlers) == 1 {
|
if len(handlers) > 1 {
|
||||||
delete(p.handlers, *topic)
|
delete(p.handlers, *topic)
|
||||||
// topic caps might have changed now that a handler is gone
|
// topic caps might have changed now that a handler is gone
|
||||||
var caps byte
|
caps := &handlerCaps{}
|
||||||
for h := range handlers {
|
for h := range handlers {
|
||||||
caps |= h.caps
|
if h.caps.raw {
|
||||||
|
caps.raw = true
|
||||||
|
}
|
||||||
|
if h.caps.prox {
|
||||||
|
caps.prox = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.topicHandlerCaps[*topic] = caps
|
p.topicHandlerCaps[*topic] = caps
|
||||||
return
|
return
|
||||||
|
|
@ -379,7 +396,7 @@ func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error {
|
||||||
// raw is simplest handler contingency to check, so check that first
|
// raw is simplest handler contingency to check, so check that first
|
||||||
var isRaw bool
|
var isRaw bool
|
||||||
if pssmsg.isRaw() {
|
if pssmsg.isRaw() {
|
||||||
if p.topicHandlerCaps[psstopic]&handlerCapRaw == 0 {
|
if !p.topicHandlerCaps[psstopic].raw {
|
||||||
log.Debug("No handler for raw message", "topic", psstopic)
|
log.Debug("No handler for raw message", "topic", psstopic)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -390,7 +407,10 @@ func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error {
|
||||||
// - no prox handler on message and partial address matches
|
// - no prox handler on message and partial address matches
|
||||||
// - prox handler on message and we are in prox regardless of partial address match
|
// - prox handler on message and we are in prox regardless of partial address match
|
||||||
// store this result so we don't calculate again on every handler
|
// store this result so we don't calculate again on every handler
|
||||||
isProx := p.topicHandlerCaps[psstopic]&handlerCapProx != 0
|
var isProx bool
|
||||||
|
if _, ok := p.topicHandlerCaps[psstopic]; ok {
|
||||||
|
isProx = p.topicHandlerCaps[psstopic].prox
|
||||||
|
}
|
||||||
isRecipient := p.isSelfPossibleRecipient(pssmsg, isProx)
|
isRecipient := p.isSelfPossibleRecipient(pssmsg, isProx)
|
||||||
if !isRecipient {
|
if !isRecipient {
|
||||||
log.Trace("pss was for someone else :'( ... forwarding", "pss", common.ToHex(p.BaseAddr()), "prox", isProx)
|
log.Trace("pss was for someone else :'( ... forwarding", "pss", common.ToHex(p.BaseAddr()), "prox", isProx)
|
||||||
|
|
@ -457,12 +477,12 @@ func (p *Pss) executeHandlers(topic Topic, payload []byte, from *PssAddress, raw
|
||||||
handlers := p.getHandlers(topic)
|
handlers := p.getHandlers(topic)
|
||||||
peer := p2p.NewPeer(enode.ID{}, fmt.Sprintf("%x", from), []p2p.Cap{})
|
peer := p2p.NewPeer(enode.ID{}, fmt.Sprintf("%x", from), []p2p.Cap{})
|
||||||
for h := range handlers {
|
for h := range handlers {
|
||||||
if h.caps&handlerCapRaw == 0 && raw {
|
if !h.caps.raw && raw {
|
||||||
log.Trace("norawhandler")
|
log.Warn("norawhandler")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if h.caps&handlerCapProx == 0 && prox {
|
if !h.caps.prox && prox {
|
||||||
log.Trace("noproxhandler")
|
log.Warn("noproxhandler")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err := (h.f)(payload, peer, asymmetric, keyid)
|
err := (h.f)(payload, peer, asymmetric, keyid)
|
||||||
|
|
@ -750,7 +770,7 @@ func (p *Pss) SendRaw(address PssAddress, topic Topic, msg []byte) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic]&handlerCapProx != 0 {
|
if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic].prox {
|
||||||
return p.process(pssMsg, true, true)
|
return p.process(pssMsg, true, true)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -858,9 +878,11 @@ func (p *Pss) send(to []byte, topic Topic, msg []byte, asymmetric bool, key []by
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic]&handlerCapProx != 0 {
|
if _, ok := p.topicHandlerCaps[topic]; ok {
|
||||||
|
if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic].prox {
|
||||||
return p.process(pssMsg, true, true)
|
return p.process(pssMsg, true, true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,10 @@ func TestProxShortCircuit(t *testing.T) {
|
||||||
topic := BytesToTopic([]byte{0x2a})
|
topic := BytesToTopic([]byte{0x2a})
|
||||||
hndlrProxDereg := ps.Register(&topic, &handler{
|
hndlrProxDereg := ps.Register(&topic, &handler{
|
||||||
f: rawHandlerFunc,
|
f: rawHandlerFunc,
|
||||||
caps: handlerCapProx | handlerCapRaw,
|
caps: &handlerCaps{
|
||||||
|
raw: true,
|
||||||
|
prox: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
defer hndlrProxDereg()
|
defer hndlrProxDereg()
|
||||||
|
|
||||||
|
|
@ -554,7 +557,10 @@ func TestAddressMatchProx(t *testing.T) {
|
||||||
topic := BytesToTopic([]byte{0x2a})
|
topic := BytesToTopic([]byte{0x2a})
|
||||||
hndlrProxDereg := ps.Register(&topic, &handler{
|
hndlrProxDereg := ps.Register(&topic, &handler{
|
||||||
f: rawHandlerFunc,
|
f: rawHandlerFunc,
|
||||||
caps: handlerCapProx | handlerCapRaw,
|
caps: &handlerCaps{
|
||||||
|
raw: true,
|
||||||
|
prox: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// test the distances
|
// test the distances
|
||||||
|
|
@ -584,7 +590,9 @@ func TestAddressMatchProx(t *testing.T) {
|
||||||
// now add a non prox-capable handler and test
|
// now add a non prox-capable handler and test
|
||||||
ps.Register(&topic, &handler{
|
ps.Register(&topic, &handler{
|
||||||
f: rawHandlerFunc,
|
f: rawHandlerFunc,
|
||||||
caps: handlerCapRaw,
|
caps: &handlerCaps{
|
||||||
|
raw: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
receives = 0
|
receives = 0
|
||||||
prevReceive = 0
|
prevReceive = 0
|
||||||
|
|
@ -983,7 +991,9 @@ func TestRawAllow(t *testing.T) {
|
||||||
// now wrap the same handler function with raw capabilities and register it
|
// now wrap the same handler function with raw capabilities and register it
|
||||||
hndlrRaw := &handler{
|
hndlrRaw := &handler{
|
||||||
f: rawHandlerFunc,
|
f: rawHandlerFunc,
|
||||||
caps: handlerCapRaw,
|
caps: &handlerCaps{
|
||||||
|
raw: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
deregRawHandler := ps.Register(&topic, hndlrRaw)
|
deregRawHandler := ps.Register(&topic, hndlrRaw)
|
||||||
|
|
||||||
|
|
@ -1975,7 +1985,9 @@ func newServices(allowRaw bool) adapters.Services {
|
||||||
}
|
}
|
||||||
ps.Register(&PingTopic, &handler{
|
ps.Register(&PingTopic, &handler{
|
||||||
f: pp.Handle,
|
f: pp.Handle,
|
||||||
caps: handlerCapRaw,
|
caps: &handlerCaps{
|
||||||
|
raw: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
ps.addAPI(rpc.API{
|
ps.addAPI(rpc.API{
|
||||||
Namespace: "psstest",
|
Namespace: "psstest",
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,6 @@ const (
|
||||||
pssControlRaw = 1 << 1
|
pssControlRaw = 1 << 1
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
handlerCapRaw = 1 << 0
|
|
||||||
handlerCapProx = 1 << 1
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
topicHashMutex = sync.Mutex{}
|
topicHashMutex = sync.Mutex{}
|
||||||
topicHashFunc = storage.MakeHashFunc("SHA256")()
|
topicHashFunc = storage.MakeHashFunc("SHA256")()
|
||||||
|
|
@ -167,32 +162,34 @@ func (msg *PssMsg) String() string {
|
||||||
// Implementations of this type are passed to Pss.Register together with a topic,
|
// Implementations of this type are passed to Pss.Register together with a topic,
|
||||||
type HandlerFunc func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error
|
type HandlerFunc func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error
|
||||||
|
|
||||||
|
type handlerCaps struct {
|
||||||
|
raw bool
|
||||||
|
prox bool
|
||||||
|
}
|
||||||
|
|
||||||
// Handler defines code to be executed upon reception of content.
|
// Handler defines code to be executed upon reception of content.
|
||||||
type handler struct {
|
type handler struct {
|
||||||
f HandlerFunc
|
f HandlerFunc
|
||||||
caps byte
|
caps *handlerCaps
|
||||||
//raw bool // if true, will allow raw messages to be handled
|
|
||||||
//prox bool // if true, explicit recipient address will be truncated to minproxsize depth
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHandler returns a new message handler
|
// NewHandler returns a new message handler
|
||||||
func NewHandler(f HandlerFunc) *handler {
|
func NewHandler(f HandlerFunc) *handler {
|
||||||
return &handler{
|
return &handler{
|
||||||
f: f,
|
f: f,
|
||||||
|
caps: &handlerCaps{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRaw is a chainable method that allows raw messages to be handled.
|
// WithRaw is a chainable method that allows raw messages to be handled.
|
||||||
func (h *handler) WithRaw() *handler {
|
func (h *handler) WithRaw() *handler {
|
||||||
//h.raw = true
|
h.caps.raw = true
|
||||||
h.caps |= handlerCapRaw
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithProxBin is a chainable method that allows sending messages with full addresses to neighbourhoods using the kademlia depth as reference
|
// WithProxBin is a chainable method that allows sending messages with full addresses to neighbourhoods using the kademlia depth as reference
|
||||||
func (h *handler) WithProxBin() *handler {
|
func (h *handler) WithProxBin() *handler {
|
||||||
//h.prox = true
|
h.caps.prox = true
|
||||||
h.caps |= handlerCapProx
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue