diff --git a/Dockerfile b/Dockerfile index 700b8a78e..b8a6ab578 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,5 @@ # BUILD IMAGE -------------------------------------------------------- -FROM golang:1.19-alpine3.16 as builder - -# Get build tools and required header files -RUN apk add --no-cache build-base -RUN apk add --no-cache bash -RUN apk add --no-cache git +FROM golang:1.19 as builder WORKDIR /app COPY . . @@ -14,7 +9,7 @@ RUN make -j$(nproc) build # ACTUAL IMAGE ------------------------------------------------------- -FROM alpine:3.16 +FROM debian:12.1-slim ARG GIT_COMMIT=unknown @@ -26,6 +21,8 @@ LABEL commit=$GIT_COMMIT # color, nocolor, json ENV GOLOG_LOG_FMT=nocolor +RUN apt update && apt install -y ca-certificates + # go-waku default ports EXPOSE 9000 30303 60000 60001 8008 8009 diff --git a/Makefile b/Makefile index 98632e6f5..ca9007a00 100644 --- a/Makefile +++ b/Makefile @@ -124,7 +124,10 @@ build-example-filter2: build-example-c-bindings: cd examples/c-bindings && $(MAKE) -build-example: build-example-basic2 build-example-chat-2 build-example-filter2 build-example-c-bindings +build-example-rln: + cd examples/rln && $(MAKE) + +build-example: build-example-basic2 build-example-chat-2 build-example-filter2 build-example-c-bindings build-example-rln static-library: @echo "Building static library..." diff --git a/README.md b/README.md index a619cc248..9ae67af7a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A Go implementation of the [Waku v2 protocol](https://rfc.vac.dev/spec/10).

- +

