Skip to content

Commit

Permalink
[feature] hyperledger-iroha#3094: Generate network with n peers
Browse files Browse the repository at this point in the history
Signed-off-by: Shanin Roman <shanin1000@yandex.ru>
  • Loading branch information
Erigara authored and appetrosyan committed Feb 6, 2023
1 parent 3d5305a commit 7316336
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 97 deletions.
31 changes: 0 additions & 31 deletions .github/workflows/iroha2-release-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,37 +41,6 @@ jobs:
- name: Panic on invalid genesis test
run: bash -c './scripts/tests/panic_on_invalid_genesis.sh'

docker:
# This workflow is too unreliable to enable. Even for
# releases. The communication with docker from inside docker fails
# sometimes, works other times it doesn't. In the interest of not
# burning CI hours, we will instead run these tests locally, and
# push the docker image from main only after QA passes.
if: false
runs-on: ubuntu-latest #[self-hosted, Linux]
container:
image: 7272721/i2-ci:nightly
steps:
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
- name: Build iroha_client_cli
working-directory: client_cli
run: mold --run cargo build
- name: Build docker image
uses: docker/build-push-action@v3
with:
load: true
tags: hyperledger/iroha2:dev
- name: Setup test environment
run: bash -c './scripts/test_env.sh setup docker'
- name: Genesis test
run: bash -c './scripts/tests/genesis.sh || (cat test/peers/iroha0.log; false )'
- name: Basic register and mint
run: bash -c './scripts/tests/register_mint_quantity.sh || (cat test/peers/iroha0.log; false )'
if: always()
- name: Cleanup test environment
run: bash -c './scripts/test_env.sh cleanup docker'

bench:
runs-on: ubuntu-latest #[self-hosted, Linux]
container:
Expand Down
143 changes: 83 additions & 60 deletions scripts/test_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,64 @@ TEST=${TEST:-"./test"}
HOST=${HOST:-"127.0.0.1"}
IROHA2_CONFIG_PATH="$TEST/peers/config.json"
IROHA2_GENESIS_PATH="$TEST/peers/genesis.json"
IROHA2_PEER_COUNT=${IROHA2_PEER_COUNT:-"4"}

# TODO: don't hard-code these, instead, generate them.
declare -A public_keys
public_keys[iroha0]='ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b'
public_keys[iroha1]='ed0120cc25624d62896d3a0bfd8940f928dc2abf27cc57cefeb442aa96d9081aae58a1'
public_keys[iroha2]='ed0120faca9e8aa83225cb4d16d67f27dd4f93fc30ffa11adc1f5c88fd5495ecc91020'
public_keys[iroha3]='ed01208e351a70b6a603ed285d666b8d689b680865913ba03ce29fb7d13a166c4e7f1f'

declare -A private_keys
private_keys[iroha0]='282ed9f3cf92811c3818dbc4ae594ed59dc1a2f78e4241e31924e101d6b1fb831c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b'
private_keys[iroha1]='3bac34cda9e3763fa069c1198312d1ec73b53023b8180c822ac355435edc4a24cc25624d62896d3a0bfd8940f928dc2abf27cc57cefeb442aa96d9081aae58a1'
private_keys[iroha2]='1261a436d36779223d7d6cf20e8b644510e488e6a50bafd77a7485264d27197dfaca9e8aa83225cb4d16d67f27dd4f93fc30ffa11adc1f5c88fd5495ecc91020'
private_keys[iroha3]='a70dab95c7482eb9f159111b65947e482108cfe67df877bd8d3b9441a781c7c98e351a70b6a603ed285d666b8d689b680865913ba03ce29fb7d13a166c4e7f1f'

declare -A p2p_ports
p2p_ports[iroha0]='1337'
p2p_ports[iroha1]='1338'
p2p_ports[iroha2]='1339'
p2p_ports[iroha3]='1340'
P2P_STARTING_PORT='1337'

declare -A api_ports
api_ports[iroha0]='8080'
api_ports[iroha1]='8081'
api_ports[iroha2]='8082'
api_ports[iroha3]='8083'
API_STARTING_PORT='8080'

declare -A telemetry_ports
telemetry_ports[iroha0]='8180'
telemetry_ports[iroha1]='8181'
telemetry_ports[iroha2]='8182'
telemetry_ports[iroha3]='8183'
TELEMETRY_STARTING_PORT='8180'

