Fix priority check of topic-interest versus bloom filter

This commit is contained in:
kdeme 2020-02-13 17:48:55 +01:00 committed by zah
parent 1fcac8b30d
commit c679b9d436
2 changed files with 64 additions and 28 deletions

View File

@ -201,16 +201,16 @@ proc allowed*(msg: Message, config: WakuConfig): bool =
warn "Message PoW too low", pow = msg.pow, minPow = config.powRequirement warn "Message PoW too low", pow = msg.pow, minPow = config.powRequirement
return false return false
if not bloomFilterMatch(config.bloom, msg.bloom):
dropped_bloom_filter_mismatch_envelopes.inc()
warn "Message does not match node bloom filter"
return false
if config.topics.isSome(): if config.topics.isSome():
if msg.env.topic notin config.topics.get(): if msg.env.topic notin config.topics.get():
dropped_topic_mismatch_envelopes.inc() dropped_topic_mismatch_envelopes.inc()
warn "Message topic does not match Waku topic list" warn "Message topic does not match Waku topic list"
return false return false
else:
if not bloomFilterMatch(config.bloom, msg.bloom):
dropped_bloom_filter_mismatch_envelopes.inc()
warn "Message does not match node bloom filter"
return false
return true return true
@ -365,8 +365,9 @@ p2pProtocol Waku(version = wakuVersion,
return return
# TODO: We currently do not allow changing topic-interest. # TODO: We currently do not allow changing topic-interest.
# If we want the check here should be removed, however this would be no # We could allow this by also resetting topic-interest on a bloom filter
# consistent (with Status packet) way of changing back to no topic-interest. # exchange. But we don't for now and will instead introduce another packet
# type in the Waku Specification.
if peer.state.topics.isSome(): if peer.state.topics.isSome():
peer.state.topics = some(topics) peer.state.topics = some(topics)
@ -429,14 +430,14 @@ proc processQueue(peer: Peer) =
powReq = wakuPeer.powRequirement powReq = wakuPeer.powRequirement
continue continue
if not bloomFilterMatch(wakuPeer.bloom, message.bloom):
trace "Message does not match peer bloom filter"
continue
if wakuPeer.topics.isSome(): if wakuPeer.topics.isSome():
if message.env.topic notin wakuPeer.topics.get(): if message.env.topic notin wakuPeer.topics.get():
trace "Message does not match topics list" trace "Message does not match topics list"
continue continue
else:
if not bloomFilterMatch(wakuPeer.bloom, message.bloom):
trace "Message does not match peer bloom filter"
continue
trace "Adding envelope" trace "Adding envelope"
envelopes.add(message.env) envelopes.add(message.env)
@ -611,11 +612,14 @@ 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]): proc setTopicInterest*(node: EthereumNode, topics: seq[Topic]):
Future[bool] {.async.} = Future[bool] {.async.} =
if topics.len > topicInterestMax: if topics.len > topicInterestMax:
return false return false
if node.protocolState(Waku).config.topics.isNone():
return false
node.protocolState(Waku).config.topics = some(topics) node.protocolState(Waku).config.topics = some(topics)
var futures: seq[Future[void]] = @[] var futures: seq[Future[void]] = @[]
for peer in node.peers(Waku): for peer in node.peers(Waku):

View File

