Skip to content

Commit

Permalink
Merge pull request #176 from chainbound/feat/sidecar/deploy-dev
Browse files Browse the repository at this point in the history
feat(sidecar): quick deployment script with systemctl
  • Loading branch information
merklefruit authored Jul 31, 2024
2 parents b03b431 + 9146787 commit 4034fcf
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 26 deletions.
17 changes: 17 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,23 @@ _build-sidecar:
_build-mevboost:
cd mev-boost && docker buildx build -t ghcr.io/chainbound/bolt-mev-boost:0.1.0 . --load

# deploy the bolt sidecar to the dev server
deploy-sidecar-dev:
chmod +x ./scripts/deploy_bolt_sidecar.sh && ./scripts/deploy_bolt_sidecar.sh

# Check the status of the sidecar service on the dev server
status-sidecar-dev:
ssh shared@remotebeast "sudo systemctl status bolt_sidecar" | less

# Tail the logs of the service on the dev server
logs-sidecar-dev:
ssh shared@remotebeast "journalctl -qu bolt_sidecar -f"

# Stop the service on the dev server
stop-sidecar-dev:
ssh shared@remotebeast "sudo systemctl stop bolt_sidecar"


# build and push the docker images to the github container registry with the provided tag
[confirm("are you sure? this will build and push new images on ghcr.io")]
release tag:
Expand Down
26 changes: 26 additions & 0 deletions bolt-sidecar/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

# node + PBS URLs
BOLT_SIDECAR_EXECUTION_API_URL=http://localhost:4485
BOLT_SIDECAR_BEACON_API_URL=http://localhost:4400
BOLT_SIDECAR_ENGINE_API_URL=http://localhost:4451
BOLT_SIDECAR_MEVBOOST_URL=http://localhost:19550

# server ports
BOLT_SIDECAR_PORT=8000
BOLT_SIDECAR_MEVBOOST_PROXY_PORT=18551

# commitment limits
BOLT_SIDECAR_MAX_COMMITMENTS=128
BOLT_SIDECAR_MAX_COMMITTED_GAS=10000000

# chain configs
BOLT_SIDECAR_CHAIN=helder
BOLT_SIDECAR_COMMITMENT_DEADLINE=8000
BOLT_SIDECAR_SLOT_TIME=12

# sidecar security configs
BOLT_SIDECAR_VALIDATOR_INDEXES=
BOLT_SIDECAR_JWT_HEX=
BOLT_SIDECAR_FEE_RECIPIENT=
BOLT_SIDECAR_BUILDER_PRIVATE_KEY=
BOLT_SIDECAR_PRIVATE_KEY=
3 changes: 2 additions & 1 deletion bolt-sidecar/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
target/
.env
.env
.env.dev
2 changes: 1 addition & 1 deletion bolt-sidecar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ default-run = "bolt-sidecar"

[dependencies]
# core
clap = { version = "4.5.4", features = ["derive"] }
clap = { version = "4.5.4", features = ["derive", "env"] }
tokio = { version = "1", features = ["full"] }
axum = { version = "0.7", features = ["macros"] }
axum-extra = "0.9.3"
Expand Down
14 changes: 11 additions & 3 deletions bolt-sidecar/src/config/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,23 @@ const BUILDER_DOMAIN_HELDER: [u8; 32] =
#[derive(Debug, Clone, Args)]
pub struct ChainConfig {
/// Chain on which the sidecar is running
#[clap(short = 'C', long, default_value = "mainnet")]
#[clap(long, env = "BOLT_SIDECAR_CHAIN", default_value = "mainnet")]
chain: Chain,
/// The deadline in the slot at which the sidecar will stop accepting
/// new commitments for the next block (parsed as milliseconds).
#[clap(short = 'd', long, default_value_t = DEFAULT_COMMITMENT_DEADLINE_IN_MILLIS)]
#[clap(
long,
env = "BOLT_SIDECAR_COMMITMENT_DEADLINE",
default_value_t = DEFAULT_COMMITMENT_DEADLINE_IN_MILLIS)
]
commitment_deadline: u64,
/// The slot time duration in seconds. If provided,
/// it overrides the default for the selected [Chain].
#[clap(short = 's', long, default_value_t = DEFAULT_SLOT_TIME_IN_SECONDS)]
#[clap(
long,
env = "BOLT_SIDECAR_SLOT_TIME",
default_value_t = DEFAULT_SLOT_TIME_IN_SECONDS)
]
slot_time: u64,
}