IROHA_GENESIS_ACCOUNT_PUBLIC_KEY='ed01203f4e3e98571b55514edc5ccf7e53ca7509d89b2868e62921180a6f57c2f4e255'
IROHA_GENESIS_ACCOUNT_PRIVATE_KEY="{ \"digest_function\": \"ed25519\", \"payload\": \"038ae16b219da35aa036335ed0a43c28a2cc737150112c78a7b8034b9d99c9023f4e3e98571b55514edc5ccf7e53ca7509d89b2868e62921180a6f57c2f4e255\" }"
function generate_p2p_port {
P2P_PORT=$(($P2P_STARTING_PORT + $1))
p2p_ports[$1]=$P2P_PORT
}

function generate_api_port {
API_PORT=$(($API_STARTING_PORT + $1))
api_ports[$1]=$API_PORT
}

function generate_telemetry_port {
TELEMETRY_PORT=$(($TELEMETRY_STARTING_PORT + $1))
telemetry_ports[$1]=$TELEMETRY_PORT
}

function generate_peer_key_pair {
mapfile -t -n 3 buffer < <($TEST/kagami crypto -c)
public_keys[$1]="${buffer[0]}"
private_keys[$1]=$(printf '{"digest_function": "%s", "payload": "%s"}' "${buffer[2]}" "${buffer[1]}")
}

function generate_genesis_key_pair {
mapfile -t -n 3 buffer < <($TEST/kagami crypto -c)
IROHA_GENESIS_ACCOUNT_PUBLIC_KEY="${buffer[0]}"
IROHA_GENESIS_ACCOUNT_PRIVATE_KEY=$(printf '{"digest_function": "%s", "payload": "%s"}' "${buffer[2]}" "${buffer[1]}")
}

function trusted_peer_entry {
# This way it's easier to read when debugging the script
echo "{"
echo "\"address\": \"$HOST:${p2p_ports[$1]}\","
echo -n "\"public_key\": \"${public_keys[$1]}\""
echo -n "}"
printf '{"address": "%s", "public_key": "%s"}' "$HOST:${p2p_ports[$1]}" "${public_keys[$1]}"
}

function generate_trusted_peers {
echo -n "["
for iter in {0..2}
printf "["
for iter in $(seq 0 $(($1-2)))
do
trusted_peer_entry "iroha$iter"
echo -n ","
trusted_peer_entry "$iter"
printf ","
done
trusted_peer_entry iroha3
echo "]"
trusted_peer_entry $(($1-1))
printf "]"
}

SUMERAGI_TRUSTED_PEERS="$(generate_trusted_peers)"

function set_up_peers_common {
PEERS="$TEST/peers"
mkdir -p "$PEERS"
Expand Down Expand Up @@ -90,24 +92,34 @@ function bulk_export {
}

function run_peer () {
PEER="$TEST/peers/$1"
PEER="$TEST/peers/iroha$1"
mkdir -p "$PEER"
STORAGE="$PEER/storage"
mkdir -p "$STORAGE"
KURA_BLOCK_STORE_PATH="$STORAGE"
TORII_P2P_ADDR="$HOST:${p2p_ports[$1]}"
TORII_API_URL="$HOST:${api_ports[$1]}"
TORII_TELEMETRY_URL="$HOST:${telemetry_ports[$1]}"
IROHA_PUBLIC_KEY=${public_keys[$1]}
IROHA_PRIVATE_KEY="{ \"digest_function\": \"ed25519\", \"payload\": \"${private_keys[$1]}\" }"
exec -a "$1" "$TEST/peers/iroha" "$2" > "$PEER/.log" & disown
IROHA_PUBLIC_KEY="${public_keys[$1]}"
IROHA_PRIVATE_KEY="${private_keys[$1]}"
exec -a "iroha$1" "$TEST/peers/iroha" "$2" > "$PEER/.log" & disown
}

function run_4_peers {
run_peer iroha1
run_peer iroha2
run_peer iroha3
run_peer iroha0 --submit-genesis
function run_n_peers {
generate_genesis_key_pair
for peer in $(seq 0 $(($1-1)))
do
generate_p2p_port $peer
generate_api_port $peer
generate_telemetry_port $peer
generate_peer_key_pair $peer
done
SUMERAGI_TRUSTED_PEERS="$(generate_trusted_peers $1)"
for peer in $(seq 1 $(($1-1)))
do
run_peer $peer
done
run_peer 0 --submit-genesis
}

function clean_up_peers {
Expand All @@ -118,8 +130,24 @@ function clean_up_peers {
}

case $1 in

setup)
declare -i N_PEERS
if [ -z "$2" ]
then
echo "Number of peers is not provided, using default value of $IROHA2_PEER_COUNT"
N_PEERS="$IROHA2_PEER_COUNT"
else
N_PEERS="$2"
fi

if [ "$N_PEERS" -le 0 ]
then
echo "Expected number of peers as non-zero positive number (> 0)."
exit 1
fi

echo "Starting iroha network with $N_PEERS peers"

## Set client up to communicate with the first peer.
mkdir "$TEST" || echo "$TEST Already exists"
cp ./target/debug/iroha_client_cli "$TEST" || {
Expand All @@ -129,23 +157,18 @@ case $1 in
}
echo '{"comment":{"String": "Hello Meta!"}}' >"$TEST/metadata.json"
cp ./configs/client_cli/config.json "$TEST"
case $2 in
docker)
docker-compose up;;
*)
set_up_peers_common
bulk_export
run_4_peers
esac
;;
cp ./target/debug/kagami "$TEST" || {
echo 'Please build `kagami` by running'
echo '`cargo build --bin kagami`'
exit
}

