mirror of https://github.com/waku-org/nwaku.git
feat: add txid-based eligibility proof check for incentivization PoC (#2816)
This commit is contained in:
parent
23453cbc65
commit
a3668b0968
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue