Fabiana Cecin 6837ae0c1f
feat: bump nim-libp2p to v2.0.0 (#3929)
* bump nim-libp2p pin to v2.0.0 tag
* bump json_rpc to v0.6.1, lsquic to v0.5.1, boringssl to v0.0.8 (latest tags)
* add libp2p_mix dep; repoint libp2p/protocols/mix -> libp2p_mix
* pin nimble.lock: websock / protobuf_serialization / npeg / jwt
* Makefile: add -d:libp2p_quic_support
* regenerate nix/deps.nix (adds libp2p_mix, refreshes pins)
* migrate rng ref HmacDrbgContext -> libp2p Rng across prod/channels/tests (interface-only; same DRBG)
* waku_switch: TransportConfig factory; unified 2.0.0 connection limits (withMaxInOut, withMaxConnections); local MaxConnections
* waku_relay/rendezvous/discv5/kademlia: v2.0.0 API (rng, config, ServiceDiscovery rename)
* call Service.setup() on post-build switch services (2.0.0 split setup/start)
* drop libp2p/utils/semaphore -> chronos AsyncSemaphore
* add logos_delivery/waku/compat/option_valueor shim (Option[T] valueOr/withValue, dropped upstream)
* add std/options where a transitive re-export was removed
* add newStandardSwitch shim (libp2p removed it in 2.0.0); mounts yamux+mplex to match prod muxer
* PeerId.random(rng); common.rng()/crypto.newRng(); hoist shared rng (instantiation cleanup)
* update expectations for 2.0.0 defaults: DEFAULT_PROTOCOLS += /ipfs/id/push/1.0.0; agent "nim-libp2p"
* drop relay reboot/reconnect test (asserted a Switch restart capability that is simply not supported)
* fix up a few tests that were flaking on MacOS (libp2p upgrade may have exposed these)
2026-06-15 09:56:15 -03:00

96 lines
4.0 KiB
Nim

import logos_delivery/waku/compat/option_valueor
import std/[options, sets], chronos, web3, stew/byteutils, stint, results, chronicles
import logos_delivery/waku/incentivization/rpc, tests/waku_rln_relay/utils_onchain
const SimpleTransferGasUsed = Quantity(21000)
const TxReceiptQueryTimeout = 3.seconds
type EligibilityManager* = ref object # FIXME: make web3 private?
web3*: Web3
seenTxIds*: HashSet[TxHash]
# Initialize the eligibilityManager with a web3 instance
proc init*(
T: type EligibilityManager, ethClient: string
): Future[EligibilityManager] {.async.} =
return
EligibilityManager(web3: await newWeb3(ethClient), seenTxIds: initHashSet[TxHash]())
# TODO: handle error if web3 instance is not established
# Clean up the web3 instance
proc close*(eligibilityManager: EligibilityManager) {.async.} =
await eligibilityManager.web3.close()
proc getTransactionByHash(
eligibilityManager: EligibilityManager, txHash: TxHash
): Future[TransactionObject] {.async.} =
await eligibilityManager.web3.provider.eth_getTransactionByHash(txHash)
proc getMinedTransactionReceipt(
eligibilityManager: EligibilityManager, txHash: TxHash
): Future[Result[ReceiptObject, string]] {.async.} =
let txReceipt = eligibilityManager.web3.getMinedTransactionReceipt(txHash)
if (await txReceipt.withTimeout(TxReceiptQueryTimeout)):
return ok(txReceipt.value())
else:
return err("Timeout on tx receipt query, tx hash: " & $txHash)
proc getTxAndTxReceipt(
eligibilityManager: EligibilityManager, txHash: TxHash
): Future[Result[(TransactionObject, ReceiptObject), string]] {.async.} =
let tx = await eligibilityManager.getTransactionByHash(txHash)
let txReceipt = (await eligibilityManager.getMinedTransactionReceipt(txHash)).valueOr:
return err("Cannot get tx receipt: " & error)
return ok((tx, txReceipt))
proc isEligibleTxId*(
eligibilityManager: EligibilityManager,
eligibilityProof: EligibilityProof,
expectedToAddress: Address,
expectedValueWei: UInt256,
): Future[Result[void, string]] {.async.} =
## We consider a tx eligible,
## 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():
return err("Eligibility proof is empty")
var tx: TransactionObject
var txReceipt: ReceiptObject
let txHash = TxHash.fromHex(byteutils.toHex(eligibilityProof.proofOfPayment.get()))
# check that it is not a double-spend
let txHashWasSeen = (txHash in eligibilityManager.seenTxIds)
eligibilityManager.seenTxIds.incl(txHash)
if txHashWasSeen:
return err("TxHash " & $txHash & " was already checked (double-spend attempt)")
try:
let txAndTxReceipt = await eligibilityManager.getTxAndTxReceipt(txHash)
txAndTxReceipt.isOkOr:
return err("Failed to fetch tx or tx receipt")
(tx, txReceipt) = txAndTxReceipt.value()
except ValueError:
let errorMsg = "Failed to fetch tx or tx receipt: " & getCurrentExceptionMsg()
error "exception in isEligibleTxId", error = $errorMsg
return err($errorMsg)
# check that it is not a contract creation tx
let toAddressOption = txReceipt.to
if toAddressOption.isNone():
# this is a contract creation tx
return err("A contract creation tx is not eligible")
# check that it is a simple transfer (not a contract call)
# a simple transfer uses 21000 gas
let gasUsed = txReceipt.gasUsed
let isSimpleTransferTx = (gasUsed == SimpleTransferGasUsed)
if not isSimpleTransferTx:
return err("A contract call tx is not eligible")
# check that the to address is "as expected"
let toAddress = toAddressOption.get()
if toAddress != expectedToAddress:
return err("Wrong destination address: " & $toAddress)
# check that the amount is "as expected"
let txValueWei = tx.value
if txValueWei != expectedValueWei:
return err("Wrong tx value: got " & $txValueWei & ", expected " & $expectedValueWei)
return ok()