set_up_peers_common
bulk_export
run_n_peers "$N_PEERS"
;;
cleanup)
case $2 in
docker)
docker-compose rm -s -f;;
*)
clean_up_peers
esac
clean_up_peers
rm -rf "$TEST"
;;

Expand Down
43 changes: 39 additions & 4 deletions tools/kagami/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ The `crypto` command generate cryptographic key pairs using the given algorithm
| `--private_key` | The `private_key` used to generate the key-pair | Not applicable | String |
| `--seed` | The `seed` used to generate the key-pair | Not applicable | String |

You can also choose to output the key-pair in JSON format:
You can also choose output format:

| Flag | Description |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--json` | A flag to specify whether or not to output the key-pair in JSON format.<br />By default, the generated key-pair is printed to `stdout` **not** in JSON format. |
| Flag | Description |
| ----------- | ----------------------------------------------------------------------- |
| `--json` | A flag to specify whether or not to output the key-pair in JSON format. |
| `--compact` | A flag to specify whether or not to output the key-pair compact format. |

### `crypto` usage examples

Expand Down Expand Up @@ -88,6 +89,40 @@ You can also choose to output the key-pair in JSON format:
```
</details>

- Generate a key in JSON format:

```bash
./kagami crypto --json
```

<details> <summary>Expand to see the output</summary>

```json
{
"public_key": "ed01203189e4982f98dc293ab9e32cf2b2d75fba49adbc345318a576377b75cc9e15c1",
"private_key": {
"digest_function": "ed25519",
"payload": "d2162546e2025d28b680d062b91043a1e990de7da7861ee5e8039a6b39c9551f3189e4982f98dc293ab9e32cf2b2d75fba49adbc345318a576377b75cc9e15c1"
}
}
```
</details>

- Generate a key in compact format:

```bash
./kagami crypto --compact
```

<details> <summary>Expand to see the output</summary>

```bash
ed01208c8a612f0d20f339a0ea8df21fea777cbbe3604281e5f52311e5c5602cd38d8e
878f0fc05183857871a17605fe8f63b4aaf72ac9af4a5d8dd22536f6d016dff18c8a612f0d20f339a0ea8df21fea777cbbe3604281e5f52311e5c5602cd38d8e
ed25519
```
</details>

## `genesis`

- Generate a genesis block in JSON format:
Expand Down
14 changes: 12 additions & 2 deletions tools/kagami/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ mod crypto {
/// Use `Kagami` to generate cryptographic key-pairs.
#[derive(StructOpt, Debug, Clone)]
#[structopt(group = ArgGroup::new("generate_from").required(false))]
#[structopt(group = ArgGroup::new("format").required(false))]
pub struct Args {
/// Algorithm used to generate the key-pair.
/// Options: `ed25519`, `secp256k1`, `bls_normal`, `bls_small`.
Expand All @@ -95,16 +96,25 @@ mod crypto {
#[clap(long, short, group = "generate_from")]
seed: Option<String>,
/// Output the key-pair in JSON format
#[clap(long, short)]
#[clap(long, short, group = "format")]
json: bool,
/// Output the key-pair without additional text
#[clap(long, short, group = "format")]
compact: bool,
}

impl<T: Write> RunArgs<T> for Args {
fn run(self, writer: &mut BufWriter<T>) -> Outcome {
if self.json {
let output = serde_json::to_string_pretty(&self.key_pair()?)
let key_pair = self.key_pair()?;
let output = serde_json::to_string_pretty(&key_pair)
.wrap_err("Failed to serialise to JSON.")?;
writeln!(writer, "{output}")?;
} else if self.compact {
let key_pair = self.key_pair()?;
writeln!(writer, "{}", &key_pair.public_key())?;
writeln!(writer, "{}", &key_pair.private_key())?;
writeln!(writer, "{}", &key_pair.public_key().digest_function())?;
} else {
let key_pair = self.key_pair()?;
writeln!(writer, "Public key (multihash): {}", &key_pair.public_key())?;
Expand Down

0 comments on commit 7316336

Please sign in to comment.