corda-checkers/README.md
2024-01-11 17:59:55 +01:00

12 KiB

Demo

https://cordacheckers.djmil.dev

Since it is a turn-based board game, to have a complete experience - be sure to use at least two players. There are three LOGINs for you to choose from:

  • alice
  • bobik
  • kumar

The PASSWORD is always the same:

qaz123

The UI would definitely benefit from an extra UX polishing, non the less it works quite well as an alternative for raw JSON messages shoveled around between servers :)

One important notice though, because it was decided to cut a few corners by directly deploying Corda 5.0 CSDE as a 'production' cluster - each state (turn) update takes significant time.. ~20 sec to be exact. At times this might be a bit confusing. Please be patient and pay attention to wibbly-wobbly dance of letters from action buttons -> it is an indication that the request is being processed. Also, the React UI uses 30 sec polling intervals to fetch updated State information from server. If you do not want to wait - you can trigger immediate fetch directly by hands: simply flip online-offline toggle at the top of the screen. It can be seen immediately after big CordaCheckers inscription.

Source code overview

Backend

SpringBoot middle-ware server. Connects React front-end and Corda back-end. The heart of the repo is CordaClient class. Essentially, the whole CordaCheckers project can be seen as a set of modules grouped around an idea of this class. It has extensive set of tests covering all Corda States, Commands and behavior of respective Contracts. The tests can be found at 'backend/src/test/java/djmil/cordacheckers/cordaclient/*.java'

Corda

Uses standard directory layout recommended for Corda applications. The most significant class in this repo, to my thinking, is '/corda/workflows/src/main/java/djmil/cordacheckers/gamestate/CommitTrx.java', as all Workflows essentially is a way to prepare next State and store it into vaults of involved parties. I shall say, my overall impression of Corda 5.0 documentation is unsatisfactory. At times, it has taste of a product that was rushed to production.. for example, at the time of me starting to work on corda-code, the tests were deliberately commented out from the official 'how-to' repository. Current version of 'how-to' repo do feature working test, but it seems that developers has forgot to publish updated versions for internal dependencies to maven central.. resulting in Gradle's inability to finish the build.

Webapp

React based UI build around set of API's exposed by SpringBoot server. I believe that webapp/src/api/games.js is a nice starting point to explore the rest of JS code.

Build instructions

This document is aiming to setup single all-in-one dedicated docker container to harbour CordaChecers development environment. It can also be used as a lazy man way of building & running production environmnent.

Create 'corda-prod' container

[luke@BB8 ~]$ docker run -it --name corda-prod ubuntu
root@a9a041421f99:/# exit

[luke@BB8 ~]$ docker start corda-prod
[luke@BB8 ~]$ docker attach corda-prod
root@a9a041421f99:/#

APT

root@a9a041421f99:/ apt update
root@a9a041421f99:/ apt install software-properties-common
root@a9a041421f99:/ apt install nano

Corda CSDE

Java Azul Zulu 11

Template tutorial

Import the Zulu Repository Key for Ubuntu

root@a9a041421f99:~ apt install gnupg

root@a9a041421f99:~ apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9

Add Zulu apt Repository

root@a9a041421f99:~ sudo apt-add-repository 'deb http://repos.azulsystems.com/ubuntu stable main'

Install Zulu OpenJDK Version 11 on Ubuntu

root@a9a041421f99:~ apt install zulu-11

root@a9a041421f99:~ java -version
 openjdk version "11.0.8" 2020-07-14 LTS
 OpenJDK Runtime Environment Zulu11.41+23-CA (build 11.0.8+10-LTS)
 OpenJDK 64-Bit Server VM Zulu11.41+23-CA (build 11.0.8+10-LTS, mixed mode)

Corda CLI

Official documemtation.

Use python web server to share the CLI binaries

oxbee@MacBook % cd corda-cli-installer-5.0.0.0 
oxbee@MacBook corda-cli-installer-5.0.0.0 % python3 -m http.server

Install WGET on to the 'corda-prpd'

root@a9a041421f99:/ apt-get install wget

Download CordaCli installer onto the 'corda-prod'

