From fce0795b2a5071aac1b1c24e0bac5a19fa06d75f Mon Sep 17 00:00:00 2001 From: Sergei Tikhomirov Date: Wed, 19 Feb 2025 16:48:46 +0100 Subject: [PATCH] add reputation update from response quality --- tests/incentivization/test_poc_reputation.nim | 27 +++++++++--- waku/incentivization/reputation_manager.nim | 42 ++++++++++++------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/tests/incentivization/test_poc_reputation.nim b/tests/incentivization/test_poc_reputation.nim index 2033c0b819..b88247f8fa 100644 --- a/tests/incentivization/test_poc_reputation.nim +++ b/tests/incentivization/test_poc_reputation.nim @@ -20,7 +20,7 @@ suite "Waku Incentivization PoC Reputation": manager = ReputationManager.init() test "incentivization PoC: reputation: reputation table is empty after initialization": - check manager.peerReputation.len == 0 + check manager.reputationOf.len == 0 test "incentivization PoC: reputation: set and get reputation": manager.setReputation("peer1", GoodRep) @@ -29,10 +29,27 @@ suite "Waku Incentivization PoC Reputation": test "incentivization PoC: reputation: evaluate PushResponse valid": let validLightpushResponse = PushResponse(isSuccess: true, info: some("Everything is OK")) - # We expect evaluateResponse to return GoodRep if isSuccess is true - check evaluateResponse(validLightpushResponse) == GoodRep + # We expect evaluateResponse to return GoodResponse if isSuccess is true + check evaluateResponse(validLightpushResponse) == GoodResponse test "incentivization PoC: reputation: evaluate PushResponse invalid": - # For example, set isSuccess = false so we expect a returned BadRep + # For example, set isSuccess = false so we expect a returned BadResponse let invalidLightpushResponse = PushResponse(isSuccess: false, info: none(string)) - check evaluateResponse(invalidLightpushResponse) == BadRep + check evaluateResponse(invalidLightpushResponse) == BadResponse + + test "incentivization PoC: reputation: updateReputationFromResponse valid": + let peerId = "peerWithValidResponse" + let validResp = PushResponse(isSuccess: true, info: some("All good")) + manager.updateReputationFromResponse(peerId, validResp) + check manager.getReputation(peerId) == GoodRep + + test "incentivization PoC: reputation: updateReputationFromResponse invalid": + let peerId = "peerWithInvalidResponse" + let invalidResp = PushResponse(isSuccess: false, info: none(string)) + manager.updateReputationFromResponse(peerId, invalidResp) + check manager.getReputation(peerId) == BadRep + + test "incentivization PoC: reputation: default is UnknownRep": + let unknownPeerId = "unknown_peer" + # peer not in the table yet + check manager.getReputation(unknownPeerId) == UnknownRep diff --git a/waku/incentivization/reputation_manager.nim b/waku/incentivization/reputation_manager.nim index 30f542f60d..006356e0be 100644 --- a/waku/incentivization/reputation_manager.nim +++ b/waku/incentivization/reputation_manager.nim @@ -3,35 +3,47 @@ import waku/waku_lightpush/rpc type PeerId = string + ReputationIndicator* = enum BadRep GoodRep + UnknownRep - ResponseQuality = bool + ResponseQuality* = enum + BadResponse + GoodResponse ReputationManager* = ref object - peerReputation*: Table[PeerId, ReputationIndicator] + reputationOf*: Table[PeerId, ReputationIndicator] proc init*(T: type ReputationManager): ReputationManager = - return ReputationManager(peerReputation: initTable[PeerId, ReputationIndicator]()) + return ReputationManager(reputationOf: initTable[PeerId, ReputationIndicator]()) proc setReputation*( - manager: var ReputationManager, - peer: PeerId, - reputationIndicator: ReputationIndicator, + manager: var ReputationManager, peer: PeerId, repIndicator: ReputationIndicator ) = - manager.peerReputation[peer] = reputationIndicator + manager.reputationOf[peer] = repIndicator proc getReputation*(manager: ReputationManager, peer: PeerId): ReputationIndicator = - if peer in manager.peerReputation: - result = manager.peerReputation[peer] + if peer in manager.reputationOf: + result = manager.reputationOf[peer] else: - # Default to GoodRep if peer not found - result = GoodRep + result = UnknownRep -# Evaluate a PushResponse by checking the isSuccess field. -proc evaluateResponse*(response: PushResponse): ReputationIndicator = +# Evaluate the quality of a PushResponse by checking its isSuccess field +proc evaluateResponse*(response: PushResponse): ResponseQuality = if response.isSuccess: - return GoodRep + return GoodResponse else: - return BadRep + return BadResponse + +# Update reputation of the peer based on the quality of a response +proc updateReputationFromResponse*( + manager: var ReputationManager, peer: PeerId, response: PushResponse +) = + let respQuality = evaluateResponse(response) + case respQuality + of BadResponse: + manager.setReputation(peer, BadRep) + of GoodResponse: + manager.setReputation(peer, GoodRep)