Skip to content

Commit

Permalink
chore: run with mysql
Browse files Browse the repository at this point in the history
  • Loading branch information
vasco-santos committed Dec 22, 2020
1 parent a2d5f83 commit 4fae672
Show file tree
Hide file tree
Showing 19 changed files with 479 additions and 198 deletions.
36 changes: 36 additions & 0 deletions .aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ const WebSockets = require('libp2p-websockets')
const Muxer = require('libp2p-mplex')
const { NOISE: Crypto } = require('libp2p-noise')

const { isNode } = require('ipfs-utils/src/env')
const delay = require('delay')
const execa = require('execa')
const pWaitFor = require('p-wait-for')
const isCI = require('is-ci')

let libp2p
let containerId

const before = async () => {
// Use the last peer
Expand Down Expand Up @@ -36,10 +43,39 @@ const before = async () => {
})

await libp2p.start()

// CI runs datastore service
if (isCI || !isNode) {
return
}

const procResult = execa.commandSync('docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=test-secret-pw -e MYSQL_DATABASE=libp2p_rendezvous_db -d mysql:8 --default-authentication-plugin=mysql_native_password', {
all: true
})
containerId = procResult.stdout

console.log(`wait for docker container ${containerId} to be ready`)

await pWaitFor(() => {
const procCheck = execa.commandSync(`docker logs ${containerId}`)
const logs = procCheck.stdout + procCheck.stderr // Docker/MySQL sends to the stderr the ready for connections...

return logs.includes('ready for connections')
}, {
interval: 5000
})
await delay(5e3)
}

const after = async () => {
await libp2p.stop()

if (isCI || !isNode) {
return
}

console.log('docker container is stopping')
execa.commandSync(`docker stop ${containerId}`)
}

