diff --git a/.dockerignore b/.dockerignore index 672098a00ff..9f934264f34 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ -/.git +.git /mithril-test-lab /target +/**/data \ No newline at end of file diff --git a/mithril-aggregator/Makefile b/mithril-aggregator/Makefile index 2a4572a9c34..e49b4feeefe 100644 --- a/mithril-aggregator/Makefile +++ b/mithril-aggregator/Makefile @@ -25,4 +25,10 @@ help: @${CARGO} run -- -h doc: - ${CARGO} doc --no-deps --open \ No newline at end of file + ${CARGO} doc --no-deps --open + +docker-build: + cd ../ && docker build -t mithril/mithril-aggregator -f mithril-aggregator/Dockerfile . + +docker-run: + docker run --rm -p 8080:8080 --name='mithril-aggregator' mithril/mithril-aggregator diff --git a/mithril-aggregator/README.md b/mithril-aggregator/README.md index 6011842650b..35cb9de75f7 100644 --- a/mithril-aggregator/README.md +++ b/mithril-aggregator/README.md @@ -5,14 +5,16 @@ This is a first version of the Mithril Aggregagator --- -## Pre-requisites: + +## Pre-requisites **Install Rust** - Install a [correctly configured](https://www.rust-lang.org/learn/get-started) Rust toolchain (version 1.58.0+). - Install OpenSSL development libraries, for example on Ubuntu/Debian/Mint run `apt install libssl-dev` -## Download source code: +## Download source code + ```bash # Download sources from github git clone https://github.com/input-output-hk/mithril @@ -21,7 +23,8 @@ git clone https://github.com/input-output-hk/mithril cd mithril-aggregator ``` -## Development test and build: +## Development test and build + ```bash # Test make test @@ -36,7 +39,8 @@ make doc make debug ``` -## Release build and run binary: +## Release build and run binary + ```bash # Build and run in release with default configuration make run @@ -58,18 +62,18 @@ make build NETWORK=testnet URL_SNAPSHOT_MANIFEST=https://storage.googleapis.com/cardano-testnet/snapshots.json ./mithril-aggregator ``` -## Build and run Docker container: +## Build and run Docker container ```bash # Build Docker image -cd ../ -docker build -t mithril/mithril-aggregator -f mithril-aggregator/Dockerfile . +make docker-build # Run Docker container -docker run --rm -p 8080:8080 --name='mithril-aggregator' mithril/mithril-aggregator +make docker-run ``` ## Interact with the Mithril Aggregator + ```bash # Interact with the aggregator through the OpenAPI UI open -u https://input-output-hk.github.io/mithril/openapi-ui/ diff --git a/mithril-client/Makefile b/mithril-client/Makefile index 90c90e2c16c..a4f468b8535 100644 --- a/mithril-client/Makefile +++ b/mithril-client/Makefile @@ -34,3 +34,9 @@ help: doc: ${CARGO} doc --no-deps --open + +docker-build: + cd ../ && docker build -t mithril/mithril-client -f mithril-client/Dockerfile . + +docker-run: + docker run --rm --name='mithril-client' mithril/mithril-client diff --git a/mithril-client/README.md b/mithril-client/README.md index bbcf17f373d..e4fa623ceb4 100644 --- a/mithril-client/README.md +++ b/mithril-client/README.md @@ -7,15 +7,16 @@ * This cli implements a MVP version of a **Mithril Client**. --- -## Pre-requisites: + +## Pre-requisites **Install Rust** -- Install a [correctly configured](https://www.rust-lang.org/learn/get-started) Rust toolchain (version 1.58.0+). -- Install Rust [Clippy](https://github.com/rust-lang/rust-clippy) component. +* Install a [correctly configured](https://www.rust-lang.org/learn/get-started) Rust toolchain (version 1.58.0+). +* Install Rust [Clippy](https://github.com/rust-lang/rust-clippy) component. +## Download source code -## Download source code: ```bash # Download sources from github git clone https://github.com/input-output-hk/mithril @@ -24,7 +25,8 @@ git clone https://github.com/input-output-hk/mithril cd mithril-client ``` -## Development test and build: +## Development test and build + ```bash # Test make test @@ -39,7 +41,8 @@ make doc make debug ``` -## Release build and run binary: +## Release build and run binary + ```bash # Build and run in release with default configuration make run list @@ -62,13 +65,12 @@ make build NETWORK=testnet AGGREGATOR_ENDPOINT=http://aggregator.api.mithril.network/aggregator ./mithril-client ``` -## Build and run Docker container: +## Build and run Docker container ```bash # Build Docker image -cd ../ -docker build -t mithril/mithril-client -f mithril-client/Dockerfile . +make docker-build # Run Docker container -docker run --rm --name='mithril-client' mithril/mithril-client +make docker-run ``` diff --git a/mithril-signer/Makefile b/mithril-signer/Makefile index 1cf18abb2df..09d7258fca1 100644 --- a/mithril-signer/Makefile +++ b/mithril-signer/Makefile @@ -25,4 +25,10 @@ help: @${CARGO} run -- -h doc: - ${CARGO} doc --no-deps --open \ No newline at end of file + ${CARGO} doc --no-deps --open + +docker-build: + cd ../ && docker build -t mithril/mithril-signer -f mithril-signer/Dockerfile . + +docker-run: + docker run --rm --name='mithril-signer' mithril/mithril-signer \ No newline at end of file diff --git a/mithril-signer/README.md b/mithril-signer/README.md index 6beceb33f99..1360a660120 100644 --- a/mithril-signer/README.md +++ b/mithril-signer/README.md @@ -5,14 +5,15 @@ This is a first version of the Mithril Signer --- -## Pre-requisites: + +## Pre-requisites **Install Rust** - Install a [correctly configured](https://www.rust-lang.org/learn/get-started) Rust toolchain (version 1.58.0+). +## Download source code -## Download source code: ```bash # Download sources from github git clone https://github.com/input-output-hk/mithril @@ -21,7 +22,8 @@ git clone https://github.com/input-output-hk/mithril cd mithril-signer ``` -## Development test and build: +## Development test and build + ```bash # Test make test @@ -36,7 +38,8 @@ make doc make debug ``` -## Release build and run binary: +## Release build and run binary + ```bash # Build and run in release with default configuration make run @@ -58,13 +61,12 @@ make build NETWORK=testnet AGGREGATOR_ENDPOINT=http://aggregator.api.mithril.network/aggregator ./mithril-signer ``` -## Build and run Docker container: +## Build and run Docker container ```bash # Build Docker image -cd ../ -docker build -t mithril/mithril-signer -f mithril-signer/Dockerfile . +make docker-build # Run Docker container -docker run --rm --name='mithril-signer' mithril/mithril-signer +make docker-run ``` diff --git a/mithril-test-lab/mithril-devnet/.gitignore b/mithril-test-lab/mithril-devnet/.gitignore new file mode 100644 index 00000000000..f4558788217 --- /dev/null +++ b/mithril-test-lab/mithril-devnet/.gitignore @@ -0,0 +1,9 @@ +tx +logs +ipc +.log +artifacts +cardano-cli +cardano-node +tmp +.tar.gz \ No newline at end of file diff --git a/mithril-test-lab/mithril-devnet/README.md b/mithril-test-lab/mithril-devnet/README.md new file mode 100644 index 00000000000..fbb9d267347 --- /dev/null +++ b/mithril-test-lab/mithril-devnet/README.md @@ -0,0 +1,236 @@ +# Cardano/Mithril Private Devnet + +**This is a work in progress** :hammer_and_wrench: + +It scaffolds a private compound devnet with Cardano and Mithril nodes: + +* `N` Cardano BFT nodes +* `P` Cardano SPO nodes +* `1` Mithril Aggregator node (attached to the first Cardano BFT node) +* `P` Mithril Signer nodes (attached to each Cardano SPO nodes) + +## Credits + +This cli is inspired by this [script](https://github.com/input-output-hk/cardano-node/blob/master/scripts/byron-to-alonzo/mkfiles.sh) from the Cardano node team. + +## Pre-requisites + +* You need to run a Linux computer +* You need to have a recent version of `jq` running (1.6+) + +## Download source code + +```bash +# Download sources from github +git clone https://github.com/input-output-hk/mithril + +# Go to sources directory +cd mithril-test-lab/mitril-devnet + +# Chmod scripts +chmod u+x *.sh +``` + +## One step run with default configuration + +```bash +# Run devnet with 1 BFT node and 2 SPO nodes (with local docker images) +./devnet-run.sh + +# Run devnet with 1 BFT node and 2 SPO nodes (with remote docker images) +MITHRIL_IMAGE_ID=main-c9213ca ./devnet-run.sh + +# Logs devnet +./devnet-log.sh + +# Query devnet +./devnet-query.sh + +# Stop devnet +./devnet-stop.sh +``` + +## One step run with custom configuration + +```bash +# Run devnet with 2 BFT nodes and 5 SPO nodes +ROOT=artifacts NUM_BFT_NODES=2 NUM_POOL_NODES=5 ./devnet-run.sh + +# Logs devnet +ROOT=artifacts LINES=10 ./devnet-log.sh + +# Query devnet +ROOT=artifacts ./devnet-query.sh + +# Stop devnet +ROOT=artifacts ./devnet-stop.sh +``` + +## Step by step run with custom configuration + +```bash +# Parameters +ROOT=artifacts # Directory where artifacts are produced +NUM_BFT_NODES=1 # Number of Cardano BFT nodes +NUM_POOL_NODES=3 # Number of Cardano SPO nodes + +# Bootstrap devnet with 1 BFT nodes and 3 SPO nodes +rm -rf ${ROOT} && ./devnet-mkfiles.sh ${ROOT} ${NUM_BFT_NODES} ${NUM_POOL_NODES} + +# Change directory +cd ${ROOT} + +# Start devnet +./start.sh + +# Query devnet +./query.sh + +# Logs devnet +./log.sh 10 + +# Stop devnet +./stop.sh +``` + +## Artifacts generated for the network + +```bash +# Example of artifacts +tree artifacts +artifacts +├── activate.sh +├── addresses +│ ├── pool-owner1.addr +│ ├── pool-owner1.skey +│ ├── pool-owner1-stake.addr +│ ├── pool-owner1-stake.reg.cert +│ ├── pool-owner1-stake.skey +│ ├── pool-owner1-stake.vkey +│ ├── pool-owner1.vkey +│ ├── user1.addr +│ ├── user1.skey +│ ├── user1-stake.addr +│ ├── user1-stake.deleg.cert +│ ├── user1-stake.reg.cert +│ ├── user1-stake.skey +│ ├── user1-stake.vkey +│ ├── user1.vkey +│ ├── utxo1.addr +│ ├── utxo1.skey +│ └── utxo1.vkey +├── cardano-cli +├── cardano-node +├── docker-compose.yaml +├── log.sh +├── node-bft1 +│ ├── byron +│ │ ├── delegate.cert +│ │ ├── delegate.key +│ │ ├── genesis.json +│ │ └── genesis.spec.json +│ ├── configuration.yaml +│ ├── ipc +│ ├── shelley +│ │ ├── genesis.alonzo.json +│ │ ├── genesis.alonzo.spec.json +│ │ ├── genesis.json +│ │ ├── genesis.spec.json +│ │ ├── kes.skey +│ │ ├── kes.vkey +│ │ ├── node.cert +│ │ ├── operator.counter +│ │ ├── operator.skey +│ │ ├── operator.vkey +│ │ ├── vrf.skey +│ │ └── vrf.vkey +│ ├── start-node.sh +│ ├── topology.docker.json +│ ├── topology.json +│ └── tx +├── node-pool1 +│ ├── byron +│ │ ├── genesis.json +│ │ └── genesis.spec.json +│ ├── configuration.yaml +│ ├── ipc +│ ├── owner.skey +│ ├── owner.vkey +│ ├── registration.cert +│ ├── shelley +│ │ ├── genesis.alonzo.json +│ │ ├── genesis.alonzo.spec.json +│ │ ├── genesis.json +│ │ ├── genesis.spec.json +│ │ ├── kes.skey +│ │ ├── kes.vkey +│ │ ├── node.cert +│ │ ├── operator.counter +│ │ ├── operator.skey +│ │ ├── operator.vkey +│ │ ├── vrf.skey +│ │ └── vrf.vkey +│ ├── start-node.sh +│ ├── topology.docker.json +│ ├── topology.json +│ └── tx +├── query.sh +├── start.sh +└── stop.sh +``` + +## Example utxo & stakes informations retrieved from the network + +```bash +> Query Mithril/Cardano devnet +===================================================================== +=== Cardano Network +===================================================================== + +>> Query chain tip +{ + "era": "Alonzo", + "syncProgress": "100.00", + "hash": "b7fde5dea1a85879410c03c049f2ce199f9b1a17f22043e801ed7328a3a8f0ac", + "epoch": 4, + "slot": 400, + "block": 18 +} + +>> Query whole utxo + TxHash TxIx Amount +-------------------------------------------------------------------------------------- +23f3844ba659a38da8d857ebd6ec93528adc603cc46f1605cdabdaaea57111d0 0 447999157 lovelace + TxOutDatumNone +23f3844ba659a38da8d857ebd6ec93528adc603cc46f1605cdabdaaea57111d0 1 2000000 lovelace + TxOutDatumNone +2c754076364cfc2a5279e97165f7d46b4035f7ff288ae41c407e1c3001ab895c 0 448999157 lovelace + TxOutDatumNone +2c754076364cfc2a5279e97165f7d46b4035f7ff288ae41c407e1c3001ab895c 1 1000000 lovelace + TxOutDatumNone +32ca53e1d9c33b221aff44f57f94b25f4523170912a5fa5ff32cd1c26b72a70d 0 1002000000 lovelace + TxOutDatumNone + +>> Query stake pools +pool1vqpavnczv7v2nrlx4l8f0prn4g4hmdyakrpfa8svkgls5clz5ck +pool1s7rnz8hzkeu8fu62enc0x6smn2yzhnufrwxpxz0f4l2dk3vs4kc + +>> Query stake distribution + PoolId Stake frac +------------------------------------------------------------------------------ +pool1vqpavnczv7v2nrlx4l8f0prn4g4hmdyakrpfa8svkgls5clz5ck 1.052e-3 +pool1s7rnz8hzkeu8fu62enc0x6smn2yzhnufrwxpxz0f4l2dk3vs4kc 5.258e-4 + +===================================================================== +=== Mithril Network +===================================================================== + +>> Query pending certificate +>> Query snapshots +[ + { + "digest": "d508794f186c2a6c75ccf71f13fccf37256fd01246b3ec74bcf456ee6ed8dddd", + "certificate_hash": "a0386153a88a52683fc2bb6f97914221445dee335858b15f023cbadc1166b103", + "size": 6212, + "created_at": "2022-06-15T11:36:29.362686957Z", + "locations": [ + "http://0.0.0.0:8080/aggregator/snapshot/d508794f186c2a6c75ccf71f13fccf37256fd01246b3ec74bcf456ee6ed8dddd/download" + ] + } +] +``` diff --git a/mithril-test-lab/mithril-devnet/configuration.yaml b/mithril-test-lab/mithril-devnet/configuration.yaml new file mode 100644 index 00000000000..d4672de07bf --- /dev/null +++ b/mithril-test-lab/mithril-devnet/configuration.yaml @@ -0,0 +1,263 @@ +########################################################## +############### Mainnet ######### +############### Cardano Byron Node Configuration ######### +########################################################## + +##### Locations ##### + +GenesisFile: genesis.json +SocketPath: db/node.socket + +##### Blockfetch Protocol + +# The maximum number of used peers during bulk sync. +MaxConcurrencyBulkSync: 1 +# The maximum number of used peers when fetching newly forged blocks. +MaxConcurrencyDeadline: 2 + +#TODO: These parameters cannot yet be used in the config file, only on the CLI: +#DatabasePath: db/ +#Topology: configuration/mainnet-topology.json +#Port 7776 + +##### Core protocol parameters ##### + +# This is the instance of the Ouroboros family that we are running. +# "RealPBFT" is the real (permissive) OBFT protocol, which is what we use on +# mainnet in Byron era. +Protocol: RealPBFT + +# The mainnet does not include the network magic into addresses. Testnets do. +RequiresNetworkMagic: RequiresNoMagic + +##### Update system parameters ##### + +# This protocol version number gets used by block producing nodes as part +# of the system for agreeing on and synchronising protocol updates. +LastKnownBlockVersion-Major: 0 +LastKnownBlockVersion-Minor: 2 +LastKnownBlockVersion-Alt: 0 + +# In the Byron era some software versions are also published on the chain. +# We do this only for Byron compatibility now. +ApplicationName: cardano-sl +ApplicationVersion: 1 + +##### Logging configuration ##### + +# Enable or disable logging overall +TurnOnLogging: True + +# Enable the collection of various OS metrics such as memory and CPU use. +# These metrics are traced in the context name: 'cardano.node.metrics' and can +# be directed to the logs or monitoring backends. +TurnOnLogMetrics: True + +# Global logging severity filter. Messages must have at least this severity to +# pass. Typical values would be Warning, Notice, Info or Debug. +minSeverity: Info + +# Log items can be rendered with more or less verbose detail. +# Verbosity ranges from MinimalVerbosity, NormalVerbosity to MaximalVerbosity +TracingVerbosity: NormalVerbosity + +# The system supports a number of backends for logging and monitoring. +# This setting lists the backends that will be available to use in the +# configuration below. The logging backend is called Katip. +setupBackends: + - KatipBK + +# This specifies the default backends that trace output is sent to if it +# is not specifically configured to be sent to other backends. +defaultBackends: + - KatipBK + +# EKG is a simple metrics monitoring system. Uncomment the following to enable +# this backend and listen on the given local port and point your web browser to +# http://localhost:12788/ +# hasEKG: 12788 + +# The Prometheus monitoring system exports EKG metrics. Uncomment the following +# to listen on the given port. Output is provided on +# http://localhost:12789/metrics +# hasPrometheus: +# - "127.0.0.1" +# - 12789 + +# To enable the 'TraceForwarder' backend, uncomment the following setting. Log +# items are then forwarded based on an entry in 'mapBackends' to a separate +# process running a 'TraceAcceptor'. +# Example using UNIX pipes: +# traceForwardTo: +# tag: RemotePipe +# contents: "logs/pipe" +# +# Example using Windows named pipes: +# traceForwardTo: +# tag: RemotePipe +# contents: "\\\\.\\pipe\\acceptor" +# +# Example using network socket: +# traceForwardTo: +# tag: RemoteSocket +# contents: +# - "127.0.0.1" +# - "2997" + +# For the Katip logging backend we must set up outputs (called scribes) +# The available types of scribe are: +# FileSK for files +# StdoutSK/StderrSK for stdout/stderr +# JournalSK for systemd's journal system +# DevNullSK ignores all output +# The scribe output format can be ScText or ScJson. Log rotation settings can +# be specified in the defaults below or overidden on a per-scribe basis here. +setupScribes: + - scKind: FileSK + scName: "logs/devnet.log" + scFormat: ScText + + - scKind: StdoutSK + scName: stdout + scFormat: ScText + +# For the Katip logging backend this specifies the default scribes that trace +# output is sent to if it is not configured to be sent to other scribes. +defaultScribes: + - - FileSK + - "logs/devnet.log" + - - StdoutSK + - stdout + +# The default file rotation settings for katip scribes, unless overridden +# in the setupScribes above for specific scribes. +rotation: + rpLogLimitBytes: 5000000 + rpKeepFilesNum: 3 + rpMaxAgeHours: 24 + +##### Coarse grained logging control ##### + +# Trace output from whole subsystems can be enabled/disabled using the following +# settings. This provides fairly coarse grained control, but it is relatively +# efficient at filtering out unwanted trace output. + +# Trace BlockFetch client. +TraceBlockFetchClient: False + +# Trace BlockFetch decisions made by the BlockFetch client. +TraceBlockFetchDecisions: False + +# Trace BlockFetch protocol messages. +TraceBlockFetchProtocol: False + +# Serialised Trace BlockFetch protocol messages. +TraceBlockFetchProtocolSerialised: False + +# Trace BlockFetch server. +TraceBlockFetchServer: False + +# Trace BlockchainTime. +TraceBlockchainTime: False + +# Verbose tracer of ChainDB +TraceChainDb: True + +# Trace ChainSync client. +TraceChainSyncClient: False + +# Trace ChainSync server (blocks). +TraceChainSyncBlockServer: False + +# Trace ChainSync server (headers). +TraceChainSyncHeaderServer: False + +# Trace ChainSync protocol messages. +TraceChainSyncProtocol: False + +# Trace DNS Resolver messages. +TraceDNSResolver: False + +# Trace DNS Subscription messages. +TraceDNSSubscription: False + +# Trace error policy resolution. +TraceErrorPolicy: True + +# Trace local error policy resolution. +TraceLocalErrorPolicy: True + +# Trace block forging. +TraceForge: False + +# Trace Handshake protocol messages. +TraceHandshake: False + +# Trace IP Subscription messages. +TraceIpSubscription: False + +# Trace local ChainSync protocol messages. +TraceLocalChainSyncProtocol: False + +# Trace local Handshake protocol messages. +TraceLocalHandshake: False + +# Trace local TxSubmission protocol messages. +TraceLocalTxSubmissionProtocol: False + +# Trace local TxSubmission server. +TraceLocalTxSubmissionServer: False + +# Trace mempool. +TraceMempool: True + +# Trace Mux Events. +TraceMux: False + +# Trace TxSubmission server (inbound transactions). +TraceTxInbound: False + +# Trace TxSubmission client (outbound transactions). +TraceTxOutbound: False + +# Trace TxSubmission protocol messages. +TraceTxSubmissionProtocol: False + +##### Fine grained logging control ##### + +# It is also possible to have more fine grained control over filtering of +# trace output, and to match and route trace output to particular backends. +# This is less efficient than the coarse trace filters above but provides +# much more precise control. + +options: + # This routes metrics matching specific names to particular backends. + # This overrides the 'defaultBackends' listed above. And note that it is + # an override and not an extension so anything matched here will not + # go to the default backend, only to the explicitly listed backends. + mapBackends: + cardano.node.metrics: + - TraceForwarderBK + - EKGViewBK + cardano.node.release: + - TraceForwarderBK + - KatipBK + cardano.node.version: + - TraceForwarderBK + - KatipBK + cardano.node.commit: + - TraceForwarderBK + - KatipBK + + # redirects traced values to a specific scribe which is identified by its + # type and its name, separated by "::": + mapScribes: + cardano.node.metrics: + - "FileSK::logs/mainnet.log" + + # apply a filter on message severity on messages in a specific named context. + # this filter is applied additionally to the global 'minSeverity' and thus + # needs to be at least as high. + mapSeverity: + cardano.node.ChainDB: Notice + cardano.node.DnsSubscription: Debug diff --git a/mithril-test-lab/mithril-devnet/devnet-log.sh b/mithril-test-lab/mithril-devnet/devnet-log.sh new file mode 100755 index 00000000000..3cd5441a4a9 --- /dev/null +++ b/mithril-test-lab/mithril-devnet/devnet-log.sh @@ -0,0 +1,18 @@ +# Default values +if [ -z "${ROOT}" ]; then + ROOT="artifacts" +fi +if [ -z "${LINES}" ]; then + LINES="10" +fi + +# Change directory +cd ${ROOT} + +# Logs devnet +echo "=====================================================================" +echo " Logs Mithril/Cardano devnet" +echo "=====================================================================" +echo +./log.sh ${LINES} +echo \ No newline at end of file diff --git a/mithril-test-lab/mithril-devnet/devnet-mkfiles.sh b/mithril-test-lab/mithril-devnet/devnet-mkfiles.sh new file mode 100755 index 00000000000..897db561663 --- /dev/null +++ b/mithril-test-lab/mithril-devnet/devnet-mkfiles.sh @@ -0,0 +1,1028 @@ +#!/usr/bin/env bash + +set -e +#set -x + +# This script sets up a cluster that starts out in Byron, and can transition to Mary. +# +# The script generates all the files needed for the setup, and prints commands +# to be run manually (to start the nodes, post transactions, etc.). +# +# There are three ways of triggering the transition to Shelley: +# 1. Trigger transition at protocol version 2.0.0 (as on mainnet) +# The system starts at 0.0.0, and we can only increase it by 1 in the major +# version, so this does require to +# a) post an update proposal and votes to transition to 1.0.0 +# b) wait for the protocol to change (end of the epoch, or end of the last +# epoch if it's posted near the end of the epoch) +# c) change configuration.yaml to have 'LastKnownBlockVersion-Major: 2', +# and restart the nodes +# d) post an update proposal and votes to transition to 2.0.0 +# This is what will happen on the mainnet, so it's vital to test this, but +# it does contain some manual steps. +# 2. Trigger transition at protocol version 2.0.0 +# For testing purposes, we can also modify the system to do the transition to +# Shelley at protocol version 1.0.0, by uncommenting the line containing +# 'TestShelleyHardForkAtVersion' below. Then, we just need to execute step a) +# above in order to trigger the transition. +# This is still close to the procedure on the mainnet, and requires less +# manual steps. +# 3. Schedule transition in the configuration +# To do this, uncomment the line containing 'TestShelleyHardForkAtEpoch' +# below. It's good for a quick test, and does not rely on posting update +# proposals to the chain. +# This is quite convenient, but it does not test that we can do the +# transition by posting update proposals to the network. +# + +ROOT=$1 +NUM_BFT_NODES=$2 +NUM_POOL_NODES=$3 + +NODE_PORT_START=3000 +SUPPLY=1000000000 +NETWORK_MAGIC=42 +SECURITY_PARAM=2 +NODE_ADDR_PREFIX="172.16.238" +NODE_ADDR_INCREMENT=10 +CARDANO_BINARY_URL="https://hydra.iohk.io/build/13065769/download/1/cardano-node-1.34.1-linux.tar.gz" + +BFT_NODES=() +BFT_NODES_N=() +for (( i=1; i<=${NUM_BFT_NODES}; i++ )) + do + BFT_NODES=("${BFT_NODES[@]}" "node-bft${i}") + BFT_NODES_N=("${BFT_NODES_N[@]}" "${i}") +done +BFT_NODES=${BFT_NODES[@]} +BFT_NODES_N=${BFT_NODES_N[@]} + +POOL_NODES=() +POOL_NODES_N=() +UTXO_ADDRS=() +USER_ADDRS=() +POOL_ADDRS=() +for (( i=1; i<=${NUM_POOL_NODES}; i++ )) + do + POOL_NODES=("${POOL_NODES[@]}" "node-pool${i}") + POOL_NODES_N=("${POOL_NODES_N[@]}" "${i}") + UTXO_ADDRS=("${UTXO_ADDRS[@]}" "utxo${i}") + USER_ADDRS=("${USER_ADDRS[@]}" "user${i}") + POOL_ADDRS=("${POOL_ADDRS[@]}" "pool-owner${i}") +done +POOL_NODES=${POOL_NODES[@]} +POOL_NODES_N=${POOL_NODES_N[@]} +UTXO_ADDRS=${UTXO_ADDRS[@]} +USER_ADDRS=${USER_ADDRS[@]} +POOL_ADDRS=${POOL_ADDRS[@]} + +ALL_NODES="${BFT_NODES} ${POOL_NODES}" + +INIT_SUPPLY=$(( SUPPLY+2000000 )) +FUNDS_PER_GENESIS_ADDRESS=$((${INIT_SUPPLY} / ${NUM_BFT_NODES})) +FUNDS_PER_BYRON_ADDRESS=$((${FUNDS_PER_GENESIS_ADDRESS} - 1000000)) +# We need to allow for a fee to transfer the funds out of the genesis. +# We don't care too much, 1 ada is more than enough. + +OS=$(uname -s) DATE= +case $OS in + Darwin ) DATE="gdate";; + * ) DATE="date";; +esac + +START_TIME="$(${DATE} -d "now + 30 seconds" +%s)" + +if ! mkdir -p "${ROOT}"; then + echo "The ${ROOT} directory already exists, please move or remove it" + exit +fi + +# download cardano-cli & cardano-node +curl -s ${CARDANO_BINARY_URL} --output cardano-bin.tar.gz +mkdir tmp +tar xzf cardano-bin.tar.gz -C tmp +cp tmp/cardano-cli . +cp tmp/cardano-node . +rm -rf tmp +rm -f cardano-bin.tar.gz + +# and copy cardano-cli & cardano-node +cp cardano-cli ${ROOT}/cardano-cli +cp cardano-node ${ROOT}/cardano-node + +# copy and tweak the configuration +cp configuration.yaml ${ROOT}/ +sed -i ${ROOT}/configuration.yaml \ + -e 's/Protocol: RealPBFT/Protocol: Cardano\nPBftSignatureThreshold: 0.6/' \ + -e 's/minSeverity: Info/minSeverity: Info/' \ + -e 's/TracingVerbosity: NormalVerbosity/TracingVerbosity: MinimalVerbosity/' \ + -e 's/TurnOnLogMetrics: True/TurnOnLogMetrics: False/' \ + -e 's|GenesisFile: genesis.json|ByronGenesisFile: byron/genesis.json|' \ + -e '/ByronGenesisFile/ aAlonzoGenesisFile: shelley/genesis.alonzo.json' \ + -e '/ByronGenesisFile/ aShelleyGenesisFile: shelley/genesis.json' \ + -e 's/RequiresNoMagic/RequiresMagic/' \ + -e 's/LastKnownBlockVersion-Major: 0/LastKnownBlockVersion-Major: 5/' \ + -e 's/LastKnownBlockVersion-Minor: 2/LastKnownBlockVersion-Minor: 0/' \ + -e 's/LastKnownBlockVersion-Alt: 0/LastKnownBlockVersion-Alt: 0/' +# Options for making it easier to trigger the transition to Shelley +# If neither of those are used, we have to +# - post an update proposal + votes to go to protocol version 1 +# - after that's activated, change the configuration to have +# 'LastKnownBlockVersion-Major: 2', and restart the nodes +# - post another proposal + vote to go to protocol version 2 + +#uncomment this for an automatic transition after the first epoch +echo "TestShelleyHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml +echo "TestAllegraHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml +echo "TestMaryHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml +echo "TestAlonzoHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml +echo "TestEnableDevelopmentHardForkEras: True" >> ${ROOT}/configuration.yaml +echo "TestEnableDevelopmentNetworkProtocols: True" >> ${ROOT}/configuration.yaml + +#uncomment this to trigger the hardfork with protocol version 1 +#echo "TestShelleyHardForkAtVersion: 1" >> ${ROOT}/configuration.yaml + + +pushd ${ROOT} + +# create the node directories +for NODE in ${ALL_NODES}; do + + mkdir ${NODE} ${NODE}/byron ${NODE}/shelley ${NODE}/ipc ${NODE}/tx + +done + +# create the configuration files +for NODE in ${ALL_NODES}; do + + cp configuration.yaml ${NODE}/configuration.yaml + +done + +# create the topology files +NODE_PORT=NODE_PORT_START +TOPOLOGY='{"Producers": []}' +TOPOLOGY_DOCKER=$TOPOLOGY +for NODE in ${ALL_NODES}; do + + NODE_PORT=$(( ${NODE_PORT} + 1)) + echo ${NODE_PORT} > ${NODE}/port + NODE_ADDR="0.0.0.0" + TOPOLOGY=$(echo ${TOPOLOGY} | jq '.Producers[.Producers| length] |= . + {"addr": "'${NODE_ADDR}'","port": '${NODE_PORT}', "valency": 1}') + NODE_ADDR_DOCKER="${NODE_ADDR_PREFIX}.${NODE_ADDR_INCREMENT}" + NODE_ADDR_INCREMENT=$(( ${NODE_ADDR_INCREMENT} + 10)) + echo ${NODE_ADDR_DOCKER} > ${NODE}/host + TOPOLOGY_DOCKER=$(echo ${TOPOLOGY_DOCKER} | jq '.Producers[.Producers| length] |= . + {"addr": "'${NODE_ADDR_DOCKER}'","port": '3001', "valency": 1}') + +done +echo $TOPOLOGY | jq . > topology.json +echo $TOPOLOGY_DOCKER | jq . > topology.docker.json + +NODE_IX=0 +for NODE in ${ALL_NODES}; do + + cat topology.json | jq '.Producers |= del(.['${NODE_IX}'])' > ${NODE}/topology.json + cat topology.docker.json | jq '.Producers |= del(.['${NODE_IX}'])' > ${NODE}/topology.docker.json + NODE_IX=$(( ${NODE_IX} + 1)) + +done +rm topology.docker.json + +# Byron setup +cat > byron.genesis.spec.json < byron/address-00$((${N} - 1)) + + ./cardano-cli byron key signing-key-address \ + --testnet-magic ${NETWORK_MAGIC} \ + --secret byron/genesis-keys.00$((${N} - 1)).key > byron/genesis-address-00$((${N} - 1)) +done + +# Update Proposal and votes +./cardano-cli byron governance create-update-proposal \ + --filepath byron/update-proposal \ + --testnet-magic ${NETWORK_MAGIC} \ + --signing-key byron/delegate-keys.000.key \ + --protocol-version-major 1 \ + --protocol-version-minor 0 \ + --protocol-version-alt 0 \ + --application-name "cardano-sl" \ + --software-version-num 1 \ + --system-tag "linux" \ + --installer-hash 0 + +for N in ${BFT_NODES_N}; do + ./cardano-cli byron governance create-proposal-vote \ + --proposal-filepath byron/update-proposal \ + --testnet-magic ${NETWORK_MAGIC} \ + --signing-key byron/delegate-keys.00$((${N} - 1)).key \ + --vote-yes \ + --output-filepath byron/update-vote.00$((${N} - 1)) +done + +./cardano-cli byron governance create-update-proposal \ + --filepath byron/update-proposal-1 \ + --testnet-magic ${NETWORK_MAGIC} \ + --signing-key byron/delegate-keys.000.key \ + --protocol-version-major 2 \ + --protocol-version-minor 0 \ + --protocol-version-alt 0 \ + --application-name "cardano-sl" \ + --software-version-num 1 \ + --system-tag "linux" \ + --installer-hash 0 + +for N in ${BFT_NODES_N}; do + ./cardano-cli byron governance create-proposal-vote \ + --proposal-filepath byron/update-proposal-1 \ + --testnet-magic ${NETWORK_MAGIC} \ + --signing-key byron/delegate-keys.00$((${N} - 1)).key \ + --vote-yes \ + --output-filepath byron/update-vote-1.00$((${N} - 1)) +done + +echo "=====================================================================" +echo "Generated genesis keys and genesis files:" +echo +ls -1 byron/* +echo "=====================================================================" + + +# Shelley era. Set up our template +mkdir shelley +./cardano-cli genesis create --testnet-magic ${NETWORK_MAGIC} --genesis-dir shelley + +# Then edit the genesis.spec.json ... + +# We're going to use really quick epochs (300 seconds), by using short slots 0.2s +# and K=10, but we'll keep long KES periods so we don't have to bother +# cycling KES keys +sed -i shelley/genesis.spec.json \ + -e 's/"slotLength": 1/"slotLength": 0.75/' \ + -e 's/"activeSlotsCoeff": 5.0e-2/"activeSlotsCoeff": 0.05/' \ + -e 's/"securityParam": 2160/"securityParam": '${SECURITY_PARAM}'/' \ + -e 's/"epochLength": 432000/"epochLength": 100/' \ + -e 's/"maxLovelaceSupply": 0/"maxLovelaceSupply": 1000000000/' \ + -e 's/"decentralisationParam": 1.0/"decentralisationParam": 0.7/' \ + -e 's/"major": 0/"major": 4/' \ + -e 's/"updateQuorum": 5/"updateQuorum": 2/' + +# Now generate for real: + +./cardano-cli genesis create \ + --testnet-magic ${NETWORK_MAGIC} \ + --genesis-dir shelley/ \ + --gen-genesis-keys ${NUM_BFT_NODES} \ + --gen-utxo-keys ${NUM_POOL_NODES} + +echo "=====================================================================" +echo "Generated genesis keys and genesis files:" +echo +ls -1 shelley/* +echo "=====================================================================" + +echo "Generated genesis.json:" +echo +cat shelley/genesis.json +echo +echo "=====================================================================" + +# Copy the genesis files +for NODE in ${ALL_NODES}; do + + cp shelley/genesis*.json ${NODE}/shelley/ + +done + +# Make the pool operator cold keys +# This was done already for the BFT nodes as part of the genesis creation + +for NODE in ${POOL_NODES}; do + + ./cardano-cli node key-gen \ + --cold-verification-key-file ${NODE}/shelley/operator.vkey \ + --cold-signing-key-file ${NODE}/shelley/operator.skey \ + --operational-certificate-issue-counter-file ${NODE}/shelley/operator.counter + + ./cardano-cli node key-gen-VRF \ + --verification-key-file ${NODE}/shelley/vrf.vkey \ + --signing-key-file ${NODE}/shelley/vrf.skey + +done + +# Copy the BFT operator keys from the genesis delegates, for uniformity + +for N in ${BFT_NODES_N}; do + + cp shelley/delegate-keys/delegate${N}.skey node-bft${N}/shelley/operator.skey + cp shelley/delegate-keys/delegate${N}.vkey node-bft${N}/shelley/operator.vkey + cp shelley/delegate-keys/delegate${N}.counter node-bft${N}/shelley/operator.counter + cp shelley/delegate-keys/delegate${N}.vrf.vkey node-bft${N}/shelley/vrf.vkey + cp shelley/delegate-keys/delegate${N}.vrf.skey node-bft${N}/shelley/vrf.skey + +done + + +# Make hot keys and for all nodes + +for NODE in ${ALL_NODES}; do + + ./cardano-cli node key-gen-KES \ + --verification-key-file ${NODE}/shelley/kes.vkey \ + --signing-key-file ${NODE}/shelley/kes.skey + + ./cardano-cli node issue-op-cert \ + --kes-period 0 \ + --kes-verification-key-file ${NODE}/shelley/kes.vkey \ + --cold-signing-key-file ${NODE}/shelley/operator.skey \ + --operational-certificate-issue-counter-file ${NODE}/shelley/operator.counter \ + --out-file ${NODE}/shelley/node.cert + +done + +echo "Generated node operator keys (cold, hot) and operational certs:" +echo +ls -1 ${ALL_NODES} +echo "=====================================================================" + + +# Make some payment and stake addresses +# user1..n: will own all the funds in the system, we'll set this up from +# initial utxo the +# pool-owner1..n: will be the owner of the pools and we'll use their reward +# account for pool rewards + +ADDRS="${USER_ADDRS} ${POOL_ADDRS}" + +mkdir addresses + +cp -r shelley/utxo-keys/* addresses + +for ADDR in ${UTXO_ADDRS}; do + # Payment addresses + ./cardano-cli address build \ + --payment-verification-key-file addresses/${ADDR}.vkey \ + --testnet-magic ${NETWORK_MAGIC} \ + --out-file addresses/${ADDR}.addr +done + +for ADDR in ${ADDRS}; do + + # Payment address keys + ./cardano-cli address key-gen \ + --verification-key-file addresses/${ADDR}.vkey \ + --signing-key-file addresses/${ADDR}.skey + + # Stake address keys + ./cardano-cli stake-address key-gen \ + --verification-key-file addresses/${ADDR}-stake.vkey \ + --signing-key-file addresses/${ADDR}-stake.skey + + # Payment addresses + ./cardano-cli address build \ + --payment-verification-key-file addresses/${ADDR}.vkey \ + --stake-verification-key-file addresses/${ADDR}-stake.vkey \ + --testnet-magic ${NETWORK_MAGIC} \ + --out-file addresses/${ADDR}.addr + + # Stake addresses + ./cardano-cli stake-address build \ + --stake-verification-key-file addresses/${ADDR}-stake.vkey \ + --testnet-magic ${NETWORK_MAGIC} \ + --out-file addresses/${ADDR}-stake.addr + + # Stake addresses registration certs + ./cardano-cli stake-address registration-certificate \ + --stake-verification-key-file addresses/${ADDR}-stake.vkey \ + --out-file addresses/${ADDR}-stake.reg.cert + +done + +# user N will delegate to pool N +for N in ${POOL_NODES_N}; do + + # Stake address delegation certs + ./cardano-cli stake-address delegation-certificate \ + --stake-verification-key-file addresses/user${N}-stake.vkey \ + --cold-verification-key-file node-pool${N}/shelley/operator.vkey \ + --out-file addresses/user${N}-stake.deleg.cert + + cp addresses/pool-owner${N}-stake.vkey node-pool${N}/owner.vkey + cp addresses/pool-owner${N}-stake.skey node-pool${N}/owner.skey + +done + +echo "Generated payment address keys, stake address keys," +echo "stake address regitration certs, and stake address delegatation certs" +echo +ls -1 addresses/ +echo "=====================================================================" + + +# Next is to make the stake pool registration cert + +for NODE in ${POOL_NODES}; do + + ./cardano-cli stake-pool registration-certificate \ + --testnet-magic ${NETWORK_MAGIC} \ + --pool-pledge 0 --pool-cost 0 --pool-margin 0 \ + --cold-verification-key-file ${NODE}/shelley/operator.vkey \ + --vrf-verification-key-file ${NODE}/shelley/vrf.vkey \ + --reward-account-verification-key-file ${NODE}/owner.vkey \ + --pool-owner-stake-verification-key-file ${NODE}/owner.vkey \ + --out-file ${NODE}/registration.cert +done + +echo "Generated stake pool registration certs:" +ls -1 node-*/registration.cert +echo "=====================================================================" + +# Prepare transactions for activating stake pools +for N in ${POOL_NODES_N}; do + + AMOUNT_STAKED=$(( N*1000000 )) + + # We'll transfer all the funds to the user1, which delegates to pool1 + # We'll register certs to: + # 1. register the pool-owner1 stake address + # 2. register the stake pool 1 + # 3. register the user1 stake address + # 4. delegate from the user1 stake address to the stake pool + cat >> activate.sh <> activate.sh <> activate.sh <> query.sh <> Query chain tip" +CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query tip \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} + +echo +echo ">> Query whole utxo" +CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query utxo \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} \\ + --whole-utxo +echo + +echo ">> Query stake pools" +CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query stake-pools \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} +echo + +echo ">> Query stake distribution" +CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query stake-distribution \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} +echo + +echo "=====================================================================" +echo "=== Mithril Network" +echo "=====================================================================" +echo + +AGGREGATOR_API_ENDPOINT="http://0.0.0.0:8080/aggregator" + +echo ">> Query pending certificate" +curl -s \${AGGREGATOR_API_ENDPOINT}/certificate-pending | jq . +echo + +echo ">> Query snapshots" +curl -s \${AGGREGATOR_API_ENDPOINT}/snapshots | jq . +echo + +EOF + +cat >> query-unused.sh <> Query utxo1 utxo 'utxo1.addr'" +CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query utxo \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} \\ + --address \$(cat addresses/utxo1.addr) + +echo +echo ">> Query user1 utxo 'user1.addr'" +CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query utxo \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} \\ + --address \$(cat addresses/user1.addr) + +echo ">> Query stake pool params" +echo CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query pool-params \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} \\ + --stake-pool-id \${STAKE_POOL_ID} +echo + +echo ">> Query stake pool snapshot" +echo CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query stake-snapshot \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} \\ + --stake-pool-id \${STAKE_POOL_ID} +echo + +EOF + +chmod u+x query.sh + +echo "Generated query.sh script" +echo "=====================================================================" +echo + +echo "Generate docker-compose.yaml file" +cat >> docker-compose.yaml <> docker-compose.yaml <> docker-compose.yaml <> docker-compose.yaml <> docker-compose.yaml <> docker-compose.yaml <> docker-compose.yaml <> start.sh <> Start Cardano network" +killall cardano-node + +EOF +for NODE in ${BFT_NODES}; do + + echo ./${ROOT}/${NODE}/start-node.sh + + cat >> ${NODE}/start-node.sh < ${NODE}/node.log +EOF + chmod u+x ${NODE}/start-node.sh + + cat >> start.sh <> Starting Cardano node '${NODE}'" +./${NODE}/start-node.sh & + +EOF + +done +for NODE in ${POOL_NODES}; do + + echo ./${ROOT}/${NODE}/start-node.sh + + cat >> ${NODE}/start-node.sh < ${NODE}/node.log +EOF + chmod u+x ${NODE}/start-node.sh + + cat >> start.sh <> Starting Cardano node '${NODE}'" +./${NODE}/start-node.sh & + +EOF + +done + +cat >> start.sh <> Build Mithril node Docker images" + PWD=$(pwd) + cd ../../../ + echo ">>>> Building Mithril Aggregator node Docker image" + cd mithril-aggregator && make docker-build > /dev/null && cd .. + echo ">>>> Building Mithril Client node Docker image" + cd mithril-client && make docker-build > /dev/null && cd .. + echo ">>>> Building Mithril Signer node Docker image" + cd mithril-signer && make docker-build > /dev/null && cd .. + cd $PWD +fi + +echo ">> Wait for Cardano network to be ready" +while true +do + EPOCH=\$(CARDANO_NODE_SOCKET_PATH=node-bft1/ipc/node.sock ./cardano-cli query tip \\ + --cardano-mode \\ + --testnet-magic ${NETWORK_MAGIC} 2> /dev/null | jq .epoch | sed -e "s/null//" | sed -e "s/ //" | tr -d '\n') + if [ "\$EPOCH" != "" ] ; then + echo ">>>> Ready!" + break + else + echo ">>>> Not ready yet" + sleep 2 + fi +done + +echo ">> Activate Cardano pools" +./activate.sh ${ROOT} + +echo ">> Start Mithril network" +docker-compose rm -f +if [ -z "\${MITHRIL_IMAGE_ID}" ]; then + MITHRIL_AGGREGATOR_IMAGE="mithril/mithril-aggregator" + MITHRIL_CLIENT_IMAGE="mithril/mithril-client" + MITHRIL_SIGNER_IMAGE="mithril/mithril-signer" +else + MITHRIL_AGGREGATOR_IMAGE="ghcr.io/input-output-hk/mithril-aggregator:\${MITHRIL_IMAGE_ID}" + MITHRIL_CLIENT_IMAGE="ghcr.io/input-output-hk/mithril-client:\${MITHRIL_IMAGE_ID}" + MITHRIL_SIGNER_IMAGE="ghcr.io/input-output-hk/mithril-signer:\${MITHRIL_IMAGE_ID}" +fi +MITHRIL_AGGREGATOR_IMAGE=\${MITHRIL_AGGREGATOR_IMAGE} MITHRIL_CLIENT_IMAGE=\${MITHRIL_CLIENT_IMAGE} MITHRIL_SIGNER_IMAGE=\${MITHRIL_SIGNER_IMAGE} docker-compose -f docker-compose.yaml --profile mithril up --remove-orphans --force-recreate -d --no-build +EOF +chmod u+x start.sh + +cat >> stop.sh <> Stop Cardano network" +killall cardano-node + +echo ">> Stop Mithril network" +if [ -z "\${MITHRIL_IMAGE_ID}" ]; then + MITHRIL_AGGREGATOR_IMAGE="mithril/mithril-aggregator" + MITHRIL_CLIENT_IMAGE="mithril/mithril-client" + MITHRIL_SIGNER_IMAGE="mithril/mithril-signer" +else + MITHRIL_AGGREGATOR_IMAGE="ghcr.io/input-output-hk/mithril-aggregator:\${MITHRIL_IMAGE_ID}" + MITHRIL_CLIENT_IMAGE="ghcr.io/input-output-hk/mithril-client:\${MITHRIL_IMAGE_ID}" + MITHRIL_SIGNER_IMAGE="ghcr.io/input-output-hk/mithril-signer:\${MITHRIL_IMAGE_ID}" +fi +MITHRIL_AGGREGATOR_IMAGE=\${MITHRIL_AGGREGATOR_IMAGE} MITHRIL_CLIENT_IMAGE=\${MITHRIL_CLIENT_IMAGE} MITHRIL_SIGNER_IMAGE=\${MITHRIL_SIGNER_IMAGE} docker-compose -f docker-compose.yaml --profile mithril down +EOF +chmod u+x stop.sh + +cat >> log.sh <> Directory: ${ROOT}" +echo ">> Cardano BFT nodes: ${NUM_BFT_NODES}" +echo ">> Cardano SPO nodes: ${NUM_POOL_NODES}" +echo ">> Info: Mithril Aggregator will be attached to the first Cardano BFT node" +echo ">> Info: Mithril Signers will be attached to each Cardano SPO node" +rm -rf ${ROOT} && ./devnet-mkfiles.sh ${ROOT} ${NUM_BFT_NODES} ${NUM_POOL_NODES} > /dev/null +echo + +# Change directory +cd ${ROOT} + +# Start devnet +echo "=====================================================================" +echo " Start Mithril/Cardano devnet" +echo "=====================================================================" +echo +./start.sh +echo \ No newline at end of file diff --git a/mithril-test-lab/mithril-devnet/devnet-stop.sh b/mithril-test-lab/mithril-devnet/devnet-stop.sh new file mode 100755 index 00000000000..b8ddc0fc354 --- /dev/null +++ b/mithril-test-lab/mithril-devnet/devnet-stop.sh @@ -0,0 +1,15 @@ +# Default values +if [ -z "${ROOT}" ]; then + ROOT="artifacts" +fi + +# Change directory +cd ${ROOT} + +# Stop devnet +echo "=====================================================================" +echo " Stop Mithril/Cardano devnet" +echo "=====================================================================" +echo +./stop.sh +echo \ No newline at end of file