Avoid opening an uTP stream when no content was accepted (#1001)

When the returned content key bitlist of an accept message is all
zeroes, neither side should try to set up an uTP stream.
This commit is contained in:
Kim De Mey 2022-03-18 18:29:06 +01:00 committed by GitHub
parent 08aa20a791
commit aff785ab48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 14 deletions

View File

@ -191,16 +191,18 @@ proc handleOffer(p: PortalProtocol, o: OfferMessage, srcId: NodeId): seq[byte] =
# Return empty response when content key validation fails
return @[]
let connectionId = p.stream.addContentOffer(srcId, contentKeys)
let connectionId =
if contentKeysBitList.countOnes() != 0:
p.stream.addContentOffer(srcId, contentKeys)
else:
# When the node does not accept any of the content offered, reply with an
# all zeroes bitlist and connectionId.
# Note: What to do in this scenario is not defined in the Portal spec.
Bytes2([byte 0x00, 0x00])
encodeMessage(
AcceptMessage(connectionId: connectionId, contentKeys: contentKeysBitList))
# TODO: Neighborhood gossip
# After data has been received and validated from an offer, we need to
# get the closest neighbours of that data from our routing table, select a
# random subset and offer the same data to them.
proc messageHandler(protocol: TalkProtocol, request: seq[byte],
srcId: NodeId, srcUdpAddress: Address): seq[byte] =
doAssert(protocol of PortalProtocol)
@ -439,6 +441,16 @@ proc offer*(p: PortalProtocol, dst: Node, contentKeys: ContentKeysList):
if acceptMessageResponse.isOk():
let m = acceptMessageResponse.get()
# Filter contentKeys with bitlist
var requestedContentKeys: seq[ByteList]
for i, b in m.contentKeys:
if b:
requestedContentKeys.add(contentKeys[i])
if requestedContentKeys.len() == 0:
# Don't open an uTP stream if no content was requested
return ok()
let nodeAddress = NodeAddress.init(dst)
if nodeAddress.isNone():
# It should not happen as we are already after succesfull talkreq/talkresp
@ -457,12 +469,6 @@ proc offer*(p: PortalProtocol, dst: Node, contentKeys: ContentKeysList):
clientSocket.close()
return err("Portal uTP socket is not in connected state")
# Filter contentKeys with bitlist
var requestedContentKeys: seq[ByteList]
for i, b in m.contentKeys:
if b:
requestedContentKeys.add(contentKeys[i])
for contentKey in requestedContentKeys:
let contentIdOpt = p.toContentId(contentKey)
if contentIdOpt.isSome():
@ -512,7 +518,7 @@ proc neighborhoodGossip*(p: PortalProtocol, contentKeys: ContentKeysList) {.asyn
# will not propagate well over to nodes with "large" Radius?
let closestNodes = p.routingTable.neighbours(
NodeId(contentId), k = 6, seenOnly = false)
echo closestNodes.len()
for node in closestNodes:
# Not doing anything if this fails
discard await p.offer(node, contentKeys)

View File

@ -107,7 +107,7 @@ iterator blocks*(
transactions: rlp.read(seq[Transaction]),
uncles: rlp.read(seq[BlockHeader]))
let rlpdata = encode(blockBody)
echo rlpdata.toHex()
res.add((contentKey, rlpdata))
# res.add((contentKey, @(rlp.rawData())))
# rlp.skipElem()