root@a9a041421f99:/ cd
root@a9a041421f99:~ ls
root@a9a041421f99:~ pwd
/root

root@a9a041421f99:~ wget -r corda-cli-installer-5.0.0.0 %host%:8000
...
Downloaded: 14 files, 178M in 16s (11.4 MB/s)

root@a9a041421f99:/%host% ls
corda-cli.jar  index.html  install.ps1  install.sh  plugins

Run the installer

root@a9a041421f99:/%host% install.sh

root@a9a041421f99:~/.corda/cli# pwd
/root/.corda/cli

root@a9a041421f99:~/.corda/cli# ls -la
total 27380
drwxr-xr-x 4 root root     4096 Nov 28 10:33 .
drwxr-xr-x 3 root root     4096 Nov 28 10:24 ..
-rw-r--r-- 1 root root 27999276 Nov 28 10:24 corda-cli.jar
-rwxr-xr-x 1 root root       91 Nov 28 10:24 corda-cli.sh
-rw-r--r-- 1 root root     1195 Nov 28 10:24 install.ps1
-rwxr-xr-x 1 root root      416 Nov 28 10:24 install.sh
drwxr-xr-x 2 root root     4096 Nov 28 10:33 logs
drwxr-xr-x 2 root root     4096 Nov 28 10:24 plugins
-rw-r--r-- 1 root root        8 Nov 28 10:33 profile.yaml

Add corda-cli.sh to the PATH

  • Creat an alias

    root@BB8:/$ nano ~/.bash_aliases
      + alias corda-cli=${HOME}/.corda/cli/corda-cli.sh
    source ~/.bashrc
    
  • Modifying .bashrc

    nano ~/.bashrc
      + export PATH=~/.corda/cli/:${PATH}
    source ~/.bashrc
    
  • Creating a symlink via ln -s source_file symbolic_link

    root@BB8:~/.corda/cli echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    
    root@BB8:~/.corda/cli ln -s ~/.corda/cli/corda-cli.sh /usr/local/bin/corda-cli
    
    root@BB8:~/.corda/cli corda-cli -h
    Usage: corda-cli [-h] [COMMAND]
    -h, -?, -help, --help   Display help and exit.
    

Docker inside Docker

We need to go deeper ;)

Create an image from a container

docker commit container_id imagename

[luke@BB8 ~]$ docker commit a9a041421f99 corda-cherckers
sha256:bd9e801599214c3e3d4b0cb1884bc94b76f085bbe8fc86fbde42c0077c4cb0ab

[luke@BB8 ~]$ docker image ls
REPOSITORY                 TAG       IMAGE ID       CREATED          SIZE
corda-cherckers            latest    bd9e80159921   23 seconds ago   781MB
gitea/gitea                latest    c24cd4cd2ad5   7 weeks ago      273MB

Mount your host's Docker socket to the container

[luke@BB8 ~]$ docker container rm corda-prod
[luke@BB8 ~]$ docker run -itd --name corda-prod -v /var/run/docker.sock:/var/run/docker.sock corda-cherckers
5676046d2dc2b82472230b3d028ba42aa37e9c5a9aeaaa420c167483beb5abd6

[luke@BB8 ~]$ docker ps
CONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                 PORTS     NAMES
5676046d2dc2   corda-cherckers                   "/bin/bash"              10 seconds ago   Up 9 seconds                     corda-prod

[luke@BB8 ~]$ docker exec -it corda-prod /bin/bash
root@5676046d2dc2:/# corda-cli -h
Usage: corda-cli [-h] [COMMAND]
  -h, -?, -help, --help   Display help and exit.

Install Docker

Official documentation. Use apt option. Eventually, you shall be able to run docker command inside container.

root@5babbb69aaa4:/# docker ps
CONTAINER ID   IMAGE                             COMMAND                  CREATED         STATUS                 PORTS     NAMES
5babbb69aaa4   corda-cherckers                   "/bin/bash"              9 minutes ago   Up 9 minutes                     corda-prod
f8cf3e498010   gitea/gitea:latest                "/usr/bin/entrypoint…"   6 weeks ago     Up 2 weeks                       gitea-front-1

