Skip to content

Commit

Permalink
feat: adding testable docker behavior
Browse files Browse the repository at this point in the history
Signed-off-by: Freyskeyd <[email protected]>
  • Loading branch information
Freyskeyd committed Jan 5, 2023
1 parent f3b8a4e commit 1f6e548
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 16 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
!crates
!tests
!Cargo.*
!tools/init.sh

!LICENSE
7 changes: 6 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ RUN adduser \
WORKDIR /usr/src/app

COPY --from=build /usr/src/app/target/release/topos .
COPY tools/init.sh ./init.sh

RUN apt-get update && apt-get install jq -y

USER topos:topos

ENTRYPOINT ["./topos"]
RUN mkdir /tmp/shared

ENTRYPOINT ["./init.sh"]
14 changes: 14 additions & 0 deletions crates/topos-p2p/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,18 @@ pub mod utils {
None => identity::Keypair::generate_ed25519(),
}
}

pub fn local_key_pair_from_slice(slice: &[u8]) -> identity::Keypair {
// todo: load from protobuf encoded|base64 encoded config.local_key_pair
let mut bytes = [0u8; 32];
if slice.len() <= 32 {
bytes[..slice.len()].clone_from_slice(slice);
} else {
bytes.clone_from_slice(&slice[..32]);
}

let secret_key = identity::ed25519::SecretKey::from_bytes(&mut bytes)
.expect("this returns `Err` only if the length is wrong; the length is correct; qed");
identity::Keypair::Ed25519(secret_key.into())
}
}
9 changes: 9 additions & 0 deletions crates/topos-tce-synchronizer/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::future::IntoFuture;
use futures::{future::BoxFuture, FutureExt, TryFutureExt};
use tokio::{spawn, sync::mpsc};
use tokio_stream::wrappers::ReceiverStream;
use topos_p2p::Client as NetworkClient;
use topos_tce_gatekeeper::GatekeeperClient;

