From 15a224a4240d8a4f3ab5d669724c2f4ab168d766 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:57:40 +0800 Subject: [PATCH 01/12] Commit progress. --- fluffy/database/content_db_custom_sql_functions.nim | 2 +- fluffy/network/wire/portal_protocol.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fluffy/database/content_db_custom_sql_functions.nim b/fluffy/database/content_db_custom_sql_functions.nim index 21fb2eefd4..406f49c361 100644 --- a/fluffy/database/content_db_custom_sql_functions.nim +++ b/fluffy/database/content_db_custom_sql_functions.nim @@ -13,7 +13,7 @@ func xorDistance(a: openArray[byte], b: openArray[byte]): seq[byte] = doAssert(a.len == b.len) let length = a.len - var distance: seq[byte] = newSeq[byte](length) + var distance: seq[byte] = newSeqUninitialized[byte](length) for i in 0 ..< length: distance[i] = a[i] xor b[i] diff --git a/fluffy/network/wire/portal_protocol.nim b/fluffy/network/wire/portal_protocol.nim index c26f8ced43..d508396323 100644 --- a/fluffy/network/wire/portal_protocol.nim +++ b/fluffy/network/wire/portal_protocol.nim @@ -319,7 +319,7 @@ func inRange( let distance = p.distance(nodeId, contentId) distance <= nodeRadius -proc inRange*(p: PortalProtocol, contentId: ContentId): bool = +template inRange*(p: PortalProtocol, contentId: ContentId): bool = p.inRange(p.localNode.id, p.dataRadius(), contentId) func truncateEnrs( From 29ed761111bd137796e6953681195aaaa8380738 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:16:17 +0800 Subject: [PATCH 02/12] Remove getSszDecoded from ContentDb. --- fluffy/database/content_db.nim | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/fluffy/database/content_db.nim b/fluffy/database/content_db.nim index 7a80e3f5c7..1987cc9350 100644 --- a/fluffy/database/content_db.nim +++ b/fluffy/database/content_db.nim @@ -296,16 +296,6 @@ proc get(kv: KvStoreRef, key: openArray[byte]): Opt[seq[byte]] = return res -proc getSszDecoded(kv: KvStoreRef, key: openArray[byte], T: type auto): Opt[T] = - let res = kv.get(key) - if res.isSome(): - try: - Opt.some(SSZ.decode(res.get(), T)) - except SerializationError: - raiseAssert("Stored data should always be serialized correctly") - else: - Opt.none(T) - ## Private ContentDB calls proc get(db: ContentDB, key: openArray[byte]): Opt[seq[byte]] = @@ -321,9 +311,6 @@ proc del(db: ContentDB, key: openArray[byte]) = # TODO: Do we want to return the bool here too? discard db.kv.del(key).expectDb() -proc getSszDecoded(db: ContentDB, key: openArray[byte], T: type auto): Opt[T] = - db.kv.getSszDecoded(key, T) - ## Public ContentId based ContentDB calls # TODO: Could also decide to use the ContentKey SSZ bytestring, as this is what @@ -347,9 +334,6 @@ proc contains*(db: ContentDB, key: ContentId): bool = proc del*(db: ContentDB, key: ContentId) = db.del(key.toBytesBE()) -proc getSszDecoded*(db: ContentDB, key: ContentId, T: type auto): Opt[T] = - db.getSszDecoded(key.toBytesBE(), T) - ## Pruning related calls proc deleteContentFraction*( From f0cf1fa047b0dd556aa98775233c84be1196d168 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:22:33 +0800 Subject: [PATCH 03/12] Update ContentDb get to use onData callback to reduce copies. --- fluffy/database/content_db.nim | 29 +++++++------------ .../test_history_network.nim | 2 +- .../rpc_tests/test_portal_rpc_client.nim | 2 +- fluffy/tests/test_content_db.nim | 13 +++++---- .../test_portal_wire_protocol.nim | 8 ++--- 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/fluffy/database/content_db.nim b/fluffy/database/content_db.nim index 1987cc9350..c3828807da 100644 --- a/fluffy/database/content_db.nim +++ b/fluffy/database/content_db.nim @@ -285,21 +285,10 @@ proc close*(db: ContentDB) = db.largestDistanceStmt.disposeSafe() discard db.kv.close() -## Private KvStoreRef Calls - -proc get(kv: KvStoreRef, key: openArray[byte]): Opt[seq[byte]] = - var res: Opt[seq[byte]] - proc onData(data: openArray[byte]) = - res = Opt.some(@data) - - discard kv.get(key, onData).expectDb() - - return res - ## Private ContentDB calls -proc get(db: ContentDB, key: openArray[byte]): Opt[seq[byte]] = - db.kv.get(key) +proc get(db: ContentDB, key: openArray[byte], onData: DataProc): bool = + db.kv.get(key, onData).expectDb() proc put(db: ContentDB, key, value: openArray[byte]) = db.kv.put(key, value).expectDb() @@ -321,9 +310,9 @@ proc del(db: ContentDB, key: openArray[byte]) = # checked with the Radius/distance of the node anyhow. So lets see how we end up # using this mostly in the code. -proc get*(db: ContentDB, key: ContentId): Opt[seq[byte]] = +proc get*(db: ContentDB, key: ContentId, onData: DataProc): bool = # TODO: Here it is unfortunate that ContentId is a uint256 instead of Digest256. - db.get(key.toBytesBE()) + db.get(key.toBytesBE(), onData) proc put*(db: ContentDB, key: ContentId, value: openArray[byte]) = db.put(key.toBytesBE(), value) @@ -468,10 +457,14 @@ proc adjustRadius( proc createGetHandler*(db: ContentDB): DbGetHandler = return ( proc(contentKey: ContentKeyByteList, contentId: ContentId): Opt[seq[byte]] = - let content = db.get(contentId).valueOr: - return Opt.none(seq[byte]) + var res = Opt.none(seq[byte]) + + proc onData(data: openArray[byte]) = + res = Opt.some(@data) + + discard db.get(contentId, onData) - ok(content) + ensureMove(res) ) proc createStoreHandler*(db: ContentDB, cfg: RadiusConfig): DbStoreHandler = diff --git a/fluffy/tests/history_network_tests/test_history_network.nim b/fluffy/tests/history_network_tests/test_history_network.nim index d942852372..52aea1c0aa 100644 --- a/fluffy/tests/history_network_tests/test_history_network.nim +++ b/fluffy/tests/history_network_tests/test_history_network.nim @@ -54,7 +54,7 @@ proc stop(hn: HistoryNode) {.async.} = await hn.discoveryProtocol.closeWait() proc containsId(hn: HistoryNode, contentId: ContentId): bool = - return hn.historyNetwork.contentDB.get(contentId).isSome() + return hn.historyNetwork.contentDB.contains(contentId) proc createEmptyHeaders(fromNum: int, toNum: int): seq[Header] = var headers: seq[Header] diff --git a/fluffy/tests/rpc_tests/test_portal_rpc_client.nim b/fluffy/tests/rpc_tests/test_portal_rpc_client.nim index ea4c5187c8..7be6c2257d 100644 --- a/fluffy/tests/rpc_tests/test_portal_rpc_client.nim +++ b/fluffy/tests/rpc_tests/test_portal_rpc_client.nim @@ -57,7 +57,7 @@ proc stop(hn: HistoryNode) {.async.} = await hn.discoveryProtocol.closeWait() proc containsId(hn: HistoryNode, contentId: ContentId): bool = - return hn.historyNetwork.contentDB.get(contentId).isSome() + return hn.historyNetwork.contentDB.contains(contentId) proc store*(hn: HistoryNode, blockHash: Hash32, blockHeader: Header) = let diff --git a/fluffy/tests/test_content_db.nim b/fluffy/tests/test_content_db.nim index d1093c7328..cfee320cbc 100644 --- a/fluffy/tests/test_content_db.nim +++ b/fluffy/tests/test_content_db.nim @@ -24,9 +24,10 @@ suite "Content Database": "", uint32.high, RadiusConfig(kind: Dynamic), testId, inMemory = true ) key = ContentId(UInt256.high()) # Some key + dbGet = db.createGetHandler() block: - let val = db.get(key) + let val = dbGet(ContentKeyByteList.init(@[]), key) check: val.isNone() @@ -34,7 +35,7 @@ suite "Content Database": block: discard db.putAndPrune(key, [byte 0, 1, 2, 3]) - let val = db.get(key) + let val = dbGet(ContentKeyByteList.init(@[]), key) check: val.isSome() @@ -43,7 +44,7 @@ suite "Content Database": block: db.del(key) - let val = db.get(key) + let val = dbGet(ContentKeyByteList.init(@[]), key) check: val.isNone() @@ -137,9 +138,9 @@ suite "Content Database": # With the current settings the 2 furthest elements will be deleted, # i.e key 30 and 40. The furthest non deleted one will have key 20. pr10.distanceOfFurthestElement == thirdFurthest - db.get(furthestElement).isNone() - db.get(secondFurthest).isNone() - db.get(thirdFurthest).isSome() + not db.contains(furthestElement) + not db.contains(secondFurthest) + db.contains(thirdFurthest) test "ContentDB force pruning": const diff --git a/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim b/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim index 11d7b3c72e..42c20725fa 100644 --- a/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim +++ b/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim @@ -364,10 +364,10 @@ procSuite "Portal Wire Protocol Tests": # Index 2 should be still be in database and its distance should be <= # updated radius check: - db.get((distances[0] xor proto1.localNode.id)).isNone() - db.get((distances[1] xor proto1.localNode.id)).isNone() - db.get((distances[2] xor proto1.localNode.id)).isNone() - db.get((distances[3] xor proto1.localNode.id)).isSome() + not db.contains((distances[0] xor proto1.localNode.id)) + not db.contains((distances[1] xor proto1.localNode.id)) + not db.contains((distances[2] xor proto1.localNode.id)) + db.contains((distances[3] xor proto1.localNode.id)) # The radius has been updated and is lower than the maximum start value. proto1.dataRadius() < UInt256.high # Yet higher than or equal to the furthest non deleted element. From 37c795b39101d6467bdefca3dc235b56f2da9525 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:31:24 +0800 Subject: [PATCH 04/12] Use templates for helper procs in ContentDb. --- fluffy/database/content_db.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fluffy/database/content_db.nim b/fluffy/database/content_db.nim index c3828807da..32ef725ff9 100644 --- a/fluffy/database/content_db.nim +++ b/fluffy/database/content_db.nim @@ -287,16 +287,16 @@ proc close*(db: ContentDB) = ## Private ContentDB calls -proc get(db: ContentDB, key: openArray[byte], onData: DataProc): bool = +template get(db: ContentDB, key: openArray[byte], onData: DataProc): bool = db.kv.get(key, onData).expectDb() -proc put(db: ContentDB, key, value: openArray[byte]) = +template put(db: ContentDB, key, value: openArray[byte]) = db.kv.put(key, value).expectDb() -proc contains(db: ContentDB, key: openArray[byte]): bool = +template contains(db: ContentDB, key: openArray[byte]): bool = db.kv.contains(key).expectDb() -proc del(db: ContentDB, key: openArray[byte]) = +template del(db: ContentDB, key: openArray[byte]) = # TODO: Do we want to return the bool here too? discard db.kv.del(key).expectDb() From 39aa06f0ad8954d767cf3c12350ac3a0fb45e0cc Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:02:02 +0800 Subject: [PATCH 05/12] Add contains handler to portal protocol. --- fluffy/database/content_db.nim | 6 + fluffy/network/beacon/beacon_db.nim | 128 ++++++++++-------- fluffy/network/beacon/beacon_network.nim | 1 + fluffy/network/history/history_network.nim | 1 + fluffy/network/state/state_network.nim | 1 + fluffy/network/wire/portal_protocol.nim | 10 +- fluffy/tests/test_content_db.nim | 18 ++- .../test_portal_wire_protocol.nim | 2 + 8 files changed, 102 insertions(+), 65 deletions(-) diff --git a/fluffy/database/content_db.nim b/fluffy/database/content_db.nim index 32ef725ff9..c6f02b5bd7 100644 --- a/fluffy/database/content_db.nim +++ b/fluffy/database/content_db.nim @@ -497,6 +497,12 @@ proc createStoreHandler*(db: ContentDB, cfg: RadiusConfig): DbStoreHandler = db.put(contentId, content) ) +proc createContainsHandler*(db: ContentDB): DbContainsHandler = + return ( + proc(contentKey: ContentKeyByteList, contentId: ContentId): bool = + db.contains(contentId) + ) + proc createRadiusHandler*(db: ContentDB): DbRadiusHandler = return ( proc(): UInt256 {.raises: [], gcsafe.} = diff --git a/fluffy/network/beacon/beacon_db.nim b/fluffy/network/beacon/beacon_db.nim index 6481ed6052..c70c7a1a5a 100644 --- a/fluffy/network/beacon/beacon_db.nim +++ b/fluffy/network/beacon/beacon_db.nim @@ -442,68 +442,72 @@ func keepBootstrapsFrom*(db: BeaconDb, minSlot: Slot) = let res = db.bootstraps.keepFromStmt.exec(minSlot.int64) res.expect("SQL query OK") +proc getHandlerImpl( + db: BeaconDb, contentKey: ContentKeyByteList, contentId: ContentId +): results.Opt[seq[byte]] = + let contentKey = contentKey.decode().valueOr: + # TODO: as this should not fail, maybe it is better to raiseAssert ? + return Opt.none(seq[byte]) + + case contentKey.contentType + of unused: + raiseAssert "Should not be used and fail at decoding" + of lightClientBootstrap: + db.getBootstrap(contentId) + of lightClientUpdate: + let + # TODO: add validation that startPeriod is not from the future, + # this requires db to be aware off the current beacon time + startPeriod = contentKey.lightClientUpdateKey.startPeriod + # get max 128 updates + numOfUpdates = min( + uint64(MAX_REQUEST_LIGHT_CLIENT_UPDATES), contentKey.lightClientUpdateKey.count + ) + toPeriod = startPeriod + numOfUpdates # Not inclusive + updates = db.getLightClientUpdates(startPeriod, toPeriod) + + if len(updates) == 0: + Opt.none(seq[byte]) + else: + # Note that this might not return all of the requested updates. + # This might seem faulty/tricky as it is also used in handleOffer to + # check if an offer should be accepted. + # But it is actually fine as this will occur only when the node is + # synced and it would not be able to verify the older updates in the + # range anyhow. + Opt.some(SSZ.encode(updates)) + of lightClientFinalityUpdate: + # TODO: + # Return only when the update is better than what is requested by + # contentKey. This is currently not possible as the contentKey does not + # include best update information. + if db.finalityUpdateCache.isSome(): + let slot = contentKey.lightClientFinalityUpdateKey.finalizedSlot + let cache = db.finalityUpdateCache.get() + if cache.lastFinalityUpdateSlot >= slot: + Opt.some(cache.lastFinalityUpdate) + else: + Opt.none(seq[byte]) + else: + Opt.none(seq[byte]) + of lightClientOptimisticUpdate: + # TODO same as above applies here too. + if db.optimisticUpdateCache.isSome(): + let slot = contentKey.lightClientOptimisticUpdateKey.optimisticSlot + let cache = db.optimisticUpdateCache.get() + if cache.lastOptimisticUpdateSlot >= slot: + Opt.some(cache.lastOptimisticUpdate) + else: + Opt.none(seq[byte]) + else: + Opt.none(seq[byte]) + of beacon_content.ContentType.historicalSummaries: + db.get(contentId) + proc createGetHandler*(db: BeaconDb): DbGetHandler = return ( proc(contentKey: ContentKeyByteList, contentId: ContentId): results.Opt[seq[byte]] = - let contentKey = contentKey.decode().valueOr: - # TODO: as this should not fail, maybe it is better to raiseAssert ? - return Opt.none(seq[byte]) - - case contentKey.contentType - of unused: - raiseAssert "Should not be used and fail at decoding" - of lightClientBootstrap: - db.getBootstrap(contentId) - of lightClientUpdate: - let - # TODO: add validation that startPeriod is not from the future, - # this requires db to be aware off the current beacon time - startPeriod = contentKey.lightClientUpdateKey.startPeriod - # get max 128 updates - numOfUpdates = min( - uint64(MAX_REQUEST_LIGHT_CLIENT_UPDATES), - contentKey.lightClientUpdateKey.count, - ) - toPeriod = startPeriod + numOfUpdates # Not inclusive - updates = db.getLightClientUpdates(startPeriod, toPeriod) - - if len(updates) == 0: - Opt.none(seq[byte]) - else: - # Note that this might not return all of the requested updates. - # This might seem faulty/tricky as it is also used in handleOffer to - # check if an offer should be accepted. - # But it is actually fine as this will occur only when the node is - # synced and it would not be able to verify the older updates in the - # range anyhow. - Opt.some(SSZ.encode(updates)) - of lightClientFinalityUpdate: - # TODO: - # Return only when the update is better than what is requested by - # contentKey. This is currently not possible as the contentKey does not - # include best update information. - if db.finalityUpdateCache.isSome(): - let slot = contentKey.lightClientFinalityUpdateKey.finalizedSlot - let cache = db.finalityUpdateCache.get() - if cache.lastFinalityUpdateSlot >= slot: - Opt.some(cache.lastFinalityUpdate) - else: - Opt.none(seq[byte]) - else: - Opt.none(seq[byte]) - of lightClientOptimisticUpdate: - # TODO same as above applies here too. - if db.optimisticUpdateCache.isSome(): - let slot = contentKey.lightClientOptimisticUpdateKey.optimisticSlot - let cache = db.optimisticUpdateCache.get() - if cache.lastOptimisticUpdateSlot >= slot: - Opt.some(cache.lastOptimisticUpdate) - else: - Opt.none(seq[byte]) - else: - Opt.none(seq[byte]) - of beacon_content.ContentType.historicalSummaries: - db.get(contentId) + db.getHandlerImpl(contentKey, contentId) ) proc createStoreHandler*(db: BeaconDb): DbStoreHandler = @@ -573,6 +577,12 @@ proc createStoreHandler*(db: BeaconDb): DbStoreHandler = db.put(contentId, content) ) +proc createContainsHandler*(db: BeaconDb): DbContainsHandler = + return ( + proc(contentKey: ContentKeyByteList, contentId: ContentId): bool = + db.getHandlerImpl(contentKey, contentId).isSome() + ) + proc createRadiusHandler*(db: BeaconDb): DbRadiusHandler = return ( proc(): UInt256 {.raises: [], gcsafe.} = diff --git a/fluffy/network/beacon/beacon_network.nim b/fluffy/network/beacon/beacon_network.nim index 3806fd4f99..7ad438648b 100644 --- a/fluffy/network/beacon/beacon_network.nim +++ b/fluffy/network/beacon/beacon_network.nim @@ -208,6 +208,7 @@ proc new*( toContentIdHandler, createGetHandler(beaconDb), createStoreHandler(beaconDb), + createContainsHandler(beaconDb), createRadiusHandler(beaconDb), stream, bootstrapRecords, diff --git a/fluffy/network/history/history_network.nim b/fluffy/network/history/history_network.nim index 0a9d59114d..e01147f73f 100644 --- a/fluffy/network/history/history_network.nim +++ b/fluffy/network/history/history_network.nim @@ -677,6 +677,7 @@ proc new*( toContentIdHandler, createGetHandler(contentDB), createStoreHandler(contentDB, portalConfig.radiusConfig), + createContainsHandler(contentDB), createRadiusHandler(contentDB), stream, bootstrapRecords, diff --git a/fluffy/network/state/state_network.nim b/fluffy/network/state/state_network.nim index 5ed2fac9d8..37afa9f48c 100644 --- a/fluffy/network/state/state_network.nim +++ b/fluffy/network/state/state_network.nim @@ -64,6 +64,7 @@ proc new*( toContentIdHandler, createGetHandler(contentDB), createStoreHandler(contentDB, portalConfig.radiusConfig), + createContainsHandler(contentDB), createRadiusHandler(contentDB), s, bootstrapRecords, diff --git a/fluffy/network/wire/portal_protocol.nim b/fluffy/network/wire/portal_protocol.nim index d508396323..5cfb4acb62 100644 --- a/fluffy/network/wire/portal_protocol.nim +++ b/fluffy/network/wire/portal_protocol.nim @@ -151,6 +151,10 @@ type contentKey: ContentKeyByteList, contentId: ContentId, content: seq[byte] ) {.raises: [], gcsafe.} + DbContainsHandler* = proc(contentKey: ContentKeyByteList, contentId: ContentId): bool {. + raises: [], gcsafe + .} + DbRadiusHandler* = proc(): UInt256 {.raises: [], gcsafe.} PortalProtocolId* = array[2, byte] @@ -183,6 +187,7 @@ type contentCache: ContentCache dbGet*: DbGetHandler dbPut*: DbStoreHandler + dbContains*: DbContainsHandler dataRadius*: DbRadiusHandler bootstrapRecords*: seq[Record] lastLookup: chronos.Moment @@ -474,7 +479,7 @@ proc handleOffer(p: PortalProtocol, o: OfferMessage, srcId: NodeId): seq[byte] = ) if p.inRange(contentId): - if p.dbGet(contentKey, contentId).isErr: + if not p.dbContains(contentKey, contentId): contentKeysBitList.setBit(i) discard contentKeys.add(contentKey) else: @@ -561,6 +566,7 @@ proc new*( toContentId: ToContentIdHandler, dbGet: DbGetHandler, dbPut: DbStoreHandler, + dbContains: DbContainsHandler, dbRadius: DbRadiusHandler, stream: PortalStream, bootstrapRecords: openArray[Record] = [], @@ -580,6 +586,7 @@ proc new*( ContentCache.init(if config.disableContentCache: 0 else: config.contentCacheSize), dbGet: dbGet, dbPut: dbPut, + dbContains: dbContains, dataRadius: dbRadius, bootstrapRecords: @bootstrapRecords, stream: stream, @@ -1627,7 +1634,6 @@ proc getLocalContent*( # Check first if content is in range, as this is a cheaper operation # than the database lookup. if p.inRange(contentId): - doAssert(p.dbGet != nil) p.dbGet(contentKey, contentId) else: Opt.none(seq[byte]) diff --git a/fluffy/tests/test_content_db.nim b/fluffy/tests/test_content_db.nim index cfee320cbc..fac0ac0075 100644 --- a/fluffy/tests/test_content_db.nim +++ b/fluffy/tests/test_content_db.nim @@ -24,29 +24,39 @@ suite "Content Database": "", uint32.high, RadiusConfig(kind: Dynamic), testId, inMemory = true ) key = ContentId(UInt256.high()) # Some key - dbGet = db.createGetHandler() block: - let val = dbGet(ContentKeyByteList.init(@[]), key) + var val = Opt.none(seq[byte]) + proc onData(data: openArray[byte]) = + val = Opt.some(@data) check: + db.get(key, onData) == false val.isNone() db.contains(key) == false block: discard db.putAndPrune(key, [byte 0, 1, 2, 3]) - let val = dbGet(ContentKeyByteList.init(@[]), key) + + var val = Opt.none(seq[byte]) + proc onData(data: openArray[byte]) = + val = Opt.some(@data) check: + db.get(key, onData) == true val.isSome() val.get() == [byte 0, 1, 2, 3] db.contains(key) == true block: db.del(key) - let val = dbGet(ContentKeyByteList.init(@[]), key) + + var val = Opt.none(seq[byte]) + proc onData(data: openArray[byte]) = + val = Opt.some(@data) check: + db.get(key, onData) == false val.isNone() db.contains(key) == false diff --git a/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim b/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim index 42c20725fa..a18aeecf96 100644 --- a/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim +++ b/fluffy/tests/wire_protocol_tests/test_portal_wire_protocol.nim @@ -50,6 +50,7 @@ proc initPortalProtocol( toContentId, createGetHandler(db), createStoreHandler(db, defaultRadiusConfig), + createContainsHandler(db), createRadiusHandler(db), stream, bootstrapRecords = bootstrapRecords, @@ -346,6 +347,7 @@ procSuite "Portal Wire Protocol Tests": toContentId, createGetHandler(db), createStoreHandler(db, defaultRadiusConfig), + createContainsHandler(db), createRadiusHandler(db), stream, ) From 3a93b24a3ed48d11801c8dca645348ac937a7af7 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:28:52 +0800 Subject: [PATCH 06/12] Update test. --- fluffy/tests/state_network_tests/state_test_helpers.nim | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fluffy/tests/state_network_tests/state_test_helpers.nim b/fluffy/tests/state_network_tests/state_test_helpers.nim index acca9181f1..90260e293d 100644 --- a/fluffy/tests/state_network_tests/state_test_helpers.nim +++ b/fluffy/tests/state_network_tests/state_test_helpers.nim @@ -142,11 +142,10 @@ proc stop*(sn: StateNode) {.async.} = await sn.discoveryProtocol.closeWait() proc containsId*(sn: StateNode, contentId: ContentId): bool {.inline.} = - return sn.stateNetwork.portalProtocol - # The contentKey parameter isn't used but is required for compatibility - # with the dbGet handler inside getLocalContent. - .getLocalContent(ContentKeyByteList.init(@[]), contentId) - .isSome() + # The contentKey parameter isn't used but is required for compatibility with + # the dbContains handler + return + sn.stateNetwork.portalProtocol.dbContains(ContentKeyByteList.init(@[]), contentId) proc mockStateRootLookup*( sn: StateNode, blockNumOrHash: uint64 | Hash32, stateRoot: Hash32 From 29002618a6a9f05f13197f2fcf3ae3e401052a73 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:20:11 +0800 Subject: [PATCH 07/12] Update fluffy-tools. --- fluffy/tools/fcli_db.nim | 6 +++++- fluffy/tools/portalcli.nim | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fluffy/tools/fcli_db.nim b/fluffy/tools/fcli_db.nim index 70a2318597..93c99f6a83 100644 --- a/fluffy/tools/fcli_db.nim +++ b/fluffy/tools/fcli_db.nim @@ -108,7 +108,11 @@ proc cmdBench(conf: DbConf) = for key in keys: withTimer(timers[tDbGet]): - let _ = db.get(key) + var val = Opt.none(seq[byte]) + proc onData(data: openArray[byte]) = + val = Opt.some(@data) + + let _ = db.get(key, onData) for key in keys: withTimer(timers[tDbContains]): diff --git a/fluffy/tools/portalcli.nim b/fluffy/tools/portalcli.nim index 690d7fec76..097944f21e 100644 --- a/fluffy/tools/portalcli.nim +++ b/fluffy/tools/portalcli.nim @@ -255,6 +255,7 @@ proc run(config: PortalCliConf) = testContentIdHandler, createGetHandler(db), createStoreHandler(db, defaultRadiusConfig), + createContainsHandler(db), createRadiusHandler(db), stream, bootstrapRecords = bootstrapRecords, From 09a9951a13ed85cd23c200fb5d192c3a39572ccc Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:13:56 +0800 Subject: [PATCH 08/12] Improve performance of DbGetHandler. --- fluffy/database/content_db.nim | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fluffy/database/content_db.nim b/fluffy/database/content_db.nim index c6f02b5bd7..fd9b0bd5e3 100644 --- a/fluffy/database/content_db.nim +++ b/fluffy/database/content_db.nim @@ -457,14 +457,15 @@ proc adjustRadius( proc createGetHandler*(db: ContentDB): DbGetHandler = return ( proc(contentKey: ContentKeyByteList, contentId: ContentId): Opt[seq[byte]] = - var res = Opt.none(seq[byte]) + var res: seq[byte] proc onData(data: openArray[byte]) = - res = Opt.some(@data) + res = @data - discard db.get(contentId, onData) - - ensureMove(res) + if db.get(contentId, onData): + Opt.some(res) + else: + Opt.none(seq[byte]) ) proc createStoreHandler*(db: ContentDB, cfg: RadiusConfig): DbStoreHandler = From 64045655a8248d5c6971736955ff5f8dfe80ec52 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Mon, 4 Nov 2024 20:38:31 +0800 Subject: [PATCH 09/12] Implement offer cache. --- fluffy/conf.nim | 20 ++- fluffy/fluffy.nim | 2 +- fluffy/network/beacon/beacon_network.nim | 4 +- fluffy/network/history/history_network.nim | 4 +- fluffy/network/state/state_network.nim | 5 +- fluffy/network/wire/portal_protocol.nim | 144 +++++++++++------- .../network/wire/portal_protocol_config.nim | 10 ++ 7 files changed, 125 insertions(+), 64 deletions(-) diff --git a/fluffy/conf.nim b/fluffy/conf.nim index 2e3bf6a57e..f9c84e79d9 100644 --- a/fluffy/conf.nim +++ b/fluffy/conf.nim @@ -316,14 +316,30 @@ type "Size of the in memory local content cache. This is the max number " & "of content values that can be stored in the cache.", defaultValue: defaultPortalProtocolConfig.contentCacheSize, - name: "content-cache-size" + name: "debug-content-cache-size" .}: int disableContentCache* {. hidden, desc: "Disable the in memory local content cache", defaultValue: defaultPortalProtocolConfig.disableContentCache, - name: "disable-content-cache" + name: "debug-disable-content-cache" + .}: bool + + offerCacheSize* {. + hidden, + desc: + "Size of the in memory local offer cache. This is the max number " & + "of content values that can be stored in the cache.", + defaultValue: defaultPortalProtocolConfig.offerCacheSize, + name: "debug-offer-cache-size" + .}: int + + disableOfferCache* {. + hidden, + desc: "Disable the in memory local offer cache", + defaultValue: defaultPortalProtocolConfig.disableOfferCache, + name: "debug-disable-offer-cache" .}: bool disablePoke* {. diff --git a/fluffy/fluffy.nim b/fluffy/fluffy.nim index 1558bc3ae5..546d1cdb93 100644 --- a/fluffy/fluffy.nim +++ b/fluffy/fluffy.nim @@ -183,7 +183,7 @@ proc run( portalProtocolConfig = PortalProtocolConfig.init( config.tableIpLimit, config.bucketIpLimit, config.bitsPerHop, config.radiusConfig, config.disablePoke, config.maxGossipNodes, config.contentCacheSize, - config.disableContentCache, + config.disableContentCache, config.offerCacheSize, config.disableOfferCache, ) portalNodeConfig = PortalNodeConfig( diff --git a/fluffy/network/beacon/beacon_network.nim b/fluffy/network/beacon/beacon_network.nim index 7ad438648b..6dec14d1c8 100644 --- a/fluffy/network/beacon/beacon_network.nim +++ b/fluffy/network/beacon/beacon_network.nim @@ -354,7 +354,9 @@ proc validateContent( return false let contentId = contentIdOpt.get() - n.portalProtocol.storeContent(contentKey, contentId, contentItem) + n.portalProtocol.storeContent( + contentKey, contentId, contentItem, cacheOffer = true + ) debug "Received offered content validated successfully", contentKey else: diff --git a/fluffy/network/history/history_network.nim b/fluffy/network/history/history_network.nim index e01147f73f..cc78a1c351 100644 --- a/fluffy/network/history/history_network.nim +++ b/fluffy/network/history/history_network.nim @@ -704,7 +704,9 @@ proc validateContent( error "Received offered content with invalid content key", contentKey return false - n.portalProtocol.storeContent(contentKey, contentId, contentItem) + n.portalProtocol.storeContent( + contentKey, contentId, contentItem, cacheOffer = true + ) debug "Received offered content validated successfully", contentKey else: diff --git a/fluffy/network/state/state_network.nim b/fluffy/network/state/state_network.nim index 37afa9f48c..a0898fe18d 100644 --- a/fluffy/network/state/state_network.nim +++ b/fluffy/network/state/state_network.nim @@ -182,7 +182,10 @@ proc processOffer*( return err("Received offered content with invalid content key") n.portalProtocol.storeContent( - contentKeyBytes, contentId, contentValue.toRetrievalValue().encode() + contentKeyBytes, + contentId, + contentValue.toRetrievalValue().encode(), + cacheOffer = true, ) await gossipOffer( diff --git a/fluffy/network/wire/portal_protocol.nim b/fluffy/network/wire/portal_protocol.nim index 5cfb4acb62..3f29bd0fce 100644 --- a/fluffy/network/wire/portal_protocol.nim +++ b/fluffy/network/wire/portal_protocol.nim @@ -75,10 +75,16 @@ declareCounter portal_gossip_without_lookup, "Portal wire protocol neighborhood gossip that did not require a node lookup", labels = ["protocol_id"] declareCounter portal_content_cache_hits, - "Portal wire protocol local content lookups that hit the cache", + "Portal wire protocol local content lookups that hit the content cache", labels = ["protocol_id"] declareCounter portal_content_cache_misses, - "Portal wire protocol local content lookups that don't hit the cache", + "Portal wire protocol local content lookups that don't hit the content cache", + labels = ["protocol_id"] +declareCounter portal_offer_cache_hits, + "Portal wire protocol local content lookups that hit the offer cache", + labels = ["protocol_id"] +declareCounter portal_offer_cache_misses, + "Portal wire protocol local content lookups that don't hit the offer cache", labels = ["protocol_id"] declareCounter portal_poke_offers, @@ -161,8 +167,16 @@ type RadiusCache* = LRUCache[NodeId, UInt256] + # Caches content fetched from the network during lookups. + # Content outside our radius is also cached in order to improve performance + # of queries when we frequently lookup data outside our radius. ContentCache = LRUCache[ContentId, seq[byte]] + # Caches the most recently received content/offers. + # Content is only stored in this cache if it is within our radius and similarly + # the cache is only checked if the content id is within our radius. + OfferCache = LRUCache[ContentId, seq[byte]] + ContentKV* = object contentKey*: ContentKeyByteList content*: seq[byte] @@ -197,6 +211,7 @@ type radiusCache: RadiusCache offerQueue: AsyncQueue[OfferRequest] offerWorkers: seq[Future[void]] + offerCache: OfferCache pingTimings: Table[NodeId, chronos.Moment] config*: PortalProtocolConfig @@ -401,6 +416,55 @@ proc handleFindNodes(p: PortalProtocol, fn: FindNodesMessage): seq[byte] = let enrs = List[ByteList[2048], 32](@[]) encodeMessage(NodesMessage(total: 1, enrs: enrs)) +proc storeContent*( + p: PortalProtocol, + contentKey: ContentKeyByteList, + contentId: ContentId, + content: seq[byte], + cacheContent = false, + cacheOffer = false, +): bool {.discardable.} = + if cacheContent and not p.config.disableContentCache: + # We cache content regardless of whether it is in our radius or not + p.contentCache.put(contentId, content) + + # Always re-check that the key is still in the node range to make sure only + # content in range is stored. + if p.inRange(contentId): + p.dbPut(contentKey, contentId, content) + + if cacheOffer and not p.config.disableOfferCache: + p.offerCache.put(contentId, content) + + true + else: + false + +proc getLocalContent*( + p: PortalProtocol, contentKey: ContentKeyByteList, contentId: ContentId +): Opt[seq[byte]] = + # The cache can contain content that is not in our radius + let maybeContent = p.contentCache.get(contentId) + if maybeContent.isSome(): + portal_content_cache_hits.inc(labelValues = [$p.protocolId]) + return maybeContent + + portal_content_cache_misses.inc(labelValues = [$p.protocolId]) + + # Check first if content is in range, as this is a cheaper operation + # than the database lookup. + if p.inRange(contentId): + let maybeContent = p.offerCache.get(contentId) + if maybeContent.isSome(): + portal_offer_cache_hits.inc(labelValues = [$p.protocolId]) + return maybeContent + + portal_offer_cache_misses.inc(labelValues = [$p.protocolId]) + + p.dbGet(contentKey, contentId) + else: + Opt.none(seq[byte]) + proc handleFindContent( p: PortalProtocol, fc: FindContentMessage, srcId: NodeId ): seq[byte] = @@ -421,24 +485,21 @@ proc handleFindContent( ) # Check first if content is in range, as this is a cheaper operation - if p.inRange(contentId): - let contentResult = p.dbGet(fc.contentKey, contentId) - if contentResult.isOk(): - let content = contentResult.get() - if content.len <= maxPayloadSize: - return encodeMessage( - ContentMessage( - contentMessageType: contentType, content: ByteList[2048](content) - ) + let contentResult = p.getLocalContent(fc.contentKey, contentId) + if contentResult.isOk(): + let content = contentResult.get() + if content.len <= maxPayloadSize: + return encodeMessage( + ContentMessage( + contentMessageType: contentType, content: ByteList[2048](content) ) - else: - let connectionId = p.stream.addContentRequest(srcId, content) + ) + else: + let connectionId = p.stream.addContentRequest(srcId, content) - return encodeMessage( - ContentMessage( - contentMessageType: connectionIdType, connectionId: connectionId - ) - ) + return encodeMessage( + ContentMessage(contentMessageType: connectionIdType, connectionId: connectionId) + ) # Node does not have the content, or content is not even in radius, # send closest neighbours to the requested content id. @@ -479,7 +540,10 @@ proc handleOffer(p: PortalProtocol, o: OfferMessage, srcId: NodeId): seq[byte] = ) if p.inRange(contentId): - if not p.dbContains(contentKey, contentId): + # Checking the offer cache first to reduce the load on the database + # for the case when the offer already exists and it was recently accepted + if not p.offerCache.contains(contentId) and + not p.dbContains(contentKey, contentId): contentKeysBitList.setBit(i) discard contentKeys.add(contentKey) else: @@ -592,6 +656,8 @@ proc new*( stream: stream, radiusCache: RadiusCache.init(256), offerQueue: newAsyncQueue[OfferRequest](concurrentOffers), + offerCache: + OfferCache.init(if config.disableContentCache: 0 else: config.contentCacheSize), pingTimings: Table[NodeId, chronos.Moment](), config: config, ) @@ -955,7 +1021,7 @@ proc offer( if contentIdResult.isOk(): let contentId = contentIdResult.get() - contentResult = p.dbGet(contentKey, contentId) + contentResult = p.getLocalContent(contentKey, contentId) var output = memoryOutput() if contentResult.isOk(): @@ -1600,44 +1666,6 @@ proc randomGossipDiscardPeers*( ): Future[void] {.async: (raises: [CancelledError]).} = discard await p.randomGossip(srcNodeId, contentKeys, content) -proc storeContent*( - p: PortalProtocol, - contentKey: ContentKeyByteList, - contentId: ContentId, - content: seq[byte], - cacheContent = false, -): bool {.discardable.} = - if cacheContent and not p.config.disableContentCache: - # We cache content regardless of whether it is in our radius or not - p.contentCache.put(contentId, content) - - # Always re-check that the key is still in the node range to make sure only - # content in range is stored. - if p.inRange(contentId): - doAssert(p.dbPut != nil) - p.dbPut(contentKey, contentId, content) - true - else: - false - -proc getLocalContent*( - p: PortalProtocol, contentKey: ContentKeyByteList, contentId: ContentId -): Opt[seq[byte]] = - # The cache can contain content that is not in our radius - let maybeContent = p.contentCache.get(contentId) - if maybeContent.isSome(): - portal_content_cache_hits.inc(labelValues = [$p.protocolId]) - return maybeContent - - portal_content_cache_misses.inc(labelValues = [$p.protocolId]) - - # Check first if content is in range, as this is a cheaper operation - # than the database lookup. - if p.inRange(contentId): - p.dbGet(contentKey, contentId) - else: - Opt.none(seq[byte]) - proc seedTable*(p: PortalProtocol) = ## Seed the table with specifically provided Portal bootstrap nodes. These are ## nodes that must support the wire protocol for the specific content network. diff --git a/fluffy/network/wire/portal_protocol_config.nim b/fluffy/network/wire/portal_protocol_config.nim index da70a636f1..c440138e13 100644 --- a/fluffy/network/wire/portal_protocol_config.nim +++ b/fluffy/network/wire/portal_protocol_config.nim @@ -43,6 +43,8 @@ type maxGossipNodes*: int contentCacheSize*: int disableContentCache*: bool + offerCacheSize*: int + disableOfferCache*: bool const defaultRadiusConfig* = RadiusConfig(kind: Dynamic) @@ -51,6 +53,8 @@ const defaultMaxGossipNodes* = 4 defaultContentCacheSize* = 100 defaultDisableContentCache* = false + defaultOfferCacheSize* = 100 + defaultDisableOfferCache* = false revalidationTimeout* = chronos.seconds(30) defaultPortalProtocolConfig* = PortalProtocolConfig( @@ -61,6 +65,8 @@ const maxGossipNodes: defaultMaxGossipNodes, contentCacheSize: defaultContentCacheSize, disableContentCache: defaultDisableContentCache, + offerCacheSize: defaultOfferCacheSize, + disableOfferCache: defaultDisableOfferCache, ) proc init*( @@ -73,6 +79,8 @@ proc init*( maxGossipNodes: int, contentCacheSize: int, disableContentCache: bool, + offerCacheSize: int, + disableOfferCache: bool, ): T = PortalProtocolConfig( tableIpLimits: @@ -83,6 +91,8 @@ proc init*( maxGossipNodes: maxGossipNodes, contentCacheSize: contentCacheSize, disableContentCache: disableContentCache, + offerCacheSize: offerCacheSize, + disableOfferCache: disableOfferCache, ) func fromLogRadius*(T: type UInt256, logRadius: uint16): T = From a76d7122e47d136dfc12160d9d2761e19ea39de1 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:28:09 +0800 Subject: [PATCH 10/12] Cache offers in json rpc APIs. --- fluffy/rpc/rpc_portal_beacon_api.nim | 2 +- fluffy/rpc/rpc_portal_history_api.nim | 2 +- fluffy/rpc/rpc_portal_state_api.nim | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fluffy/rpc/rpc_portal_beacon_api.nim b/fluffy/rpc/rpc_portal_beacon_api.nim index 891fa10798..71b7dc613f 100644 --- a/fluffy/rpc/rpc_portal_beacon_api.nim +++ b/fluffy/rpc/rpc_portal_beacon_api.nim @@ -116,7 +116,7 @@ proc installPortalBeaconApiHandlers*(rpcServer: RpcServer, p: PortalProtocol) = contentId = p.toContentId(key).valueOr: raise invalidKeyErr() - p.storeContent(key, contentId, contentValueBytes) + p.storeContent(key, contentId, contentValueBytes, cacheOffer = true) rpcServer.rpc("portal_beaconLocalContent") do(contentKey: string) -> string: let diff --git a/fluffy/rpc/rpc_portal_history_api.nim b/fluffy/rpc/rpc_portal_history_api.nim index b74f08bed6..bf0fb122b6 100644 --- a/fluffy/rpc/rpc_portal_history_api.nim +++ b/fluffy/rpc/rpc_portal_history_api.nim @@ -116,7 +116,7 @@ proc installPortalHistoryApiHandlers*(rpcServer: RpcServer, p: PortalProtocol) = contentId = p.toContentId(key).valueOr: raise invalidKeyErr() - p.storeContent(key, contentId, contentValueBytes) + p.storeContent(key, contentId, contentValueBytes, cacheOffer = true) rpcServer.rpc("portal_historyLocalContent") do(contentKey: string) -> string: let diff --git a/fluffy/rpc/rpc_portal_state_api.nim b/fluffy/rpc/rpc_portal_state_api.nim index c35ae0d271..4cbbef763b 100644 --- a/fluffy/rpc/rpc_portal_state_api.nim +++ b/fluffy/rpc/rpc_portal_state_api.nim @@ -137,7 +137,7 @@ proc installPortalStateApiHandlers*(rpcServer: RpcServer, p: PortalProtocol) = contentValue = validateOfferGetValue(Opt.none(Hash32), key, contentBytes).valueOr: raise invalidValueErr() - p.storeContent(keyBytes, contentId, contentValue) + p.storeContent(keyBytes, contentId, contentValue, cacheOffer = true) rpcServer.rpc("portal_stateLocalContent") do(contentKey: string) -> string: let @@ -159,7 +159,7 @@ proc installPortalStateApiHandlers*(rpcServer: RpcServer, p: PortalProtocol) = contentValue = validateOfferGetValue(Opt.none(Hash32), key, contentBytes).valueOr: raise invalidValueErr() - p.storeContent(keyBytes, contentId, contentValue) + p.storeContent(keyBytes, contentId, contentValue, cacheOffer = true) await p.neighborhoodGossip( Opt.none(NodeId), ContentKeysList(@[keyBytes]), @[contentBytes] From 24d9cdb7a991a8f5fad0f9df48af3a31849f253e Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:42:05 +0800 Subject: [PATCH 11/12] Fix last merge. --- fluffy/network/wire/portal_protocol.nim | 43 ++----------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/fluffy/network/wire/portal_protocol.nim b/fluffy/network/wire/portal_protocol.nim index 18d27ff914..7a8cc5c837 100644 --- a/fluffy/network/wire/portal_protocol.nim +++ b/fluffy/network/wire/portal_protocol.nim @@ -169,11 +169,11 @@ type # Caches content fetched from the network during lookups. # Content outside our radius is also cached in order to improve performance - # of queries when we frequently lookup data outside our radius. + # of queries which may lookup data outside our radius. ContentCache = LruCache[ContentId, seq[byte]] # Caches the most recently received content/offers. - # Content is only stored in this cache if it is within our radius and similarly + # Content is only stored in this cache if it falls within our radius and similarly # the cache is only checked if the content id is within our radius. OfferCache = LruCache[ContentId, seq[byte]] @@ -540,7 +540,6 @@ proc handleOffer(p: PortalProtocol, o: OfferMessage, srcId: NodeId): seq[byte] = ) if p.inRange(contentId): - # Checking the offer cache first to reduce the load on the database # for the case when the offer already exists and it was recently accepted if not p.offerCache.contains(contentId) and @@ -1667,44 +1666,6 @@ proc randomGossipDiscardPeers*( ): Future[void] {.async: (raises: [CancelledError]).} = discard await p.randomGossip(srcNodeId, contentKeys, content) -proc storeContent*( - p: PortalProtocol, - contentKey: ContentKeyByteList, - contentId: ContentId, - content: seq[byte], - cacheContent = false, -): bool {.discardable.} = - if cacheContent and not p.config.disableContentCache: - # We cache content regardless of whether it is in our radius or not - p.contentCache.put(contentId, content) - - # Always re-check that the key is still in the node range to make sure only - # content in range is stored. - if p.inRange(contentId): - doAssert(p.dbPut != nil) - p.dbPut(contentKey, contentId, content) - true - else: - false - -proc getLocalContent*( - p: PortalProtocol, contentKey: ContentKeyByteList, contentId: ContentId -): Opt[seq[byte]] = - # The cache can contain content that is not in our radius - let maybeContent = p.contentCache.get(contentId) - if maybeContent.isSome(): - portal_content_cache_hits.inc(labelValues = [$p.protocolId]) - return maybeContent - - portal_content_cache_misses.inc(labelValues = [$p.protocolId]) - - # Check first if content is in range, as this is a cheaper operation - # than the database lookup. - if p.inRange(contentId): - p.dbGet(contentKey, contentId) - else: - Opt.none(seq[byte]) - proc seedTable*(p: PortalProtocol) = ## Seed the table with specifically provided Portal bootstrap nodes. These are ## nodes that must support the wire protocol for the specific content network. From 7a37a08cf5b5ccd2e2a5057dc35cae8a9f150b32 Mon Sep 17 00:00:00 2001 From: bhartnett <51288821+bhartnett@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:49:23 +0800 Subject: [PATCH 12/12] Update init config. --- fluffy/network/wire/portal_protocol.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fluffy/network/wire/portal_protocol.nim b/fluffy/network/wire/portal_protocol.nim index 7a8cc5c837..e9b214068d 100644 --- a/fluffy/network/wire/portal_protocol.nim +++ b/fluffy/network/wire/portal_protocol.nim @@ -484,7 +484,6 @@ proc handleFindContent( int64(logDistance), labelValues = [$p.protocolId] ) - # Check first if content is in range, as this is a cheaper operation let contentResult = p.getLocalContent(fc.contentKey, contentId) if contentResult.isOk(): let content = contentResult.get() @@ -657,7 +656,7 @@ proc new*( radiusCache: RadiusCache.init(256), offerQueue: newAsyncQueue[OfferRequest](concurrentOffers), offerCache: - OfferCache.init(if config.disableContentCache: 0 else: config.contentCacheSize), + OfferCache.init(if config.disableOfferCache: 0 else: config.offerCacheSize), pingTimings: Table[NodeId, chronos.Moment](), config: config, )