MCC

The MESH Companion Container (MCC) is a p2p layer and modified Kademlia DHT that provides functionality for service discovery, data storage (including DID documents), encrypted communication channels.

Table of Contents

Quickstart

In this part, we set you up to build and run MCC.

Build

The prerequisites for building MCC are as follows:

  • Go >= 1.17
  • make
  • libsodium and libsodium-dev. Install it with your favourite package manager.

Open the terminal window and run:

git clone <ADDR>
cd mcc
make build

A binary file with the name mcc is created.

List of flags

Flag Default Description Env
-loglevel [0-6] 4 Set the logging level, 0 is lowest (less logs), 6 is highest (more logs).
-boot <addr>,<addr> A list of bootnodes that the MCC will contact to populate its routing table and register itself in the network. For example -boot 127.0.0.1:8000,127.0.0.1:8001. BOOT
-cert <path_to_cert> Path to the file with certificate base64 encoded string. If not provided or “random” is passed – random certificate will be generated. See Certificates section for more information about certificates. CERTIFICATE
-privkey <path_to_private_key> Path to the file with private key base64 encoded string. If not provided – random certificate mode is required. See Certificates section for more information about certificates. PRIVKEY
-listen <addr> 127.0.0.1:9376 Specify the UDP address on which the MCC will listen for new packets. LISTEN
-http <addr> 127.0.0.1:8080 This address is used to serve the REST-API. HTTP
-enable-cors <cors> List of addresses for which CORS would be enabled. Pass * to enable CORS for any domain. CORS
-data-folder <folder> ./.mcc/ Set a folder for storing binary data.
-keep-blobs <bool> true The node will claim itself a seeder after getting a BLOB from another node
-cpu-profile <N> 0 CPU profile write interval (seconds). 0 means profiling is disabled.
-goroutine-profile <N> 0 Goroutine profile write interval (seconds). 0 means profiling is disabled.
-heap-profile <N> 0 Heap profile write interval (seconds). 0 means profiling is disabled.
-profile-dir <folder> traces A directory to write profiles.
-enable-monitoring Monitoring using prometheus at /metrics.
-dht-alpha N 3 The concurrency factor. Larger values reduce time consumed by DHT operations, but may significantly increase the CPU and network load.
-version Print MCC version.
-help Print the usage message.
-newcert Generate, save a new random certificate, certificate request and exit.
-trust-ca <path_to_root_ca_cert> Path to the file with root CA server certificate base64 encoded string. See Certificates section for more information about certificates. TRUSTCACERT
-label <node_label> random_name Set a human-readable name for MCC node. It will be normalized to lowercase, characters which are not symbols or numbers will be trimmed. Label cannot be more than 30 byte (simplified – 30 “single-byte” symbols, see ASCII). If not provided – random label will be generated.
-config <config_file> A config file with initial setup. See the config section.

Certificates

The default option is to use MCC with random generated certificate – if no parameter passed, but you could also set it explicitly by setting -cert random.
Use -privkey for private key path defining if certificate path is set.
To generate a random certificate with All permissions, use the -newcert. In order to create a customized one, please use the https://github.com/staex-mcc/certlib library.

Node label

Node label is the part of node certificate. You can set your own label (use the -label flag) for the first start of the mcc node.
If node certificate is defined – -label flag will be ignored.
Use -label flag with -newcert flag for custom label in new random certificate.
If -label is not provided – random label will be generated.

Config file

A config file provides some initial setup for services and port listeners.

services:
  - name: service3
    address: "tcp://localhost:1111"


listen:
  - service: service
    address: "tcp://localhost:5000"

  - service: service2
    address: "tcp://localhost:5001"

Starting local nodes

Start one MCC-node with automatic configuration by executing the main binary:

$ ./mcc 

Start two nodes from two shell instances that connect to each other on your local machine.
Run the first node on first shell with a specified socket for incoming UDP packets and an HTTP-Server on 127.0.0.1:8080.
The second node needs to listen on a different port, in the example, the first node is specified as bootnode.
In order to run 2 MCC instances from the same binary (and same directory), you need to explicitly specify different data folders (-data-folder).

Shell 1: $ ./mcc -listen 127.0.0.1:9376 -http 127.0.0.1:8080 -data-folder ./.data/node1

Shell 2: $ ./mcc -listen 127.0.0.1:9375 -http 127.0.0.1:8081 -boot 127.0.0.1:9376 -data-folder ./.data/node2

Interacting with nodes

Communication and interaction with client nodes via REST

Interaction with MCC nodes is enabled via the REST API. You can either access the REST API via tools like curl or wget or you can use the SWAGGER UI. Follow the steps below to try that out:

Start a node with a REST API on 127.0.0.1:8080 and enabled Cross-origin resource sharing (CORS):

$ ./mcc -listen 127.0.0.1:9375 -http 127.0.0.1:8080 -enable-cors '*'

Then from the root directory build and run the Swagger container.

$ cd swagger
$ docker build -t mcc-swagger .
$ docker run -d -p 80:8080 -v $(pwd):/usr/share/nginx/html/swagger mcc-swagger

Then open your browser and navigate to localhost:80. The Swagger UI should appear. Select the node (localhost:8080) in the Servers-dropdown.

Swagger OpenAPI documentation

The API specification is available here.

Client library

Golang client library for MCC provides access to the REST API via the interface lib.MCCInterface (see pkg/lib/lib.go).
You can find the implementation in pkg/client/mcc_client.go.

Embedded MCC

MCC can be run embedded into another golang application. Please see pkg/mcc/mcc.go for the implementation.

Logging

MCC uses the staxlog library for logging. Changing of logging parameters is available via staxlog.Init() method.
For example, in order to change the log level to debug, make the following call:

staxlog.Init(&staxlog.Options{
    Level: "debug",
})

Also, you can use the build tag mcclogprefix to append the word mcc to the component name.
That would clearly highlight each MCC message. In order to do that modify the build command to contain this tag:
go build ... -tags mcclogprefix.

Tests

The test reference is available here.

Known Issues

Unable to reuse the same connection for another request after a forwarding.

If you make a forwarding request (either http or tcp one) to some service, please don’t use the same connection
to send another request to a different service or MCC. In this case please open a new HTTP connection.

It’s OK if you send several requests to a single service via the same connection.

Using nginx as a reverse proxy.

The default nginx settings don’t work well with MCC. ngx_http_proxy_module should be configured to use HTTP 1.1 and
keep-alive connections should be disabled (see the previous known issue).

Here is the nginx location configuration to correctly proxify requests to MCC:

proxy_pass http://mcc-node-address:8080;
proxy_http_version 1.1;
keepalive_requests 0;
keepalive_timeout 0;

“sendto: invalid argument” error

You might be running out of ARP cache if you have a lot of sendto: invalid argument messages.
In such a case, please consider increasing limits:

sysctl -w net.ipv4.neigh.default.gc_thresh1=1024
sysctl -w net.ipv4.neigh.default.gc_thresh2=4096
sysctl -w net.ipv4.neigh.default.gc_thresh3=8192
sysctl -w net.ipv6.neigh.default.gc_thresh1=1024
sysctl -w net.ipv6.neigh.default.gc_thresh2=4096
sysctl -w net.ipv6.neigh.default.gc_thresh3=8192

Additional Info

For more information please check the Specification.

GitHub

View Github