@@ -38,7 +38,7 @@ nix develop #### Docker ``` docker run -i -t -p 60000:60000 -p 9000:9000/udp \ - statusteam/go-waku:v0.5.2 \ # or, the image:tag of your choice + statusteam/go-waku:latest \ # or, the image:tag of your choice --dns-discovery:true \ --dns-discovery-url:enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.waku.nodes.status.im \ --discv5-discovery @@ -47,9 +47,9 @@ docker run -i -t -p 60000:60000 -p 9000:9000/udp \ or build and run the image with: ``` -docker build -t go-waku:latest . +docker build -t statusteam/go-waku:latest . -docker run go-waku:latest --help +docker run statusteam/go-waku:latest --help ``` #### Building on windows diff --git a/docs/operators/how-to/build.md b/docs/operators/how-to/build.md index fd8f875b8..0c08d662e 100644 --- a/docs/operators/how-to/build.md +++ b/docs/operators/how-to/build.md @@ -4,7 +4,7 @@ Go-waku can be built on Linux, macOS and Windows ## Installing dependencies -Cloning and building go-waku requires Go +1.17, a C compiler, Make, Bash and Git. +Cloning and building go-waku requires Go +1.19, a C compiler, Make, Bash and Git. Go can be installed by following [these instructions](https://go.dev/doc/install) @@ -31,13 +31,13 @@ Assuming you use [Homebrew](https://brew.sh/) to manage packages brew install cmake ``` -## Building nwaku +## Building go-waku -### 1. Clone the nwaku repository +### 1. Clone the go-waku repository ```sh git clone https://github.com/waku-org/go-waku -cd nwaku +cd go-waku ``` ### 2. Build waku diff --git a/docs/operators/how-to/run-with-rln.md b/docs/operators/how-to/run-with-rln.md new file mode 100644 index 000000000..c4e5969c1 --- /dev/null +++ b/docs/operators/how-to/run-with-rln.md @@ -0,0 +1,74 @@ +# How to run spam prevention on your go-waku node (RLN) + +This guide explains how to run a go-waku node with RLN (Rate Limiting Nullifier) enabled. + +[RLN](https://rfc.vac.dev/spec/32/) is a protocol integrated into waku v2, +which prevents spam-based attacks on the network. + +For further background on the research for RLN tailored to waku, refer +to [this](https://rfc.vac.dev/spec/17/) RFC. + +Registering to the membership group has been left out for brevity. +If you would like to register to the membership group and send messages with RLN, +refer to the [on-chain chat2 tutorial](../../tutorial/onchain-rln-relay-chat2.md). + +This guide specifically allows a node to participate in RLN testnet +You may alter the rln-specific arguments as required. + + +## 1. Update the runtime arguments + +Follow the steps from the [build](./build.md) and [run](./run.md) guides while replacing the run command with - + +```bash +export WAKU_FLEET= +export SEPOLIA_WS_NODE_ADDRESS= +export RLN_RELAY_CONTRACT_ADDRESS="0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4" # Replace this with any compatible implementation +$WAKUNODE_DIR/build/waku \ +--dns-discovery \ +--dns-discovery-url="$WAKU_FLEET" \ +--discv5-discovery=true \ +--rln-relay=true \ +--rln-relay-dynamic=true \ +--rln-relay-eth-contract-address="$RLN_RELAY_CONTRACT_ADDRESS" \ +--rln-relay-eth-client-address="$SEPOLIA_WS_NODE_ADDRESS" +``` + +OR + +If you installed go-waku using a `.dpkg` or `.rpm` package, you can use the `waku` command instead of building go-waku yourself + +OR + +If you have the go-waku node within docker, you can replace the run command with - + +```bash +export WAKU_FLEET= +export SEPOLIA_WS_NODE_ADDRESS= +export RLN_RELAY_CONTRACT_ADDRESS="0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4" # Replace this with any compatible implementation +docker run -i -t -p 60000:60000 -p 9000:9000/udp \ + -v /absolute/path/to/your/rlnKeystore.json:/rlnKeystore.json:ro \ + statusteam/go-waku:latest \ + --dns-discovery=true \ + --dns-discovery-url="$WAKU_FLEET" \ + --discv5-discovery \ + --rln-relay=true \ + --rln-relay-dynamic=true \ + --rln-relay-eth-contract-address="$RLN_RELAY_CONTRACT_ADDRESS" \ + --rln-relay-eth-client-address="$SEPOLIA_WS_NODE_ADDRESS" +``` + +Following is the list of additional fields that have been added to the +runtime arguments - + +1. `--rln-relay`: Allows waku-rln-relay to be mounted into the setup of the go-waku node. All messages sent and received in this node will require to contain a valid proof that will be verified, and nodes that relay messages with invalid proofs will have their peer scoring affected negatively and will be eventually disconnected. +2. `--rln-relay-dynamic`: Enables waku-rln-relay to connect to an ethereum node to fetch the membership group +3. `--rln-relay-eth-contract-address`: The contract address of an RLN membership group +4. `--rln-relay-eth-client-address`: The websocket url to a Sepolia ethereum node + +The `--dns-discovery-url` flag should contain a valid URL with nodes encoded according to EIP-1459. You can read more about DNS Discovery [here](https://github.com/waku-org/nwaku/blob/master/docs/tutorial/dns-disc.md) + +You should now have go-waku running, with RLN enabled! + + +> Note: This guide will be updated in the future to include features like slashing. \ No newline at end of file diff --git a/docs/operators/how-to/run.md b/docs/operators/how-to/run.md index aeb577bfa..98f8de108 100644 --- a/docs/operators/how-to/run.md +++ b/docs/operators/how-to/run.md @@ -17,13 +17,13 @@ See [this tutorial](./configure-key.md) if you want to generate and configure a - enable `relay` protocol - subscribe to the default pubsub topic, namely `/waku/2/default-waku/proto` - enable `store` protocol, but only as a client. -This implies that the nwaku node will not persist any historical messages itself, +This implies that the go-waku node will not persist any historical messages itself, but can query `store` service peers who do so. To configure `store` as a service node, see [this tutorial](./configure-store.md). > **Note:** The `filter` and `lightpush` protocols are _not_ enabled by default. -Consult the [configuration guide](./configure.md) on how to configure your nwaku node to run these protocols. +Consult the [configuration guide](./configure.md) on how to configure your go-waku node to run these protocols. Some typical non-default configurations are explained below. For more advanced configuration, see the [configuration guide](./configure.md). @@ -33,7 +33,7 @@ Different ways to connect to other nodes are expanded upon in our [connection gu Find the log entry beginning with `Listening on`. It should be printed at INFO level when you start your node -and contains a list of all publically announced listening addresses for the nwaku node. +and contains a list of all publically announced listening addresses for the go-waku node. For example @@ -80,7 +80,7 @@ returns a response similar to ## Finding your discoverable ENR address(es) -A nwaku node can encode its addressing information in an [Ethereum Node Record (ENR)](https://eips.ethereum.org/EIPS/eip-778) according to [`31/WAKU2-ENR`](https://rfc.vac.dev/spec/31/). +A go-waku node can encode its addressing information in an [Ethereum Node Record (ENR)](https://eips.ethereum.org/EIPS/eip-778) according to [`31/WAKU2-ENR`](https://rfc.vac.dev/spec/31/). These ENR are most often used for discovery purposes. ### ENR for DNS discovery and DiscV5 @@ -111,10 +111,10 @@ to continually discover and connect to random peers for a more robust mesh. A typical run configuration for a go-waku node is to connect to existing peers with known listening addresses using the `--staticnode` option. The `--staticnode` option can be repeated for each peer you want to connect to on startup. -This is also useful if you want to run several nwaku instances locally +This is also useful if you want to run several go-waku instances locally and therefore know the listening addresses of all peers. -As an example, consider a nwaku node that connects to two known peers +As an example, consider a go-waku node that connects to two known peers on the same local host (with IP `0.0.0.0`) with TCP ports `60002` and `60003`, and peer IDs `16Uiu2HAkzjwwgEAXfeGNMKFPSpc6vGBRqCdTLG5q3Gmk2v4pQw7H` and `16Uiu2HAmFBA7LGtwY5WVVikdmXVo3cKLqkmvVtuDu63fe8safeQJ` respectively. @@ -180,5 +180,5 @@ See our [store configuration tutorial](./configure-store.md) for more. A running go-waku node can be interacted with using the [Waku v2 JSON RPC API](https://rfc.vac.dev/spec/16/). > **Note:** Private and Admin API functionality are disabled by default. -To configure a nwaku node with these enabled, +To configure a go-waku node with these enabled, use the `--rpc-admin:true` and `--rpc-private:true` CLI options. \ No newline at end of file diff --git a/docs/operators/quickstart.md b/docs/operators/quickstart.md index 7d1177c3c..1c6ddf6b6 100644 --- a/docs/operators/quickstart.md +++ b/docs/operators/quickstart.md @@ -16,7 +16,7 @@ or download a precompiled binary from our [releases page](https://github.com/wak [Run the go-waku node](./how-to/run.md) using a default or common configuration or [configure](./how-to/configure.md) the node for more advanced use cases. -[Connect](./how-to/connect.md) the nwaku node to other peers to start communicating. +[Connect](./how-to/connect.md) the go-waku node to other peers to start communicating. ## 3. Interact diff --git a/docs/tutorials/onchain-rln-relay-chat2.md b/docs/tutorials/onchain-rln-relay-chat2.md index e82208083..90aaf9185 100644 --- a/docs/tutorials/onchain-rln-relay-chat2.md +++ b/docs/tutorials/onchain-rln-relay-chat2.md @@ -11,14 +11,14 @@ To complete this tutorial, you will need 1. An rln keystore file with credentials to the rln membership smart contract you wish to use. You may obtain this by registering to the smart contract and generating a keystore. It is possible to use go-waku to register into the smart contract: ``` make -./build/waku generate-rln-credentials --eth-account-private-key= --eth-contract-address=<0x000...> --eth-client-address= --cred-path=rlnKeystore.json +./build/waku generate-rln-credentials --eth-account-private-key= --eth-contract-address=<0x000...> --eth-client-address= --cred-path=./rlnKeystore.json ``` +Once this command is executed, A keystore file will be generated at the path defined in the `--cred-path` flag. You may now use this keystore with wakunode2 or chat2. + ## Overview Figure 1 provides an overview of the interaction of the chat2 clients with the test fleets and the membership contract. At a high level, when a chat2 client is run with Waku-RLN-Relay mounted in on-chain mode, the passed in credential will get displayed on the console of your chat2 client. -You may copy the displayed RLN credential and reuse them for the future execution of the chat2 application. -Proper instructions in this regard is provided in the following [section](#how-to-persist-and-reuse-rln-credential). Under the hood, the chat2 client constantly listens to the membership contract and keeps itself updated with the latest state of the group. In the following test setting, the chat2 clients are to be connected to the Waku test fleets as their first hop. @@ -56,7 +56,7 @@ Run the following command to set up your chat2 client. --content-topic=/toy-chat/3/mingde/proto \ --rln-relay=true \ --rln-relay-dynamic=true \ ---rln-relay-eth-contract-address=0x9C09146844C1326c2dBC41c451766C7138F88155 \ +--rln-relay-eth-contract-address=0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4 \ --rln-relay-cred-path=xxx/xx/rlnKeystore.json \ --rln-relay-cred-password=xxxx \ --rln-relay-eth-client-address=xxxx @@ -68,8 +68,8 @@ In this command - the `--rln-relay` flag is set to `true` to enable the Waku-RLN-Relay protocol for spam protection. - the `--rln-relay-dynamic` flag is set to `true` to enable the on-chain mode of Waku-RLN-Relay protocol with dynamic group management. - the `--rln-relay-eth-contract-address` option gets the address of the membership contract. - The current address of the contract is `0x9C09146844C1326c2dBC41c451766C7138F88155`. - You may check the state of the contract on the [Sepolia testnet](https://sepolia.etherscan.io/address/0x9C09146844C1326c2dBC41c451766C7138F88155). + The current address of the contract is `0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4`. + You may check the state of the contract on the [Sepolia testnet](https://sepolia.etherscan.io/address/0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4). - the `--rln-relay-cred-path` option denotes the path to the keystore file described above - the `--rln-relay-cred-password` option denotes the password to the keystore - the `rln-relay-eth-client-address` is the WebSocket address of the hosted node on the Sepolia testnet. @@ -176,7 +176,7 @@ You may provide an index to the membership you wish to use (within the same memb --content-topic=/toy-chat/3/mingde/proto \ --rln-relay=true \ --rln-relay-dynamic=true \ ---rln-relay-eth-contract-address=0x9C09146844C1326c2dBC41c451766C7138F88155 \ +--rln-relay-eth-contract-address=0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4 \ --rln-relay-eth-client-address=your_sepolia_node \ --rln-relay-cred-path=./rlnKeystore.json \ --rln-relay-cred-password=your_password \ @@ -197,7 +197,7 @@ You can check this fact by looking at `Bob`'s console, where `message3` is missi **Alice** ```bash -./build/chat2 --fleet=test --content-topic=/toy-chat/3/mingde/proto --rln-relay=true --rln-relay-dynamic=true --rln-relay-eth-contract-address=0x9C09146844C1326c2dBC41c451766C7138F88155 --rln-relay-cred-path=rlnKeystore.json --rln-relay-cred-password=password --rln-relay-eth-client-address=wss://sepolia.infura.io/ws/v3/12345678901234567890123456789012 --nickname=Alice +./build/chat2 --fleet=test --content-topic=/toy-chat/3/mingde/proto --rln-relay=true --rln-relay-dynamic=true --rln-relay-eth-contract-address=0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4 --rln-relay-cred-path=rlnKeystore.json --rln-relay-cred-password=password --rln-relay-eth-client-address=wss://sepolia.infura.io/ws/v3/12345678901234567890123456789012 --nickname=Alice ``` ``` @@ -247,7 +247,7 @@ INFO RLN Epoch: 165886593 **Bob** ```bash -./build/chat2 --fleet=test --content-topic=/toy-chat/3/mingde/proto --rln-relay=true --rln-relay-dynamic=true --rln-relay-eth-contract-address=0x9C09146844C1326c2dBC41c451766C7138F88155 --rln-relay-cred-path=rlnKeystore.json --rln-relay-cred-index=1 --rln-relay-cred-password=password --rln-relay-eth-client-address=wss://sepolia.infura.io/ws/v3/12345678901234567890123456789012 --nickname=Bob +./build/chat2 --fleet=test --content-topic=/toy-chat/3/mingde/proto --rln-relay=true --rln-relay-dynamic=true --rln-relay-eth-contract-address=0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4 --rln-relay-cred-path=rlnKeystore.json --rln-relay-cred-index=1 --rln-relay-cred-password=password --rln-relay-eth-client-address=wss://sepolia.infura.io/ws/v3/12345678901234567890123456789012 --nickname=Bob ``` ``` diff --git a/examples/rln/README.md b/examples/rln/README.md index aad4461b8..da81f7c12 100644 --- a/examples/rln/README.md +++ b/examples/rln/README.md @@ -10,7 +10,7 @@ Edit `main.go` and set proper values to these constants and variables: ```go const ethClientAddress = "wss://sepolia.infura.io/ws/v3/API_KEY_GOES_HERE" const ethPrivateKey = "PRIVATE_KEY_GOES_HERE" -const contractAddress = "0x9C09146844C1326c2dBC41c451766C7138F88155" +const contractAddress = "0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4" const credentialsPath = "" const credentialsPassword = "" diff --git a/examples/rln/main.go b/examples/rln/main.go index 6269ff49d..3c566d8df 100644 --- a/examples/rln/main.go +++ b/examples/rln/main.go @@ -25,13 +25,12 @@ var log = utils.Logger().Named("rln") // Update these values // ============================================================================ -const ethClientAddress = "wss://sepolia.infura.io/ws/v3/API_KEY_GOES_HERE" -const contractAddress = "0x9C09146844C1326c2dBC41c451766C7138F88155" -const keystorePath = "" // Empty to store in current folder -const keystorePassword = "" // Empty to use default -const membershipIndex = 0 - -var contentTopic = protocol.NewContentTopic("rln", 1, "test", "proto").String() +var ethClientAddress = "wss://sepolia.infura.io/ws/v3/API_KEY_GOES_HERE" +var contractAddress = "0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4" +var keystorePath = "./rlnKeystore.json" +var keystorePassword = "password" +var membershipIndex = uint(0) +var contentTopic, _ = protocol.NewContentTopic("rln", 1, "test", "proto") var pubsubTopic = protocol.DefaultPubsubTopic() // ============================================================================ @@ -51,7 +50,7 @@ func main() { ctx := context.Background() - spamHandler := func(message *pb.WakuMessage) error { + spamHandler := func(message *pb.WakuMessage, topic string) error { fmt.Println("Spam message received") return nil } @@ -66,7 +65,7 @@ func main() { keystorePassword, "", // Will use default tree path common.HexToAddress(contractAddress), - membershipIndex, + &membershipIndex, spamHandler, ethClientAddress, ), @@ -120,7 +119,7 @@ func write(ctx context.Context, wakuNode *node.WakuNode, msgContent string) { msg := &pb.WakuMessage{ Payload: payload, Version: version, - ContentTopic: contentTopic, + ContentTopic: contentTopic.String(), Timestamp: timestamp, } @@ -150,7 +149,7 @@ func readLoop(ctx context.Context, wakuNode *node.WakuNode) { } for envelope := range sub.Ch { - if envelope.Message().ContentTopic != contentTopic { + if envelope.Message().ContentTopic != contentTopic.String() { continue } diff --git a/scripts/linux/Dockerfile b/scripts/linux/Dockerfile index dd95d2049..9c128b3b3 100644 --- a/scripts/linux/Dockerfile +++ b/scripts/linux/Dockerfile @@ -1,5 +1,5 @@ # BUILD IMAGE -------------------------------------------------------- -FROM ubuntu:18.04 +FROM ubuntu:22.04 ARG UNAME=jenkins ARG UID=1001 ARG GID=1001 diff --git a/waku/v2/protocol/rln/keystore/keystore.go b/waku/v2/protocol/rln/keystore/keystore.go index 0b1e24267..a5bbd46d4 100644 --- a/waku/v2/protocol/rln/keystore/keystore.go +++ b/waku/v2/protocol/rln/keystore/keystore.go @@ -87,6 +87,11 @@ func (k *AppKeystore) GetMembershipCredentials(keystorePassword string, index *r var key Key var err error + + if len(k.Credentials) == 0 { + return nil, nil + } + if len(k.Credentials) == 1 { // Only one credential, the tree index does not matter. k.logger.Warn("automatically loading the only credential found on the keystore")