Installation guide



Install Java

  • Install Java JRE 11 or more.
sudo apt install openjdk-11-jdk

Install libsodium

The Sodium crypto library (libsodium) is a modern, easy-to-use software library for encryption, decryption, signatures, password hashing and more.

  • Get libsodium (version 1.0.14 or newer)
wget -kL
tar -xvf libsodium-1.0.14.tar.gz
  • Installation:
cd libsodium-1.0.14
sudo apt-get install build-essential
sudo ./configure
sudo make && sudo make check
sudo make install        

Install bundle (ElasticSearch and Cesium+ Pod)

  • Download lastest release of file

  • Unzip the archive:

    cd cesium-plus-pod-X.Y
  • Edit the configuration file config/elasticsearch.yml, in particular this properties:

  # Your ES cluster name cesium-plus-pod-g1-TEST

  # Your ES cluster public host name/port (optional - required for publishing peering document)
  cluster.remote.port: 443
  # Use a descriptive name for the node: ES-NODE-1
  # Set the bind address to a specific IP (IPv4 or IPv6):
  # Set a custom port for HTTP:
  http.port: 9200
  # Duniter node to connect with
  duniter.port: 10900
  # Initial list of hosts to perform synchronization
  duniter.p2p.includes.endpoints: [
    "ES_CORE_API 443",
    "ES_USER_API 443",

- Launch the Pod:

 cd cesium-plus-pod-X.Y/bin
 ./cesium-plus-pod start

 You should see in console something like (example on the [G1-test]( currency):
 $ ./cesium-plus-pod start
 [2016-09-24 00:16:45,803][INFO ][node                     ] [ES-NODE-1] version[2.4.6], pid[15365], build[218bdf1/2016-05-17T15:40:04Z]
 [2016-09-24 00:16:45,804][INFO ][node                     ] [ES-NODE-1] initializing ...
 [2016-09-24 00:16:46,257][INFO ][plugins                  ] [ES-NODE-1] modules [reindex, lang-expression, lang-groovy], plugins [mapper-attachments, cesium-plus-pod-g1-TEST], sites [cesium-plus-pod-g1-TEST]
 [2016-09-24 00:16:46,270][INFO ][env                      ] [ES-NODE-1] using [1] data paths, mounts [[/home (/dev/mapper/isw_defjaaicfj_Volume1p1)]], net usable_space [1tb], net total_space [1.7tb], spins? [possibly], types [ext4]
 [2016-09-24 00:16:46,270][INFO ][env                      ] [ES-NODE-1] heap size [989.8mb], compressed ordinary object pointers [true]
 [2016-09-24 00:16:47,757][INFO ][node                     ] [ES-NODE-1] initialized
 [2016-09-24 00:16:47,757][INFO ][node                     ] [ES-NODE-1] starting ...
 [2016-09-24 00:16:47,920][INFO ][transport                ] [ES-NODE-1] publish_address {}, bound_addresses {}
 [2016-09-24 00:16:47,924][INFO ][discovery                ] [ES-NODE-1] cesium-plus-pod-g1-TEST/jdzzh_jUTbuN26Enl-9whQ
 [2016-09-24 00:16:50,982][INFO ][cluster.service          ] [ES-NODE-1] detected_master {SERVERNAME}{FD0IzkxETM6tyOqzrKuVYw}{}{}, added {{SERVERNAME}{FD0IzkxETM6tyOqzrKuVYw}{}{},}, reason: zen-disco-receive(from master [{SERVERNAME}{FD0IzkxETM6tyOqzrKuVYw}{}{}])
 [2016-09-24 00:16:53,570][INFO ][http                     ] [ES-NODE-1] publish_address {}, bound_addresses {}
 [2016-09-24 00:16:53,570][INFO ][node                     ] [ES-NODE-1] started
 [2016-09-24 00:16:57,850][INFO ][node                     ] Checking Duniter indices...
 [2016-09-24 00:16:57,859][INFO ][node                     ] Checking Duniter indices... [OK]
 [2016-09-24 00:17:08,026][INFO ][duniter.blockchain       ] [g1-test] [] Indexing last blocks...
 [2016-09-24 00:17:08,026][INFO ][duniter.blockchain       ] [g1-test] [] Indexing block #999 / 41282 (2%)...
 [2016-09-24 00:17:08,045][INFO ][duniter.blockchain       ] [g1-test] [] Indexing block #1998 / 41282 (4%)...
 [2016-09-24 00:17:09,026][INFO ][duniter.blockchain       ] [g1-test] [] Indexing block #2997 / 41282 (6%)...
 [2016-09-24 00:17:10,057][INFO ][duniter.blockchain       ] [g1-test] [] Indexing block #3996 / 41282 (8%)...
 [2016-09-24 00:17:11,026][INFO ][duniter.blockchain       ] [g1-gtest] [] Indexing block #41282 - hash [00000AAD73B0E76B870E6779CD7ACCCE175802D7867C13B5C8ED077F380548C5]

- To show help, run `./cesium-plus-pod --help` :

 Usage: ./cesium-plus-pod {start|stop|restart|status} OPTIONS
   start        Start the Cesium+ Pod
   stop         Stop the Cesium+ Pod
   restart      Do a stop/start on the Cesium+ Pod
   status       Say if the the Cesium+ Pod is running
   -Dproperty=value             Configures an Elasticsearch specific property, like
   --property=value             Configures an elasticsearch specific property, like
   --property value
 PROPERTIES        Remote host to join the pod (outside your local network)
   --cluster.remote.port        Remote port to join the pod (outside your local network)               The local network interface to use
   --http.port                  The local port to use. Can be a range, like --http.port 9200-9210

## Test your node

### Using a web browser 

The following web address should works: http://localhost:9200/node/summary

### Using Cesium

You should also be able to use your Pod in the [Cesium]( application:

- In settings, enable to Cesium+ extension;
- Replace the Pod address (e.g. `localhost:9200`) ;
- check if profile's avatar, graph, etc. are displayed correctly. 

### Request the ES node

When a blockchain currency has been indexed, you can test some fun queries :

- get a block by number (e.g the block #0):
 [/blockchain/block/0](http://localhost:9200/blockchain/block/0) -> the original block
 [/g1-test/block/0](http://localhost:9200/g1-test/block/0) -> Same, with more fields    
- Block #125 with only hash, dividend and memberCount:

- All blocks using a pubkey (or whatever):

- All blocks with a dividend, with only some selected fields (like dividend, number, hahs).
Note : Query executed in command line, using CURL:

 curl -XGET 'http://localhost:9200/g1-test/block/_search' -d '{
 "query": {
         "bool" : {
             "filter": {
                 "exists" : { "field" : "dividend" }
     "_source": ["number", "dividend", "hash", "membersCount"]

## Update to latest version

- Download [latest stable version](

- Unzip into a new directory (e.g. `/opt/cesium-plus-vX.Y.Z`)

- Stop existing pod, if running: `/bin/cesium-plus-pod stop` 
or, if running as a `systemd` service: `sudo service cesium-plus-pod stop`

- From the old Pod directory: 
* Copy the directory `data`, that contains all indexed data, into the new installation directory
* Merge the old file `config/elasiticsearch.yml` with the new configuration file (using `diff` to compare options).
 cd path/to/old/cesium-plus-pod
 cp -r data /path/to/new/cesium-plus-pod
 diff config/elasticsearch.yml   /path/to/new/cesium-plus-pod/config/elasticsearch.yml

- Start the new pod: `/bin/cesium-plus-pod start`
If was running as systemd service, __don't forget__ to update the service file, to make sure it use the new 
installation directory;

- Check everething is fine, in logs:

tail -f /path/to/new/cesium-plus-pod/logs/<pod_cluster_name>.log

## More documentation

More documentation can be found here :

- Cesium+ Pod [development tutorial](./development_tutorial.html) (french);

- Cesium+ Pod [RESTfull HTTP API](./;
- [ElasticSearch official web site](
- [a good tutorial on ElasticSearch request API]( 

## Troubleshooting

### Error `Refused GET request to [/ws/event/user/…`

- Message:
    Refused GET request to [/ws/event/user/<pubkey>…

- Cause:

  Cesium try to open a WebSocket on your pod throw HTTP v1.0, and not throw HTTP v1.1.

  - Solution: 

    Configure your web server to force HTTP 1.1 connection.

    On a Nginx server: 
     * Edit the web site configuration (usually at `/etc/nginx/site-available/<site-name>`);
     * Add this lines:
    server {


      location /ws/ {
        # Replace by your Pod local address:
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        # This is required for quota by IP
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
      location / {
        # Replace by your Pod local address:
        proxy_set_header Host $host;
        # This is required for quota by IP 
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      * Restart Nginx service;

### Error `Could not find an implementation class`

- Message:
    java.lang.RuntimeException: java.lang.RuntimeException: Could not find an implementation class.
            at org.duniter.core.util.websocket.WebsocketClientEndpoint.<init>(
            at org.duniter.core.client.service.bma.BlockchainRemoteServiceImpl.addNewBlockListener(
            at org.duniter.elasticsearch.service.BlockchainService.listenAndIndexNewBlock(

- Cause:

  Plugin use Websocket to get notification from a Duniter nodes. The current library ([Tyrus]( is loaded throw java Service Loader, that need access to file `META-INF/services/javax.websocket.ContainerProvider` contains by Tyrus.
  ElasticSearch use separated classloader, for each plugin, that disable access to META-INF resource.

- Solution :

  Move Tyrus libraries into elasticsearch `lib/` directory :

    cd <INSTALL_DIR>
    mv plugins/cesium-plus-pod-core/tyrus-*.jar lib
    mv plugins/cesium-plus-pod-core/javax.websocket-api-*.jar lib