This campaign is over.
Quickstart
# Running a Koinos node
The Koinos cluster is comprised of multiple microservices. To simplify the deployment of the Koinos cluster, it is recommended to use the provided Docker compose script to launch a local node. The most time consuming part would be installing Docker, after that its just a matter of cloning the repository and running a single command.
## Installing on macOS/Linux
1. Download and install [Docker](https://www.docker.com/products/docker-desktop)
2. Clone (or download) the Koinos repository from [github](http://github.com/koinos/koinos)
3. Copy `config-example` to `config` and `env.example` to `.env`
4. Open the terminal in the downloaded directory and run the following command:
```console
$ docker compose --profile all up
```
## Installing on Windows
1. Download and install Docker
2. Clone (or download) the Koinos repository from [github](http://github.com/koinos/koinos)
3. Copy `config-example` to `config` and `env.example` to `.env`
4. Edit the first line in the .env file to read:
```console
BASEDIR=c:\koinos
```
5. Open the terminal in the downloaded directory and run the following command:
```console
$ docker compose up
```
---
## Managing a node
Nodes can be configured through two mechanisms, environment variables that change which servies are running, and the node config.
By default, each container will use `~/.koinos` on the host as their base directory. This can be changed by setting `BASEDIR` in `.env`, or exporting `BASEDIR`, to a different location on the host machine.
Different images can be run by setting environment variables or setting them in `.env`. For each microservice, append `_TAG` (e.g. `export P2P_TAG=64-auto-gossip`).
By default the node will only run core required microservices (chain, block_store, mempool, and p2p).
You can run optional microservices by enabling the associated docker compose profiles:
- `block_production` to enable the block production.
- `jsonrpc` to enable JSON-RPC API handling.
- `grpc` to enable gRPC API handling.
- `transaction_store` to enable transaction history tracking.
- `contract_meta_store` to enable service of contract ABIs.
- `account_history` to enable account history tracking.
- `api` to enable API related microservices (`jsonrpc`, `grpc`, `transaction_store`, `contract_meta_store`, and `account_history`).
- `all` to enable all microservices.
These profiles can be set with the `--profile` options (i.e. `docker compose --profile jsonrpc up`) or by setting the `COMPOSE_PROFILES` environment variable during invocation or in `.env`.
For more information on docker compose profiles, please read the official [documentation](https://docs.docker.com/compose/profiles/).
Inside the `config` directory are four config files, `config.yml`, `genesis_data.json`, `koinos_descriptors.pb`, and `rabbitmq.conf`.
`config.yml` directly configures the Koinos microservices. Options in the global namespace apply to all microservices. Options under a specific microservice apply just to that microservice. Many options, such as `log`, are the same across all microservices to allow configuration in the global namespace as well as microservice specific overrides.
`genesis_data.json` is the initial genesis state of the blockchain (block 0). This sets important system variables such as the genesis public key to boot the blockchain. The hash of all the genesis data is called the Chain ID. The Chain ID is used to quickly differentiate between different blockchains. This file should never be changed.
`koinos_descriptors.pb` is an encoded representation of all Koinos Protocol Buffers definitions. It is used by the JSON RPC microservice to service API calls. This file should be updated with new versions but not manually editted.
`rabbitmq.conf` is the configuration file for the AMQP microservice. It can be modified, but is recommended only advanced users modify this file. For more information on configuring Rabbit MQ, please read the official [documentation](https://www.rabbitmq.com/configure.html#config-items).
# Microservice options
These options can be set in the `config.yml`. If an option is shared by multiple microservices (such as `log`), you can set it for all of them by specifying it under `global`. Any option set for an individual microservice will override the global setting. Using this behavior you could enable debug level logging for one microservice while keeping info logs for the rest.
## Chain
- `help`: Print this help message and exit
- `version`: Print version string and exit
- `basedir`: Koinos base directory
- `amqp`: AMQP server URL
- `log-level`: The log filtering level
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: The number of worker jobs
- `read-compute-bandwidth-limit`: The compute bandwidth when reading contracts via the API
- `genesis-data`: The genesis data file
- `statedir`: The location of the blockchain state files (absolute path or relative to basedir/chain)
- `reset`: Reset the database
- `fork-algorithm`: The fork resolution algorithm to use. Can be 'pob', 'fifo', or 'block-time'. (Default: 'pob')
## Mempool
- `help`: Print this help message and exit
- `version`: Print version string and exit
- `basedir`: Koinos base directory
- `amqp`: AMQP server URL
- `log-level`: The log filtering level
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: The number of worker jobs
- `transaction-expiration`: The number of seconds a transaction should expire in
- `fork-algorithm`: The fork resolution algorithm to use. Can be 'fifo', 'pob', or 'block-time'. (Default: 'fifo')
## Block Store
- `amqp`: AMQP server URL
- `basedir`: Koinos base directory
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: Number of RPC jobs to run (default 32)
- `log-level`: The log filtering level
- `reset`: Reset the database
- `version`: Print version and exit
## P2P
- `amqp`: AMQP server URL
- `basedir`: Koinos base directory
- `checkpoint`: Block checkpoint in the form height:blockid (may specify multiple times)
- `disable-gossip`: Disable gossip mode
- `force-gossip`: Force gossip mode
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: Number of RPC jobs to run (default 32)
- `listen`: The multiaddress on which the node will listen
- `log-level`: The log filtering level
- `peer`: Address of a peer to which to connect (may specify multiple)
- `seed`: Seed string with which the node will generate an ID (A randomized seed will be generated if none is provided)
- `version`: Print version and exit
## Block Producer
- `help`: Print this help message and exit
- `version`: Print version string and exit
- `basedir`: Koinos base directory
- `amqp`: AMQP server URL
- `log-level`: The log filtering level
- `instance-id`: An ID that uniquely identifies the instance
- `algorithm`: The consensus algorithm to use
- `jobs`: The number of worker jobs
- `work-groups`: The number of worker groups
- `private-key-file`: The private key file
- `pow-contract-id`: The PoW contract ID
- `pob-contract-id`: The PoB contract ID
- `vhp-contract-id`: The VHP contract ID
- `max-inclusion-attempts`: The maximum transaction inclusion attempts per block
- `resources-lower-bound`: The lower bound of resource utilization a newly created block will be considered adequate for submission
- `resources-upper-bound`: The upper bound of resource utilization a newly created block should not exceed
- `gossip-production`: Use p2p gossip status to determine block production
- `producer`: The beneficiary address used during PoB production
- `approve-proposals`: A list a proposal to approve when producing a block
## Transaction Store
- `amqp`: AMQP server URL
- `basedir`: Koinos base directory
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: Number of RPC jobs to run (default 32)
- `log-level`: The log filtering level
- `reset`: Reset the database
- `version`: Print version and exit
## JSON-RPC
- `amqp`: AMQP server URL
- `basedir`: Koinos base directory
- `blacklist`: RPC targets to blacklist
- `descriptors`: The directory containing protobuf descriptors for rpc message types
- `endpoint`: HTTP listen endpoint
- `gateway-timeout`: The timeout to enqueue a request (default 3)
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: Number of jobs (default 16)
- `listen`: Multiaddr to listen on
- `log-level`: The log filtering level
- `mq-timeout`: The timeout for MQ requests (default 5)
- `version`: Print version and exit
- `whitelist`: RPC targets to whitelist
## gRPC
- `basedir`: Koinos base directory
- `amqp`: AMQP server URL
- `log-level`: The log filtering level
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: The number of worker jobs
- `mq-timeout`: The timeout for MQ requests
- `endpoint`: The endpoint the server listens on
- `whitelist`: RPC targets to whitelist
- `blacklist`: RPC targets to blacklist
## Contract Meta Store
- `amqp`: AMQP server URL
- `basedir`: Koinos base directory
- `instance-id`: An ID that uniquely identifies the instance
- `jobs`: Number of RPC jobs to run (default 32)
- `log-level`: The log filtering level
- `reset`: Reset the database
- `version`: Print version and exit
## Account History
- `help`: Print this help message and exit
- `version`: Print version string and exit
- `basedir`: Koinos base directory
- `amqp`: AMQP server URL
- `log-level`: The log filtering level
- `instance-id`: And ID that uniquely identifies the instance
- `jobs`: The number of worker jobs
- `statedir`: The location of the blockchain state files (absolute path or relative to basedir/chain)
- `reset`: Reset the database
- `fork-algorithm`: The fork resolution algorithm to use. Can be 'fifo', 'pob', or 'block-time'. (Default: 'fifo')</pre>
<pre># Block production
Koinos uses the novel consensus algorithm, Proof-of-Burn (PoB). To participate in block production you will need to configure your node as well as perform some simple actions on the blockchain.
## Proof-of-Burn basics
Proof-of-Burn has similarities to both Proof-of-Work (PoW) and Proof-of-Stake (PoS) with some notable differences. Like Proof-of-Stake, no mining occurs to produce blocks; this places all physical nodes on an equal playing field. Hashing is simulated in Proof-of-Burn by burning KOIN in order to gain Virtual Hash Power (VHP). Aside from using VHP rather than physical machines performing hashes, the algorithm works similarly to Proof-of-Work.
## Prerequisites
Please follow our guide on [running a node](../index.md). Be sure to start the node with the `--profile all` or `--profile block_producer` option to start the optional block producer microservice.
## Retrieving your address and key
Upon starting a new node, a private block production key will be automatically generated for you. This key will be at `$KOINOS_BASEDIR/block_producer/private.key` (`$KOINOS_BASEDIR` is `~/.koinos` on macOS/Linux and `C:\koinos` for Windows if following our guide). There is a corresponding `public.key` file that is written out when the block producer runs and is always the public key corresponding to the private key that the block producer is configured to use (`private.key` by default).
You will want to copy the contents of `public.key` and save this for later use. This is our "hot" key.
```console
cat $KOINOS_BASEDIR/block_producer/public.key
Aq4Ps_Ch-f8OZDnpQOov2SiMvdYyA5tn0oWa36QWnTeH
```
Next, you will want your main account to hold VHP and KOIN for block production. Let us use the `koinos-cli` to register the PoB contract and open the wallet for our main account.
```console
./koinos-cli -r http://localhost:8080/
🔐 > register pob 159myq5YUhhoVWu3wsHKHiJYKPKGUrGiyv
🔐 > open <wallet_file> <password>
```
Let us grab our main account address so that we can register it within the Proof-of-Burn contract.
```console
🔓 > address
Wallet address: 1P4msR22FXKHZragcLk2dCNweTEi9JWgxn
```
## Registering your key and burning
Using the address from our main account and the public key from our block producer we will now create the association in the Proof-of-Burn contract.
```console
🔓 > pob.register_public_key 1P4msR22FXKHZragcLk2dCNweTEi9JWgxn Aq4Ps_Ch-f8OZDnpQOov2SiMvdYyA5tn0oWa36QWnTeH
```
Next, we must burn some KOIN in order to receive VHP. Let us burn 10,000 KOIN in exchange for 10,000 VHP. The `pob.burn` call is requesting that 10,000 KOIN be burned from the first address and place 10,000 VHP in to the second address. In our case, we want the address to burn KOIN from to be the same that receives VHP.
```console
🔓 > pob.burn 1000000000000 1P4msR22FXKHZragcLk2dCNweTEi9JWgxn 1P4msR22FXKHZragcLk2dCNweTEi9JWgxn
```
> _**Note:** You may repeat this process to top off your VHP as you run your block producer over time. Do not burn your entire KOIN balance as you will need liquid KOIN and its associated mana in order to produce blocks._
## Configuring the block producer
At this point, the chain has all the information required in order for us to produce blocks. Let us update our block producer configuration file to reflect the information we provided the chain. We should uncomment or add the `producer` line to let the block producer know which account holds our VHP. Below is an example configuration using the address and key from this guide.
```yml
block_producer:
algorithm: pob
pob-contract-id: 159myq5YUhhoVWu3wsHKHiJYKPKGUrGiyv
vhp-contract-id: 1AdzuXSpC6K9qtXdCBgD5NUpDNwHjMgrc9
producer: 1P4msR22FXKHZragcLk2dCNweTEi9JWgxn
```
## Producing blocks
Now that our configuration file is prepared we may restart our block producer in order to use the new settings. From the directory containing your `docker-compose.yml` execute:
```console
docker compose restart block_producer
```
If everything is working as expected your block production logs should look like this:
```console
koinos-block_producer-1 | 2022-08-18 17:56:08.489496 (block_producer.Koinos) [block_producer.cpp:296] <info>: Produced block - Height: 220753, ID: 0x1220003c080793c08de2bb3a7d94986b85cbe4f0c8c3c9ad3b6dd036379bc048f421
koinos-block_producer-1 | 2022-08-18 17:56:08.495517 (block_producer.Koinos) [block_producer.cpp:219] <info>: Created block containing 0 transactions utilizing approximately 0/204800 disk, 0/1048576 network, 0/287500000 compute
koinos-block_producer-1 | 2022-08-18 17:56:08.501338 (block_producer.Koinos) [pob_producer.cpp:347] <info>: Difficulty target: 0x00000000000002c7bf812846eacfa2a3
koinos-block_producer-1 | 2022-08-18 17:56:08.502196 (block_producer.Koinos) [pob_producer.cpp:349] <info>: Estimated total VHP producing: 863917.30411773 VHP
koinos-block_producer-1 | 2022-08-18 17:56:08.502890 (block_producer.Koinos) [pob_producer.cpp:352] <info>: Producing with 10000.00000000 VHP
koinos-block_producer-1 | 2022-08-18 17:56:10.539163 (block_producer.Koinos) [pob_producer.cpp:98] <info>: Burn difficulty met at quantum 1660845375530
```
Congratulations, you are now producing blocks using Proof-of-Burn!<br /><br /></pre>
<pre># Developer guide
## C++ projects
Koinos projects that are written in C++ utilize [CMake](https://cmake.org/) for generating build files. CMake is a flexible pre-build step that allows developers to utilize a variety of Integrated Development Environments (IDE).
Dependencies are handled using the [Hunter package manager](https://github.com/cpp-pm/hunter). Hunter will download the necessary dependencies and compile them on your development machine as well as cache the resulting libraries. Normally, a developer need not be aware of the Hunter mechanism - which is its great advantage. Be aware that the first time you generate a CMake project it will build the dependency cache increasing your build times. Subsequent calls to CMake will leverage the Hunter cache.
### Dependencies
You will need a modern C++ compiler as well as CMake to build Koinos C++ projects. This should be easily handled by your operating systems package manager.
#### macOS
```console
$ brew install cmake
```
> _**Note:** If you have Xcode installed, you will have Apple Clang, which should be sufficient for Koinos projects._
```console
$ brew install cmake clang
```
> _**Note:** If you opt to not use Xcode or its compiler, you may install Clang using brew._
#### Debian/Ubuntu
```console
$ sudo apt install build-essentials libgmp cmake
```
### Building projects
For this example we will use the [Koinos Chain](https://github.com/koinos/koinos-chain) microservice. Let's begin by cloning the repository.
```console
$ git clone --recursive https://github.com/koinos/koinos-chain.git
```
> _Koinos makes heavy use of git submodules, so we recommend using `--recursive` when cloning a repository._
Now let's generate the project. One may opt to create Unix Makefiles, Xcode, or another project type that is supported by CMake (the default project is Unix Makefiles).
You may also choose to build Debug or Release files.
Below find some common CMake incantations.
```console
# Unix Makefile (Release mode)
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make -j
```
```console
# Unix Makefile (Debug mode)
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make -j
```
```console
# Xcode project
$ mkdir build
$ cd build
$ cmake -GXcode ..
$ open koinos_chain.xcodeproj
```
### Running unit tests
Koinos C++ projects use a combination of Boost test and CTest for unit testing. Tests are written in standard Boost test format while CTest allows for running tests in parallel.
After compilation, one may navigate to the `tests/` directory and invoke `ctest` to execute test suites.
[PLEASE REFER TO THE COMPLETE DOCUMENTATION HERE.][1]{:target='_blank'}
[1]: https://docs.koinos.io/