Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to omit peerId and seqno #372

Merged
merged 10 commits into from
Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions libp2p/protocols/pubsub/floodsub.nim
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,19 @@ method rpcHandler*(f: FloodSub,
trace "Dropping already-seen message", msgId, peer
continue

if f.verifySignature and not msg.verify(peer.peerId):
if (msg.signature.len > 0 or f.verifySignature) and not msg.verify():
# always validate if signature is present or required
debug "Dropping message due to failed signature verification", msgId, peer
continue

if msg.seqno.len > 0 and msg.seqno.len != 8:
# if we have seqno should be 8 bytes long
debug "Dropping message due to invalid seqno length", msgId, peer
continue

# g.anonymize needs no evaluation when receiving messages
# as we have a "lax" policy and allow signed messages

if not (await f.validate(msg)):
trace "Dropping message due to failed validation", msgId, peer
continue
Expand Down Expand Up @@ -129,7 +138,11 @@ method publish*(f: FloodSub,

inc f.msgSeqno
let
msg = Message.init(f.peerInfo, data, topic, f.msgSeqno, f.sign)
msg =
if f.anonymize:
Message.init(none(PeerInfo), data, topic, none(uint64), false)
else:
Message.init(some(f.peerInfo), data, topic, some(f.msgSeqno), f.sign)
msgId = f.msgIdProvider(msg)

trace "Created new message",
Expand Down
18 changes: 16 additions & 2 deletions libp2p/protocols/pubsub/gossipsub.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1046,11 +1046,21 @@ method rpcHandler*(g: GossipSub,

g.mcache.put(msgId, msg)

if g.verifySignature and not msg.verify(peer.peerId):
if (msg.signature.len > 0 or g.verifySignature) and not msg.verify():
# always validate if signature is present or required
debug "Dropping message due to failed signature verification", msgId, peer
g.punishPeer(peer, msg)
continue

if msg.seqno.len > 0 and msg.seqno.len != 8:
# if we have seqno should be 8 bytes long
debug "Dropping message due to invalid seqno length", msgId, peer
g.punishPeer(peer, msg)
continue

# g.anonymize needs no evaluation when receiving messages
# as we have a "lax" policy and allow signed messages

if not (await g.validate(msg)):
debug "Dropping message due to failed validation", msgId, peer
g.punishPeer(peer, msg)
Expand Down Expand Up @@ -1197,7 +1207,11 @@ method publish*(g: GossipSub,

inc g.msgSeqno
let
msg = Message.init(g.peerInfo, data, topic, g.msgSeqno, g.sign)
msg =
if g.anonymize:
Message.init(none(PeerInfo), data, topic, none(uint64), false)
else:
Message.init(some(g.peerInfo), data, topic, some(g.msgSeqno), g.sign)
msgId = g.msgIdProvider(msg)

logScope: msgId
Expand Down
17 changes: 15 additions & 2 deletions libp2p/protocols/pubsub/gossipsub10.nim
Original file line number Diff line number Diff line change
Expand Up @@ -451,10 +451,19 @@ method rpcHandler*(g: GossipSub,

g.mcache.put(msgId, msg)

if g.verifySignature and not msg.verify(peer.peerId):
if (msg.signature.len > 0 or g.verifySignature) and not msg.verify():
# always validate if signature is present or required
debug "Dropping message due to failed signature verification", msgId, peer
continue

if msg.seqno.len > 0 and msg.seqno.len != 8:
# if we have seqno should be 8 bytes long
debug "Dropping message due to invalid seqno length", msgId, peer
continue

# g.anonymize needs no evaluation when receiving messages
# as we have a "lax" policy and allow signed messages

if not (await g.validate(msg)):
trace "Dropping message due to failed validation", msgId, peer
continue
Expand Down Expand Up @@ -556,7 +565,11 @@ method publish*(g: GossipSub,

inc g.msgSeqno
let
msg = Message.init(g.peerInfo, data, topic, g.msgSeqno, g.sign)
msg =
if g.anonymize:
Message.init(none(PeerInfo), data, topic, none(uint64), false)
else:
Message.init(some(g.peerInfo), data, topic, some(g.msgSeqno), g.sign)
msgId = g.msgIdProvider(msg)

logScope: msgId
Expand Down
4 changes: 4 additions & 0 deletions libp2p/protocols/pubsub/pubsub.nim
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type
observers: ref seq[PubSubObserver] # ref as in smart_ptr
msgIdProvider*: MsgIdProvider # Turn message into message id (not nil)
msgSeqno*: uint64
anonymize*: bool # if we omit fromPeer and seqno from RPC messages we send

method unsubscribePeer*(p: PubSub, peerId: PeerID) {.base.} =
## handle peer disconnects
Expand Down Expand Up @@ -329,6 +330,7 @@ proc init*[PubParams: object | bool](
P: typedesc[PubSub],
switch: Switch,
triggerSelf: bool = false,
anonymize: bool = false,
verifySignature: bool = true,
sign: bool = true,
msgIdProvider: MsgIdProvider = defaultMsgIdProvider,
Expand All @@ -338,6 +340,7 @@ proc init*[PubParams: object | bool](
P(switch: switch,
peerInfo: switch.peerInfo,
triggerSelf: triggerSelf,
anonymize: anonymize,
verifySignature: verifySignature,
sign: sign,
peers: initTable[PeerID, PubSubPeer](),
Expand All @@ -347,6 +350,7 @@ proc init*[PubParams: object | bool](
P(switch: switch,
peerInfo: switch.peerInfo,
triggerSelf: triggerSelf,
anonymize: anonymize,
verifySignature: verifySignature,
sign: sign,
peers: initTable[PeerID, PubSubPeer](),
Expand Down
32 changes: 19 additions & 13 deletions libp2p/protocols/pubsub/rpc/message.nim
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func defaultMsgIdProvider*(m: Message): string =
proc sign*(msg: Message, privateKey: PrivateKey): CryptoResult[seq[byte]] =
ok((? privateKey.sign(PubSubPrefix & encodeMessage(msg))).getBytes())

proc verify*(m: Message, p: PeerID): bool =
proc verify*(m: Message): bool =
if m.signature.len > 0 and m.key.len > 0:
var msg = m
msg.signature = @[]
Expand All @@ -52,20 +52,26 @@ proc verify*(m: Message, p: PeerID): bool =

proc init*(
T: type Message,
peer: PeerInfo,
peer: Option[PeerInfo],
data: seq[byte],
topic: string,
seqno: uint64,
seqno: Option[uint64],
sign: bool = true): Message {.gcsafe, raises: [CatchableError, Defect].} =
result = Message(
fromPeer: peer.peerId,
data: data,
seqno: @(seqno.toBytesBE), # unefficient, fine for now
topicIDs: @[topic])
var msg = Message(data: data, topicIDs: @[topic])

if sign:
if peer.keyType != KeyType.HasPrivate:
raise (ref CatchableError)(msg: "Cannot sign message without private key")
# order matters, we want to include seqno in the signature
if seqno.isSome:
msg.seqno = @(seqno.get().toBytesBE())

result.signature = sign(result, peer.privateKey).tryGet()
result.key = peer.privateKey.getKey().tryGet().getBytes().tryGet()
if peer.isSome:
let peer = peer.get()
msg.fromPeer = peer.peerId
if sign:
if peer.keyType != KeyType.HasPrivate:
raise (ref CatchableError)(msg: "Cannot sign message without private key")
msg.signature = sign(msg, peer.privateKey).tryGet()
msg.key = peer.privateKey.getKey().tryGet().getBytes().tryGet()
elif sign:
raise (ref CatchableError)(msg: "Cannot sign message without peer info")

msg
9 changes: 5 additions & 4 deletions tests/pubsub/testgossipinternal.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include ../../libp2p/protocols/pubsub/gossipsub

{.used.}

import options
import unittest, bearssl
import stew/byteutils
import ../../libp2p/standard_setup
Expand Down Expand Up @@ -267,7 +268,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("HELLO" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

check gossipSub.fanout[topic].len == 15
Expand Down Expand Up @@ -321,7 +322,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("HELLO" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

let peers = gossipSub.getGossipPeers()
Expand Down Expand Up @@ -369,7 +370,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("HELLO" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

let peers = gossipSub.getGossipPeers()
Expand Down Expand Up @@ -417,7 +418,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("bar" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("bar" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

let peers = gossipSub.getGossipPeers()
Expand Down
9 changes: 5 additions & 4 deletions tests/pubsub/testgossipinternal10.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include ../../libp2p/protocols/pubsub/gossipsub10

{.used.}

import options
import unittest, bearssl
import stew/byteutils
import ../../libp2p/standard_setup
Expand Down Expand Up @@ -244,7 +245,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("HELLO" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

check gossipSub.fanout[topic].len == 15
Expand Down Expand Up @@ -296,7 +297,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("HELLO" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

let peers = gossipSub.getGossipPeers()
Expand Down Expand Up @@ -341,7 +342,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("HELLO" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

let peers = gossipSub.getGossipPeers()
Expand Down Expand Up @@ -386,7 +387,7 @@ suite "GossipSub internal":
let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo
inc seqno
let msg = Message.init(peerInfo, ("bar" & $i).toBytes(), topic, seqno, false)
let msg = Message.init(some(peerInfo), ("bar" & $i).toBytes(), topic, some(seqno), false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

let peers = gossipSub.getGossipPeers()
Expand Down
5 changes: 3 additions & 2 deletions tests/pubsub/testmessage.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import unittest

{.used.}

import options
import ../../libp2p/[peerid, peerinfo,
crypto/crypto,
protocols/pubsub/rpc/message,
Expand All @@ -14,6 +15,6 @@ suite "Message":
var seqno = 11'u64
let
peer = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
msg = Message.init(peer, @[], "topic", seqno, sign = true)
msg = Message.init(some(peer), @[], "topic", some(seqno), sign = true)

check verify(msg, peer.peerId)
check verify(msg)