-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: incentivization PoC: client-side reputation system basics (#3293)
* chore: rename test file for eligibility tests * add reputation manager * add simple boolean reputation with dummy response * set default reputation to true * use reputation indicator term; remove unnecessary updateReputation * use PushResponse in reputation manager * add custom type for reputation * add reputation update from response quality * encode reputation indicators as Option[bool]
- Loading branch information
1 parent
a3876f1
commit a4e92a3
Showing
4 changed files
with
103 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
import ./test_rpc_codec, ./test_poc | ||
import ./test_rpc_codec, ./test_poc_eligibility, ./test_poc_reputation |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import | ||
std/options, | ||
testutils/unittests, | ||
chronos, | ||
web3, | ||
stew/byteutils, | ||
stint, | ||
strutils, | ||
tests/testlib/testasync | ||
|
||
import | ||
waku/[node/peer_manager, waku_core], | ||
waku/incentivization/[rpc, reputation_manager], | ||
waku/waku_lightpush/rpc | ||
|
||
suite "Waku Incentivization PoC Reputation": | ||
var manager {.threadvar.}: ReputationManager | ||
|
||
setup: | ||
manager = ReputationManager.init() | ||
|
||
test "incentivization PoC: reputation: reputation table is empty after initialization": | ||
check manager.reputationOf.len == 0 | ||
|
||
test "incentivization PoC: reputation: set and get reputation": | ||
manager.setReputation("peer1", some(true)) # Encodes GoodRep | ||
check manager.getReputation("peer1") == some(true) | ||
|
||
test "incentivization PoC: reputation: evaluate PushResponse valid": | ||
let validLightpushResponse = | ||
PushResponse(isSuccess: true, info: some("Everything is OK")) | ||
# We expect evaluateResponse to return GoodResponse if isSuccess is true | ||
check evaluateResponse(validLightpushResponse) == GoodResponse | ||
|
||
test "incentivization PoC: reputation: evaluate PushResponse invalid": | ||
let invalidLightpushResponse = PushResponse(isSuccess: false, info: none(string)) | ||
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) == some(true) | ||
|
||
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) == some(false) | ||
|
||
test "incentivization PoC: reputation: default is None": | ||
let unknownPeerId = "unknown_peer" | ||
# The peer is not in the table yet | ||
check manager.getReputation(unknownPeerId) == none(bool) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import tables, std/options | ||
import waku/waku_lightpush/rpc | ||
|
||
type | ||
PeerId = string | ||
|
||
ResponseQuality* = enum | ||
BadResponse | ||
GoodResponse | ||
|
||
# Encode reputation indicator as Option[bool]: | ||
# some(true) => GoodRep | ||
# some(false) => BadRep | ||
# none(bool) => unknown / not set | ||
ReputationManager* = ref object | ||
reputationOf*: Table[PeerId, Option[bool]] | ||
|
||
proc init*(T: type ReputationManager): ReputationManager = | ||
return ReputationManager(reputationOf: initTable[PeerId, Option[bool]]()) | ||
|
||
proc setReputation*( | ||
manager: var ReputationManager, peer: PeerId, repValue: Option[bool] | ||
) = | ||
manager.reputationOf[peer] = repValue | ||
|
||
proc getReputation*(manager: ReputationManager, peer: PeerId): Option[bool] = | ||
if peer in manager.reputationOf: | ||
result = manager.reputationOf[peer] | ||
else: | ||
result = none(bool) | ||
|
||
# Evaluate the quality of a PushResponse by checking its isSuccess field | ||
proc evaluateResponse*(response: PushResponse): ResponseQuality = | ||
if response.isSuccess: | ||
return GoodResponse | ||
else: | ||
return BadResponse | ||
|
||
# Update reputation of the peer based on the quality of the response | ||
proc updateReputationFromResponse*( | ||
manager: var ReputationManager, peer: PeerId, response: PushResponse | ||
) = | ||
let respQuality = evaluateResponse(response) | ||
case respQuality | ||
of BadResponse: | ||
manager.setReputation(peer, some(false)) # false => BadRep | ||
of GoodResponse: | ||
manager.setReputation(peer, some(true)) # true => GoodRep |