From e7fb8b5fb10bcee9ca231d3c99f860ba08ac978b Mon Sep 17 00:00:00 2001 From: Sergei Tikhomirov Date: Tue, 26 Mar 2024 18:25:42 +0100 Subject: [PATCH] feat(incentivization): add codec for eligibility proof and status (#2419) * incentivization: add codec for eligibility proofs * add codec for eligibility proof and eligibility status * address minor comments * make status code mandatory in eligibility status --- tests/all_tests_waku.nim | 3 +- tests/incentivization/test_all.nim | 2 + tests/incentivization/test_rpc_codec.nim | 32 +++++++++++++ waku/incentivization/rpc.nim | 17 +++++++ waku/incentivization/rpc_codec.nim | 59 ++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 tests/incentivization/test_all.nim create mode 100644 tests/incentivization/test_rpc_codec.nim create mode 100644 waku/incentivization/rpc.nim create mode 100644 waku/incentivization/rpc_codec.nim diff --git a/tests/all_tests_waku.nim b/tests/all_tests_waku.nim index 36cfba9cd..222aaae35 100644 --- a/tests/all_tests_waku.nim +++ b/tests/all_tests_waku.nim @@ -42,7 +42,8 @@ import ./waku_filter_v2/test_all, ./waku_peer_exchange/test_all, ./waku_lightpush/test_all, - ./waku_relay/test_all + ./waku_relay/test_all, + ./incentivization/test_all import # Waku v2 tests diff --git a/tests/incentivization/test_all.nim b/tests/incentivization/test_all.nim new file mode 100644 index 000000000..4a38f788b --- /dev/null +++ b/tests/incentivization/test_all.nim @@ -0,0 +1,2 @@ +import + ./test_rpc_codec \ No newline at end of file diff --git a/tests/incentivization/test_rpc_codec.nim b/tests/incentivization/test_rpc_codec.nim new file mode 100644 index 000000000..11c804016 --- /dev/null +++ b/tests/incentivization/test_rpc_codec.nim @@ -0,0 +1,32 @@ +import + std/options, + std/strscans, + testutils/unittests, + chronicles, + chronos, + libp2p/crypto/crypto + +import + ../../../waku/incentivization/rpc, + ../../../waku/incentivization/rpc_codec + + +suite "Waku Incentivization Eligibility Codec": + + asyncTest "encode eligibility proof": + var byteSequence: seq[byte] = @[1, 2, 3, 4, 5, 6, 7, 8] + let epRpc = EligibilityProof(proofOfPayment: some(byteSequence)) + let encoded = encode(epRpc) + let decoded = EligibilityProof.decode(encoded.buffer).get() + check: + epRpc == decoded + + asyncTest "encode eligibility status": + let esRpc = EligibilityStatus( + statusCode: uint32(200), + statusDesc: some("OK") + ) + let encoded = encode(esRpc) + let decoded = EligibilityStatus.decode(encoded.buffer).get() + check: + esRpc == decoded diff --git a/waku/incentivization/rpc.nim b/waku/incentivization/rpc.nim new file mode 100644 index 000000000..5b0d0e99b --- /dev/null +++ b/waku/incentivization/rpc.nim @@ -0,0 +1,17 @@ +import + json_serialization, + std/options +import + ../waku_core + +# Implementing the RFC: +# https://github.com/vacp2p/rfc/tree/master/content/docs/rfcs/73 + +type + + EligibilityProof* = object + proofOfPayment*: Option[seq[byte]] + + EligibilityStatus* = object + statusCode*: uint32 + statusDesc*: Option[string] diff --git a/waku/incentivization/rpc_codec.nim b/waku/incentivization/rpc_codec.nim new file mode 100644 index 000000000..dbe6e9daf --- /dev/null +++ b/waku/incentivization/rpc_codec.nim @@ -0,0 +1,59 @@ +import + std/options +import + ../common/protobuf, + ../waku_core, + ./rpc + + +# Codec for EligibilityProof + +proc encode*(epRpc: EligibilityProof): ProtoBuffer = + var pb = initProtoBuffer() + if epRpc.proofOfPayment.isSome(): + let proofOfPayment = epRpc.proofOfPayment.get() + pb.write3(1, proofOfPayment) + else: + # there is no proof + discard + pb + +proc decode*(T: type EligibilityProof, buffer: seq[byte]): ProtobufResult[T] = + let pb = initProtoBuffer(buffer) + var epRpc = EligibilityProof() + var proofOfPayment = newSeq[byte]() + if not ?pb.getField(1, proofOfPayment): + epRpc.proofOfPayment = none(seq[byte]) + else: + epRpc.proofOfPayment = some(proofOfPayment) + ok(epRpc) + + +# Codec for EligibilityStatus + +proc encode*(esRpc: EligibilityStatus): ProtoBuffer = + var pb = initProtoBuffer() + pb.write3(1, esRpc.statusCode) + if esRpc.statusDesc.isSome(): + pb.write3(2, esRpc.statusDesc.get()) + pb + +proc decode*(T: type EligibilityStatus, buffer: seq[byte]): ProtobufResult[T] = + let pb = initProtoBuffer(buffer) + var esRpc = EligibilityStatus() + # status code + var code = uint32(0) + if not ?pb.getField(1, code): + # status code is mandatory + return err(ProtobufError.missingRequiredField("status_code")) + else: + esRpc.statusCode = code + # status description + var description = "" + if not ?pb.getField(2, description): + esRpc.statusDesc = none(string) + else: + esRpc.statusDesc = some(description) + ok(esRpc) + +