fix: make autostart default behavior, remove start/create node endpoints

This commit is contained in:
Arseniy Klempner 2025-09-04 16:56:03 -07:00
parent a05d8a7bc0
commit 15d8134e5f
No known key found for this signature in database
GPG Key ID: 51653F18863BD24B
7 changed files with 20 additions and 162 deletions

View File

@ -53,9 +53,7 @@ This will:
- `GET /debug/v1/info`: Get debug information from the Waku node
- `POST /push`: Push a message to the Waku network (legacy)
- `POST /lightpush/v1/message`: Push a message to the Waku network (Waku REST API compatible)
- `POST /admin/v1/create-node`: Create a new Waku node (requires networkConfig)
- `POST /admin/v1/start-node`: Start the Waku node
- `POST /admin/v1/stop-node`: Stop the Waku node
- Waku nodes are now automatically created and started when the server launches
- `POST /admin/v1/peers`: Dial to specified peers (Waku REST API compatible)
- `GET /filter/v2/messages/:contentTopic`: Subscribe to messages on a specific content topic using Server-Sent Events (Waku REST API compatible)
- `GET /filter/v1/messages/:contentTopic`: Retrieve stored messages from a content topic (Waku REST API compatible)
@ -91,29 +89,13 @@ curl -X POST http://localhost:3000/execute \
-d '{"functionName": "getPeerInfo", "params": []}'
```
### Example: Creating a Waku node
### Node Configuration
```bash
curl -X POST http://localhost:3000/admin/v1/create-node \
-H "Content-Type: application/json" \
-d '{
"defaultBootstrap": true,
"networkConfig": {
"clusterId": 1,
"shards": [0, 1]
}
}'
```
Waku nodes are automatically created and started when the server launches. Configuration is controlled via environment variables:
### Example: Starting and stopping a Waku node
```bash
# Start the node
curl -X POST http://localhost:3000/admin/v1/start-node
# Stop the node
curl -X POST http://localhost:3000/admin/v1/stop-node
```
- `WAKU_CLUSTER_ID`: Set the cluster ID (default: uses bootstrap configuration)
- `WAKU_SHARD`: Set a specific shard (optional)
- `WAKU_LIGHTPUSH_NODE`: Specify a preferred lightpush node address (optional)
### Example: Dialing to specific peers with the Waku REST API compatible endpoint

View File

@ -1,49 +0,0 @@
import { Router } from "express";
import { createEndpointHandler, validators } from "../utils/endpoint-handler.js";
const router = Router();
// HEAD endpoints for CORS preflight
router.head("/admin/v1/create-node", (_req, res) => {
res.status(200).end();
});
router.head("/admin/v1/start-node", (_req, res) => {
res.status(200).end();
});
// Create Waku node endpoint
router.post("/admin/v1/create-node", createEndpointHandler({
methodName: "createWakuNode",
validateInput: (body) => {
if (!body.networkConfig || body.networkConfig.clusterId === undefined) {
throw new Error("networkConfig.clusterId is required");
}
return {
defaultBootstrap: body.defaultBootstrap ?? true,
networkConfig: body.networkConfig
};
},
transformResult: (result) => ({
success: result?.success || false,
message: result?.success ? "Waku node created successfully" : "Failed to create Waku node"
})
}));
// Start Waku node endpoint
router.post("/admin/v1/start-node", createEndpointHandler({
methodName: "startNode",
validateInput: validators.noInput,
transformResult: (result) => {
const success = result && (result.success === undefined || result.success);
return {
success,
message: success ? "Waku node started successfully" : "Failed to start Waku node",
...(result?.error && { details: result.error })
};
}
}));
export default router;

View File

@ -6,9 +6,6 @@ const router = Router();
// CORS preflight handlers
const corsEndpoints = [
"/waku/v1/create-node",
"/waku/v1/start-node",
"/waku/v1/stop-node",
"/waku/v1/wait-for-peers",
"/waku/v1/dial-peers",
"/waku/v1/peer-info",
@ -25,33 +22,7 @@ corsEndpoints.forEach(endpoint => {
});
});
// Node lifecycle endpoints
router.post("/waku/v1/create-node", createEndpointHandler({
methodName: "createWakuNode",
validateInput: validators.requireNetworkConfig,
transformResult: (result) => ({
success: result?.success || false,
message: result?.success ? "Waku node created successfully" : "Failed to create Waku node"
})
}));
router.post("/waku/v1/start-node", createEndpointHandler({
methodName: "startNode",
validateInput: validators.noInput,
transformResult: (result) => ({
success: result?.success || false,
message: result?.success ? "Waku node started successfully" : "Failed to start Waku node"
})
}));
router.post("/waku/v1/stop-node", createEndpointHandler({
methodName: "stopNode",
validateInput: validators.noInput,
transformResult: (result) => ({
success: result?.success || false,
message: result?.success ? "Waku node stopped successfully" : "Failed to stop Waku node"
})
}));
// Node lifecycle is now handled automatically on server start
// Messaging endpoints

View File

@ -4,7 +4,6 @@ import * as path from "path";
import cors from "cors";
import express, { Request, Response } from "express";
import adminRouter from "./routes/admin.js";
import wakuRouter from "./routes/waku.js";
import { initBrowser, getPage, closeBrowser } from "./browser/index.js";
@ -64,7 +63,6 @@ app.get("/app/index.html", (_req: Request, res: Response) => {
// Serve static files (excluding index.html which is handled above)
app.use("/app", express.static(webDir, { index: false }));
app.use(adminRouter);
app.use(wakuRouter);

View File

@ -148,14 +148,6 @@ export function createEndpointHandler<TInput = any, TOutput = any>(
* Common validation functions
*/
export const validators = {
requireNetworkConfig: (body: any) => {
if (!body.networkConfig || body.networkConfig.clusterId === undefined) {
throw new Error("networkConfig.clusterId is required");
}
return body;
},
requireLightpushV3: (body: any): LightpushV3Request => {
if (!body.pubsubTopic || typeof body.pubsubTopic !== "string") {
throw new Error("pubsubTopic is required and must be a string");

View File

@ -106,29 +106,17 @@ test("container: health endpoint", async () => {
expect(res.data.status).toBe("Waku simulation server is running");
});
// New focused test: validate create-node using window.wakuApi.start()
test("container: create-node only (wakuApi.start)", async () => {
const res = await axios.post(`${baseUrl}/admin/v1/create-node`, {
defaultBootstrap: true,
networkConfig: {
clusterId: 1,
numShardsInCluster: 8 // Enable auto-sharding
}
});
// Test that the node is auto-created and auto-started
test("container: node auto-started", async () => {
// Node should be auto-created and started, so just check peer info
const res = await axios.get(`${baseUrl}/waku/v1/peer-info`);
expect(res.status).toBe(200);
expect(res.data.success).toBe(true);
expect(res.data.peerId).toBeDefined();
expect(res.data.multiaddrs).toBeDefined();
});
test("container: create/start node and push", async () => {
// Create node with required networkConfig
await axios.post(`${baseUrl}/admin/v1/create-node`, {
defaultBootstrap: true,
networkConfig: {
clusterId: 1,
numShardsInCluster: 8 // Enable auto-sharding
}
});
await axios.post(`${baseUrl}/admin/v1/start-node`);
test("container: node ready and push", async () => {
// Node is auto-created and started with environment variables
// Wait for Lightpush peers with longer timeout for real network connections
console.log("⏳ Waiting for Lightpush peers to connect...");
@ -268,18 +256,8 @@ test("cross-network message delivery: SDK light node receives server lightpush",
checkForMessage();
});
// Create and start server node
console.log("🔧 Creating server node...");
await axios.post(`${baseUrl}/admin/v1/create-node`, {
defaultBootstrap: true,
networkConfig: {
clusterId: 1,
numShardsInCluster: 8
}
});
await axios.post(`${baseUrl}/admin/v1/start-node`);
console.log("✅ Server node created and started");
// Server node is auto-created and started
console.log("✅ Server node auto-configured and ready");
// CRITICAL: Wait for server node to find peers BEFORE attempting to send
console.log("⏳ Waiting for server to connect to Lightpush peers...");

View File

@ -84,24 +84,10 @@ test.describe("Server Tests", () => {
expect(jsRes.data).toContain("WakuHeadless");
});
test("create and start Waku node", async () => {
test("Waku node auto-started", async () => {
try {
// Create a Waku node
const createRes = await axios.post(`${baseUrl}/admin/v1/create-node`, {
defaultBootstrap: true,
networkConfig: {
clusterId: 1
}
});
expect(createRes.status).toBe(200);
expect(createRes.data.success).toBe(true);
// Start the node
const startRes = await axios.post(`${baseUrl}/admin/v1/start-node`);
expect(startRes.status).toBe(200);
expect(startRes.data.success).toBe(true);
// Now the peer info endpoint should work
// Node should be auto-created and started on server initialization
// Check that the peer info endpoint works
const infoRes = await axios.get(`${baseUrl}/waku/v1/peer-info`);
expect(infoRes.status).toBe(200);
expect(infoRes.data.peerId).toBeDefined();