diff --git a/tests/incentivization/test_poc_reputation.nim b/tests/incentivization/test_poc_reputation.nim index a74ebd102..95348874f 100644 --- a/tests/incentivization/test_poc_reputation.nim +++ b/tests/incentivization/test_poc_reputation.nim @@ -13,9 +13,6 @@ import waku/[node/peer_manager, waku_core], waku/incentivization/[rpc, reputation_manager], waku/waku_lightpush/[rpc, common] -import std/options, testutils/unittests, chronos, web3 - -import waku/incentivization/reputation_manager, waku/waku_lightpush_legacy/rpc suite "Waku Incentivization PoC Reputation": var manager {.threadvar.}: ReputationManager @@ -44,6 +41,18 @@ suite "Waku Incentivization PoC Reputation": ) check evaluateResponse(invalidLightLightPushResponse) == BadResponse + test "incentivization PoC: reputation: evaluate LightPushResponse neutral - payment required": + let neutralLightPushResponse = LightPushResponse( + requestId: "", statusCode: LightpushStatusCode.PAYMENT_REQUIRED.uint32 + ) + check evaluateResponse(neutralLightPushResponse) == NeutralResponse + + test "incentivization PoC: reputation: evaluate LightPushResponse bad - no peers": + let badLightPushResponse = LightPushResponse( + requestId: "", statusCode: LightpushStatusCode.NO_PEERS_TO_RELAY.uint32 + ) + check evaluateResponse(badLightPushResponse) == BadResponse + test "incentivization PoC: reputation: updateReputationFromResponse valid": let validResp = LightPushResponse(requestId: "", statusCode: LightpushStatusCode.SUCCESS.uint32) @@ -57,5 +66,46 @@ suite "Waku Incentivization PoC Reputation": manager.updateReputationFromResponse(peerId1, invalidResp) check manager.getReputation(peerId1) == some(false) + test "incentivization PoC: reputation: updateReputationFromResponse neutral - no change": + # First set a good reputation + manager.setReputation(peerId1, some(true)) + check manager.getReputation(peerId1) == some(true) + + # Send a neutral response (payment required) + let neutralResp = LightPushResponse( + requestId: "", statusCode: LightpushStatusCode.PAYMENT_REQUIRED.uint32 + ) + manager.updateReputationFromResponse(peerId1, neutralResp) + + # Reputation should remain unchanged + check manager.getReputation(peerId1) == some(true) + + test "incentivization PoC: reputation: updateReputationFromResponse neutral - no change from bad": + # First set a bad reputation + manager.setReputation(peerId1, some(false)) + check manager.getReputation(peerId1) == some(false) + + # Send a neutral response (payment required) + let neutralResp = LightPushResponse( + requestId: "", statusCode: LightpushStatusCode.PAYMENT_REQUIRED.uint32 + ) + manager.updateReputationFromResponse(peerId1, neutralResp) + + # Reputation should remain unchanged + check manager.getReputation(peerId1) == some(false) + + test "incentivization PoC: reputation: updateReputationFromResponse neutral - no change from none": + # Start with no reputation set + check manager.getReputation(peerId1) == none(bool) + + # Send a neutral response (payment required) + let neutralResp = LightPushResponse( + requestId: "", statusCode: LightpushStatusCode.PAYMENT_REQUIRED.uint32 + ) + manager.updateReputationFromResponse(peerId1, neutralResp) + + # Reputation should remain none + check manager.getReputation(peerId1) == none(bool) + test "incentivization PoC: reputation: default is None": check manager.getReputation(peerId1) == none(bool) diff --git a/waku/incentivization/reputation_manager.nim b/waku/incentivization/reputation_manager.nim index 2ddb16c92..582aa29bf 100644 --- a/waku/incentivization/reputation_manager.nim +++ b/waku/incentivization/reputation_manager.nim @@ -2,9 +2,17 @@ import tables, std/options, chronicles import ../waku_lightpush/[rpc, common] import libp2p/peerid +const BadResponseStatusCodes* = [ + LightpushStatusCode.INTERNAL_SERVER_ERROR, + LightpushStatusCode.SERVICE_NOT_AVAILABLE, + LightpushStatusCode.OUT_OF_RLN_PROOF, + LightpushStatusCode.NO_PEERS_TO_RELAY +] + type ResponseQuality* = enum BadResponse + NeutralResponse GoodResponse # Encode reputation indicator as Option[bool]: @@ -34,8 +42,10 @@ proc getReputation*(manager: ReputationManager, peer: PeerId): Option[bool] = proc evaluateResponse*(response: LightPushResponse): ResponseQuality = if response.statusCode == LightpushStatusCode.SUCCESS.uint32: return GoodResponse - else: + elif LightpushStatusCode(response.statusCode) in BadResponseStatusCodes: return BadResponse + else: + return NeutralResponse # Update reputation of the peer based on LightPushResponse quality proc updateReputationFromResponse*( @@ -49,3 +59,6 @@ proc updateReputationFromResponse*( of GoodResponse: debug "Assign good reputation for peer", peer = peer manager.setReputation(peer, some(true)) # true => GoodRep + of NeutralResponse: + debug "Neutral response - reputation unchanged for peer", peer = peer + # Don't change reputation for neutral responses