Optional

Create corda user that has access to docker and owns the /sources directory.

[!INFO] Password: corda

root@b9a8b2a71d7d:/# groupadd docker
root@b9a8b2a71d7d:/# adduser corda
root@5babbb69aaa4:/# usermod -aG docker corda
root@b9a8b2a71d7d:/# chown corda /sources/

CordaApp

Clone source code repo

It looks that for some reason git was already installed. It is extremely important to have network mode set to HOST.

[luke@BB8 ~]$ docker run -itd --name corda-prod -v /var/run/docker.sock:/var/run/docker.sock -v corda-checkers-src:/sources --network host corda-checkers
b8b724b99be40077455cd57e50919b7baf0c8bb435faef596b07a44dd811e720

luke@BB8 ~]$ docker exec -it corda-prod /bin/bash
root@BB8:/# cd /sources/corda/

root@BB8:/$ cd /sources/
root@BB8:/sources$ git clone https://gitea.djmil.dev/HQLAx/CordaCheckers.git .

Commentout java path in gradle.properties, we have only one java version installed, so it will be used by default:

corda@b9a8b2a71d7d:/sources/corda$ nano gradle.properties

Build & run

oxbee@MacBook backend % ssh luke@bb8
[luke@BB8 ~]$ docker exec -it corda-prod2 /bin/bash
root@BB8:/ cd /source/cord
root@BB8:/ ./gradlew startCorda #run CSDE worker (shall not quit)
root@BB8:/ ./gradlew 5-vNodesSetup # deploy&run your Cordapp

SpringBoot

Aka middleware server.

Java17

Yes, we need two different Java versions for this to work :(

apt-get update
apt install openjdk-17-jdk

Check available java versions:

update-alternatives --config java

or

update-java-alternatives -l

Commit changes to the docker image

Processing triggers for libgdk-pixbuf-2.0-0:amd64 (2.42.8+dfsg-1ubuntu0.2) ...
root@BB8:/# exit
exit

[luke@BB8 ~]$ docker ps
CONTAINER ID   IMAGE                             COMMAND                  CREATED         STATUS                 PORTS     NAMES
eb0679d30d0b   corda-checkers                    "/bin/bash"              3 minutes ago   Up 3 minutes                     corda-prod

[luke@BB8 ~]$ docker commit -m "commit msg" eb0679 corda-checkers

Build & Run

We have to tell gradle where to find proper java version.

root@BB8:/sources/backend> ./gradlew --stop #stop current server
root@BB8:/sources/backend> ./gradlew bootrun -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64

Frontend

Node.js

Official instructions on how to install latest version.

Download and import the Nodesource GPG key

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

Create deb repository

NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

[!OPTIONAL] NODE_MAJOR can be changed depending on the version you need NODE_MAJOR=16 NODE_MAJOR=18 NODE_MAJOR=20 NODE_MAJOR=21

Run Update and Install

sudo apt-get update
sudo apt-get install nodejs -y

Check the versions

root@BB8:/sources/webapp> nodejs -v
v20.10.0
root@BB8:/sources/webapp> npm -v
10.2.3

NPM

NPM shall be installed by the previous step. And we are going to use SpringBoot to server JS as a set of static resources. So no additional SW installation needed (like npm install -g serve)

Note

At this point, you probably should make another commit to the docker image.

The final size of an image is about 2.2 Gig:

[luke@BB8 ~]$ docker images
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
corda-checkers     latest    76eddb47d7c5   54 seconds ago   2.16GB

Project dependancies

root@BB8:/sources/webapp> rm -rf build/ node_modules/ package-lock.json
root@BB8:/sources/webapp> npm install

Build and run

Build the release version of frontend

root@BB8:/sources/webapp> npm run build

Copy build directory to the backend

root@BB8:/sources/webapp> cp -r build/* ../backend/src/main/resources/static

You have to restart Springboot in order for changes to take effect.

root@BB8:/sources/backend> ./gradlew --stop
root@BB8:/sources/backend> ./gradlew bootrun -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64