-
Notifications
You must be signed in to change notification settings - Fork 110
swarm/pss: Allow transmission of raw messages #376
Conversation
} | ||
|
||
func (self *Pss) executeHandlers(topic Topic, payload []byte, from *PssAddress, asymmetric bool, keyid string) { | ||
handlers := self.getHandlers(topic) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this peer created can you remind me?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need the peer passed to the PssProtocol handler.
swarm/pss/pss.go
Outdated
@@ -365,17 +371,25 @@ func (self *Pss) process(pssmsg *PssMsg) bool { | |||
self.outbox <- pssmsg | |||
}() | |||
} | |||
handlers := self.getHandlers(psstopic) | |||
if psstopic == rawTopic { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so lets talk about this. I dont understand why for no encryption there would be a specific topic rather than a bool field on the message or nothing (just the first assumption)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing sounds better. Let's try that. nothing is not possible, because whisper topics are 4 byte fixed arrays. If we detach from whisper (to allow for more bytes in topic) we can do this.
Bool on message, well, yeah;
- That's one more byte pr msg.
- If we later want to use empty topic instead and would want to revert, that will change the pss message structure itself, which means version change in protocol and incompatible nodes, I guess.
Disallowing certain hashes is not so elegant either, I know.
I don't have a strong opinion here, but I would like to avoid changing the message structure in the future.
swarm/pss/pss_test.go
Outdated
@@ -1172,13 +1254,13 @@ func benchmarkSymkeyBruteforceSameaddr(b *testing.B) { | |||
} | |||
|
|||
// setup simulated network and connect nodes in circle | |||
func setupNetwork(numnodes int) (clients []*rpc.Client, err error) { | |||
func setupNetwork(numnodes int, allowRaw bool) (clients []*rpc.Client, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please document setupNetwork
explaining about allowRaw
... something along the lines of
setupNetwork is creating a simulated network with `numnodes` number of nodes. `allowRaw` is ...
swarm/pss/pss.go
Outdated
@@ -71,6 +72,7 @@ type PssParams struct { | |||
CacheTTL time.Duration | |||
privateKey *ecdsa.PrivateKey | |||
SymKeyCacheCapacity int | |||
AllowRaw bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should start to document the params in structs like this one. Please add a comment next to AllowRaw
explaining its purpose and usage.
swarm/pss/pss.go
Outdated
@@ -365,17 +371,25 @@ func (self *Pss) process(pssmsg *PssMsg) bool { | |||
self.outbox <- pssmsg | |||
}() | |||
} | |||
handlers := self.getHandlers(psstopic) | |||
if psstopic == rawTopic { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure I understand this - how is it possible to end up in this if-condition? If we are using rawTopic
for psstopic
wouldn't we always end up in the err != nil
block above?
This if-condition
looks redundant to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the message is encrypted but has topic 0x0
it will hit this check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I don't understand the raw
concept... from the description of this PR - It also introduces a protected topic value 0x0 which, if set, denotes an unencrypted message, and is passed through to the raw message handler in case of failed decryption.
@nolash maybe we do an interactive review, on a call, so that we don't have another 100 comments on this PR - I just want to understand the background a bit better :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I'll move the topic check up. We don't need to waste cycles trying to decrypt the message if it has topic 0x0
swarm/pss/pss.go
Outdated
@@ -365,17 +371,25 @@ func (self *Pss) process(pssmsg *PssMsg) bool { | |||
self.outbox <- pssmsg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is quite error-prone to create a go-routine for adding messages to the outbox channel. We should have some other mechanism to signal to the user if the outbox size is reached, and we should do something about it, not create unlimited number of go-routines that are blocked in memory.
I would just remove this goroutine altogether as a start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using channels for the outbox
is good, but when you have a buffered channel you should address what happens when the limit of the buffer is reached, and address this pressure. AFAIK you cannot have an unlimited buffer, as this basically means unlimited memory and this doesn't exist.
what you are doing now (goroutine which blocks once you reach the size of the outbox), means that you essentially have an unlimited number of goroutines that might block and you have a memory problem. we should not have that, but rather return an error and block if the outbox size is reached.
here is a summary of the questions we should answer when we have a buffered channel - https://www.ardanlabs.com/blog/2017/10/the-behavior-of-channels.html
@nolash you don't have to maintain a counter to keep track whether the buffered channel is full or not. you can do the same with a |
swarm/pss/pss.go
Outdated
}() | ||
if !self.enqueue(pssmsg) { | ||
log.Error("outbox full!") | ||
return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not return error?
swarm/pss/pss.go
Outdated
return true | ||
default: | ||
} | ||
return true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return false
or better errOutboxFull
swarm/pss/pss.go
Outdated
@@ -745,11 +798,14 @@ func (self *Pss) forward(msg *PssMsg) { | |||
if sent == 0 { | |||
log.Debug("unable to forward to any peers") | |||
time.Sleep(time.Millisecond) | |||
self.outbox <- msg | |||
if !self.enqueue(msg) { | |||
return errors.New("outbox full!") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3rd way of calling enqueue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh?
still dont understand |
@zelig did you read my comment on your comment on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
This PR enables sending and receiving of raw messages, bypassing the builtin pss encryption mechanisms.
The intended usage is for applications that prefer to handle encryption themselves.
It also makes it possible to use the pss node as a multiplexing node, in essence handling several clients with different public keys, something that is not currently possible in a pss node since the public key is unique for this node.
It also introduces a protected topic value
0x0
which, if set, denotes an unencrypted message, and is passed to the raw message handler before decryption is attempted.The PR also introduces outbox capacity handling code, which errs on failed attempt of message enqueueing.