mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-07 16:33:08 +00:00
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]
This commit is contained in:
parent
a3876f1ec4
commit
a4e92a3d02
@ -1 +1 @@
|
|||||||
import ./test_rpc_codec, ./test_poc
|
import ./test_rpc_codec, ./test_poc_eligibility, ./test_poc_reputation
|
||||||
|
|||||||
54
tests/incentivization/test_poc_reputation.nim
Normal file
54
tests/incentivization/test_poc_reputation.nim
Normal file
@ -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)
|
||||||
48
waku/incentivization/reputation_manager.nim
Normal file
48
waku/incentivization/reputation_manager.nim
Normal file
@ -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
|
||||||
Loading…
x
Reference in New Issue
Block a user