use crate::{
Expand All @@ -13,6 +14,7 @@ use crate::{
#[derive(Default)]
pub struct SynchronizerBuilder {
gatekeeper_client: Option<GatekeeperClient>,
network_client: Option<NetworkClient>,
}

impl IntoFuture for SynchronizerBuilder {
Expand All @@ -34,6 +36,7 @@ impl IntoFuture for SynchronizerBuilder {

CheckpointsCollector::builder()
.set_gatekeeper_client(self.gatekeeper_client.take())
.set_network_client(self.network_client.take())
.into_future()
.map_err(Into::into)
.and_then(
Expand Down Expand Up @@ -66,4 +69,10 @@ impl SynchronizerBuilder {

self
}

pub fn with_network_client(mut self, network_client: NetworkClient) -> Self {
self.network_client = Some(network_client);

self
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ impl CheckpointsCollectorBuilder {

self
}

pub fn set_network_client(mut self, network_client: Option<NetworkClient>) -> Self {
self.network_client = network_client;

self
}
}

impl IntoFuture for CheckpointsCollectorBuilder {
Expand Down
11 changes: 9 additions & 2 deletions crates/topos-tce/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use opentelemetry::sdk::Resource;
use opentelemetry::{global, KeyValue};
use tce_transport::ReliableBroadcastParams;
use tokio::spawn;
use topos_p2p::utils::local_key_pair_from_slice;
use topos_p2p::{utils::local_key_pair, Multiaddr, PeerId};
use topos_tce_broadcast::{ReliableBroadcastClient, ReliableBroadcastConfig};
use topos_tce_storage::{Connection, RocksDBStorage};
Expand All @@ -18,7 +19,7 @@ use tracing_subscriber::{prelude::*, EnvFilter};

#[derive(Debug)]
pub struct TceConfiguration {
pub local_key_seed: Option<u8>,
pub local_key_seed: Option<Vec<u8>>,
pub jaeger_agent: String,
pub jaeger_service_name: String,
pub tce_params: ReliableBroadcastParams,
Expand All @@ -36,7 +37,12 @@ pub enum StorageConfiguration {

#[instrument(name = "TCE", fields(peer_id), skip(config))]
pub async fn run(config: &TceConfiguration) -> Result<(), Box<dyn std::error::Error>> {
let key = local_key_pair(config.local_key_seed);
let key = if let Some(seed) = &config.local_key_seed {
local_key_pair_from_slice(seed)
} else {
local_key_pair(None)
};

let peer_id = key.public().to_peer_id();

tracing::Span::current().record("peer_id", &peer_id.to_string());
Expand Down Expand Up @@ -132,6 +138,7 @@ pub async fn run(config: &TceConfiguration) -> Result<(), Box<dyn std::error::Er
let (synchronizer_client, synchronizer_runtime, synchronizer_stream) =
topos_tce_synchronizer::Synchronizer::builder()
.with_gatekeeper_client(gatekeeper_client.clone())
.with_network_client(network_client.clone())
.await
.expect("Can't create the Synchronizer");

Expand Down
4 changes: 1 addition & 3 deletions crates/topos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ tracing = { workspace = true, features = ["log"] }
tracing-subscriber = { workspace = true, features = ["env-filter", "json"] }
uuid.workspace = true
clap.workspace = true

insta = { version = "1.21", features = ["json", "redactions"] }
tower = "0.4.13"

[dev-dependencies]
serde.workspace = true
serde_json.workspace = true
assert_cmd = "2.0.6"
insta = "1.21"
insta = { version = "1.21", features = ["json", "redactions"] }

4 changes: 4 additions & 0 deletions crates/topos/src/components/tce/commands.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use clap::{Args, Subcommand};

mod peer_id;
mod push_peer_list;
mod run;

pub(crate) use push_peer_list::PushPeerList;
pub(crate) use run::Run;

use self::peer_id::PeerId;

#[derive(Args, Debug)]
pub(crate) struct TceCommand {
#[clap(
Expand All @@ -23,6 +26,7 @@ pub(crate) struct TceCommand {
#[derive(Subcommand, Debug)]
pub(crate) enum TceCommands {
PushPeerList(PushPeerList),
PeerId(PeerId),
Run(Box<Run>),
}

Expand Down
7 changes: 7 additions & 0 deletions crates/topos/src/components/tce/commands/peer_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use clap::Args;

#[derive(Args, Debug)]
pub(crate) struct PeerId {
#[arg(long = "from-slice")]
pub(crate) from_slice: Option<String>,
}
2 changes: 1 addition & 1 deletion crates/topos/src/components/tce/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct Run {

/// Local peer secret key seed (optional, used for testing)
#[clap(long, env = "TCE_LOCAL_KS")]
pub local_key_seed: Option<u8>,
pub local_key_seed: Option<String>,

/// Local peer key-pair (in base64 format)
#[clap(long, env = "TCE_LOCAL_KEYPAIR")]
Expand Down
17 changes: 16 additions & 1 deletion crates/topos/src/components/tce/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ pub(crate) async fn handle_command(
Some(TceCommands::Run(cmd)) => {
let config = TceConfiguration {
boot_peers: cmd.parse_boot_peers(),
local_key_seed: cmd.local_key_seed,
local_key_seed: cmd.local_key_seed.map(|s| s.as_bytes().to_vec()),
jaeger_agent: cmd.jaeger_agent,
jaeger_service_name: cmd.jaeger_service_name,
tce_local_port: cmd.tce_local_port,
Expand Down Expand Up @@ -115,6 +115,21 @@ pub(crate) async fn handle_command(

Ok(())
}

Some(TceCommands::PeerId(cmd)) => {
match cmd.from_slice {
Some(slice) => println!(
"{}",
topos_p2p::utils::local_key_pair_from_slice(slice.as_bytes())
.public()
.to_peer_id()
),
_ => {}
};

Ok(())
}

None => Ok(()),
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: crates/topos/tests/tce.rs
expression: result
---
12D3KooWRhFCXBhmsMnur3up3vJsDoqWh4c39PKXgSWwzAzDHNLn

14 changes: 14 additions & 0 deletions crates/topos/tests/tce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ async fn do_not_push_empty_list() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

#[tokio::test]
async fn can_get_a_peer_id_from_a_seed() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("topos")?;
cmd.arg("tce").arg("peer-id").arg("--from-slice").arg("1");

let output = cmd.assert().success();

let result: &str = std::str::from_utf8(&output.get_output().stdout)?;

insta::assert_snapshot!(result);

Ok(())
}

struct DummyServer;

#[tonic::async_trait]
Expand Down
25 changes: 17 additions & 8 deletions tools/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ services:
jaeger:
image: jaegertracing/all-in-one:latest
container_name: jaeger
restart: always
ports:
- "6831/udp"
- "6832/udp"
- "16685"
- "16686:16686"
boot:
container_name: boot
command: tce run -vv
command: boot tce run -vv
image: ghcr.io/toposware/tce:pr-4
init: true
volumes:
- shared:/tmp/shared
build:
context: ../
args:
Expand All @@ -27,8 +28,9 @@ services:
- RUST_LOG=info,topos_p2p=debug,topos_tce_node_app=debug,topos_tce_protocols_reliable_broadcast=debug
- TOOLCHAIN_VERSION=stable
- RUST_BACKTRACE=full
- TCE_DB_PATH=/tmp/default-db
- TCE_API_ADDR=0.0.0.0:1340
- TCE_LOCAL_KS=1 # 12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X
- TCE_LOCAL_KS=1 # 12D3KooWRhFCXBhmsMnur3up3vJsDoqWh4c39PKXgSWwzAzDHNLn
- TCE_JAEGER_SERVICE_NAME=tce-boot-node
- TCE_JAEGER_AGENT=jaeger:6831
- TCE_ECHO_SAMPLE_SIZE=3
Expand All @@ -42,6 +44,8 @@ services:
image: ghcr.io/toposware/tce:pr-4
command: tce run
init: true
volumes:
- shared:/tmp/shared
build:
context: ../
args:
Expand All @@ -56,11 +60,13 @@ services:
deploy:
replicas: 5
environment:
- LOCAL_TEST_NET=true
- RUST_LOG=info,topos_p2p=debug,topos_tce_node_app=debug,topos_tce_protocols_reliable_broadcast=debug
- TCE_DB_PATH=/tmp/default-db
- TCE_API_ADDR=0.0.0.0:1340
- TCE_JAEGER_SERVICE_NAME=tce-regular-node
- TCE_JAEGER_AGENT=jaeger:6831
- TCE_BOOT_PEERS=12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X /dns4/boot/tcp/9090
- TCE_BOOT_PEERS=12D3KooWRhFCXBhmsMnur3up3vJsDoqWh4c39PKXgSWwzAzDHNLn /dns4/boot/tcp/9090
- TCE_ECHO_SAMPLE_SIZE=3
- TCE_READY_SAMPLE_SIZE=3
- TCE_DELIVERY_SAMPLE_SIZE=3
Expand All @@ -72,11 +78,14 @@ services:
container_name: spam
image: ghcr.io/toposware/cert-spammer:main
init: true
volumes:
- shared:/tmp/shared
environment:
- RUST_LOG=debug
- TARGET_NODES_PATH=/nodes.json
- RUST_LOG=info
- TARGET_NODES_PATH=/tmp/shared/peer_nodes.json
depends_on:
- jaeger
- peer
volumes:
- ./peer_nodes.json:/nodes.json

volumes:
shared:
57 changes: 57 additions & 0 deletions tools/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

set -e

if ! command -v jq &> /dev/null
then
echo "jq could not be found"
exit
fi

JQ=$(which jq)
TOPOS_BIN=./topos
PEER_LIST_PATH=/tmp/shared/peer_ids.json
NODE_LIST_PATH=/tmp/shared/peer_nodes.json
NODE="http://$HOSTNAME:1340"

case "$1" in

"boot")
echo "Generating peer list file..."
$JQ -n --arg PEER $($TOPOS_BIN tce peer-id --from-slice=$TCE_LOCAL_KS) '[$PEER]' > $PEER_LIST_PATH
echo "Peer list file have been successfully generated"

echo "Generating node list file..."
$JQ -n --arg NODE $NODE '{"nodes": [$NODE]}' > $NODE_LIST_PATH
echo "Peer nodes list have been successfully generated"

echo "Starting boot node..."
exec "$TOPOS_BIN" "${@:2}"
;;

*)
if [[ ! -z ${LOCAL_TEST_NET+x} ]]; then
until [ -f "$PEER_LIST_PATH" ]
do
echo "Waiting 1s for peer_list file $PEER_LIST_PATH to be created by boot container..."
sleep 1
done

PEER=$($TOPOS_BIN tce peer-id --from-slice=$HOSTNAME)
cat <<< $($JQ --arg PEER $PEER '. += [$PEER]' $PEER_LIST_PATH) > $PEER_LIST_PATH

export TCE_LOCAL_KS=$HOSTNAME

until [ -f "$NODE_LIST_PATH" ]
do
echo "Waiting 1s for node_list file $NODE_LIST_PATH to be created by boot container..."
sleep 1
done

cat <<< $($JQ --arg NODE $NODE '.nodes += [$NODE]' $NODE_LIST_PATH) > $NODE_LIST_PATH
fi

exec "$TOPOS_BIN" "$@"
;;

esac

0 comments on commit 1f6e548

Please sign in to comment.