@ -19,11 +19,12 @@ const
# TODO: Just repeat all the test_shh_connect tests here that are applicable or # TODO: Just repeat all the test_shh_connect tests here that are applicable or
# have some commonly shared test code for both protocols. # have some commonly shared test code for both protocols.
suite "Waku connections": suite "Waku connections":
asyncTest "Test Waku connections": asyncTest "Waku connections":
var n1 = setupTestNode(Waku) var
var n2 = setupTestNode(Waku) n1 = setupTestNode(Waku)
var n3 = setupTestNode(Waku) n2 = setupTestNode(Waku)
var n4 = setupTestNode(Waku) n3 = setupTestNode(Waku)
n4 = setupTestNode(Waku)
var topics: seq[Topic] var topics: seq[Topic]
n1.protocolState(Waku).config.topics = some(topics) n1.protocolState(Waku).config.topics = some(topics)
@ -34,27 +35,30 @@ suite "Waku connections":
n1.startListening() n1.startListening()
n3.startListening() n3.startListening()
let p1 = await n2.rlpxConnect(newNode(initENode(n1.keys.pubKey, n1.address))) let
let p2 = await n2.rlpxConnect(newNode(initENode(n3.keys.pubKey, n3.address))) p1 = await n2.rlpxConnect(newNode(initENode(n1.keys.pubKey, n1.address)))
let p3 = await n4.rlpxConnect(newNode(initENode(n3.keys.pubKey, n3.address))) p2 = await n2.rlpxConnect(newNode(initENode(n3.keys.pubKey, n3.address)))
p3 = await n4.rlpxConnect(newNode(initENode(n3.keys.pubKey, n3.address)))
check: check:
p1.isNil p1.isNil
p2.isNil == false p2.isNil == false
p3.isNil == false p3.isNil == false
asyncTest "Test Waku topic-interest": asyncTest "Waku topic-interest":
var wakuTopicNode = setupTestNode(Waku) var
var wakuNode = setupTestNode(Waku) wakuTopicNode = setupTestNode(Waku)
wakuNode = setupTestNode(Waku)
let topic1 = [byte 0xDA, 0xDA, 0xDA, 0xAA] let
let topic2 = [byte 0xD0, 0xD0, 0xD0, 0x00] topic1 = [byte 0xDA, 0xDA, 0xDA, 0xAA]
let wrongTopic = [byte 0x4B, 0x1D, 0x4B, 0x1D] topic2 = [byte 0xD0, 0xD0, 0xD0, 0x00]
wrongTopic = [byte 0x4B, 0x1D, 0x4B, 0x1D]
wakuTopicNode.protocolState(Waku).config.topics = some(@[topic1, topic2]) wakuTopicNode.protocolState(Waku).config.topics = some(@[topic1, topic2])
wakuNode.startListening() wakuNode.startListening()
await wakuTopicNode.peerPool.connectToNode(newNode(initENode(wakuNode.keys.pubKey, await wakuTopicNode.peerPool.connectToNode(newNode(
wakuNode.address))) initENode(wakuNode.keys.pubKey, wakuNode.address)))
let payload = repeat(byte 0, 10) let payload = repeat(byte 0, 10)
check: check:
@ -66,6 +70,34 @@ suite "Waku connections":
check: check:
wakuTopicNode.protocolState(Waku).queue.items.len == 2 wakuTopicNode.protocolState(Waku).queue.items.len == 2
asyncTest "Waku topic-interest versus bloom filter":
var
wakuTopicNode = setupTestNode(Waku)
wakuNode = setupTestNode(Waku)
let
topic1 = [byte 0xDA, 0xDA, 0xDA, 0xAA]
topic2 = [byte 0xD0, 0xD0, 0xD0, 0x00]
bloomTopic = [byte 0x4B, 0x1D, 0x4B, 0x1D]
# It was checked that the topics don't trigger false positives on the bloom.
wakuTopicNode.protocolState(Waku).config.topics = some(@[topic1, topic2])
wakuTopicNode.protocolState(Waku).config.bloom = toBloom([bloomTopic])
wakuNode.startListening()
await wakuTopicNode.peerPool.connectToNode(newNode(
initENode(wakuNode.keys.pubKey, wakuNode.address)))
let payload = repeat(byte 0, 10)
check:
wakuNode.postMessage(ttl = safeTTL, topic = topic1, payload = payload)
wakuNode.postMessage(ttl = safeTTL, topic = topic2, payload = payload)
wakuNode.postMessage(ttl = safeTTL, topic = bloomTopic, payload = payload)
wakuNode.protocolState(Waku).queue.items.len == 3
await sleepAsync(waitInterval)
check:
wakuTopicNode.protocolState(Waku).queue.items.len == 2
asyncTest "Light node posting": asyncTest "Light node posting":
var ln = setupTestNode(Waku) var ln = setupTestNode(Waku)
ln.setLightNode(true) ln.setLightNode(true)