ensure peers are retrieved in random order from peer store (#3860)

This commit is contained in:
Ivan FB 2026-05-13 15:29:11 +02:00 committed by GitHub
parent 3c98aa7fac
commit f23983f488
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 3 deletions

View File

@ -1,6 +1,6 @@
{.used.}
import std/options, testutils/unittests, chronos, libp2p/crypto/crypto
import std/[options, sets], testutils/unittests, chronos, libp2p/crypto/crypto
import
waku/[node/peer_manager, waku_core, waku_store, waku_store/client, common/paging],
@ -223,3 +223,24 @@ suite "Store Client":
not await handlerFuture.withTimeout(FUTURE_TIMEOUT)
queryResponse.isErr()
queryResponse.error.kind == ErrorCode.PEER_DIAL_FAILURE
asyncTest "queryToAny shuffles peers across calls":
# Register several fake store peers (no servers running) so every dial
# fails. PEER_DIAL_FAILURE carries the peerId of the last peer tried in
# the shuffled order, so observing different "last" peerIds across calls
# confirms shuffle is active inside queryToAny.
for _ in 0 ..< 3:
let fakeSwitch = newTestSwitch()
let peerInfo = fakeSwitch.peerInfo.toRemotePeerInfo()
peerInfo.protocols = @[WakuStoreCodec]
clientSwitch.peerStore.addPeer(peerInfo)
var observedLastPeers: HashSet[string]
for _ in 0 ..< 20:
let res = await client.queryToAny(storeQuery)
check:
res.isErr()
res.error.kind == ErrorCode.PEER_DIAL_FAILURE
observedLastPeers.incl(res.error.address)
check observedLastPeers.len >= 2

View File

@ -1,7 +1,7 @@
{.push raises: [].}
import
std/[options, tables, sequtils, algorithm],
std/[options, tables, sequtils, algorithm, random],
results,
chronicles,
chronos,
@ -100,7 +100,8 @@ proc queryToAny*(
if peers.len == 0:
return err(StoreError(kind: BAD_RESPONSE, cause: "no service store peer connected"))
# Shuffle to distribute load and limit retries
# Shuffle to distribute load across store peers and limit retries
shuffle(peers)
let peersToTry = peers[0 ..< min(peers.len, MaxQueryRetries)]
var lastError: StoreError