feat: add txid-based eligibility proof check for incentivization PoC (#2816)

This commit is contained in:
Sergei Tikhomirov 2024-06-27 17:07:28 +02:00
parent 23453cbc65
commit a3668b0968
No known key found for this signature in database
GPG Key ID: 6A1F8ED9D6538027
7 changed files with 104 additions and 58 deletions

View File

@ -4,21 +4,19 @@ import
chronos chronos
import import
../../../waku/incentivization/[ ../../../waku/incentivization/[rpc, common, txid_proof]
rpc,common
]
suite "Waku Incentivization Eligibility Testing": suite "Waku Incentivization Eligibility Testing":
asyncTest "check eligibility success": asyncTest "check eligibility success with a txid-based proof":
var byteSequence: seq[byte] = @[1, 2, 3, 4, 5, 6, 7, 8] let eligibilityProof = genTxIdEligibilityProof(true)
let eligibilityProof = EligibilityProof(proofOfPayment: some(byteSequence)) let isValid = await txidEligiblityCriteriaMet(eligibilityProof)
check: check:
isEligible(eligibilityProof) isValid
asyncTest "check eligibility failure": asyncTest "check eligibility failure with a txid-based proof":
var byteSequence: seq[byte] = @[0, 2, 3, 4, 5, 6, 7, 8] let eligibilityProof = genTxIdEligibilityProof(false)
let eligibilityProof = EligibilityProof(proofOfPayment: some(byteSequence)) let isValid = await txidEligiblityCriteriaMet(eligibilityProof)
check: check:
not isEligible(eligibilityProof) not isValid

View File

@ -19,6 +19,7 @@ import
common, common,
client, client,
protocol, protocol,
txid_proof
] ]
@ -73,14 +74,14 @@ suite "Waku Incentivization PoC Dummy Protocol":
asyncTeardown: asyncTeardown:
await allFutures(clientSwitch.stop(), serverSwitch.stop()) await allFutures(clientSwitch.stop(), serverSwitch.stop())
asyncTest "incentivization PoC: dummy protocol with a valid eligibility proof": asyncTest "incentivization PoC: dummy protocol with a valid txid eligibility proof":
let request = genDummyRequestWithEligibilityProof(true) let request = genDummyRequestWithTxIdEligibilityProof(true)
let response = await client.sendRequest(request, serverRemotePeerInfo) let response = await client.sendRequest(request, serverRemotePeerInfo)
check: check:
response.isOk() response.isOk()
asyncTest "incentivization PoC: dummy protocol client with an invalid eligibility proof": asyncTest "incentivization PoC: dummy protocol client with an invalid txid eligibility proof":
let request = genDummyRequestWithEligibilityProof(false) let request = genDummyRequestWithTxIdEligibilityProof(false)
let response = await client.sendRequest(request, serverRemotePeerInfo) let response = await client.sendRequest(request, serverRemotePeerInfo)
check: check:
response.isErr() response.isErr()

View File

@ -1,20 +1,22 @@
import import
std/options, std/options,
std/strscans,
testutils/unittests, testutils/unittests,
chronicles,
chronos, chronos,
libp2p/crypto/crypto libp2p/crypto/crypto
import import
../../../waku/incentivization/rpc, ../../../waku/incentivization/[
../../../waku/incentivization/rpc_codec, rpc,
../../../waku/incentivization/common rpc_codec,
common,
txid_proof,
eligibility
]
suite "Waku Incentivization Eligibility Codec": suite "Waku Incentivization Eligibility Codec":
asyncTest "encode eligibility proof": asyncTest "encode eligibility proof":
let eligibilityProof = genEligibilityProof(true) let eligibilityProof = genTxIdEligibilityProof(true)
let encoded = encode(eligibilityProof) let encoded = encode(eligibilityProof)
let decoded = EligibilityProof.decode(encoded.buffer).get() let decoded = EligibilityProof.decode(encoded.buffer).get()
check: check:
@ -28,7 +30,7 @@ suite "Waku Incentivization Eligibility Codec":
eligibilityStatus == decoded eligibilityStatus == decoded
asyncTest "encode dummy request": asyncTest "encode dummy request":
let dummyRequest = genDummyRequestWithEligibilityProof(true) let dummyRequest = genDummyRequestWithTxIdEligibilityProof(true)
let encoded = encode(dummyRequest) let encoded = encode(dummyRequest)
let decoded = DummyRequest.decode(encoded.buffer).get() let decoded = DummyRequest.decode(encoded.buffer).get()
check: check:

View File