Expand Down
35 changes: 17 additions & 18 deletions bolt-sidecar/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,48 +27,48 @@ pub const DEFAULT_MEV_BOOST_PROXY_PORT: u16 = 18551;
#[derive(Parser, Debug)]
pub struct Opts {
/// Port to listen on for incoming JSON-RPC requests
#[clap(short = 'p', long)]
#[clap(long, env = "BOLT_SIDECAR_PORT")]
pub(super) port: Option<u16>,
/// URL for the beacon client
#[clap(short = 'c', long)]
#[clap(long, env = "BOLT_SIDECAR_BEACON_API_URL")]
pub(super) beacon_api_url: String,
/// URL for the MEV-Boost sidecar client to use
#[clap(short = 'b', long)]
#[clap(long, env = "BOLT_SIDECAR_MEVBOOST_URL")]
pub(super) mevboost_url: String,
/// Execution client API URL
#[clap(short = 'x', long)]
#[clap(long, env = "BOLT_SIDECAR_EXECUTION_API_URL")]
pub(super) execution_api_url: String,
/// Execution client Engine API URL
#[clap(short = 'e', long)]
#[clap(long, env = "BOLT_SIDECAR_ENGINE_API_URL")]
pub(super) engine_api_url: String,
/// MEV-Boost proxy server port to use
#[clap(short = 'y', long)]
#[clap(long, env = "BOLT_SIDECAR_MEVBOOST_PROXY_PORT")]
pub(super) mevboost_proxy_port: u16,
/// Max number of commitments to accept per block
#[clap(short = 'm', long)]
#[clap(long, env = "BOLT_SIDECAR_MAX_COMMITMENTS")]
pub(super) max_commitments: Option<NonZero<usize>>,
/// Max committed gas per slot
#[clap(short = 'g', long)]
#[clap(long, env = "BOLT_SIDECAR_MAX_COMMITTED_GAS")]
pub(super) max_committed_gas: Option<NonZero<u64>>,
/// Validator indexes of connected validators that the sidecar
/// should accept commitments on behalf of. Accepted values:
/// - a comma-separated list of indexes (e.g. "1,2,3,4")
/// - a contiguous range of indexes (e.g. "1..4")
/// - a mix of the above (e.g. "1,2..4,6..8")
#[clap(short = 'v', long, value_parser = ValidatorIndexes::from_str)]
#[clap(long, value_parser = ValidatorIndexes::from_str, env = "BOLT_SIDECAR_VALIDATOR_INDEXES")]
pub(super) validator_indexes: ValidatorIndexes,
/// The JWT secret token to authenticate calls to the engine API.
///
/// It can either be a hex-encoded string or a file path to a file
/// containing the hex-encoded secret.
#[clap(short = 'j', long)]
#[clap(long, env = "BOLT_SIDECAR_JWT_HEX")]
pub(super) jwt_hex: String,
/// The fee recipient address for fallback blocks
#[clap(short = 'f', long)]
#[clap(long, env = "BOLT_SIDECAR_FEE_RECIPIENT")]
pub(super) fee_recipient: Address,
/// Secret BLS key to sign fallback payloads with
/// (If not provided, a random key will be used)
#[clap(short = 'K', long)]
#[clap(long, env = "BOLT_SIDECAR_BUILDER_PRIVATE_KEY")]
pub(super) builder_private_key: Option<String>,
/// Chain config for the chain on which the sidecar is running
#[clap(flatten)]
Expand Down Expand Up @@ -186,19 +186,18 @@ impl TryFrom<Opts> for Config {
.transpose()?;

config.private_key = if let Some(sk) = opts.signing.private_key {
// Check if the string starts with "0x" and remove it
let hex_sk = sk.strip_prefix("0x").unwrap_or(&sk);

let sk = SecretKey::from_bytes(&hex::decode(hex_sk)?)
.map_err(|e| eyre::eyre!("Failed decoding BLS secret key: {:?}", e))?;
.map_err(|e| eyre::eyre!("Failed decoding BLS signer secret key: {:?}", e))?;
Some(sk)
} else {
None
};

if let Some(builder_private_key) = opts.builder_private_key {
let sk = SecretKey::from_bytes(&hex::decode(builder_private_key)?)
.map_err(|e| eyre::eyre!("Failed decoding BLS secret key: {:?}", e))?;
if let Some(builder_sk) = opts.builder_private_key {
let hex_sk = builder_sk.strip_prefix("0x").unwrap_or(&builder_sk);
let sk = SecretKey::from_bytes(&hex::decode(hex_sk)?)
.map_err(|e| eyre::eyre!("Failed decoding BLS builder secret key: {:?}", e))?;
config.builder_private_key = sk;
}

Expand Down
12 changes: 10 additions & 2 deletions bolt-sidecar/src/config/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ use clap::{ArgGroup, Args};
)]
pub struct SigningOpts {
/// Private key to use for signing preconfirmation requests
#[clap(short = 'k', long)]
#[clap(
long,
env = "BOLT_SIDECAR_PRIVATE_KEY",
conflicts_with("commit_boost_url")
)]
pub(super) private_key: Option<String>,
/// URL for the commit-boost sidecar
#[clap(short = 'B', long, conflicts_with("private_key"))]
#[clap(
long,
env = "BOLT_SIDECAR_COMMIT_BOOST_URL",
conflicts_with("private_key")
)]
pub(super) commit_boost_url: Option<String>,
}
8 changes: 7 additions & 1 deletion bolt-sidecar/src/state/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ impl<C: StateFetcher> ExecutionState<C> {
//
// If the templates do not exist, or this is the first request for this sender,
// its diffs will be zero.
// TODO: why highest slot here?
let (nonce_diff, balance_diff, highest_slot_for_account) =
self.block_templates.iter().fold(
(0, U256::ZERO, 0),
Expand Down Expand Up @@ -333,6 +332,13 @@ impl<C: StateFetcher> ExecutionState<C> {
}
};

tracing::debug!(
?account_state,
?nonce_diff,
?balance_diff,
"Validating transaction"
);

let sender_nonce_diff = bundle_nonce_diff_map.entry(sender).or_insert(0);
let sender_balance_diff = bundle_balance_diff_map.entry(sender).or_insert(U256::ZERO);

Expand Down
12 changes: 12 additions & 0 deletions scripts/bolt_sidecar.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Bolt Sidecar Development Service
After=network.target

[Service]
User=shared
ExecStart=/usr/local/bin/bolt-sidecar
Restart=on-failure
EnvironmentFile=/home/shared/bolt_sidecar/.env.dev

[Install]
WantedBy=multi-user.target
24 changes: 24 additions & 0 deletions scripts/deploy_bolt_sidecar.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

# This script is used to deploy the bolt_sidecar binary as a service on
# our remote dev server. Requirements:
# - Access to Chainbound's Tailnet dev server "remotebeast"
# - A .env.dev file in the bolt_sidecar directory, filled with the necessary vars

set -e

# check if ".env.dev" exists. if not, exit with error
test -f ./bolt-sidecar/.env.dev || (echo "No .env.dev file found. Exiting." && exit 1)

# copy the files to the remote dev server
rsync -av --exclude target --exclude .git ./bolt-sidecar/ shared@remotebeast:/home/shared/bolt_sidecar
rsync -av ./scripts/bolt_sidecar.service shared@remotebeast:/home/shared/bolt_sidecar/bolt_sidecar.service

# build the project on the remote dev server
ssh shared@remotebeast "cd ~/bolt_sidecar && CC=clang ~/.cargo/bin/cargo build --release"
ssh shared@remotebeast "mv ~/bolt_sidecar/target/release/bolt-sidecar /usr/local/bin/bolt-sidecar || true"
ssh shared@remotebeast "cp -f ~/bolt_sidecar/bolt_sidecar.service /etc/systemd/system/bolt_sidecar.service"
ssh shared@remotebeast "sudo systemctl daemon-reload && sudo systemctl enable bolt_sidecar"
ssh shared@remotebeast "sudo systemctl restart bolt_sidecar"

echo "Deployed bolt_sidecar successfully"

0 comments on commit 4034fcf

Please sign in to comment.