Skip to content

Commit

Permalink
feat(unionvisor): add set-binary command (#2880)
Browse files Browse the repository at this point in the history
Adds the `set-binary` command to unionvisor enabling users to easily set
the version of `uniond` being used by unionvisor. This allows users to
more easily use tools like state sync and node snapshots.

Usage:
```shell
unionvisor --root $ROOT set-binary --bundle $BUNDLE $UNIOND_VERSION
```
  • Loading branch information
PoisonPhang authored Sep 5, 2024
2 parents 95e7c12 + 48b3480 commit d01d305
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
18 changes: 18 additions & 0 deletions docs/src/content/docs/joining-testnet/unionvisor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,24 @@ We use `sudo` here because Docker created the files we are copying with elevated

:::

### Using Snapshots or State Sync

For networks that have been producing blocks for more than a few weeks, syncing from genesis is often not recommended. Most validators and node operators prefer to use node snapshots or state sync to jump start their nodes.

To use state sync or node snapshots with Unionvisor, you will need to use the `set-uniond-version` sub-command of Unionvisor. You should set Unionvisor to use the version of `uniond` that was used to generate the node snapshot or state sync snapshot.

You can use the `set-uniond-version` command as follows:

```sh frame="none"
docker run \
--volume ~/.unionvisor:/.unionvisor \
--volume /tmp:/tmp \
-it ghcr.io/unionlabs/bundle-testnet-8:$UNIONVISOR_VERSION \
set-uniond-version $UNIOND_VERSION
```
*Where `UNIOND_VERSION` is the version of `uniond` used when the snapshot was generated*


### Issuing Sub-Commands to uniond via Unionvisor

To run `uniond` sub-commands, it will be useful to alias the Docker command in your shell `.*rc` file.
Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@

SQLX_OFFLINE = true;
LIBCLANG_PATH = "${pkgs.llvmPackages_14.libclang.lib}/lib";
PROTOC = "${pkgs.protobuf}/bin/protoc";
};

treefmt = {
Expand Down
55 changes: 54 additions & 1 deletion unionvisor/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
init::{self, SetSeedsError},
logging::LogFormat,
supervisor::{self, RuntimeError},
symlinker::{MakeFallbackLinkError, Symlinker},
symlinker::{MakeFallbackLinkError, Symlinker, SymlinkerError},
};

#[derive(Parser, Clone)]
Expand Down Expand Up @@ -55,6 +55,10 @@ pub struct Cli {

#[derive(Clone, Parser)]
pub enum Command {
/// Set the current binary to a specific version in the bundle.
/// Use this when using unionvisor in combination with a node snapshot or state sync.
SetUniondVersion(SetUniondVersionCmd),

/// Call the current binary, forwarding all arguments passed.
/// `unionvisor call ..arg` is equivalent to `uniond ..args`.
Call(CallCmd),
Expand All @@ -66,6 +70,15 @@ pub enum Command {
Init(InitCmd),
}

#[derive(Clone, Parser)]
pub struct SetUniondVersionCmd {
/// Path to where the binary bundle is stored.
#[arg(short, long, env = "UNIONVISOR_BUNDLE")]
bundle: PathBuf,

version: String,
}

#[derive(Clone, Parser)]
pub struct CallCmd {
/// Path to where the binary bundle is stored.
Expand Down Expand Up @@ -116,6 +129,10 @@ pub struct RunCmd {
impl Cli {
pub fn run(self) -> Result<(), RunCliError> {
match &self.command {
Command::SetUniondVersion(cmd) => {
cmd.set_uniond_version(self.root)?;
Ok(())
}
Command::Call(cmd) => {
cmd.call(self.root)?;
Ok(())
Expand All @@ -134,6 +151,8 @@ impl Cli {

#[derive(Debug, Error)]
pub enum RunCliError {
#[error("set binary error")]
SetUniondVersion(#[from] SetUniondVersionError),
#[error("call command error")]
Call(#[from] CallError),
#[error("run command error")]
Expand Down Expand Up @@ -229,6 +248,40 @@ pub enum RunError {
Runtime(#[from] RuntimeError),
}

#[derive(Debug, Error)]
pub enum SetUniondVersionError {
#[error("runtime error")]
Runtime(#[from] RuntimeError),
#[error("new bundle error")]
NewBundle(#[from] NewBundleError),
#[error("symlink error")]
Symlink(#[from] SymlinkerError),
}

impl SetUniondVersionCmd {
fn set_uniond_version(&self, root: impl Into<PathBuf>) -> Result<(), SetUniondVersionError> {
let root = root.into();
let bundle = Bundle::new(self.bundle.clone())?;
log_bundle(&bundle);
let symlinker = Symlinker::new(root.clone(), bundle);

// Ensure version exists in bundle
symlinker
.bundle
.path_to(&self.version)
.validate()
.map_err(|source| RuntimeError::BinaryUnavailable {
name: self.version.clone(),
source,
})?;

// Swap version symlink
symlinker.swap(&self.version)?;

Ok(())
}
}

impl CallCmd {
/// Executes the logic for the Call variant. Will panic if the enum is not [`Command::Call`].
fn call(&self, root: impl Into<PathBuf>) -> Result<(), CallError> {
Expand Down
2 changes: 1 addition & 1 deletion versions/versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"union-testnet-8": {
"versions": ["v0.21.0", "v0.22.0", "v0.23.0", "v0.24.0"],
"current": "v0.22.0",
"current": "v0.24.0",
"seeds": "c2bf0d5b2ad3a1df0f4e9cc32debffa239c0af90@testnet.seed.poisonphang.com:26656"
}
}

0 comments on commit d01d305

Please sign in to comment.