@ -1,16 +1,16 @@
import import
std/options, std/options,
std/strscans, std/strscans,
std/sequtils,
testutils/unittests, testutils/unittests,
chronicles, chronicles,
chronos, chronos,
libp2p/crypto/crypto libp2p/crypto/crypto
import stew/results, chronos, libp2p/peerid import stew/results, libp2p/peerid
import import
../../../waku/incentivization/rpc, ../../../waku/incentivization/rpc
../../../waku/incentivization/rpc_codec
const DummyCodec* = "/vac/waku/dummy/0.0.1" const DummyCodec* = "/vac/waku/dummy/0.0.1"
@ -42,15 +42,6 @@ type
DummyProtocolResult* = Result[void, DummyProtocolError] DummyProtocolResult* = Result[void, DummyProtocolError]
proc genEligibilityProof*(startsWithOne: bool): EligibilityProof =
let byteSequence: seq[byte] = (
if startsWithOne:
@[1, 2, 3, 4, 5, 6, 7, 8]
else:
@[0, 2, 3, 4, 5, 6, 7, 8])
EligibilityProof(proofOfPayment: some(byteSequence))
proc genEligibilityStatus*(isEligible: bool): EligibilityStatus = proc genEligibilityStatus*(isEligible: bool): EligibilityStatus =
if isEligible: if isEligible:
EligibilityStatus( EligibilityStatus(
@ -60,24 +51,3 @@ proc genEligibilityStatus*(isEligible: bool): EligibilityStatus =
EligibilityStatus( EligibilityStatus(
statusCode: uint32(402), statusCode: uint32(402),
statusDesc: some("Payment Required")) statusDesc: some("Payment Required"))
proc genDummyRequestWithEligibilityProof*(proofValid: bool, requestId: string = ""): DummyRequest =
let eligibilityProof = genEligibilityProof(proofValid)
result.requestId = requestId
result.eligibilityProof = eligibilityProof
proc genDummyResponseWithEligibilityStatus*(proofValid: bool, requestId: string = ""): DummyResponse =
let eligibilityStatus = genEligibilityStatus(proofValid)
result.requestId = requestId
result.eligibilityStatus = eligibilityStatus
proc dummyEligibilityCriteriaMet(eligibilityProof: EligibilityProof): bool =
# a dummy criterion: the first element of the proof byte array equals 1
let proofOfPayment = eligibilityProof.proofOfPayment
if proofOfPayment.isSome:
return (proofOfPayment.get()[0] == 1)
else:
return false
proc isEligible*(eligibilityProof: EligibilityProof): bool =
dummyEligibilityCriteriaMet(eligibilityProof)

View File

@ -0,0 +1,26 @@
import
std/options,
std/strscans,
std/sequtils,
testutils/unittests,
chronicles,
chronos,
libp2p/crypto/crypto
import stew/results, libp2p/peerid
import
../../../waku/incentivization/rpc,
../../../waku/incentivization/rpc_codec,
../../../waku/incentivization/common,
../../../waku/incentivization/txid_proof
proc isEligible*(eligibilityProof: EligibilityProof): Future[bool] {.async.} =
result = await txidEligiblityCriteriaMet(eligibilityProof)
proc genDummyResponseWithEligibilityStatus*(proofValid: bool, requestId: string = ""): DummyResponse =
let eligibilityStatus = genEligibilityStatus(proofValid)
result.requestId = requestId
result.eligibilityStatus = eligibilityStatus

View File

@ -10,7 +10,8 @@ import
../waku_core, ../waku_core,
./common, ./common,
./rpc_codec, ./rpc_codec,
./rpc ./rpc,
./eligibility
logScope: logScope:
topics = "waku incentivization PoC" topics = "waku incentivization PoC"
@ -29,7 +30,7 @@ proc handleRequest*(
let dummyRequest = reqDecodeRes.get() let dummyRequest = reqDecodeRes.get()
let eligibilityProof = dummyRequest.eligibilityProof let eligibilityProof = dummyRequest.eligibilityProof
requestId = dummyRequest.requestId requestId = dummyRequest.requestId
isProofValid = isEligible(eligibilityProof) isProofValid = await isEligible(eligibilityProof)
let response = genDummyResponseWithEligibilityStatus(isProofValid, requestId) let response = genDummyResponseWithEligibilityStatus(isProofValid, requestId)
return response return response

View File

@ -0,0 +1,48 @@
import
std/options,
chronos,
web3,
stew/byteutils
import ../../../waku/incentivization/rpc
# a random confirmed txis (Sepolia)
const TxHashExisting* = TxHash.fromHex(
"0xc1be5f442d3688a8d3e4b5980a73f15e4351358e0f16e2fdd99c2517c9cf6270"
)
const TxHashNonExisting* = TxHash.fromHex(
"0x0000000000000000000000000000000000000000000000000000000000000000"
)
const EthClient = "https://sepolia.infura.io/v3/470c2e9a16f24057aee6660081729fb9"
proc genTxIdEligibilityProof*(txIdExists: bool): EligibilityProof =
let txHash: TxHash = (
if txIdExists:
TxHashExisting
else:
TxHashNonExisting)
let txHashAsBytes = @(txHash.bytes())
EligibilityProof(proofOfPayment: some(txHashAsBytes))
proc genDummyRequestWithTxIdEligibilityProof*(proofValid: bool, requestId: string = ""): DummyRequest =
let eligibilityProof = genTxIdEligibilityProof(proofValid)
result.requestId = requestId
result.eligibilityProof = eligibilityProof
proc checkTxIdExists(txHash: TxHash): Future[bool] {.async.} =
let web3 = await newWeb3(EthClient)
try:
discard await web3.provider.eth_getTransactionByHash(txHash)
result = true
except ValueError as e:
result = false
await web3.close()
result
proc txidEligiblityCriteriaMet*(eligibilityProof: EligibilityProof): Future[bool] {.async.} =
if eligibilityProof.proofOfPayment.isNone():
return false
let txHash = TxHash.fromHex(byteutils.toHex(eligibilityProof.proofOfPayment.get()))
let txExists = await checkTxIdExists(txHash)
return txExists