mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-07 16:33:08 +00:00
Added not key handling
This commit is contained in:
parent
82e0bf8cf5
commit
c78d92a131
248
tests/factory/test_waku_conf.nim
Normal file
248
tests/factory/test_waku_conf.nim
Normal file
@ -0,0 +1,248 @@
|
||||
{.used.}
|
||||
|
||||
import
|
||||
libp2p/crypto/[crypto, secp],
|
||||
nimcrypto/utils,
|
||||
std/[options, sequtils],
|
||||
results,
|
||||
testutils/unittests
|
||||
import
|
||||
waku/factory/waku_conf,
|
||||
waku/factory/networks_config,
|
||||
waku/common/utils/parse_size_units
|
||||
|
||||
suite "Waku Conf - build with cluster conf":
|
||||
test "Cluster Conf is passed and relay is enabled":
|
||||
## Setup
|
||||
let clusterConf = ClusterConf.TheWakuNetworkConf()
|
||||
var builder = WakuConfBuilder.init()
|
||||
# Mount all shards in network
|
||||
let expectedShards = toSeq[0.uint16 .. 7.uint16]
|
||||
|
||||
## Given
|
||||
builder.withRlnRelayEthClientAddress("https://my_eth_rpc_url/")
|
||||
builder.withClusterConf(clusterConf)
|
||||
builder.withRelay(true)
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
assert res.isOk(), $res.error
|
||||
|
||||
## Then
|
||||
let conf = res.get()
|
||||
assert conf.clusterId == clusterConf.clusterId
|
||||
assert conf.numShardsInNetwork == clusterConf.numShardsInNetwork
|
||||
assert conf.shards == expectedShards
|
||||
assert conf.maxMessageSizeBytes ==
|
||||
int(parseCorrectMsgSize(clusterConf.maxMessageSize))
|
||||
|
||||
assert conf.discv5BootstrapNodes.map(
|
||||
proc(e: TextEnr): string =
|
||||
e.string
|
||||
) == clusterConf.discv5BootstrapNodes
|
||||
|
||||
if clusterConf.rlnRelay:
|
||||
assert conf.rlnRelayConf.isSome
|
||||
|
||||
let rlnRelayConf = conf.rlnRelayConf.get()
|
||||
assert rlnRelayConf.rlnRelayEthContractAddress.string ==
|
||||
clusterConf.rlnRelayEthContractAddress
|
||||
assert rlnRelayConf.rlnRelayDynamic == clusterConf.rlnRelayDynamic
|
||||
assert rlnRelayConf.rlnRelayChainId == clusterConf.rlnRelayChainId
|
||||
assert rlnRelayConf.rlnRelayBandwidthThreshold ==
|
||||
clusterConf.rlnRelayBandwidthThreshold
|
||||
assert rlnRelayConf.rlnEpochSizeSec == clusterConf.rlnEpochSizeSec
|
||||
assert rlnRelayConf.rlnRelayUserMessageLimit ==
|
||||
clusterConf.rlnRelayUserMessageLimit
|
||||
|
||||
test "Cluster Conf is passed, but relay is disabled":
|
||||
## Setup
|
||||
let clusterConf = ClusterConf.TheWakuNetworkConf()
|
||||
var builder = WakuConfBuilder.init()
|
||||
|
||||
let # Mount all shards in network
|
||||
expectedShards = toSeq[0.uint16 .. 7.uint16]
|
||||
|
||||
## Given
|
||||
builder.withRlnRelayEthClientAddress("https://my_eth_rpc_url/")
|
||||
builder.withClusterConf(clusterConf)
|
||||
builder.withRelay(false)
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
assert res.isOk(), $res.error
|
||||
|
||||
## Then
|
||||
let conf = res.get()
|
||||
assert conf.clusterId == clusterConf.clusterId
|
||||
assert conf.numShardsInNetwork == clusterConf.numShardsInNetwork
|
||||
assert conf.shards == expectedShards
|
||||
assert conf.maxMessageSizeBytes ==
|
||||
int(parseCorrectMsgSize(clusterConf.maxMessageSize))
|
||||
assert conf.discv5BootstrapNodes.map(
|
||||
proc(e: TextEnr): string =
|
||||
e.string
|
||||
) == clusterConf.discv5BootstrapNodes
|
||||
|
||||
assert conf.rlnRelayConf.isNone
|
||||
|
||||
test "Cluster Conf is passed, but rln relay is disabled":
|
||||
## Setup
|
||||
let clusterConf = ClusterConf.TheWakuNetworkConf()
|
||||
var builder = WakuConfBuilder.init()
|
||||
|
||||
let # Mount all shards in network
|
||||
expectedShards = toSeq[0.uint16 .. 7.uint16]
|
||||
|
||||
## Given
|
||||
builder.withRlnRelayEthClientAddress("https://my_eth_rpc_url/")
|
||||
builder.withClusterConf(clusterConf)
|
||||
builder.withRlnRelay(false)
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
assert res.isOk(), $res.error
|
||||
|
||||
## Then
|
||||
let conf = res.get()
|
||||
assert conf.clusterId == clusterConf.clusterId
|
||||
assert conf.numShardsInNetwork == clusterConf.numShardsInNetwork
|
||||
assert conf.shards == expectedShards
|
||||
assert conf.maxMessageSizeBytes ==
|
||||
int(parseCorrectMsgSize(clusterConf.maxMessageSize))
|
||||
assert conf.discv5BootstrapNodes.map(
|
||||
proc(e: TextEnr): string =
|
||||
e.string
|
||||
) == clusterConf.discv5BootstrapNodes
|
||||
|
||||
assert conf.rlnRelayConf.isNone
|
||||
|
||||
test "Cluster Conf is passed and valid shards are specified":
|
||||
## Setup
|
||||
let clusterConf = ClusterConf.TheWakuNetworkConf()
|
||||
var builder = WakuConfBuilder.init()
|
||||
let shards = @[2.uint16, 3.uint16]
|
||||
|
||||
## Given
|
||||
builder.withRlnRelayEthClientAddress("https://my_eth_rpc_url/")
|
||||
builder.withClusterConf(clusterConf)
|
||||
builder.withShards(shards)
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
assert res.isOk(), $res.error
|
||||
|
||||
## Then
|
||||
let conf = res.get()
|
||||
assert conf.clusterId == clusterConf.clusterId
|
||||
assert conf.numShardsInNetwork == clusterConf.numShardsInNetwork
|
||||
assert conf.shards == shards
|
||||
assert conf.maxMessageSizeBytes ==
|
||||
int(parseCorrectMsgSize(clusterConf.maxMessageSize))
|
||||
assert conf.discv5BootstrapNodes.map(
|
||||
proc(e: TextEnr): string =
|
||||
e.string
|
||||
) == clusterConf.discv5BootstrapNodes
|
||||
|
||||
test "Cluster Conf is passed and invalid shards are specified":
|
||||
## Setup
|
||||
let clusterConf = ClusterConf.TheWakuNetworkConf()
|
||||
var builder = WakuConfBuilder.init()
|
||||
let shards = @[2.uint16, 10.uint16]
|
||||
|
||||
## Given
|
||||
builder.withRlnRelayEthClientAddress("https://my_eth_rpc_url/")
|
||||
builder.withClusterConf(clusterConf)
|
||||
builder.withShards(shards)
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
|
||||
## Then
|
||||
assert res.isErr(), "Invalid shard was accepted"
|
||||
|
||||
test "Cluster Conf is passed and RLN contract is overridden":
|
||||
## Setup
|
||||
let clusterConf = ClusterConf.TheWakuNetworkConf()
|
||||
var builder = WakuConfBuilder.init()
|
||||
# Mount all shards in network
|
||||
let expectedShards = toSeq[0.uint16 .. 7.uint16]
|
||||
let contractAddress = "0x0123456789ABCDEF"
|
||||
|
||||
## Given
|
||||
builder.withRlnRelayEthClientAddress("https://my_eth_rpc_url/")
|
||||
builder.withRlnRelayEthContractAddress(contractAddress)
|
||||
builder.withClusterConf(clusterConf)
|
||||
builder.withRelay(true)
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
assert res.isOk(), $res.error
|
||||
|
||||
## Then
|
||||
let conf = res.get()
|
||||
assert conf.clusterId == clusterConf.clusterId
|
||||
assert conf.numShardsInNetwork == clusterConf.numShardsInNetwork
|
||||
assert conf.shards == expectedShards
|
||||
assert conf.maxMessageSizeBytes ==
|
||||
int(parseCorrectMsgSize(clusterConf.maxMessageSize))
|
||||
|
||||
assert conf.discv5BootstrapNodes.map(
|
||||
proc(e: TextEnr): string =
|
||||
e.string
|
||||
) == clusterConf.discv5BootstrapNodes
|
||||
|
||||
if clusterConf.rlnRelay:
|
||||
assert conf.rlnRelayConf.isSome
|
||||
|
||||
let rlnRelayConf = conf.rlnRelayConf.get()
|
||||
assert rlnRelayConf.rlnRelayEthContractAddress.string == contractAddress
|
||||
assert rlnRelayConf.rlnRelayDynamic == clusterConf.rlnRelayDynamic
|
||||
assert rlnRelayConf.rlnRelayChainId == clusterConf.rlnRelayChainId
|
||||
assert rlnRelayConf.rlnRelayBandwidthThreshold ==
|
||||
clusterConf.rlnRelayBandwidthThreshold
|
||||
assert rlnRelayConf.rlnEpochSizeSec == clusterConf.rlnEpochSizeSec
|
||||
assert rlnRelayConf.rlnRelayUserMessageLimit ==
|
||||
clusterConf.rlnRelayUserMessageLimit
|
||||
|
||||
suite "Waku Conf - node key":
|
||||
test "Node key is generated":
|
||||
## Setup
|
||||
var builder = WakuConfBuilder.init()
|
||||
builder.withClusterId(1)
|
||||
builder.withMaxMessageSizeBytes(1)
|
||||
|
||||
## Given
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
assert res.isOk(), $res.error
|
||||
let conf = res.get()
|
||||
|
||||
## Then
|
||||
let pubkey = getPublicKey(conf.nodeKey)
|
||||
assert pubkey.isOk()
|
||||
|
||||
test "Passed node key is used":
|
||||
## Setup
|
||||
let nodeKeyStr =
|
||||
"0011223344556677889900aabbccddeeff0011223344556677889900aabbccddeeff"
|
||||
let nodeKey = block:
|
||||
let key = SkPrivateKey.init(utils.fromHex(nodeKeyStr)).tryGet()
|
||||
crypto.PrivateKey(scheme: Secp256k1, skkey: key)
|
||||
var builder = WakuConfBuilder.init()
|
||||
builder.withClusterId(1)
|
||||
builder.withMaxMessageSizeBytes(1)
|
||||
|
||||
## Given
|
||||
builder.withNodeKey(nodeKey)
|
||||
|
||||
## When
|
||||
let res = builder.build()
|
||||
assert res.isOk(), $res.error
|
||||
let conf = res.get()
|
||||
|
||||
## Then
|
||||
assert utils.toHex(conf.nodeKey.getRawBytes().get()) ==
|
||||
utils.toHex(nodeKey.getRawBytes().get()),
|
||||
"Passed node key isn't in config:" & $nodeKey & $conf.nodeKey
|
||||
@ -13,7 +13,8 @@ import
|
||||
../waku_enr/capabilities,
|
||||
../waku_enr,
|
||||
../waku_core,
|
||||
./networks_config
|
||||
./networks_config,
|
||||
./waku_conf
|
||||
|
||||
proc enrConfiguration*(
|
||||
conf: WakuNodeConf, netConfig: NetConfig, key: crypto.PrivateKey
|
||||
@ -159,41 +160,25 @@ proc networkConfiguration*(conf: WakuNodeConf, clientId: string): NetConfigResul
|
||||
|
||||
return netConfigRes
|
||||
|
||||
proc applyPresetConfiguration*(srcConf: WakuNodeConf): Result[WakuNodeConf, string] =
|
||||
var resConf = srcConf
|
||||
proc applyPresetConfiguration*(
|
||||
srcConf: WakuNodeConf, wakuConfBuilder: var WakuConfBuilder
|
||||
): void =
|
||||
var preset = srcConf.preset
|
||||
|
||||
if resConf.clusterId == 1:
|
||||
if srcConf.clusterId == 1:
|
||||
warn(
|
||||
"TWN - The Waku Network configuration will not be applied when `--cluster-id=1` is passed in future releases. Use `--preset=twn` instead."
|
||||
)
|
||||
resConf.preset = "twn"
|
||||
preset = "twn"
|
||||
|
||||
case toLowerAscii(resConf.preset)
|
||||
case toLowerAscii(preset)
|
||||
of "twn":
|
||||
let twnClusterConf = ClusterConf.TheWakuNetworkConf()
|
||||
|
||||
# Override configuration
|
||||
resConf.maxMessageSize = twnClusterConf.maxMessageSize
|
||||
resConf.clusterId = twnClusterConf.clusterId
|
||||
resConf.rlnRelay = twnClusterConf.rlnRelay
|
||||
resConf.rlnRelayEthContractAddress = twnClusterConf.rlnRelayEthContractAddress
|
||||
resConf.rlnRelayChainId = twnClusterConf.rlnRelayChainId
|
||||
resConf.rlnRelayDynamic = twnClusterConf.rlnRelayDynamic
|
||||
resConf.rlnRelayBandwidthThreshold = twnClusterConf.rlnRelayBandwidthThreshold
|
||||
resConf.discv5Discovery = twnClusterConf.discv5Discovery
|
||||
resConf.discv5BootstrapNodes =
|
||||
resConf.discv5BootstrapNodes & twnClusterConf.discv5BootstrapNodes
|
||||
resConf.rlnEpochSizeSec = twnClusterConf.rlnEpochSizeSec
|
||||
resConf.rlnRelayUserMessageLimit = twnClusterConf.rlnRelayUserMessageLimit
|
||||
resConf.numShardsInNetwork = twnClusterConf.numShardsInNetwork
|
||||
|
||||
if resConf.relay:
|
||||
resConf.rlnRelay = twnClusterConf.rlnRelay
|
||||
wakuConfBuilder.withClusterConf(twnClusterConf)
|
||||
else:
|
||||
discard
|
||||
|
||||
return ok(resConf)
|
||||
|
||||
# TODO: numShardsInNetwork should be mandatory with autosharding, and unneeded otherwise
|
||||
proc getNumShardsInNetwork*(conf: WakuNodeConf): uint32 =
|
||||
if conf.numShardsInNetwork != 0:
|
||||
@ -201,28 +186,3 @@ proc getNumShardsInNetwork*(conf: WakuNodeConf): uint32 =
|
||||
# If conf.numShardsInNetwork is not set, use 1024 - the maximum possible as per the static sharding spec
|
||||
# https://github.com/waku-org/specs/blob/master/standards/core/relay-sharding.md#static-sharding
|
||||
return uint32(MaxShardIndex + 1)
|
||||
|
||||
proc validateShards*(conf: WakuNodeConf): Result[void, string] =
|
||||
let numShardsInNetwork = getNumShardsInNetwork(conf)
|
||||
|
||||
for shard in conf.shards:
|
||||
if shard >= numShardsInNetwork:
|
||||
let msg =
|
||||
"validateShards invalid shard: " & $shard & " when numShardsInNetwork: " &
|
||||
$numShardsInNetwork # fmt doesn't work
|
||||
error "validateShards failed", error = msg
|
||||
return err(msg)
|
||||
|
||||
return ok()
|
||||
|
||||
proc getNodeKey*(
|
||||
conf: WakuNodeConf, rng: ref HmacDrbgContext = crypto.newRng()
|
||||
): Result[PrivateKey, string] =
|
||||
if conf.nodekey.isSome():
|
||||
return ok(conf.nodekey.get())
|
||||
|
||||
warn "missing node key, generating new set"
|
||||
let key = crypto.PrivateKey.random(Secp256k1, rng[]).valueOr:
|
||||
error "Failed to generate key", error = error
|
||||
return err("Failed to generate key: " & $error)
|
||||
return ok(key)
|
||||
|
||||
@ -145,28 +145,18 @@ proc setupAppCallbacks(
|
||||
return ok()
|
||||
|
||||
proc new*(
|
||||
T: type Waku, wakuConf: var WakuConf, appCallbacks: AppCallbacks = nil
|
||||
T: type Waku, wakuNodeConf: WakuNodeConf, appCallbacks: AppCallbacks = nil
|
||||
): Result[Waku, string] =
|
||||
let rng = crypto.newRng()
|
||||
|
||||
logging.setupLog(wakuConf.logLevel, wakuConf.logFormat)
|
||||
logging.setupLog(wakuNodeConf.logLevel, wakuNodeConf.logFormat)
|
||||
|
||||
confCopy = block:
|
||||
let res = applyPresetConfiguration(confCopy)
|
||||
if res.isErr():
|
||||
error "Failed to complete the config", error = res.error
|
||||
return err("Failed to complete the config:" & $res.error)
|
||||
res.get()
|
||||
var confBuilder = WakuConfBuilder.init()
|
||||
|
||||
wakuConf.log()
|
||||
applyPresetConfiguration(wakuNodeConf, confBuilder)
|
||||
|
||||
info "Running nwaku node", version = git_version
|
||||
|
||||
let validateShardsRes = validateShards(confCopy)
|
||||
if validateShardsRes.isErr():
|
||||
error "Failed validating shards", error = $validateShardsRes.error
|
||||
return err("Failed validating shards: " & $validateShardsRes.error)
|
||||
|
||||
let keyRes = getNodeKey(confCopy, rng)
|
||||
if keyRes.isErr():
|
||||
error "Failed to generate key", error = $keyRes.error
|
||||
|
||||
453
waku/factory/waku_conf.nim
Normal file
453
waku/factory/waku_conf.nim
Normal file
@ -0,0 +1,453 @@
|
||||
import std/[options, sequtils], chronicles, libp2p/crypto/crypto, results
|
||||
|
||||
import ../common/logging, ../common/utils/parse_size_units
|
||||
|
||||
import waku/factory/networks_config
|
||||
|
||||
logScope:
|
||||
topics = "wakunode conf"
|
||||
|
||||
type
|
||||
TextEnr* = distinct string
|
||||
ContractAddress* = distinct string
|
||||
EthRpcUrl* = distinct string
|
||||
|
||||
# TODO: this should come from RLN relay module
|
||||
type RlnRelayConf* = ref object
|
||||
rlnRelayEthContractAddress*: ContractAddress
|
||||
rlnRelayChainId*: uint
|
||||
rlnRelayDynamic*: bool
|
||||
rlnRelayBandwidthThreshold*: int
|
||||
rlnEpochSizeSec*: uint64
|
||||
rlnRelayUserMessageLimit*: uint64
|
||||
rlnRelayEthClientAddress*: EthRpcUrl
|
||||
|
||||
type WakuConf* = ref object
|
||||
nodeKey*: PrivateKey
|
||||
|
||||
clusterId*: uint16
|
||||
numShardsInNetwork*: uint32
|
||||
shards*: seq[uint16]
|
||||
|
||||
relay*: bool
|
||||
store*: bool
|
||||
filter*: bool
|
||||
lightPush*: bool
|
||||
peerExchange*: bool
|
||||
|
||||
discv5BootstrapNodes*: seq[TextEnr]
|
||||
|
||||
rlnRelayConf*: Option[RlnRelayConf]
|
||||
|
||||
maxMessageSizeBytes*: int
|
||||
|
||||
logLevel*: logging.LogLevel
|
||||
logFormat*: logging.LogFormat
|
||||
|
||||
proc log*(conf: WakuConf) =
|
||||
info "Configuration: Enabled protocols",
|
||||
relay = conf.relay,
|
||||
rlnRelay = conf.rlnRelayConf.isSome,
|
||||
store = conf.store,
|
||||
filter = conf.filter,
|
||||
lightPush = conf.lightPush,
|
||||
peerExchange = conf.peerExchange
|
||||
|
||||
info "Configuration. Network", cluster = conf.clusterId
|
||||
|
||||
for shard in conf.shards:
|
||||
info "Configuration. Shards", shard = shard
|
||||
|
||||
for i in conf.discv5BootstrapNodes:
|
||||
info "Configuration. Bootstrap nodes", node = i.string
|
||||
|
||||
if conf.rlnRelayConf.isSome:
|
||||
var rlnRelayConf = conf.rlnRelayConf.geT()
|
||||
if rlnRelayConf.rlnRelayDynamic:
|
||||
info "Configuration. Validation",
|
||||
mechanism = "onchain rln",
|
||||
contract = rlnRelayConf.rlnRelayEthContractAddress.string,
|
||||
maxMessageSize = conf.maxMessageSizeBytes,
|
||||
rlnEpochSizeSec = rlnRelayConf.rlnEpochSizeSec,
|
||||
rlnRelayUserMessageLimit = rlnRelayConf.rlnRelayUserMessageLimit,
|
||||
rlnRelayEthClientAddress = string(rlnRelayConf.rlnRelayEthClientAddress)
|
||||
|
||||
type RlnRelayConfBuilder = ref object
|
||||
rlnRelay: Option[bool]
|
||||
rlnRelayEthContractAddress: Option[ContractAddress]
|
||||
rlnRelayChainId: Option[uint]
|
||||
rlnRelayDynamic: Option[bool]
|
||||
rlnRelayBandwidthThreshold: Option[int]
|
||||
rlnEpochSizeSec: Option[uint64]
|
||||
rlnRelayUserMessageLimit: Option[uint64]
|
||||
rlnRelayEthClientAddress: Option[EthRpcUrl]
|
||||
|
||||
proc init(T: type RlnRelayConfBuilder): RlnRelayConfBuilder =
|
||||
RlnRelayConfBuilder()
|
||||
|
||||
proc withRlnRelay(builder: var RlnRelayConfBuilder, rlnRelay: bool) =
|
||||
builder.rlnRelay = some(rlnRelay)
|
||||
|
||||
proc withRlnRelayEthClientAddress(
|
||||
builder: var RlnRelayConfBuilder, rlnRelayEthClientAddress: EthRpcUrl
|
||||
) =
|
||||
builder.rlnRelayEthClientAddress = some(rlnRelayEthClientAddress)
|
||||
|
||||
proc withRlnRelayEthContractAddress(
|
||||
builder: var RlnRelayConfBuilder, withRlnRelayEthContractAddress: ContractAddress
|
||||
) =
|
||||
builder.rlnRelayEthContractAddress = some(withRlnRelayEthContractAddress)
|
||||
|
||||
proc build(builder: RlnRelayConfBuilder): Result[Option[RlnRelayConf], string] =
|
||||
if builder.rlnRelay.isNone or not builder.rlnRelay.get():
|
||||
info "RLN Relay is disabled"
|
||||
return ok(none(RlnRelayConf))
|
||||
|
||||
let rlnRelayEthContractAddress =
|
||||
if builder.rlnRelayEthContractAddress.isSome:
|
||||
builder.rlnRelayEthContractAddress.get()
|
||||
else:
|
||||
return err("RLN Eth Contract Address was not specified")
|
||||
|
||||
let rlnRelayChainId =
|
||||
if builder.rlnRelayChainId.isSome:
|
||||
builder.rlnRelayChainId.get()
|
||||
else:
|
||||
return err("RLN Relay Chain Id was not specified")
|
||||
|
||||
let rlnRelayDynamic =
|
||||
if builder.rlnRelayDynamic.isSome:
|
||||
builder.rlnRelayDynamic.get()
|
||||
else:
|
||||
return err("RLN Relay Dynamic was not specified")
|
||||
|
||||
let rlnRelayBandwidthThreshold =
|
||||
if builder.rlnRelayBandwidthThreshold.isSome:
|
||||
builder.rlnRelayBandwidthThreshold.get()
|
||||
else:
|
||||
return err("RLN Relay Bandwidth Threshold was not specified")
|
||||
|
||||
let rlnEpochSizeSec =
|
||||
if builder.rlnEpochSizeSec.isSome:
|
||||
builder.rlnEpochSizeSec.get()
|
||||
else:
|
||||
return err("RLN Epoch Size was not specified")
|
||||
|
||||
let rlnRelayUserMessageLimit =
|
||||
if builder.rlnRelayUserMessageLimit.isSome:
|
||||
builder.rlnRelayUserMessageLimit.get()
|
||||
else:
|
||||
return err("RLN Relay User Message Limit was not specified")
|
||||
|
||||
let rlnRelayEthClientAddress =
|
||||
if builder.rlnRelayEthClientAddress.isSome:
|
||||
builder.rlnRelayEthClientAddress.get()
|
||||
else:
|
||||
return err("RLN Relay Eth Client Address was not specified")
|
||||
|
||||
return ok(
|
||||
some(
|
||||
RlnRelayConf(
|
||||
rlnRelayChainId: rlnRelayChainId,
|
||||
rlnRelayDynamic: rlnRelayDynamic,
|
||||
rlnRelayEthContractAddress: rlnRelayEthContractAddress,
|
||||
rlnEpochSizeSec: rlnEpochSizeSec,
|
||||
rlnRelayUserMessageLimit: rlnRelayUserMessageLimit,
|
||||
rlnRelayEthClientAddress: rlnRelayEthClientAddress,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
type WakuConfBuilder* = ref object
|
||||
nodeKey*: Option[PrivateKey]
|
||||
|
||||
clusterId: Option[uint16]
|
||||
numShardsInNetwork: Option[uint32]
|
||||
shards: Option[seq[uint16]]
|
||||
|
||||
relay: Option[bool]
|
||||
store: Option[bool]
|
||||
filter: Option[bool]
|
||||
lightPush: Option[bool]
|
||||
peerExchange: Option[bool]
|
||||
|
||||
clusterConf: Option[ClusterConf]
|
||||
|
||||
rlnRelayConf: RlnRelayConfBuilder
|
||||
|
||||
maxMessageSizeBytes: Option[int]
|
||||
|
||||
discv5Discovery: Option[bool]
|
||||
discv5BootstrapNodes: Option[seq[TextEnr]]
|
||||
|
||||
logLevel: Option[logging.LogLevel]
|
||||
logFormat: Option[logging.LogFormat]
|
||||
|
||||
proc init*(T: type WakuConfBuilder): WakuConfBuilder =
|
||||
WakuConfBuilder(rlnRelayConf: RlnRelayConfBuilder.init())
|
||||
|
||||
proc withClusterConf*(builder: var WakuConfBuilder, clusterConf: ClusterConf) =
|
||||
builder.clusterConf = some(clusterConf)
|
||||
|
||||
proc withNodeKey*(builder: var WakuConfBuilder, nodeKey: PrivateKey) =
|
||||
builder.nodeKey = some(nodeKey)
|
||||
|
||||
proc withClusterId*(builder: var WakuConfBuilder, clusterId: uint16) =
|
||||
builder.clusterid = some(clusterId)
|
||||
|
||||
proc withShards*(builder: var WakuConfBuilder, shards: seq[uint16]) =
|
||||
builder.shards = some(shards)
|
||||
|
||||
proc withRelay*(builder: var WakuConfBuilder, relay: bool) =
|
||||
builder.relay = some(relay)
|
||||
|
||||
proc withRlnRelay*(builder: var WakuConfBuilder, rlnRelay: bool) =
|
||||
builder.rlnRelayConf.withRlnRelay(rlnRelay)
|
||||
|
||||
proc withRlnRelayEthClientAddress*(
|
||||
builder: var WakuConfBuilder, rlnRelayEthClientAddress: string
|
||||
) =
|
||||
builder.rlnRelayConf.withRlnRelayEthClientAddress(rlnRelayEthClientAddress.EthRpcUrl)
|
||||
|
||||
proc withRlnRelayEthContractAddress*(
|
||||
builder: var WakuConfBuilder, rlnRelayEthContractAddress: string
|
||||
) =
|
||||
builder.rlnRelayConf.withRlnRelayEthContractAddress(
|
||||
rlnRelayEthContractAddress.ContractAddress
|
||||
)
|
||||
|
||||
proc withMaxMessageSizeBytes*(builder: WakuConfBuilder, maxMessageSizeBytes: int) =
|
||||
builder.maxMessageSizeBytes = some(maxMessageSizeBytes)
|
||||
|
||||
proc validateShards*(wakuConf: WakuConf): Result[void, string] =
|
||||
let numShardsInNetwork = wakuConf.numShardsInNetwork
|
||||
|
||||
for shard in wakuConf.shards:
|
||||
if shard >= numShardsInNetwork:
|
||||
let msg =
|
||||
"validateShards invalid shard: " & $shard & " when numShardsInNetwork: " &
|
||||
$numShardsInNetwork # fmt doesn't work
|
||||
error "validateShards failed", error = msg
|
||||
return err(msg)
|
||||
|
||||
return ok()
|
||||
|
||||
proc validate(wakuConf: WakuConf): Result[void, string] =
|
||||
?validateShards(wakuConf)
|
||||
|
||||
return ok()
|
||||
|
||||
proc nodeKey(
|
||||
builder: WakuConfBuilder, rng: ref HmacDrbgContext
|
||||
): Result[PrivateKey, string] =
|
||||
if builder.nodeKey.isSome():
|
||||
return ok(builder.nodeKey.get())
|
||||
else:
|
||||
warn "missing node key, generating new set"
|
||||
let nodeKey = crypto.PrivateKey.random(Secp256k1, rng[]).valueOr:
|
||||
error "Failed to generate key", error = error
|
||||
return err("Failed to generate key: " & $error)
|
||||
return ok(nodeKey)
|
||||
|
||||
proc build*(
|
||||
builder: var WakuConfBuilder, rng: ref HmacDrbgContext = crypto.newRng()
|
||||
): Result[WakuConf, string] =
|
||||
## Return a WakuConf that contains all mandatory parameters
|
||||
## Applies some sane defaults that are applicable across any usage
|
||||
## of libwaku. It aims to be agnostic so it does not apply a
|
||||
## default when it is opinionated.
|
||||
|
||||
let nodeKey = ?nodeKey(builder, rng)
|
||||
|
||||
let relay =
|
||||
if builder.relay.isSome:
|
||||
builder.relay.get()
|
||||
else:
|
||||
warn "whether to mount relay is not specified, defaulting to not mounting"
|
||||
false
|
||||
|
||||
let store =
|
||||
if builder.store.isSome:
|
||||
builder.store.get()
|
||||
else:
|
||||
warn "whether to mount store is not specified, defaulting to not mounting"
|
||||
false
|
||||
|
||||
let filter =
|
||||
if builder.filter.isSome:
|
||||
builder.filter.get()
|
||||
else:
|
||||
warn "whether to mount filter is not specified, defaulting to not mounting"
|
||||
false
|
||||
|
||||
let lightPush =
|
||||
if builder.lightPush.isSome:
|
||||
builder.lightPush.get()
|
||||
else:
|
||||
warn "whether to mount lightPush is not specified, defaulting to not mounting"
|
||||
false
|
||||
|
||||
let peerExchange =
|
||||
if builder.peerExchange.isSome:
|
||||
builder.peerExchange.get()
|
||||
else:
|
||||
warn "whether to mount peerExchange is not specified, defaulting to not mounting"
|
||||
false
|
||||
|
||||
# Apply cluster conf - values passed manually override cluster conf
|
||||
if builder.clusterConf.isSome:
|
||||
var clusterConf = builder.clusterConf.get()
|
||||
|
||||
if builder.clusterId.isNone:
|
||||
builder.clusterId = some(clusterConf.clusterId)
|
||||
else:
|
||||
warn "Cluster id was manually provided alongside a cluster conf",
|
||||
used = builder.clusterId, discarded = clusterConf.clusterId
|
||||
|
||||
if relay and clusterConf.rlnRelay:
|
||||
var rlnRelayConf = builder.rlnRelayConf
|
||||
|
||||
if rlnRelayConf.rlnRelay.isNone:
|
||||
rlnRelayConf.rlnRelay = some(true)
|
||||
else:
|
||||
warn "RLN Relay was manually provided alongside a cluster conf",
|
||||
used = rlnRelayConf.rlnRelay, discarded = clusterConf.rlnRelay
|
||||
|
||||
if rlnRelayConf.rlnRelayEthContractAddress.isNone:
|
||||
rlnRelayConf.rlnRelayEthContractAddress =
|
||||
some(clusterConf.rlnRelayEthContractAddress.ContractAddress)
|
||||
else:
|
||||
warn "RLN Relay ETH Contract Address was manually provided alongside a cluster conf",
|
||||
used = rlnRelayConf.rlnRelayEthContractAddress.get().string,
|
||||
discarded = clusterConf.rlnRelayEthContractAddress.string
|
||||
|
||||
if rlnRelayConf.rlnRelayChainId.isNone:
|
||||
rlnRelayConf.rlnRelayChainId = some(clusterConf.rlnRelayChainId)
|
||||
else:
|
||||
warn "RLN Relay Chain Id was manually provided alongside a cluster conf",
|
||||
used = rlnRelayConf.rlnRelayChainId, discarded = clusterConf.rlnRelayChainId
|
||||
|
||||
if rlnRelayConf.rlnRelayDynamic.isNone:
|
||||
rlnRelayConf.rlnRelayDynamic = some(clusterConf.rlnRelayDynamic)
|
||||
else:
|
||||
warn "RLN Relay Dynamic was manually provided alongside a cluster conf",
|
||||
used = rlnRelayConf.rlnRelayDynamic, discarded = clusterConf.rlnRelayDynamic
|
||||
|
||||
if rlnRelayConf.rlnRelayBandwidthThreshold.isNone:
|
||||
rlnRelayConf.rlnRelayBandwidthThreshold =
|
||||
some(clusterConf.rlnRelayBandwidthThreshold)
|
||||
else:
|
||||
warn "RLN Relay Bandwidth Threshold was manually provided alongside a cluster conf",
|
||||
used = rlnRelayConf.rlnRelayBandwidthThreshold,
|
||||
discarded = clusterConf.rlnRelayBandwidthThreshold
|
||||
|
||||
if rlnRelayConf.rlnEpochSizeSec.isNone:
|
||||
rlnRelayConf.rlnEpochSizeSec = some(clusterConf.rlnEpochSizeSec)
|
||||
else:
|
||||
warn "RLN Epoch Size in Seconds was manually provided alongside a cluster conf",
|
||||
used = rlnRelayConf.rlnEpochSizeSec, discarded = clusterConf.rlnEpochSizeSec
|
||||
|
||||
if rlnRelayConf.rlnRelayUserMessageLimit.isNone:
|
||||
rlnRelayConf.rlnRelayUserMessageLimit =
|
||||
some(clusterConf.rlnRelayUserMessageLimit)
|
||||
else:
|
||||
warn "RLN Relay Dynamic was manually provided alongside a cluster conf",
|
||||
used = rlnRelayConf.rlnRelayUserMessageLimit,
|
||||
discarded = clusterConf.rlnRelayUserMessageLimit
|
||||
|
||||
if builder.maxMessageSizeBytes.isNone:
|
||||
builder.maxMessageSizeBytes =
|
||||
some(int(parseCorrectMsgSize(clusterConf.maxMessageSize)))
|
||||
else:
|
||||
warn "Max Message Size was manually provided alongside a cluster conf",
|
||||
used = builder.maxMessageSizeBytes, discarded = clusterConf.maxMessageSize
|
||||
|
||||
if builder.numShardsInNetwork.isNone:
|
||||
builder.numShardsInNetwork = some(clusterConf.numShardsInNetwork)
|
||||
else:
|
||||
warn "Num Shards In Network was manually provided alongside a cluster conf",
|
||||
used = builder.numShardsInNetwork, discarded = clusterConf.numShardsInNetwork
|
||||
|
||||
if builder.discv5Discovery.isNone:
|
||||
builder.discv5Discovery = some(clusterConf.discv5Discovery)
|
||||
|
||||
if builder.discv5BootstrapNodes.isNone:
|
||||
builder.discv5BootstrapNodes = some(
|
||||
clusterConf.discv5BootstrapNodes.map(
|
||||
proc(e: string): TextEnr =
|
||||
e.TextEnr
|
||||
)
|
||||
)
|
||||
# Apply preset - end
|
||||
|
||||
let clusterId =
|
||||
if builder.clusterId.isSome:
|
||||
builder.clusterId.get()
|
||||
else:
|
||||
return err("Cluster Id is missing")
|
||||
|
||||
let numShardsInNetwork =
|
||||
if builder.numShardsInNetwork.isSome:
|
||||
builder.numShardsInNetwork.get()
|
||||
else:
|
||||
warn "Number of shards in network not specified, defaulting to one shard"
|
||||
1
|
||||
|
||||
let shards =
|
||||
if builder.shards.isSome:
|
||||
builder.shards.get()
|
||||
else:
|
||||
warn "shards not specified, defaulting to all shards in network"
|
||||
# TODO: conversion should not be needed
|
||||
let upperShard: uint16 = uint16(numShardsInNetwork - 1)
|
||||
toSeq(0.uint16 .. upperShard)
|
||||
|
||||
let discv5BootstrapNodes =
|
||||
if builder.discv5BootstrapNodes.isSome:
|
||||
builder.discv5BootstrapNodes.get()
|
||||
else:
|
||||
@[]
|
||||
|
||||
let rlnRelayConf = builder.rlnRelayConf.build().valueOr:
|
||||
return err("RLN Relay Conf building failed: " & $error)
|
||||
|
||||
let maxMessageSizeBytes =
|
||||
if builder.maxMessageSizeBytes.isSome:
|
||||
builder.maxMessageSizeBytes.get()
|
||||
else:
|
||||
return err("Max Message Size is missing")
|
||||
|
||||
let logLevel =
|
||||
if builder.logLevel.isSome:
|
||||
builder.logLevel.get()
|
||||
else:
|
||||
warn "Log Level not specified, defaulting to INFO"
|
||||
logging.LogLevel.INFO
|
||||
|
||||
let logFormat =
|
||||
if builder.logFormat.isSome:
|
||||
builder.logFormat.get()
|
||||
else:
|
||||
warn "Log Format not specified, defaulting to TEXT"
|
||||
logging.LogFormat.TEXT
|
||||
|
||||
let wakuConf = WakuConf(
|
||||
nodeKey: nodeKey,
|
||||
clusterId: clusterId,
|
||||
numShardsInNetwork: numShardsInNetwork,
|
||||
shards: shards,
|
||||
relay: relay,
|
||||
store: store,
|
||||
filter: filter,
|
||||
lightPush: lightPush,
|
||||
peerExchange: peerExchange,
|
||||
discv5BootstrapNodes: discv5BootstrapNodes,
|
||||
rlnRelayConf: rlnRelayConf,
|
||||
maxMessageSizeBytes: maxMessageSizeBytes,
|
||||
logLevel: logLevel,
|
||||
logFormat: logFormat,
|
||||
)
|
||||
|
||||
?validate(wakuConf)
|
||||
|
||||
return ok(wakuConf)
|
||||
Loading…
x
Reference in New Issue
Block a user