mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-03-14 16:43:10 +00:00
pass eligibilityEnabled as config parameter
This commit is contained in:
parent
5d3af6d3c3
commit
1e1d89ec93
@ -46,6 +46,10 @@ type
|
||||
#Rate limit configs for non-relay req-resp protocols
|
||||
rateLimitSettings: Option[seq[string]]
|
||||
|
||||
# Eligibility enabled
|
||||
# FIXME: is this the right way to propagate eligibility-related config items?
|
||||
eligibilityEnabled: bool
|
||||
|
||||
WakuNodeBuilderResult* = Result[void, string]
|
||||
|
||||
## Init
|
||||
@ -113,6 +117,7 @@ proc withPeerManagerConfig*(
|
||||
maxConnections: int,
|
||||
relayServiceRatio: string,
|
||||
shardAware = false,
|
||||
eligibilityEnabled = false,
|
||||
) =
|
||||
let (relayRatio, serviceRatio) = parseRelayServiceRatio(relayServiceRatio).get()
|
||||
var relayPeers = int(ceil(float(maxConnections) * relayRatio))
|
||||
@ -121,6 +126,7 @@ proc withPeerManagerConfig*(
|
||||
builder.maxServicePeers = servicePeers
|
||||
builder.maxRelayPeers = relayPeers
|
||||
builder.shardAware = shardAware
|
||||
builder.eligibilityEnabled = eligibilityEnabled
|
||||
|
||||
proc withColocationLimit*(builder: var WakuNodeBuilder, colocationLimit: int) =
|
||||
builder.colocationLimit = colocationLimit
|
||||
@ -206,7 +212,8 @@ proc build*(builder: WakuNodeBuilder): Result[WakuNode, string] =
|
||||
colocationLimit = builder.colocationLimit,
|
||||
shardedPeerManagement = builder.shardAware,
|
||||
dnsNameServers = netConfig.dnsNameServers,
|
||||
eligibilityEnabled = true, # FIXME: i13n: read config or something instead
|
||||
# FIXME: should eligibilityEnabled be part of some eligibilityConfig within WakuNodeBuilder here?
|
||||
eligibilityEnabled = builder.eligibilityEnabled
|
||||
#reputationEnabled = true, # FIXME: i13n: read config or something instead
|
||||
)
|
||||
|
||||
|
||||
60
waku/factory/conf_builder/eligibility_conf_builder.nim
Normal file
60
waku/factory/conf_builder/eligibility_conf_builder.nim
Normal file
@ -0,0 +1,60 @@
|
||||
import chronicles, std/options, results
|
||||
import ../waku_conf
|
||||
import eth/common as eth_common
|
||||
|
||||
logScope:
|
||||
topics = "waku conf builder eligibility"
|
||||
|
||||
type EligibilityConfBuilder* = object
|
||||
enabled*: Option[bool]
|
||||
receiverAddress*: Option[string]
|
||||
paymentAmountWei*: Option[uint32]
|
||||
ethClientUrls*: Option[seq[string]]
|
||||
|
||||
proc init*(T: type EligibilityConfBuilder): EligibilityConfBuilder =
|
||||
EligibilityConfBuilder()
|
||||
|
||||
proc withEnabled*(b: var EligibilityConfBuilder, enabled: bool) =
|
||||
b.enabled = some(enabled)
|
||||
|
||||
proc withReceiverAddress*(b: var EligibilityConfBuilder, receiverAddress: string) =
|
||||
b.receiverAddress = some(receiverAddress)
|
||||
|
||||
proc withPaymentAmountWei*(b: var EligibilityConfBuilder, amount: uint32) =
|
||||
b.paymentAmountWei = some(amount)
|
||||
|
||||
proc withEthClientUrls*(b: var EligibilityConfBuilder, urls: seq[string]) =
|
||||
b.ethClientUrls = some(urls)
|
||||
|
||||
proc build*(b: EligibilityConfBuilder): Result[Option[EligibilityConf], string] =
|
||||
if not b.enabled.get(false):
|
||||
debug "eligibility: EligibilityConf not enabled"
|
||||
return ok(none(EligibilityConf))
|
||||
|
||||
# Validation
|
||||
if b.receiverAddress.isNone() or b.paymentAmountWei.isNone():
|
||||
debug "eligibility: EligibilityConf validation failed - missing address or amount"
|
||||
return err("Eligibility: receiver address and payment amount must be specified")
|
||||
|
||||
# FIXME: add validation check that receiver address is validly formed
|
||||
|
||||
if b.paymentAmountWei.get() == 0:
|
||||
debug "eligibility: EligibilityConf validation failed - payment amount is zero"
|
||||
return err("Eligibility: payment amount must be above zero")
|
||||
|
||||
let urls = b.ethClientUrls.get(@[])
|
||||
if urls.len == 0:
|
||||
debug "eligibility: EligibilityConf validation failed - no eth rpc urls"
|
||||
return err("Eligibility: eligibility-eth-client-address is not specified")
|
||||
|
||||
debug "eligibility: EligibilityConf created"
|
||||
return ok(
|
||||
some(
|
||||
EligibilityConf(
|
||||
enabled: true,
|
||||
receiverAddress: b.receiverAddress.get(),
|
||||
paymentAmountWei: b.paymentAmountWei.get(),
|
||||
ethClientUrls: urls,
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -22,7 +22,8 @@ import
|
||||
./discv5_conf_builder,
|
||||
./web_socket_conf_builder,
|
||||
./metrics_server_conf_builder,
|
||||
./rln_relay_conf_builder
|
||||
./rln_relay_conf_builder,
|
||||
./eligibility_conf_builder
|
||||
|
||||
logScope:
|
||||
topics = "waku conf builder"
|
||||
@ -72,6 +73,7 @@ type WakuConfBuilder* = object
|
||||
rlnRelayConf*: RlnRelayConfBuilder
|
||||
storeServiceConf*: StoreServiceConfBuilder
|
||||
webSocketConf*: WebSocketConfBuilder
|
||||
eligibilityConf*: EligibilityConfBuilder
|
||||
# End conf builders
|
||||
relay: Option[bool]
|
||||
lightPush: Option[bool]
|
||||
@ -135,6 +137,7 @@ proc init*(T: type WakuConfBuilder): WakuConfBuilder =
|
||||
rlnRelayConf: RlnRelayConfBuilder.init(),
|
||||
storeServiceConf: StoreServiceConfBuilder.init(),
|
||||
webSocketConf: WebSocketConfBuilder.init(),
|
||||
eligibilityConf: EligibilityConfBuilder.init(),
|
||||
)
|
||||
|
||||
proc withClusterConf*(b: var WakuConfBuilder, clusterConf: ClusterConf) =
|
||||
@ -473,6 +476,9 @@ proc build*(
|
||||
|
||||
let webSocketConf = builder.webSocketConf.build().valueOr:
|
||||
return err("WebSocket Conf building failed: " & $error)
|
||||
|
||||
let eligibilityConf = builder.eligibilityConf.build().valueOr:
|
||||
return err("Eligibility Conf building failed: " & $error)
|
||||
# End - Build sub-configs
|
||||
|
||||
let logLevel =
|
||||
@ -596,6 +602,7 @@ proc build*(
|
||||
metricsServerConf: metricsServerConf,
|
||||
restServerConf: restServerConf,
|
||||
dnsDiscoveryConf: dnsDiscoveryConf,
|
||||
eligibilityConf: eligibilityConf,
|
||||
# end confs
|
||||
nodeKey: nodeKey,
|
||||
clusterId: clusterId,
|
||||
|
||||
@ -27,7 +27,8 @@ import
|
||||
../node/peer_manager,
|
||||
../waku_core/topics/pubsub_topic,
|
||||
../../tools/rln_keystore_generator/rln_keystore_generator,
|
||||
../../tools/rln_db_inspector/rln_db_inspector
|
||||
../../tools/rln_db_inspector/rln_db_inspector,
|
||||
./conf_builder/eligibility_conf_builder
|
||||
|
||||
include ../waku_core/message/default_values
|
||||
|
||||
@ -266,8 +267,8 @@ type WakuNodeConf* = object
|
||||
isRelayClient* {.
|
||||
desc:
|
||||
"""Set the node as a relay-client.
|
||||
Set it to true for nodes that run behind a NAT or firewall and
|
||||
hence would have reachability issues.""",
|
||||
Set it to true for nodes that run behind a NAT or firewall and
|
||||
hence would have reachability issues.""",
|
||||
defaultValue: false,
|
||||
name: "relay-client"
|
||||
.}: bool
|
||||
@ -489,12 +490,30 @@ hence would have reachability issues.""",
|
||||
## Eligibility config
|
||||
## Is eligibility check enabled or not
|
||||
eligibilityEnabled* {.
|
||||
desc:
|
||||
"Enable server-side eligibility (proof-of-payment) check for light protocols: true|false",
|
||||
desc: "Enable server-side eligibility (proof-of-payment) check for light protocols: true|false",
|
||||
defaultValue: false,
|
||||
name: "eligibility"
|
||||
name: "eligibility-enabled"
|
||||
.}: bool
|
||||
|
||||
## The expected blockchain address receiving payments for eligibility
|
||||
eligibilityReceiverAddress* {.
|
||||
desc: "Blockchain address receiving payment for eligibility from light protocol clients",
|
||||
defaultValue: "",
|
||||
name: "eligibility-receiver-address"
|
||||
.}: string
|
||||
|
||||
## The expected amount for eligibility payments
|
||||
eligibilityPaymentAmountWei* {.
|
||||
desc: "The expected payment amount from light protocol clients",
|
||||
defaultValue: 0,
|
||||
name: "eligibility-payment-amount-wei"
|
||||
.}: uint32
|
||||
|
||||
eligibilityEthRpcUrl* {.
|
||||
desc: "HTTP address of an Ethereum client for eligibility checks. Argument may be repeated.",
|
||||
defaultValue: @[EthRpcUrl("http://localhost:8540/")],
|
||||
name: "eligibility-eth-client-address"
|
||||
.}: seq[EthRpcUrl]
|
||||
|
||||
## Reliability config
|
||||
reliabilityEnabled* {.
|
||||
@ -1064,4 +1083,13 @@ proc toWakuConf*(n: WakuNodeConf): ConfResult[WakuConf] =
|
||||
|
||||
b.withRateLimits(n.rateLimits)
|
||||
|
||||
# Setup eligibility configuration
|
||||
b.eligibilityConf.withEnabled(n.eligibilityEnabled)
|
||||
if n.eligibilityReceiverAddress != "":
|
||||
b.eligibilityConf.withReceiverAddress(n.eligibilityReceiverAddress)
|
||||
if n.eligibilityPaymentAmountWei != 0:
|
||||
b.eligibilityConf.withPaymentAmountWei(n.eligibilityPaymentAmountWei)
|
||||
if n.eligibilityEthRpcUrl.len > 0:
|
||||
b.eligibilityConf.withEthClientUrls(n.eligibilityEthRpcUrl.mapIt(string(it)))
|
||||
|
||||
return b.build()
|
||||
|
||||
@ -109,6 +109,12 @@ proc initNode(
|
||||
)
|
||||
builder.withColocationLimit(conf.colocationLimit)
|
||||
|
||||
let eligibilityEnabled =
|
||||
if conf.eligibilityConf.isSome():
|
||||
conf.eligibilityConf.get().enabled
|
||||
else:
|
||||
false
|
||||
|
||||
if conf.maxRelayPeers.isSome():
|
||||
let
|
||||
maxRelayPeers = conf.maxRelayPeers.get()
|
||||
@ -117,10 +123,12 @@ proc initNode(
|
||||
relayRatio = (maxRelayPeers.float / maxConnections.float) * 100
|
||||
serviceRatio = 100 - relayRatio
|
||||
|
||||
# FIXME: DRY
|
||||
builder.withPeerManagerConfig(
|
||||
maxConnections = conf.maxConnections,
|
||||
relayServiceRatio = $relayRatio & ":" & $serviceRatio,
|
||||
shardAware = conf.relayShardedPeerManagement,
|
||||
eligibilityEnabled = eligibilityEnabled,
|
||||
)
|
||||
error "maxRelayPeers is deprecated. It is recommended to use relayServiceRatio instead. If relayServiceRatio is not set, it will be automatically calculated based on maxConnections and maxRelayPeers."
|
||||
else:
|
||||
@ -128,6 +136,7 @@ proc initNode(
|
||||
maxConnections = conf.maxConnections,
|
||||
relayServiceRatio = conf.relayServiceRatio,
|
||||
shardAware = conf.relayShardedPeerManagement,
|
||||
eligibilityEnabled = eligibilityEnabled,
|
||||
)
|
||||
builder.withRateLimit(conf.rateLimits)
|
||||
builder.withCircuitRelay(relay)
|
||||
|
||||
@ -58,6 +58,12 @@ type NetworkConfig* = object # TODO: make enum
|
||||
extMultiAddrs*: seq[MultiAddress]
|
||||
extMultiAddrsOnly*: bool
|
||||
|
||||
type EligibilityConf* = object
|
||||
enabled*: bool
|
||||
receiverAddress*: string
|
||||
paymentAmountWei*: uint32
|
||||
ethClientUrls*: seq[string]
|
||||
|
||||
## `WakuConf` is a valid configuration for a Waku node
|
||||
## All information needed by a waku node should be contained
|
||||
## In this object. A convenient `validate` method enables doing
|
||||
@ -93,6 +99,7 @@ type WakuConf* {.requiresInit.} = ref object
|
||||
restServerConf*: Option[RestServerConf]
|
||||
metricsServerConf*: Option[MetricsServerConf]
|
||||
webSocketConf*: Option[WebSocketConf]
|
||||
eligibilityConf*: Option[EligibilityConf]
|
||||
|
||||
portsShift*: uint16
|
||||
dnsAddrs*: bool
|
||||
@ -133,35 +140,39 @@ type WakuConf* {.requiresInit.} = ref object
|
||||
|
||||
p2pReliability*: bool
|
||||
|
||||
proc logConf*(conf: WakuConf) =
|
||||
proc logConf*(wakuConf: WakuConf) =
|
||||
info "Configuration: Enabled protocols",
|
||||
relay = conf.relay,
|
||||
rlnRelay = conf.rlnRelayConf.isSome(),
|
||||
store = conf.storeServiceConf.isSome(),
|
||||
filter = conf.filterServiceConf.isSome(),
|
||||
lightPush = conf.lightPush,
|
||||
peerExchange = conf.peerExchange
|
||||
relay = wakuConf.relay,
|
||||
rlnRelay = wakuConf.rlnRelayConf.isSome(),
|
||||
store = wakuConf.storeServiceConf.isSome(),
|
||||
filter = wakuConf.filterServiceConf.isSome(),
|
||||
lightPush = wakuConf.lightPush,
|
||||
peerExchange = wakuConf.peerExchange
|
||||
|
||||
info "Configuration. Network", cluster = conf.clusterId
|
||||
info "Configuration. Network", cluster = wakuConf.clusterId
|
||||
|
||||
for shard in conf.shards:
|
||||
for shard in wakuConf.shards:
|
||||
info "Configuration. Shards", shard = shard
|
||||
|
||||
if conf.discv5Conf.isSome():
|
||||
for i in conf.discv5Conf.get().bootstrapNodes:
|
||||
if wakuConf.discv5Conf.isSome():
|
||||
for i in wakuConf.discv5Conf.get().bootstrapNodes:
|
||||
info "Configuration. Bootstrap nodes", node = i.string
|
||||
|
||||
if conf.rlnRelayConf.isSome():
|
||||
var rlnRelayConf = conf.rlnRelayConf.get()
|
||||
if wakuConf.rlnRelayConf.isSome():
|
||||
var rlnRelayConf = wakuConf.rlnRelayConf.get()
|
||||
if rlnRelayConf.dynamic:
|
||||
info "Configuration. Validation",
|
||||
mechanism = "onchain rln",
|
||||
contract = rlnRelayConf.ethContractAddress.string,
|
||||
maxMessageSize = conf.maxMessageSizeBytes,
|
||||
maxMessageSize = wakuConf.maxMessageSizeBytes,
|
||||
rlnEpochSizeSec = rlnRelayConf.epochSizeSec,
|
||||
rlnRelayUserMessageLimit = rlnRelayConf.userMessageLimit,
|
||||
ethClientUrls = rlnRelayConf.ethClientUrls
|
||||
|
||||
if wakuConf.eligibilityConf.isSome():
|
||||
let ec = wakuConf.eligibilityConf.get()
|
||||
debug "eligibility: EligibilityConf created", enabled = ec.enabled, receiverAddress = $ec.receiverAddress, paymentAmountWei = ec.paymentAmountWei, ethClientUrls = ec.ethClientUrls
|
||||
|
||||
proc validateNodeKey(wakuConf: WakuConf): Result[void, string] =
|
||||
wakuConf.nodeKey.getPublicKey().isOkOr:
|
||||
return err("nodekey param is invalid")
|
||||
@ -240,4 +251,17 @@ proc validate*(wakuConf: WakuConf): Result[void, string] =
|
||||
?wakuConf.validateNodeKey()
|
||||
?wakuConf.validateShards()
|
||||
?wakuConf.validateNoEmptyStrings()
|
||||
|
||||
if wakuConf.eligibilityConf.isSome():
|
||||
let ec = wakuConf.eligibilityConf.get()
|
||||
debug "eligibility: EligibilityConf validation start"
|
||||
if ec.enabled:
|
||||
if not wakuConf.rlnRelayConf.isSome():
|
||||
debug "eligibility: EligibilityConf validation failed - RLN relay not enabled"
|
||||
return err("eligibility: RLN relay must be enabled if eligibility is enabled")
|
||||
if not wakuConf.lightPush:
|
||||
debug "eligibility: EligibilityConf validation failed - Lightpush not enabled"
|
||||
return err("eligibility: Lightpush must be enabled if eligibility is enabled")
|
||||
debug "eligibility: EligibilityConf validation successful"
|
||||
|
||||
return ok()
|
||||
|
||||
@ -1097,7 +1097,7 @@ proc legacyLightpushPublish*(
|
||||
except CatchableError:
|
||||
return err(getCurrentExceptionMsg())
|
||||
|
||||
# TODO: Move to application module (e.g., wakunode2.nim)
|
||||
# TODO: Move to application module (e.g, wakunode2.nim)
|
||||
proc legacyLightpushPublish*(
|
||||
node: WakuNode, pubsubTopic: Option[PubsubTopic], message: WakuMessage
|
||||
): Future[legacy_lightpush_protocol.WakuLightPushResult[string]] {.
|
||||
@ -1223,21 +1223,29 @@ proc lightpushPublish*(
|
||||
debug "eligibilityManager is enabled"
|
||||
var em = node.peerManager.eligibilityManager.get()
|
||||
# FIXME: where should I init eligibilityManager?
|
||||
# FIXME: extract values from... config parameters (which config?)
|
||||
# FIXME: how to reuse EthClient from CLI arguments?
|
||||
debug "initializing eligibilityManager..."
|
||||
let ethClient = "https://sepolia.infura.io/v3/470c2e9a16f24057aee6660081729fb9"
|
||||
em = await EligibilityManager.init(ethClient)
|
||||
debug "checking eligibilityProof..."
|
||||
let txNonExistent = TxHash.fromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
|
||||
let expectedToAddress = Address.fromHex("0xe8284Af9A5F3b0CD1334DBFaf512F09BeDA805a3")
|
||||
let expectedValueWei = 30000000000000.u256
|
||||
|
||||
let isEligible = await em.isEligibleTxId(
|
||||
eligibilityProof.get(), expectedToAddress, expectedValueWei
|
||||
)
|
||||
if isEligible.isErr():
|
||||
let msg = "Eligibility check failed!"
|
||||
#debug msg
|
||||
try:
|
||||
let ethClient = "https://sepolia.infura.io/v3/470c2e9a16f24057aee6660081729fb9"
|
||||
em = await EligibilityManager.init(ethClient)
|
||||
debug "checking eligibilityProof..."
|
||||
|
||||
# Check if eligibility proof is provided before accessing it
|
||||
if eligibilityProof.isNone():
|
||||
let msg = "Eligibility proof is required"
|
||||
return lighpushErrorResult(PAYMENT_REQUIRED, msg)
|
||||
|
||||
#let txNonExistent = TxHash.fromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
|
||||
let expectedToAddress = Address.fromHex("0xe8284Af9A5F3b0CD1334DBFaf512F09BeDA805a3")
|
||||
let expectedValueWei = 30000000000000.u256
|
||||
|
||||
let isEligible = await em.isEligibleTxId(
|
||||
eligibilityProof.get(), expectedToAddress, expectedValueWei
|
||||
)
|
||||
|
||||
except CatchableError:
|
||||
let msg = "Eligibility check threw exception: " & getCurrentExceptionMsg()
|
||||
return lighpushErrorResult(PAYMENT_REQUIRED, msg)
|
||||
|
||||
debug "Eligibility check passed!"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user