Core Running Modes
Available Running Modes
Core Server can be run in the following general modes:
- Relay Mode - listens to blockchain traffic, replicates and validates block data
- Forger Mode - creates new blocks and broadcasts them via relay nodes to the p2p network
- Relay and Forger Mode - both run under a single process
Starting a Node
If you want to start a node which consists of a relay
and forger
process you can use any of the following commands (inside packages/core
).
-
yarn core:mainnet
=>packages/core/bin/config/networks/mainnet
-
yarn core:devnet
=>packages/core/bin/config/networks/devnet
-
yarn core:testnet
=>packages/core/bin/config/networks/testnet
Starting a Relay
If you want to start a relay
you can use any of the following commands (inside packages/core
).
-
yarn relay:mainnet
=>packages/core/bin/config/networks/mainnet
-
yarn relay:devnet
=>packages/core/bin/config/networks/devnet
-
yarn relay:testnet
=>packages/core/bin/config/networks/testnet
Starting a Forger
If you want to start a forger
, you can use any of the following commands (inside packages/core
).
-
yarn forger:mainnet
=>packages/core/bin/config/networks/mainnet
-
yarn forger:devnet
=>packages/core/bin/config/networks/devnet
-
yarn forger:testnet
=>packages/core/bin/config/networks/testnet
The Core Boot Process
Command, yarn core:testnet
, is where the magic happens. Let us do a quick walkthrough of what happens when this command is run:
-
The
core:testnet
command is run withincore
, which as of the time of writing executes the following command innpm
:cross-env CORE_PATH_CONFIG=./bin/config/testnet CORE_ENV=test yarn ark core:run --networkStart
-
As seen in the previous step, the
./bin/run
file is called with thecore:run
command. That command looks like this:
- Take a look on the command config and the options passed by the
core:run
command as seen in the links above.
1import { Commands, Container, Contracts, Utils } from "@arkecosystem/core-cli"; 2import { Networks } from "@arkecosystem/crypto"; 3import Joi from "joi"; 4 5import { buildBIP38 } from "../internal/crypto"; 6 7@Container.injectable() 8export class Command extends Commands.Command { 9 public signature: string = "core:run";10 11 public description: string = "Run the Core process in foreground. Exiting the process will stop it from running.";12 13 public configure(): void {14 this.definition15 .setFlag("token", "The name of the token.", Joi.string().default("ark"))16 .setFlag("network", "The name of the network.", Joi.string().valid(...Object.keys(Networks)))17 .setFlag("env", "", Joi.string().default("production"))18 .setFlag("networkStart", "Indicate that this is the first start of seeds.", Joi.boolean())19 .setFlag("disableDiscovery", "Permanently disable all peer discovery.", Joi.boolean())20 .setFlag("skipDiscovery", "Skip the initial peer discovery.", Joi.boolean())21 .setFlag("ignoreMinimumNetworkReach", "Ignore the minimum network reach on start.", Joi.boolean())22 .setFlag("launchMode", "The mode the relay will be launched in (seed only at the moment).", Joi.string())23 .setFlag("bip38", "", Joi.string())24 .setFlag("bip39", "A delegate plain text passphrase. Referred to as BIP39.", Joi.string())25 .setFlag("password", "A custom password that encrypts the BIP39. Referred to as BIP38.", Joi.string());26 }27 28 public async execute(): Promise<void> {29 const flags: Contracts.AnyObject = { ...this.getFlags() };30 flags.processType = "core";31 32 await Utils.buildApplication({33 flags,34 plugins: {35 "@arkecosystem/core-p2p": Utils.buildPeerFlags(flags),36 "@arkecosystem/core-blockchain": {37 networkStart: flags.networkStart,38 },39 "@arkecosystem/core-forger": await buildBIP38(flags, this.app.getCorePath("config")),40 },41 });42 43 return new Promise(() => {});44 }45}
- We are going to take a brief look at the
bootstrap
method, found in thecore-kernel
package:
1public async bootstrap(options: { flags: JsonObject; plugins?: JsonObject }): Promise<void> { 2 this.bind<KeyValuePair>(Identifiers.ConfigFlags).toConstantValue(options.flags); 3 this.bind<KeyValuePair>(Identifiers.ConfigPlugins).toConstantValue(options.plugins || {}); 4 5 await this.registerEventDispatcher(); 6 7 await this.bootstrapWith("app"); 8} 9 10private async bootstrapWith(type: string): Promise<void> {11 const bootstrappers: Array<Constructor<Bootstrapper>> = Object.values(Bootstrappers[type]);12 const events: Contracts.Kernel.EventDispatcher = this.get(Identifiers.EventDispatcherService);13 14 for (const bootstrapper of bootstrappers) {15 events.dispatch(KernelEvent.Bootstrapping, { bootstrapper: bootstrapper.name });16 17 await this.resolve<Bootstrapper>(bootstrapper).bootstrap();18 19 events.dispatch(KernelEvent.Bootstrapped, { bootstrapper: bootstrapper.name });20 }21}
- After setting up environment variables based on the passed-in configuration, all Core plugins are loaded using the
options
key. You can find the enabled plugins in theapp.json
file located in thecore
package atbin/config/testnet
.
This last step is where the meat-and-potatoes of ARK Core is loaded. During this step, the Postgres database is set up, all ARK-specific tables and fields are migrated, the genesis block is created, 51 forging delegates are created and set up to forge blocks — all the blockchain goodness you would expect from of a fully-formed testnet.
A full walkthrough of the node setUp process will be accessible in the Guidebook shortly, and further posts in the tutorials will guide you through some of the most common functions you will want to perform with your testnet. However, by following the steps above, you will be up and running with your very own network.
Debugging
It is possible to run a variation of these commands that enables the Node debugger :
-
yarn debug:core
-
yarn debug:relay
-
yarn debug:forger
A good introduction about how to use the debugger is the guide to debugging of Node.js .
Testing
Every package that is developed should provide tests to guarantee it gives the expected behavior.
Our tool of choice for tests is Jest by Facebook which provides us with the ability to add custom matchers, snapshot testing and parallelizes our test runs.
All packages have a yarn test
command which you should run before sending a PR or pushing to GitHub to make sure all tests are passing. You could use yarn test:watch
to listen to changes on the files and run the tests automatically.
Additionally, we provide a variant (yarn test:debug
) that enables the Node debugger .
With theory covered let’s start our first local Testnet as shown below.