diff --git a/.github/workflows/test-nimble-install.yml b/.github/workflows/test-nimble-install.yml new file mode 100644 index 000000000..37e64baf2 --- /dev/null +++ b/.github/workflows/test-nimble-install.yml @@ -0,0 +1,56 @@ +name: Test Nimble Installation + +on: + pull_request: + push: + branches: + - master + +jobs: + test-nimble-install: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] # TODO: Windows + nim-version: ['2.2.4'] # TODO: tests with more versions + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: iffy/install-nim@v5 + with: + version: ${{ matrix.nim-version }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: nim-lang/setup-nimble-action@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Display Nim and Nimble versions + run: | + nim --version + nimble --version + + - name: Install waku from current commit + working-directory: examples/nimble + run: nimble --verbose install "waku@#${{ github.event.pull_request.head.sha }}" + + - name: List installed packages + working-directory: examples/nimble + run: | + nimble list --installed --ver + + - name: Build example project + working-directory: examples/nimble + run: | + echo "Building example project..." + nimble --verbose build + + - name: Run example project + working-directory: examples/nimble + run: | + echo "Running example project..." + nimble --verbose run \ No newline at end of file diff --git a/apps/liteprotocoltester/diagnose_connections.nim b/apps/liteprotocoltester/diagnose_connections.nim index a38de4b7b..7167d08a8 100644 --- a/apps/liteprotocoltester/diagnose_connections.nim +++ b/apps/liteprotocoltester/diagnose_connections.nim @@ -14,8 +14,8 @@ import libp2p/wire import + ../wakunode2/cli_args, waku/[ - factory/external_config, node/peer_manager, waku_lightpush/common, waku_relay, diff --git a/apps/liteprotocoltester/liteprotocoltester.nim b/apps/liteprotocoltester/liteprotocoltester.nim index d528efa90..d3adf1a81 100644 --- a/apps/liteprotocoltester/liteprotocoltester.nim +++ b/apps/liteprotocoltester/liteprotocoltester.nim @@ -11,11 +11,11 @@ import confutils import + ../wakunode2/cli_args, waku/[ common/enr, common/logging, factory/waku as waku_factory, - factory/external_config, waku_node, node/waku_metrics, node/peer_manager, diff --git a/apps/liteprotocoltester/service_peer_management.nim b/apps/liteprotocoltester/service_peer_management.nim index 7d79e0f36..a72daa2b6 100644 --- a/apps/liteprotocoltester/service_peer_management.nim +++ b/apps/liteprotocoltester/service_peer_management.nim @@ -11,8 +11,8 @@ import libp2p/wire import + ../wakunode2/cli_args, waku/[ - factory/external_config, common/enr, waku_node, node/peer_manager, diff --git a/apps/liteprotocoltester/tester_config.nim b/apps/liteprotocoltester/tester_config.nim index c06a970b1..0eca62f65 100644 --- a/apps/liteprotocoltester/tester_config.nim +++ b/apps/liteprotocoltester/tester_config.nim @@ -12,11 +12,11 @@ import secp256k1 import + ../wakunode2/cli_args, waku/[ common/confutils/envvar/defs as confEnvvarDefs, common/confutils/envvar/std/net as confEnvvarNet, common/logging, - factory/external_config, waku_core, waku_core/topics/pubsub_topic, ] diff --git a/apps/liteprotocoltester/v3_publisher.nim b/apps/liteprotocoltester/v3_publisher.nim index 339e13da0..c8353b5a3 100644 --- a/apps/liteprotocoltester/v3_publisher.nim +++ b/apps/liteprotocoltester/v3_publisher.nim @@ -1,5 +1,5 @@ import results, options, chronos -import waku/[waku_node, waku_core, waku_lightpush] +import waku/[waku_node, waku_core, waku_lightpush, waku_lightpush/common] import publisher_base type V3Publisher* = ref object of PublisherBase diff --git a/waku/factory/external_config.nim b/apps/wakunode2/cli_args.nim similarity index 98% rename from waku/factory/external_config.nim rename to apps/wakunode2/cli_args.nim index d52929680..9c6c4c3f8 100644 --- a/waku/factory/external_config.nim +++ b/apps/wakunode2/cli_args.nim @@ -19,24 +19,25 @@ import json import - ./waku_conf, - ./conf_builder/conf_builder, - ./networks_config, - ../common/confutils/envvar/defs as confEnvvarDefs, - ../common/confutils/envvar/std/net as confEnvvarNet, - ../common/logging, - ../waku_enr, - ../node/peer_manager, - ../waku_core/topics/pubsub_topic, - ../../tools/rln_keystore_generator/rln_keystore_generator, - ../../tools/rln_db_inspector/rln_db_inspector - -include ../waku_core/message/default_values + waku/factory/[waku_conf, conf_builder/conf_builder, networks_config], + waku/common/[ + confutils/envvar/defs as confEnvvarDefs, + confutils/envvar/std/net as confEnvvarNet, + logging, + ], + waku/[ + waku_enr, + node/peer_manager, + waku_core/topics/pubsub_topic, + waku_core/message/default_values, + ], + ../../tools/ + [rln_keystore_generator/rln_keystore_generator, rln_db_inspector/rln_db_inspector] export confTomlDefs, confTomlNet, confEnvvarDefs, confEnvvarNet, ProtectedShard logScope: - topics = "waku external config" + topics = "waku cli args" # Git version in git describe format (defined at compile time) const git_version* {.strdefine.} = "n/a" @@ -170,7 +171,7 @@ type WakuNodeConf* = object .}: uint16 agentString* {. - defaultValue: "nwaku-" & external_config.git_version, + defaultValue: "nwaku-" & cli_args.git_version, desc: "Node agent string which is used as identifier in network", name: "agent-string" .}: string diff --git a/apps/wakunode2/wakunode2.nim b/apps/wakunode2/wakunode2.nim index 54ecb1c43..0a48dc356 100644 --- a/apps/wakunode2/wakunode2.nim +++ b/apps/wakunode2/wakunode2.nim @@ -9,14 +9,15 @@ import system/ansi_c, libp2p/crypto/crypto import + ./cli_args, ../../tools/rln_keystore_generator/rln_keystore_generator, ../../tools/rln_db_inspector/rln_db_inspector, waku/[ common/logging, - factory/external_config, factory/waku, node/health_monitor, waku_api/rest/builder as rest_server_builder, + waku_core/message/default_values, ] logScope: diff --git a/examples/nimble/example.nimble b/examples/nimble/example.nimble new file mode 100644 index 000000000..6a1c68e47 --- /dev/null +++ b/examples/nimble/example.nimble @@ -0,0 +1,32 @@ +# Package + +version = "0.1.0" +author = "fryorcraken" +description = "Test Waku with nimble" +license = "MIT" +srcDir = "src" +bin = @["example"] + + +# Dependencies + +requires "chronos" +requires "results" +requires "waku" + +proc ensureRln(libFile: string = "build/librln.a", version = "v0.7.0") = + if not fileExists(libFile): + echo "Building RLN library..." + let buildDir = getCurrentDir() + let outFile = libFile + exec "bash ../../scripts/build_rln.sh " & buildDir & " " & version & " " & outFile + else: + echo "RLN library already exists: " & libFile + +before build: + echo "Ensure RLN before build" + ensureRln() + +before install: + echo "Ensure RLN before install" + ensureRln() diff --git a/examples/nimble/nim.cfg b/examples/nimble/nim.cfg new file mode 100644 index 000000000..1146b1c64 --- /dev/null +++ b/examples/nimble/nim.cfg @@ -0,0 +1,2 @@ +passL:"build/librln.a" +passL:"-lm" \ No newline at end of file diff --git a/examples/nimble/src/example.nim b/examples/nimble/src/example.nim new file mode 100644 index 000000000..18756cdba --- /dev/null +++ b/examples/nimble/src/example.nim @@ -0,0 +1,28 @@ +import std/options +import chronos, results +import waku + +proc main() {.async.} = + echo("Starting Waku node...") + + # Create a basic configuration for the Waku node + # No RLN so we don't need to path an eth rpc endpoint + let config = + newNodeConfig(wakuConfig = newWakuConfig(bootstrapNodes = @[], clusterId = 42)) + + # Create the node using the library API's createNode function + let node = (await createNode(config)).valueOr: + echo("Failed to create node: ", error) + quit(1) + + echo("Waku node created successfully!") + + # Start the node + (await startWaku(addr node)).isOkOr: + echo("Failed to start node: ", error) + quit(1) + + echo("Node started successfully! exiting") + +when isMainModule: + waitFor main() diff --git a/examples/wakustealthcommitments/node_spec.nim b/examples/wakustealthcommitments/node_spec.nim index 1af949314..bf61c282f 100644 --- a/examples/wakustealthcommitments/node_spec.nim +++ b/examples/wakustealthcommitments/node_spec.nim @@ -1,6 +1,7 @@ {.push raises: [].} -import waku/[common/logging, factory/[waku, networks_config, external_config]] +import ../../apps/wakunode2/cli_args +import waku/[common/logging, factory/[waku, networks_config]] import std/[options, strutils, os, sequtils], chronicles, diff --git a/library/waku_thread_requests/requests/node_lifecycle_request.nim b/library/waku_thread_requests/requests/node_lifecycle_request.nim index 6bc613406..17b7d8847 100644 --- a/library/waku_thread_requests/requests/node_lifecycle_request.nim +++ b/library/waku_thread_requests/requests/node_lifecycle_request.nim @@ -3,7 +3,7 @@ import chronos, chronicles, results, confutils, confutils/std/net import ../../../waku/node/peer_manager/peer_manager, - ../../../waku/factory/external_config, + ../../../apps/wakunode2/cli_args, ../../../waku/factory/waku, ../../../waku/factory/node_factory, ../../../waku/factory/networks_config, diff --git a/library/waku_thread_requests/requests/protocols/relay_request.nim b/library/waku_thread_requests/requests/protocols/relay_request.nim index 279a1efb4..b90b93e80 100644 --- a/library/waku_thread_requests/requests/protocols/relay_request.nim +++ b/library/waku_thread_requests/requests/protocols/relay_request.nim @@ -2,7 +2,8 @@ import std/[net, sequtils, strutils] import chronicles, chronos, stew/byteutils, results import ../../../../waku/waku_core/message/message, - ../../../../waku/factory/[external_config, validator_signed, waku], + ../../../../waku/factory/[validator_signed, waku], + ../../../../apps/wakunode2/cli_args, ../../../../waku/waku_node, ../../../../waku/waku_core/message, ../../../../waku/waku_core/time, # Timestamp diff --git a/tests/all_tests_waku.nim b/tests/all_tests_waku.nim index aac92863a..77e80f0c3 100644 --- a/tests/all_tests_waku.nim +++ b/tests/all_tests_waku.nim @@ -1,5 +1,7 @@ ## Waku v2 +import ./test_waku + # Waku core test suite import ./waku_core/test_namespaced_topics, @@ -96,3 +98,6 @@ import ./waku_rln_relay/test_all # Node Factory import ./factory/test_all + +# Waku API tests +import ./api/test_all diff --git a/tests/api/test_all.nim b/tests/api/test_all.nim new file mode 100644 index 000000000..a35d38305 --- /dev/null +++ b/tests/api/test_all.nim @@ -0,0 +1,3 @@ +{.used.} + +import ./test_node_conf diff --git a/tests/api/test_node_conf.nim b/tests/api/test_node_conf.nim new file mode 100644 index 000000000..56d6a2e93 --- /dev/null +++ b/tests/api/test_node_conf.nim @@ -0,0 +1,253 @@ +{.used.} + +import std/options, results, stint, testutils/unittests +import waku/api/api_conf, waku/factory/waku_conf, waku/factory/networks_config + +suite "LibWaku Conf - toWakuConf": + test "Minimal configuration": + ## Given + let nodeConfig = newNodeConfig(ethRpcEndpoints = @["http://someaddress"]) + + ## When + let wakuConfRes = toWakuConf(nodeConfig) + + ## Then + let wakuConf = wakuConfRes.valueOr: + raiseAssert error + wakuConf.validate().isOkOr: + raiseAssert error + check: + wakuConf.clusterId == 1 + wakuConf.shardingConf.numShardsInCluster == 8 + wakuConf.staticNodes.len == 0 + + test "Relay mode configuration": + ## Given + let wakuConfig = + newWakuConfig(bootstrapNodes = @[], staticStoreNodes = @[], clusterId = 1) + + let nodeConfig = + newNodeConfig(mode = Relay, wakuConfig = wakuConfig, storeConfirmation = false) + + ## When + let wakuConfRes = toWakuConf(nodeConfig) + + ## Then + require wakuConfRes.isOk() + let wakuConf = wakuConfRes.get() + require wakuConf.validate().isOk() + check: + wakuConf.relay == true + wakuConf.lightPush == true + wakuConf.peerExchangeService == true + wakuConf.clusterId == 1 + + test "Auto-sharding configuration": + ## Given + let nodeConfig = newNodeConfig( + mode = Relay, + wakuConfig = newWakuConfig( + bootstrapNodes = @[], + staticStoreNodes = @[], + clusterId = 42, + autoShardingConfig = AutoShardingConfig(numShardsInCluster: 16), + ), + storeConfirmation = false, + ) + + ## When + let wakuConfRes = toWakuConf(nodeConfig) + + ## Then + require wakuConfRes.isOk() + let wakuConf = wakuConfRes.get() + require wakuConf.validate().isOk() + check: + wakuConf.clusterId == 42 + wakuConf.shardingConf.numShardsInCluster == 16 + + test "Bootstrap nodes configuration": + ## Given + let bootstrapNodes = + @[ + "enr:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g", + "enr:-QEkuECnZ3IbVAgkOzv-QLnKC4dRKAPRY80m1-R7G8jZ7yfT3ipEfBrhKN7ARcQgQ-vg-h40AQzyvAkPYlHPaFKk6u9MBgmlkgnY0iXNlY3AyNTZrMaEDk49D8JjMSns4p1XVNBvJquOUzT4PENSJknkROspfAFGg3RjcIJ2X4N1ZHCCd2g", + ] + let libConf = newNodeConfig( + mode = Relay, + wakuConfig = newWakuConfig( + bootstrapNodes = bootstrapNodes, staticStoreNodes = @[], clusterId = 1 + ), + storeConfirmation = false, + ) + + ## When + let wakuConfRes = toWakuConf(libConf) + + ## Then + require wakuConfRes.isOk() + let wakuConf = wakuConfRes.get() + require wakuConf.validate().isOk() + require wakuConf.discv5Conf.isSome() + check: + wakuConf.discv5Conf.get().bootstrapNodes == bootstrapNodes + + test "Static store nodes configuration": + ## Given + let staticStoreNodes = + @[ + "/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc", + "/ip4/192.168.1.1/tcp/60001/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYd", + ] + let nodeConf = newNodeConfig( + wakuConfig = newWakuConfig( + bootstrapNodes = @[], staticStoreNodes = staticStoreNodes, clusterId = 1 + ) + ) + + ## When + let wakuConfRes = toWakuConf(nodeConf) + + ## Then + require wakuConfRes.isOk() + let wakuConf = wakuConfRes.get() + require wakuConf.validate().isOk() + check: + wakuConf.staticNodes == staticStoreNodes + + test "Message validation with max message size": + ## Given + let nodeConfig = newNodeConfig( + wakuConfig = newWakuConfig( + bootstrapNodes = @[], + staticStoreNodes = @[], + clusterId = 1, + messageValidation = MessageValidation( + maxMessageSizeBytes: 100'u64 * 1024'u64, # 100kB + rlnConfig: none(RlnConfig), + ), + ), + storeConfirmation = false, + ) + + ## When + let wakuConfRes = toWakuConf(nodeConfig) + + ## Then + require wakuConfRes.isOk() + let wakuConf = wakuConfRes.get() + require wakuConf.validate().isOk() + check: + wakuConf.maxMessageSizeBytes == 100'u64 * 1024'u64 + + test "Message validation with RLN config": + ## Given + let nodeConfig = newNodeConfig( + wakuConfig = newWakuConfig( + bootstrapNodes = @[], + clusterId = 1, + messageValidation = MessageValidation( + maxMessageSizeBytes: 150'u64 * 1024'u64, # 150KB + rlnConfig: some( + RlnConfig( + contractAddress: "0x1234567890123456789012345678901234567890", + chainId: 1'u, + epochSizeSec: 600'u64, + ) + ), + ), + ), + ethRpcEndpoints = @["http://127.0.0.1:1111"], + ) + + ## When + let wakuConf = toWakuConf(nodeConfig).valueOr: + raiseAssert error + + wakuConf.validate().isOkOr: + raiseAssert error + + check: + wakuConf.maxMessageSizeBytes == 150'u64 * 1024'u64 + + require wakuConf.rlnRelayConf.isSome() + let rlnConf = wakuConf.rlnRelayConf.get() + check: + rlnConf.dynamic == true + rlnConf.ethContractAddress == "0x1234567890123456789012345678901234567890" + rlnConf.chainId == 1'u256 + rlnConf.epochSizeSec == 600'u64 + + test "Full Relay mode configuration with all fields": + ## Given + let nodeConfig = newNodeConfig( + mode = Relay, + wakuConfig = newWakuConfig( + bootstrapNodes = + @[ + "enr:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g" + ], + staticStoreNodes = + @[ + "/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc" + ], + clusterId = 99, + autoShardingConfig = AutoShardingConfig(numShardsInCluster: 12), + messageValidation = MessageValidation( + maxMessageSizeBytes: 512'u64 * 1024'u64, # 512KB + rlnConfig: some( + RlnConfig( + contractAddress: "0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + chainId: 5'u, # Goerli + epochSizeSec: 300'u64, + ) + ), + ), + ), + storeConfirmation = true, + ethRpcEndpoints = @["https://127.0.0.1:8333"], + ) + + ## When + let wakuConfRes = toWakuConf(nodeConfig) + + ## Then + let wakuConf = wakuConfRes.valueOr: + raiseAssert error + wakuConf.validate().isOkOr: + raiseAssert error + + # Check basic settings + check: + wakuConf.relay == true + wakuConf.lightPush == true + wakuConf.peerExchangeService == true + wakuConf.clusterId == 99 + + # Check sharding + check: + wakuConf.shardingConf.numShardsInCluster == 12 + + # Check bootstrap nodes + require wakuConf.discv5Conf.isSome() + check: + wakuConf.discv5Conf.get().bootstrapNodes.len == 1 + + # Check static nodes + check: + wakuConf.staticNodes.len == 1 + wakuConf.staticNodes[0] == + "/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc" + + # Check message validation + check: + wakuConf.maxMessageSizeBytes == 512'u64 * 1024'u64 + + # Check RLN config + require wakuConf.rlnRelayConf.isSome() + let rlnConf = wakuConf.rlnRelayConf.get() + check: + rlnConf.dynamic == true + rlnConf.ethContractAddress == "0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + rlnConf.chainId == 5'u256 + rlnConf.epochSizeSec == 300'u64 diff --git a/tests/factory/test_all.nim b/tests/factory/test_all.nim index 683bc3b10..0f15035fe 100644 --- a/tests/factory/test_all.nim +++ b/tests/factory/test_all.nim @@ -1,3 +1,3 @@ {.used.} -import ./test_external_config, ./test_node_factory, ./test_waku_conf +import ./test_node_factory, ./test_waku_conf diff --git a/tests/test_waku.nim b/tests/test_waku.nim new file mode 100644 index 000000000..0792cb4fd --- /dev/null +++ b/tests/test_waku.nim @@ -0,0 +1,59 @@ +{.used.} + +import chronos, testutils/unittests, std/options + +import waku + +suite "Waku API - Create node": + asyncTest "Create node with minimal Relay configuration": + ## Given + let nodeConfig = + newNodeConfig(wakuConfig = newWakuConfig(bootstrapNodes = @[], clusterId = 1)) + + ## When + let node = (await createNode(nodeConfig)).valueOr: + raiseAssert error + + ## Then + check: + not node.isNil() + node.conf.clusterId == 1 + node.conf.relay == true + + asyncTest "Create node with full configuration": + ## Given + let nodeConfig = newNodeConfig( + mode = Relay, + wakuConfig = newWakuConfig( + bootstrapNodes = + @[ + "enr:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g" + ], + staticStoreNodes = + @[ + "/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc" + ], + clusterId = 99, + autoShardingConfig = AutoShardingConfig(numShardsInCluster: 16), + messageValidation = MessageValidation( + maxMessageSizeBytes: 1024'u64 * 1024'u64, # 1MB + rlnConfig: none(RlnConfig), + ), + ), + storeConfirmation = true, + ) + + ## When + let node = (await createNode(nodeConfig)).valueOr: + raiseAssert error + + ## Then + check: + not node.isNil() + node.conf.clusterId == 99 + node.conf.shardingConf.numShardsInCluster == 16 + node.conf.maxMessageSizeBytes == 1024'u64 * 1024'u64 + node.conf.staticNodes.len == 1 + node.conf.relay == true + node.conf.lightPush == true + node.conf.peerExchangeService == true diff --git a/tests/wakunode2/test_all.nim b/tests/wakunode2/test_all.nim index 76bc9aaad..7e658d4ca 100644 --- a/tests/wakunode2/test_all.nim +++ b/tests/wakunode2/test_all.nim @@ -1,3 +1,3 @@ {.used.} -import ./test_app, ./test_validators +import ./test_app, ./test_validators, ./test_cli_args diff --git a/tests/factory/test_external_config.nim b/tests/wakunode2/test_cli_args.nim similarity index 99% rename from tests/factory/test_external_config.nim rename to tests/wakunode2/test_cli_args.nim index 52e82a425..61e29d223 100644 --- a/tests/factory/test_external_config.nim +++ b/tests/wakunode2/test_cli_args.nim @@ -10,12 +10,15 @@ import secp256k1, confutils, stint + +import apps/wakunode2/cli_args + import - ../../waku/factory/external_config, ../../waku/factory/networks_config, ../../waku/factory/waku_conf, ../../waku/common/logging, - ../../waku/common/utils/parse_size_units + ../../waku/common/utils/parse_size_units, + ../../waku/waku_core/message/default_values suite "Waku external config - default values": test "Default sharding value": diff --git a/tests/wakunode2/test_validators.nim b/tests/wakunode2/test_validators.nim index b0a8dd8fb..323bd293d 100644 --- a/tests/wakunode2/test_validators.nim +++ b/tests/wakunode2/test_validators.nim @@ -12,14 +12,8 @@ import libp2p/multihash, secp256k1 import - waku/[ - waku_core, - node/peer_manager, - waku_node, - waku_relay, - factory/external_config, - factory/validator_signed, - ], + waku/[waku_core, node/peer_manager, waku_node, factory/validator_signed], + apps/wakunode2/cli_args, ../testlib/wakucore, ../testlib/wakunode diff --git a/vendor/nim-toml-serialization b/vendor/nim-toml-serialization index fea85b27f..f34805705 160000 --- a/vendor/nim-toml-serialization +++ b/vendor/nim-toml-serialization @@ -1 +1 @@ -Subproject commit fea85b27f0badcf617033ca1bc05444b5fd8aa7a +Subproject commit f3480570566b00a9f7ed1abf1f9731fb856ae1f2 diff --git a/waku.nim b/waku.nim new file mode 100644 index 000000000..18d52741e --- /dev/null +++ b/waku.nim @@ -0,0 +1,10 @@ +## Main module for using nwaku as a Nimble library +## +## This module re-exports the public API for creating and managing Waku nodes +## when using nwaku as a library dependency. + +import waku/api/[api, api_conf] +export api, api_conf + +import waku/factory/waku +export waku diff --git a/waku.nimble b/waku.nimble index debcc0c87..85a8eee0a 100644 --- a/waku.nimble +++ b/waku.nimble @@ -25,12 +25,13 @@ requires "nim >= 2.2.4", "stint", "metrics", "libp2p >= 1.13.0", - "web3#48fb2d4", # fix 0.7.0 undeclared field: 'stream' error + "web3#141907c", # fix 0.7.0 undeclared field: 'stream' error + readValue UInt256 "presto", "regex", "results", "db_connector", "minilru", + "toml_serialization", # Necessary for confutils/toml support "https://github.com/vacp2p/mix#0.1.0" ### Helper functions diff --git a/waku/api/api.nim b/waku/api/api.nim new file mode 100644 index 000000000..a84d13729 --- /dev/null +++ b/waku/api/api.nim @@ -0,0 +1,16 @@ +import chronicles, chronos, results + +import waku/factory/waku + +import ./api_conf + +proc createNode*(config: NodeConfig): Future[Result[Waku, string]] {.async.} = + let wakuConf = toWakuConf(config).valueOr: + return err("Failed to handle the configuration: " & error) + + ## We are not defining app callbacks at node creation + let wakuRes = (await Waku.new(wakuConf)).valueOr: + error "waku initialization failed", error = error + return err("Failed setting up Waku: " & $error) + + return ok(wakuRes) diff --git a/waku/api/api_conf.nim b/waku/api/api_conf.nim new file mode 100644 index 000000000..aa8f61196 --- /dev/null +++ b/waku/api/api_conf.nim @@ -0,0 +1,161 @@ +import + std/options, + results, + waku/factory/waku_conf, + waku/factory/conf_builder/conf_builder, + waku/factory/networks_config + +type AutoShardingConfig* {.requiresInit.} = object + numShardsInCluster*: uint16 + +type RlnConfig* {.requiresInit.} = object + contractAddress*: string + chainId*: uint + epochSizeSec*: uint64 + +type MessageValidation* {.requiresInit.} = object + maxMessageSizeBytes*: uint64 + rlnConfig*: Option[RlnConfig] + +type WakuConfig* {.requiresInit.} = object + bootstrapNodes: seq[string] + staticStoreNodes: seq[string] + clusterId: uint16 + autoShardingConfig: AutoShardingConfig + messageValidation: MessageValidation + +proc DefaultAutoShardingConfig(): AutoShardingConfig = + return AutoShardingConfig(numShardsInCluster: 1) + +proc DefaultMessageValidation(): MessageValidation = + return MessageValidation(maxMessageSizeBytes: 153600, rlnConfig: none(RlnConfig)) + +proc newWakuConfig*( + bootstrapNodes: seq[string], + staticStoreNodes: seq[string] = @[], + clusterId: uint16, + autoShardingConfig: AutoShardingConfig = DefaultAutoShardingConfig(), + messageValidation: MessageValidation = DefaultMessageValidation(), +): WakuConfig = + return WakuConfig( + bootstrapNodes: bootstrapNodes, + staticStoreNodes: staticStoreNodes, + clusterId: clusterId, + autoShardingConfig: autoShardingConfig, + messageValidation: messageValidation, + ) + +proc DefaultWakuConfig(): WakuConfig = + return WakuConfig( + bootstrapNodes: + @[ + "enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im" + ], + staticStoreNodes: @[], # TODO + clusterId: 1, + autoShardingConfig: AutoShardingConfig(numShardsInCluster: 8), + messageValidation: MessageValidation( + maxMessageSizeBytes: 153600, + rlnConfig: some( + RlnConfig( + contractAddress: "0xB9cd878C90E49F797B4431fBF4fb333108CB90e6", + chain_id: 59141, + epoch_size_sec: 600, # 10 minutes + ) + ), + ), + ) + +type WakuMode* = enum + Edge = "edge" + Relay = "relay" + +type NodeConfig* {.requiresInit.} = object + mode: WakuMode + wakuConfig: WakuConfig + storeConfirmation: bool + ethRpcEndpoints: seq[string] + +proc newNodeConfig*( + mode: WakuMode = WakuMode.Relay, + wakuConfig: WakuConfig = DefaultWakuConfig(), + storeConfirmation: bool = true, + ethRpcEndpoints: seq[string] = @[], +): NodeConfig = + return NodeConfig( + mode: mode, + wakuConfig: wakuConfig, + storeConfirmation: storeConfirmation, + ethRpcEndpoints: ethRpcEndpoints, + ) + +proc toWakuConf*(nodeConfig: NodeConfig): Result[WakuConf, string] = + var b = WakuConfBuilder.init() + + case nodeConfig.mode + of Relay: + b.withRelay(true) + + b.filterServiceConf.withEnabled(true) + b.filterServiceConf.withMaxPeersToServe(20) + + b.withLightPush(true) + + b.discv5Conf.withEnabled(true) + b.withPeerExchange(true) + + b.rateLimitConf.withRateLimits(@["filter:100/1s", "lightpush:5/1s", "px:5/1s"]) + of Edge: + return err("Edge mode is not implemented") + + #TODO: store confirmation + + ## Network Conf + let wakuConfig = nodeConfig.wakuConfig + + # Set cluster ID + b.withClusterId(wakuConfig.clusterId) + + # Set sharding configuration + b.withShardingConf(ShardingConfKind.AutoSharding) + let autoShardingConfig = wakuConfig.autoShardingConfig + b.withNumShardsInCluster(autoShardingConfig.numShardsInCluster) + + # Set bootstrap nodes + if wakuConfig.bootstrapNodes.len > 0: + b.discv5Conf.withBootstrapNodes(wakuConfig.bootstrapNodes) + + # TODO: verify behaviour + # Set static store nodes + if wakuConfig.staticStoreNodes.len > 0: + b.withStaticNodes(wakuConfig.staticStoreNodes) + + # Set message validation + + let msgValidation = wakuConfig.messageValidation + b.withMaxMessageSize(msgValidation.maxMessageSizeBytes) + + # Set RLN config if provided + if msgValidation.rlnConfig.isSome(): + let rlnConfig = msgValidation.rlnConfig.get() + b.rlnRelayConf.withEnabled(true) + b.rlnRelayConf.withEthContractAddress(rlnConfig.contractAddress) + b.rlnRelayConf.withChainId(rlnConfig.chainId) + b.rlnRelayConf.withEpochSizeSec(rlnConfig.epochSizeSec) + b.rlnRelayConf.withDynamic(true) + b.rlnRelayConf.withEthClientUrls(nodeConfig.ethRpcEndpoints) + + # TODO: we should get rid of those two + b.rlnRelayconf.withUserMessageLimit(100) + b.rlnRelayConf.withTreePath("./rln_tree") + + ## Various configurations + b.withNatStrategy("any") + + let wakuConf = b.build().valueOr: + return err("Failed to build configuration: " & error) + + wakuConf.validate().isOkOr: + return err("Failed to validate configuration: " & error) + + return ok(wakuConf) diff --git a/waku/factory/waku.nim b/waku/factory/waku.nim index c6196337f..7c2c430b6 100644 --- a/waku/factory/waku.nim +++ b/waku/factory/waku.nim @@ -42,7 +42,6 @@ import ../waku_filter_v2, ../factory/node_factory, ../factory/internal_config, - ../factory/external_config, ../factory/app_callbacks, ../waku_enr/multiaddr, ./waku_conf