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 committed Jan 31, 2023
1 parent 66b026a commit 5e30273
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 61 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/iroha2-release-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
chmod +x target/debug/iroha
chmod +x target/debug/iroha_client_cli
- name: Setup test environment
run: bash -c './scripts/test_env.sh setup'
run: bash -c './scripts/test_env.sh setup bare'
- name: Genesis test
run: bash -c './scripts/tests/genesis.sh || (cat test/peers/iroha0.log; false )'
- name: Basic register and mint
Expand Down Expand Up @@ -114,7 +114,7 @@ jobs:
chmod +x target/debug/iroha
chmod +x target/debug/iroha_client_cli
- name: Setup test environment
run: ./scripts/test_env.sh setup
run: ./scripts/test_env.sh setup bare
- name: Test iroha2-java API
run: ./scripts/API/java.sh setup && ./scripts/API/java.sh run
- name: Cleanup test iroha2-java API
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ cargo build
chmod +x target/debug/iroha
chmod +x target/debug/iroha_client_cli

bash ./scripts/test_env.sh setup
bash ./scripts/test_env.sh setup bare
bash ./scripts/tests/register_mint_quantity.sh
bash ./scripts/test_env.sh cleanup
```
Expand Down
198 changes: 146 additions & 52 deletions scripts/test_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,66 @@ TEST=${TEST:-"./test"}
HOST=${HOST:-"127.0.0.1"}
IROHA2_CONFIG_PATH="$TEST/peers/config.json"
IROHA2_GENESIS_PATH="$TEST/peers/genesis.json"
DEFAULT_N_PEERS=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\" }"
declare -A hosts

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"}' "${hosts[$1]}:${p2p_ports[$1]}" "${public_keys[$1]}"
}

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

SUMERAGI_TRUSTED_PEERS="$(generate_trusted_peers)"

function set_up_peers_common {
PEERS="$TEST/peers"
mkdir -p "$PEERS"
Expand Down Expand Up @@ -90,24 +94,85 @@ 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
TORII_P2P_ADDR="${hosts[$1]}:${p2p_ports[$1]}"
TORII_API_URL="${hosts[$1]}:${api_ports[$1]}"
TORII_TELEMETRY_URL="${hosts[$1]}:${telemetry_ports[$1]}"
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_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
hosts[$peer]="$HOST"
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 run_4_peers {
run_peer iroha1
run_peer iroha2
run_peer iroha3
run_peer iroha0 --submit-genesis
function generate_docker_compose {
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
hosts[$peer]="iroha$peer"
done
SUMERAGI_TRUSTED_PEERS="$(generate_trusted_peers $1)"

cat <<eof
version: "3.8"
services:
eof

for peer in $(seq 0 $(($1-1)))
do
if [ $peer -eq 0 ]
then
SUBMIT_GENESIS="--submit-genesis"
else
SUBMIT_GENESIS=""
fi

cat <<eof
iroha$peer:
image: hyperledger/iroha2:dev
environment:
TORII_P2P_ADDR: '${hosts[$peer]}:${p2p_ports[$peer]}'
TORII_API_URL: '${hosts[$peer]}:${api_ports[$peer]}'
TORII_TELEMETRY_URL: '${hosts[$peer]}:${telemetry_ports[$peer]}'
IROHA_PUBLIC_KEY: '${public_keys[$peer]}'
IROHA_PRIVATE_KEY: '${private_keys[$peer]}'
SUMERAGI_TRUSTED_PEERS: '$SUMERAGI_TRUSTED_PEERS'
IROHA_GENESIS_ACCOUNT_PUBLIC_KEY: '$IROHA_GENESIS_ACCOUNT_PUBLIC_KEY'
IROHA_GENESIS_ACCOUNT_PRIVATE_KEY: '$IROHA_GENESIS_ACCOUNT_PRIVATE_KEY'
ports:
- "${p2p_ports[$peer]}:${p2p_ports[$peer]}"
- "${api_ports[$peer]}:${api_ports[$peer]}"
- "${telemetry_ports[$peer]}:${telemetry_ports[$peer]}"
volumes:
- '../configs/peer:/config'
init: true
command: iroha $SUBMIT_GENESIS
eof
done
}

function clean_up_peers {
Expand All @@ -118,8 +183,22 @@ function clean_up_peers {
}

case $1 in

setup)
declare -i N_PEERS
if [ -z "$3" ]
then
echo "Number of peers is not provided, using default value of $DEFAULT_N_PEERS"
N_PEERS="$DEFAULT_N_PEERS"
else
N_PEERS="$3"
if [ "$N_PEERS" -le 0 ]
then
echo "Expected number of peers as non-zero positive number (> 0). Recieved: $3"
exit 1
fi
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,22 +208,37 @@ case $1 in
}
echo '{"comment":{"String": "Hello Meta!"}}' >"$TEST/metadata.json"
cp ./configs/client_cli/config.json "$TEST"
cp ./target/debug/kagami "$TEST" || {
echo 'Please build `kagami` by running'
echo '`cargo build --bin kagami`'
exit
}
case $2 in
docker)
docker-compose up;;
*)
generate_docker_compose "$N_PEERS" > "$TEST/docker-compose.yml"
docker-compose -f "$TEST/docker-compose.yml" up
;;
bare)
set_up_peers_common
bulk_export
run_4_peers
run_n_peers "$N_PEERS"
;;
*)
echo 'Specify either `docker` or `bare`'
exit 1
esac
;;

cleanup)
case $2 in
docker)
docker-compose rm -s -f;;
*)
docker-compose -f "$TEST/docker-compose.yml" rm -s -f
;;
bare)
clean_up_peers
;;
*)
echo 'Specify either `docker` or `bare`'
exit 1
esac
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 5e30273

Please sign in to comment.