Changes to be more according to Waku spec

This commit is contained in:
kdeme 2019-12-19 22:48:51 +01:00
parent ac30d7f589
commit 48c9adbb6a
No known key found for this signature in database
GPG Key ID: 4E8DD21420AF43F5
1 changed files with 41 additions and 4 deletions

View File

@ -19,6 +19,9 @@
## measured in seconds. Spam prevention is based on proof-of-work, where large ## measured in seconds. Spam prevention is based on proof-of-work, where large
## or long-lived messages must spend more work. ## or long-lived messages must spend more work.
## ##
## Implementation should be according to Waku specification defined here:
## https://github.com/vacp2p/specs/blob/master/waku/waku.md
##
## Example usage ## Example usage
## ---------- ## ----------
## First an `EthereumNode` needs to be created, either with all capabilities set ## First an `EthereumNode` needs to be created, either with all capabilities set
@ -70,6 +73,7 @@ const
## send to peers, in ms. ## send to peers, in ms.
pruneInterval* = chronos.milliseconds(1000) ## Interval at which message pruneInterval* = chronos.milliseconds(1000) ## Interval at which message
## queue is pruned, in ms. ## queue is pruned, in ms.
topicInterestMax = 1000
type type
WakuMode* = enum WakuMode* = enum
@ -87,6 +91,8 @@ type
bloom*: Bloom bloom*: Bloom
isLightNode*: bool isLightNode*: bool
maxMsgSize*: uint32 maxMsgSize*: uint32
confirmationsEnabled*: bool
rateLimits*: RateLimits
wakuMode*: WakuMode wakuMode*: WakuMode
topics*: seq[Topic] topics*: seq[Topic]
@ -119,6 +125,13 @@ type
lastEnvelopeHash*: Hash lastEnvelopeHash*: Hash
cursor*: Bytes cursor*: Bytes
RateLimits* = object
# TODO: uint or specifically uint32?
limitIp*: uint
limitPeerId*: uint
limitTopic*: uint
proc allowed*(msg: Message, config: WakuConfig): bool = proc allowed*(msg: Message, config: WakuConfig): bool =
# Check max msg size, already happens in RLPx but there is a specific waku # Check max msg size, already happens in RLPx but there is a specific waku
# max msg size which should always be < RLPx max msg size # max msg size which should always be < RLPx max msg size
@ -155,6 +168,12 @@ proc initProtocolState*(network: WakuNetwork, node: EthereumNode) {.gcsafe.} =
network.config.bloom = fullBloom() network.config.bloom = fullBloom()
network.config.powRequirement = defaultMinPow network.config.powRequirement = defaultMinPow
network.config.isLightNode = false network.config.isLightNode = false
# confirmationsEnabled and rateLimits is not yet used but we add it here and
# in the status message to be compatible with the Status go implementation.
network.config.confirmationsEnabled = false
# TODO: Limits of 0 are ignored I hope, this is not clearly written in spec.
network.config.rateLimits =
RateLimits(limitIp: 0, limitPeerId: 0, limitTopic:0)
network.config.maxMsgSize = defaultMaxMsgSize network.config.maxMsgSize = defaultMaxMsgSize
network.config.wakuMode = None # default no waku mode network.config.wakuMode = None # default no waku mode
network.config.topics = @[] network.config.topics = @[]
@ -175,6 +194,8 @@ p2pProtocol Waku(version = wakuVersion,
cast[uint64](wakuNet.config.powRequirement), cast[uint64](wakuNet.config.powRequirement),
@(wakuNet.config.bloom), @(wakuNet.config.bloom),
wakuNet.config.isLightNode, wakuNet.config.isLightNode,
wakuNet.config.confirmationsEnabled,
wakuNet.config.rateLimits,
wakuNet.config.wakuMode, wakuNet.config.wakuMode,
wakuNet.config.topics, wakuNet.config.topics,
timeout = chronos.milliseconds(500)) timeout = chronos.milliseconds(500))
@ -228,6 +249,8 @@ p2pProtocol Waku(version = wakuVersion,
powConverted: uint64, powConverted: uint64,
bloom: Bytes, bloom: Bytes,
isLightNode: bool, isLightNode: bool,
confirmationsEnabled: bool,
rateLimits: RateLimits,
wakuMode: WakuMode, wakuMode: WakuMode,
topics: seq[Topic]) topics: seq[Topic])
@ -289,9 +312,17 @@ p2pProtocol Waku(version = wakuVersion,
if bloom.len == bloomSize: if bloom.len == bloomSize:
peer.state.bloom.bytesCopy(bloom) peer.state.bloom.bytesCopy(bloom)
proc topicsExchange(peer: Peer, topics: seq[Topic]) = nextID 20
proc rateLimits(peer: Peer, rateLimits: RateLimits) = discard
proc topicInterest(peer: Peer, topics: openarray[Topic]) =
if not peer.state.initialized: if not peer.state.initialized:
warn "Handshake not completed yet, discarding topicsExchange" warn "Handshake not completed yet, discarding topicInterest"
return
if topics.len > topicInterestMax:
error "Too many topics in the topic-interest list"
return return
if peer.state.wakuMode == WakuChan: if peer.state.wakuMode == WakuChan:
@ -522,15 +553,21 @@ proc setBloomFilter*(node: EthereumNode, bloom: Bloom) {.async.} =
# Exceptions from sendMsg will not be raised # Exceptions from sendMsg will not be raised
await allFutures(futures) await allFutures(futures)
proc setTopics*(node: EthereumNode, topics: seq[Topic]) {.async.} = proc setTopics*(node: EthereumNode, topics: seq[Topic]):
Future[bool] {.async.} =
if topics.len > topicInterestMax:
return false
node.protocolState(Waku).config.topics = topics node.protocolState(Waku).config.topics = topics
var futures: seq[Future[void]] = @[] var futures: seq[Future[void]] = @[]
for peer in node.peers(Waku): for peer in node.peers(Waku):
futures.add(peer.topicsExchange(topics)) futures.add(peer.topicInterest(topics))
# Exceptions from sendMsg will not be raised # Exceptions from sendMsg will not be raised
await allFutures(futures) await allFutures(futures)
return true
proc setMaxMessageSize*(node: EthereumNode, size: uint32): bool = proc setMaxMessageSize*(node: EthereumNode, size: uint32): bool =
## Set the maximum allowed message size. ## Set the maximum allowed message size.
## Can not be set higher than ``defaultMaxMsgSize``. ## Can not be set higher than ``defaultMaxMsgSize``.