module.exports = {
Expand Down
62 changes: 62 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: ci
on:
push:
branches:
- master
pull_request:
branches:
- '**'

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn
- run: yarn lint
- uses: gozala/typescript-error-reporter-action@v1.0.8
- run: yarn build
- run: yarn aegir dep-check
- uses: ipfs/aegir/actions/bundle-size@master
name: size
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
test-node:
needs: check
runs-on: ${{ matrix.os }}
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: test-secret-pw
MYSQL_DATABASE: libp2p_rendezvous_db
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
matrix:
os: [ubuntu-latest]
node: [12, 14]
fail-fast: true
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: yarn
- run: npx nyc --reporter=lcov aegir test -t node -- --bail
- uses: codecov/codecov-action@v1
test-chrome:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn
- run: npx aegir test -t browser -t webworker --bail
test-firefox:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn
- run: npx aegir test -t browser -t webworker --bail -- --browsers FirefoxHeadless
42 changes: 0 additions & 42 deletions .travis.yml

This file was deleted.

56 changes: 50 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p)
[![](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)

> Javascript implementation of the rendezvous protocol for libp2p
> Javascript implementation of the rendezvous server protocol for libp2p
## Lead Maintainer <!-- omit in toc -->

Expand All @@ -23,7 +23,7 @@

## Overview

Libp2p rendezvous is a lightweight mechanism for generalized peer discovery. It can be used for bootstrap purposes, real time peer discovery, application specific routing, and so on. Any node implementing the rendezvous protocol can act as a rendezvous point, allowing the discovery of relevant peers in a decentralized fashion.
Libp2p rendezvous is a lightweight mechanism for generalized peer discovery. It can be used for bootstrap purposes, real time peer discovery, application specific routing, and so on. This module is the implementation of the rendezvous server protocol for libp2p.

See the [SPEC](https://github.com/libp2p/specs/tree/master/rendezvous) for more details.

Expand All @@ -35,17 +35,37 @@ See the [SPEC](https://github.com/libp2p/specs/tree/master/rendezvous) for more
> npm install --global libp2p-rendezvous
```

Now you can use the cli command `libp2p-rendezvous-server` to spawn a libp2p rendezvous server.
Now you can use the cli command `libp2p-rendezvous-server` to spawn a libp2p rendezvous server. Bear in mind that a MySQL database is required to run the rendezvous server.

### Testing

For running the tests in this module, you will need to have Docker installed. A docker container is used to run a MySQL database for testing purposes.

### CLI

After installing the rendezvous server, you can use its binary. It accepts several arguments: `--peerId`, `--listenMultiaddrs`, `--announceMultiaddrs`, `--metricsPort` and `--disableMetrics`
After installing the rendezvous server, you can use its binary. It accepts several arguments: `--datastoreHost`, `--datastoreUser`, `--datastorePassword`, `--datastoreDatabase`, `--enableMemoryDatabase`, `--peerId`, `--listenMultiaddrs`, `--announceMultiaddrs`, `--metricsPort` and `--disableMetrics`

```sh
libp2p-rendezvous-server [--datastoreHost <hostname>] [--datastoreUser <username>] [datastorePassword <password>] [datastoreDatabase <name>] [--enableMemoryDatabase] [--peerId <jsonFilePath>] [--listenMultiaddrs <ma> ... <ma>] [--announceMultiaddrs <ma> ... <ma>] [--metricsPort <port>] [--disableMetrics]
```

For further customization (e.g. swapping the muxer, using other transports, use other database) it is recommended to create a server via the API.

#### Datastore

A rendezvous server needs to leverage a MySQL database as a datastore for the registrations. This needs to be configured in order to run a rendezvous server. You can rely on docker to run a MySQL database using a command like:

```sh
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=your-secret-pw -e MYSQL_DATABASE=libp2p_rendezvous_db -d mysql:8 --default-authentication-plugin=mysql_native_password
```

Once a MySQL database is running, you can run the rendezvous server by providing the datastore configuration options as follows:

```sh
libp2p-rendezvous-server [--peerId <jsonFilePath>] [--listenMultiaddrs <ma> ... <ma>] [--announceMultiaddrs <ma> ... <ma>] [--metricsPort <port>] [--disableMetrics]
libp2p-rendezvous-server --datastoreHost 'localhost' --datastoreUser 'root' --datastorePassword 'your-secret-pw' --datastoreDatabase 'libp2p_rendezvous_db'
```

For further customization (e.g. swapping the muxer, using other transports) it is recommended to create a server via the API.
⚠️ For testing purposes you can skip using MySQL and use a memory datastore. This must not be used in production! For this you just need to provide the `--enableMemoryDatabase` option.

#### PeerId

Expand Down Expand Up @@ -81,8 +101,32 @@ libp2p-rendezvous-server --disableMetrics

### Docker Setup



```yml
version: '3.1'
services:
db:
image: mysql
volumes:
- mysql-db:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: your-secret-pw
MYSQL_DATABASE: libp2p_rendezvous_db
ports:
- "3306:3306"
volumes:
mysql-db:
```
## Library
TODO
Datastores
## Contribute
Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/js-libp2p-rendezvous/issues)!
Expand Down
10 changes: 0 additions & 10 deletions mysql/Dockerfile

This file was deleted.

16 changes: 8 additions & 8 deletions mysql/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ services:
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
# MYSQL_ROOT_PASSWORD: my-secret-pw
# MYSQL_USER: libp2p
# MYSQL_PASSWORD: my-secret-pw
# MYSQL_DATABASE: libp2p_rendezvous_db
MYSQL_DATABASE: ${DATABASE}
MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD}
MYSQL_USER: ${USER}
MYSQL_PASSWORD: ${PASSWORD}
MYSQL_ROOT_PASSWORD: my-secret-pw
MYSQL_USER: libp2p
MYSQL_PASSWORD: my-secret-pw
MYSQL_DATABASE: libp2p_rendezvous_db
# MYSQL_DATABASE: ${DATABASE}
# MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD}
# MYSQL_USER: ${USER}
# MYSQL_PASSWORD: ${PASSWORD}
ports:
- "3306:3306"
volumes:
Expand Down
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"node": ">=12.0.0",
"npm": ">=6.0.0"
},
"browser": {
"mysql": false
},
"scripts": {
"lint": "aegir lint",
"build": "aegir build",
Expand All @@ -48,7 +51,7 @@
"it-buffer": "^0.1.2",
"it-length-prefixed": "^3.1.0",
"it-pipe": "^1.1.0",
"libp2p": "libp2p/js-libp2p#chore/add-typedfs-with-post-install",
"libp2p": "^0.30.0",
"libp2p-mplex": "^0.10.0",
"libp2p-noise": "^2.0.1",
"libp2p-tcp": "^0.15.1",
Expand All @@ -59,14 +62,18 @@
"mysql": "^2.18.1",
"peer-id": "^0.14.1",
"protons": "^2.0.0",
"streaming-iterables": "^5.0.2"
"streaming-iterables": "^5.0.2",
"uint8arrays": "^2.0.5"
},
"devDependencies": {
"aegir": "^29.2.2",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"delay": "^4.4.0",
"dirty-chai": "^2.0.1",
"execa": "^5.0.0",
"ipfs-utils": "^5.0.1",
"is-ci": "^2.0.0",
"p-defer": "^3.0.0",
"p-times": "^3.0.0",
"p-wait-for": "^3.1.0",
Expand Down
27 changes: 27 additions & 0 deletions sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
USE libp2p_rendezvous_db

CREATE TABLE IF NOT EXISTS registration (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
namespace varchar(255) NOT NULL,
peer_id varchar(255) NOT NULL,
PRIMARY KEY (id),
INDEX (namespace, peer_id)
);

CREATE TABLE IF NOT EXISTS cookie (
id varchar(21),
namespace varchar(255),
reg_id INT UNSIGNED,
peer_id varchar(255) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id, namespace, reg_id),
INDEX (created_at)
);

INSERT INTO registration (namespace, peer_id) VALUES ('test-ns', 'QmW8rAgaaA6sRydK1k6vonShQME47aDxaFidbtMevWs73t');

SELECT * FROM registration

SELECT * FROM cookie

INSERT INTO registration (namespace, peer_id) VALUES ('test-ns', 'QmZqCdSzgpsmB3Qweb9s4fojAoqELWzqku21UVrqtVSKi4');
17 changes: 10 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class Rendezvous {
const registerTasks = []

/**
* @param {Multiaddr} m
* @param {Multiaddr} m
* @returns {Promise<number>}
*/
const taskFn = async (m) => {
Expand Down Expand Up @@ -280,16 +280,19 @@ class Rendezvous {
// track registrations
yield registrationTransformer(r)

// Store cookie
const nsCookies = this._cookies.get(ns) || new Map()
nsCookies.set(m.toString(), toString(recMessage.discoverResponse.cookie))
this._cookies.set(ns, nsCookies)

limit--
if (limit === 0) {
return
break
}
}

// Store cookie
const c = recMessage.discoverResponse.cookie
if (c && c.length) {
const nsCookies = this._cookies.get(ns) || new Map()
nsCookies.set(m.toString(), toString(c))
this._cookies.set(ns, nsCookies)
}
}
}
}
Expand Down
Loading

0 comments on commit 4fae672

Please sign in to comment.