Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integrate reputation manager into Lightpush behind a feature flag #3309

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

s-tikhomirov
Copy link
Contributor

@s-tikhomirov s-tikhomirov commented Feb 26, 2025

Description

This PR integrates a reputation system designed as part of the incentivization PoC into the Lightpush protocol behind a feature flag (reputation).

A Lightpush client uses the reputation manager to keep track of peers it used previously to publish messages. Peers that had failed at publishing a message get assigned a negative reputation and will not be chosen for future requests. If, however, a neutral- or positive-reputation peer isn't selected by the peer manager after a maximum number of attempts (10), a negative-reputation peer is still used.

This is a countinuaton of #3166, #3264, and #3293 with associated deliverable waku-org/pm#245.

Changes

  • add an optional reputation manager for Lightpush client behind a feature flag
  • add tests for the reputation manager
  • refactor the publishToAny logic for lightpush
  • add reputation-based logic to peer selection in a Lightpush client

Copy link

github-actions bot commented Feb 27, 2025

You can find the image built from this PR at

quay.io/wakuorg/nwaku-pr:3309

Built from d02f5f8

@s-tikhomirov s-tikhomirov force-pushed the feat/incentivization-poc-lightpush-integration-reputation branch from 2ffc878 to 321dc7e Compare February 28, 2025 15:29
@s-tikhomirov s-tikhomirov marked this pull request as ready for review February 28, 2025 15:40
@s-tikhomirov s-tikhomirov changed the title feat: integrate reputation manager into Lightpush behind a feature flag [WIP] feat: integrate reputation manager into Lightpush behind a feature flag Feb 28, 2025
@s-tikhomirov s-tikhomirov marked this pull request as draft March 4, 2025 11:09
@s-tikhomirov
Copy link
Contributor Author

Converting to draft after discussion with @jm-clius .

I'd appreciate the opinion of @NagyZoltanPeter (cc @Ivansete-status ) on the following question.

To introduce reputation-related functionality for Lightpush in this PR, I use a compilation flag reputation. An alternative approach would be:

  • use a config flag instead;
  • continue development in a reputation-related feature branch, instead of merging to master often (while keeping that branch reasonably up-to-date with master).

From nwaku's perspective, what would be the preferred way to develop reputation-related features?

@NagyZoltanPeter
Copy link
Contributor

Converting to draft after discussion with @jm-clius .

I'd appreciate the opinion of @NagyZoltanPeter (cc @Ivansete-status ) on the following question.

To introduce reputation-related functionality for Lightpush in this PR, I use a compilation flag reputation. An alternative approach would be:

  • use a config flag instead;
  • continue development in a reputation-related feature branch, instead of merging to master often (while keeping that branch reasonably up-to-date with master).

From nwaku's perspective, what would be the preferred way to develop reputation-related features?

IMHO, compilation flag can just make things more complicated as you should sign or know that the binary is which and can also hide certain problems from other developers not using the flag.
So I vote for a config option, default to false.
Also in any way you choose, it is wise to keep your development as up-to-date to the latest master as possible.
Personally, I have nothing against regular merging - thus to separate your work into multiple PRs just as @SionoiS did withthe latest sync protocol (which is a great example of doing so).
Please notice that we are about to merge new lightpush protocol that will mean a legacy lightpush living alongside till we decide to decommission the legacy one. I think keeping your part for the new lightpush is a good choice. But let's see other's opinions.

@s-tikhomirov
Copy link
Contributor Author

we are about to merge new lightpush protocol

For the sake of completeness, is this - #3279 - the PR in question? I'm going to look at this more closely. I agree that it makes sense to introduce reputation for the new Lightpush, as long as it's coming up soon.

@NagyZoltanPeter
Copy link
Contributor

we are about to merge new lightpush protocol

For the sake of completeness, is this - #3279 - the PR in question? I'm going to look at this more closely. I agree that it makes sense to introduce reputation for the new Lightpush, as long as it's coming up soon.

Exactly, that one.

@jm-clius jm-clius requested a review from SionoiS March 5, 2025 12:53
@s-tikhomirov s-tikhomirov force-pushed the feat/incentivization-poc-lightpush-integration-reputation branch from e8e36a3 to 0fc1862 Compare March 5, 2025 13:48

logScope:
topics = "waku lightpush client"

type WakuLightPushClient* = ref object
peerManager*: PeerManager
rng*: ref rand.HmacDrbgContext
reputationManager*: Option[ReputationManager]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this inside PeerManager it will be needed to persist reputation state anyway and it would minimize the impact on the light push code.

Comment on lines +107 to +124
proc selectPeerForLightPush*(
wl: WakuLightPushClient
): Future[Result[RemotePeerInfo, string]] {.async, gcsafe.} =
let maxAttempts = if defined(reputation): 10 else: 1
var attempts = 0
var peerResult: Result[RemotePeerInfo, string]
while attempts < maxAttempts:
let candidate = wl.peerManager.selectPeer(WakuLightPushCodec, none(PubsubTopic)).valueOr:
return err("could not retrieve a peer supporting WakuLightPushCodec")
if wl.reputationManager.isSome():
let reputation = wl.reputationManager.get().getReputation(candidate.peerId)
info "Peer selected", peerId = candidate.peerId, reputation = $reputation, attempts = $attempts
if (reputation == some(false)):
attempts += 1
continue
return ok(candidate)
warn "Maximum reputation-based retries exceeded; continuing with a bad-reputation peer."
return peerResult
Copy link
Contributor

@SionoiS SionoiS Mar 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seams a bit convoluted.

In my mind, a reputation ordered list of peers would work best. One would have to simply pick the first element, no computation needed.

edit: I see that the reputation is binary ATM maybe a number could be used instead? An exponentially smoothed moving average (simpler than it sounds) with a scoring of 1,0,-1 should work and not add too much complexity.

Copy link
Contributor Author

@s-tikhomirov s-tikhomirov Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seams a bit convoluted.

I agree, I thought it would be good enough for a POC (and maybe it is), but your other idea of moving the reputation logic inside the PeerManager could simplify things indeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants