-
Notifications
You must be signed in to change notification settings - Fork 57
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: Add incentivization PoC for RLNaaS in Lightpush #3166
base: master
Are you sure you want to change the base?
Conversation
You can find the image built from this PR at
Built from c5f7990 |
24f9aa8
to
3bf670b
Compare
@s-tikhomirov - is there anything blocking this PR? |
Good question. On the one hand, there are still things to implement before this can be considered a fully-fledged PoC. For example, the properties of a transaction that is checked for "eligibility" are now simply hard-coded. In the final vision, those should be node-specific and stored in a config file or something like that (and I'd have to figure out where such files should be located, how to manage them, etc). On the other hand, the current version is more or less self-contained, and in the spirit of merging things incrementally, I could see this PR at least considered for review. For context: the overall vision of this PoC is that a client would attach a txid as proof of payment alongside its Lightpush request, and the server would check for eligibility of that txid. By eligibility we mean that the transaction:
Here is what is implemented now:
These could be the next steps:
Given this, do you think it makes sense to consider this PR for review as it stands now? @jm-clius , WDYT? |
Without having looked at the code itself yet, based on your description I would certainly suggest opening for review - or even selecting a smaller increment that illustrates a specific function and creating a PR for that. This way we can show the POC growing, remain clear about next steps and what is WIP, while making the turnaround from PR to merge shorter due to the easier review burden on nwaku contributors. |
877db49
to
fe89f5d
Compare
fe89f5d
to
f32ee87
Compare
f32ee87
to
96fbdaf
Compare
96fbdaf
to
13144bc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing work! Thanks so much! 🤩
I added some questions and comments, please let me know if I'm missing anything in any of them :)
I also see that the Lint CI job is failing, please try installing the latest version of https://github.com/arnetheduck/nph/tree/latest and integrate it with your IDE (let me know if you have any issues with it, I can help out!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for it!
I just added some nitpick comment that I hope you find useful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Added a couple of initial comments to address below.
waku/incentivization/common.nim
Outdated
|
||
import waku/incentivization/rpc | ||
|
||
proc genEligibilityStatus*(isEligible: bool): EligibilityStatus = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to me to be interesting only for tests? In other words, this should form part of the test files as a helper function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My idea was, on the contrary, that this function (renamed to new
in later commits) would be useful for future code that would use our eligibility logic to convert a boolean eligibility value into EligibilityStatus
that will be attached to the response. Something like this:
let proof = ... # extract eligibility proof (not necessarily a txid) from the request
let isValid = isEligible(proof, ...) # check proof eligibility
let eligibilityStatus = new(EligibilityStatus, isValid)
let response = LightpushResponse(eligibilityStatus, ...) # generate response
return response # (send the response back to the client)
Does it make sense?
b3890ca
to
d865b1a
Compare
35e2479
to
ae9fb73
Compare
Re-requesting reviews after addressing the suggestions (one suggestion remains unresolved, but it shouldn't be a blocker). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooh looks great! 🤩
I added comments on some last small details - overall looks amazing! Thanks so much!
lmk in case anything I proposed doesn't make sense :))
7ac3d0e
to
ae9fb73
Compare
Co-authored-by: gabrielmer <101006718+gabrielmer@users.noreply.github.com>
Co-authored-by: gabrielmer <101006718+gabrielmer@users.noreply.github.com>
758fe5f
to
af16879
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks greatt! Thanks so much! 🤩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for it! I've added some nitpick comments that I hope you find useful
I'm happy to re-review later on :) Ping me if need any clarification 🥳
|
||
# To set up the environment variable (replace Infura with your provider if needed): | ||
# $ export WEB3_RPC_URL="https://sepolia.infura.io/v3/YOUR_API_KEY" | ||
const EthClient = os.getEnv("WEB3_RPC_URL") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is generally better to avoid external dependencies in tests. I suggest taking a look on how Anvil
is being used in other RLN tests.
For example, tests/waku_rln_relay/test_rln_group_manager_onchain.nim
and waku/waku_rln_relay/constants.nim
can serve as a good reference :) ( notice EthClient* = "http://127.0.0.1:8540"
is defined in constants and it deals with a local Anvil
instance )
const TxHashNonExisting* = | ||
TxHash.fromHex("0x0000000000000000000000000000000000000000000000000000000000000000") | ||
const TxHashContractCreation* = | ||
TxHash.fromHex("0xa2e39bee557144591fb7b2891ef44e1392f86c5ba1fc0afb6c0e862676ffd50f") | ||
const TxHashContractCall* = | ||
TxHash.fromHex("0x2761f066eeae9a259a0247f529133dd01b7f57bf74254a64d897433397d321cb") | ||
const TxHashSimpleTransfer* = | ||
TxHash.fromHex("0xa3985984b2ec3f1c3d473eb57a4820a56748f25dabbf9414f2b8380312b439cc") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think no need to be public
const TxHashNonExisting* = | |
TxHash.fromHex("0x0000000000000000000000000000000000000000000000000000000000000000") | |
const TxHashContractCreation* = | |
TxHash.fromHex("0xa2e39bee557144591fb7b2891ef44e1392f86c5ba1fc0afb6c0e862676ffd50f") | |
const TxHashContractCall* = | |
TxHash.fromHex("0x2761f066eeae9a259a0247f529133dd01b7f57bf74254a64d897433397d321cb") | |
const TxHashSimpleTransfer* = | |
TxHash.fromHex("0xa3985984b2ec3f1c3d473eb57a4820a56748f25dabbf9414f2b8380312b439cc") | |
const TxHashNonExisting = | |
TxHash.fromHex("0x0000000000000000000000000000000000000000000000000000000000000000") | |
const TxHashContractCreation = | |
TxHash.fromHex("0xa2e39bee557144591fb7b2891ef44e1392f86c5ba1fc0afb6c0e862676ffd50f") | |
const TxHashContractCall = | |
TxHash.fromHex("0x2761f066eeae9a259a0247f529133dd01b7f57bf74254a64d897433397d321cb") | |
const TxHashSimpleTransfer = | |
TxHash.fromHex("0xa3985984b2ec3f1c3d473eb57a4820a56748f25dabbf9414f2b8380312b439cc") |
check: | ||
isEligible.isOk() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this particular case I think is better to use the assert
approach
check: | |
isEligible.isOk() | |
assert isEligible.isOk(), isEligible.error |
|
||
import waku/incentivization/[rpc, txid_proof] | ||
|
||
proc new*(T: type EligibilityStatus, isEligible: bool): T = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By Nim convention, the object
types (stack allocated) should be created with init
. The new
word should be reserved for only ref object
s (heap allocated.)
proc new*(T: type EligibilityStatus, isEligible: bool): T = | |
proc init*(T: type EligibilityStatus, isEligible: bool): T = |
@@ -0,0 +1,9 @@ | |||
import std/options, chronos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe not needed chronos
?
import std/options, chronos | |
import std/options |
return err("Eligibility proof is empty") | ||
var web3: Web3 | ||
try: | ||
web3 = await newWeb3(ethClient) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating a new instance of web3
for every call to isEligibleTxId
doesn't sound very efficient. I believe it is better to do that once, when the app starts, and only close the web3
instance at the app's end.
I'd suggest creating a new type EligibilityManager
that contains the web3
instance.
return err($errorMsg) | ||
# check that it is not a contract creation tx | ||
let toAddressOption = txReceipt.to | ||
if toAddressOption.isNone: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick comment: by convention, the "verbs" should always have parenthesis when using them
if toAddressOption.isNone: | |
if toAddressOption.isNone(): |
await allFutures(txFuture, receiptFuture) | ||
let tx = txFuture.read() | ||
let txReceipt = receiptFuture.read() | ||
if txReceipt.isErr: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if txReceipt.isErr: | |
if txReceipt.isErr(): |
let tx = txFuture.read() | ||
let txReceipt = receiptFuture.read() | ||
if txReceipt.isErr: | ||
return err("Cannot get tx receipt") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this particular case we can also append the error description
return err("Cannot get tx receipt") | |
return err("Cannot get tx receipt: " & txReceipt.error) |
## in the context of service incentivization PoC, | ||
## if it is confirmed and pays the expected amount to the server's address. | ||
## See spec: https://github.com/waku-org/specs/blob/master/standards/core/incentivization.md | ||
if eligibilityProof.proofOfPayment.isNone: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if eligibilityProof.proofOfPayment.isNone: | |
if eligibilityProof.proofOfPayment.isNone(): |
Description
This WIP PR implements a PoC for light protocol incentivization as outlined in:
Changes
Some items (especially those closer to the end of this list) may be moved to later PRs to keep change sets relatively small.