-
Notifications
You must be signed in to change notification settings - Fork 222
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(hermes): move to wormhole gRPC from p2p
- Loading branch information
Showing
15 changed files
with
614 additions
and
912 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,49 @@ | ||
use std::{ | ||
env, | ||
path::PathBuf, | ||
process::{ | ||
Command, | ||
Stdio, | ||
}, | ||
process::Command, | ||
}; | ||
|
||
fn main() { | ||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
let out_var = env::var("OUT_DIR").unwrap(); | ||
|
||
// Download the Wormhole repository at a certain tag, which we need to access the protobuf definitions | ||
// for Wormhole P2P message types. | ||
// | ||
// TODO: This is ugly. Instead of this we should have our own tool | ||
// build process that can generate protobuf definitions for this and other user cases. For now | ||
// this is easy and works and matches upstream Wormhole's `Makefile`. | ||
|
||
const WORMHOLE_VERSION: &str = "2.18.1"; | ||
|
||
let wh_curl = Command::new("curl") | ||
.args([ | ||
"-s", | ||
"-L", | ||
format!("https://github.com/wormhole-foundation/wormhole/archive/refs/tags/v{WORMHOLE_VERSION}.tar.gz").as_str(), | ||
]) | ||
.stdout(Stdio::piped()) | ||
.spawn() | ||
.expect("failed to download wormhole archive"); | ||
|
||
let _ = Command::new("tar") | ||
.args(["xvz"]) | ||
.stdin(Stdio::from(wh_curl.stdout.unwrap())) | ||
.output() | ||
.expect("failed to extract wormhole archive"); | ||
|
||
// Move the tools directory to the root of the repo because that's where the build script | ||
// expects it to be, paths get hardcoded into the binaries. | ||
let _ = Command::new("mv") | ||
.args([ | ||
format!("wormhole-{WORMHOLE_VERSION}/tools").as_str(), | ||
"tools", | ||
]) | ||
// Print OUT_DIR for debugging build issues. | ||
println!("OUT_DIR={}", out_dir.display()); | ||
|
||
// We'll use git to pull in protobuf dependencies. This trick lets us use the Rust OUT_DIR | ||
// directory as a mini-repo with wormhole and googleapis as remotes, so we can copy out the | ||
// TREEISH paths we want. | ||
let protobuf_setup = r#" | ||
git init . | ||
git clean -df | ||
git remote add wormhole https://github.com/wormhole-foundation/wormhole.git | ||
git remote add googleapis https://github.com/googleapis/googleapis.git | ||
git fetch --depth=1 --porcelain wormhole main | ||
git fetch --depth=1 --porcelain googleapis master | ||
git read-tree --prefix=proto/ -u wormhole/main:proto | ||
git read-tree --prefix=proto/google/api/ -u googleapis/master:google/api | ||
"#; | ||
|
||
// Run each command to prepare the OUT_DIR with the protobuf definitions. We need to make sure | ||
// to change the working directory to OUT_DIR, otherwise git will complain. | ||
let _ = Command::new("sh") | ||
.args(["-c", protobuf_setup]) | ||
.current_dir(&out_dir) | ||
.output() | ||
.expect("failed to move wormhole tools directory"); | ||
|
||
// Move the protobuf definitions to the src/network directory, we don't have to do this | ||
// but it is more intuitive when debugging. | ||
let _ = Command::new("mv") | ||
.args([ | ||
format!("wormhole-{WORMHOLE_VERSION}/proto/gossip/v1/gossip.proto").as_str(), | ||
"src/network/p2p.proto", | ||
]) | ||
.output() | ||
.expect("failed to move wormhole protobuf definitions"); | ||
|
||
// Build the protobuf compiler. | ||
let _ = Command::new("./build.sh") | ||
.current_dir("tools") | ||
.output() | ||
.expect("failed to run protobuf compiler build script"); | ||
|
||
// Make the protobuf compiler executable. | ||
let _ = Command::new("chmod") | ||
.args(["+x", "tools/bin/*"]) | ||
.output() | ||
.expect("failed to make protofuf compiler executable"); | ||
|
||
// Generate the protobuf definitions. See buf.gen.yaml to see how we rename the module for our | ||
// particular use case. | ||
let _ = Command::new("./tools/bin/buf") | ||
.args(["generate", "--path", "src"]) | ||
.output() | ||
.expect("failed to generate protobuf definitions"); | ||
|
||
let rust_target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); | ||
|
||
// Build the Go library. | ||
let mut cmd = Command::new("go"); | ||
cmd.arg("build") | ||
.arg("-buildmode=c-archive") | ||
.arg("-o") | ||
.arg(out_dir.join("libpythnet.a")) | ||
.arg("src/network/p2p.go") | ||
.arg("src/network/p2p.pb.go"); | ||
|
||
// Cross-compile the Go binary based on the Rust target architecture | ||
match &*rust_target_arch { | ||
"x86_64" => { | ||
// CGO_ENABLED required for building amd64 on mac os | ||
cmd.env("GOARCH", "amd64").env("CGO_ENABLED", "1"); | ||
} | ||
"aarch64" => { | ||
cmd.env("GOARCH", "arm64"); | ||
} | ||
// Add other target architectures as needed. | ||
_ => {} | ||
} | ||
|
||
|
||
// Tell Rust to link our Go library at compile time. | ||
println!("cargo:rustc-link-search=native={out_var}"); | ||
println!("cargo:rustc-link-lib=static=pythnet"); | ||
println!("cargo:rustc-link-lib=resolv"); | ||
|
||
let go_build_output = cmd.output().expect("Failed to execute Go build command"); | ||
if !go_build_output.status.success() { | ||
let error_message = String::from_utf8_lossy(&go_build_output.stderr); | ||
panic!("Go build failed:\n{}", error_message); | ||
} | ||
.expect("failed to setup protobuf definitions"); | ||
|
||
// We build the resulting protobuf definitions using Rust's prost_build crate, which generates | ||
// Rust code from the protobuf definitions. | ||
tonic_build::configure() | ||
.build_server(false) | ||
.compile( | ||
&[ | ||
out_dir.join("proto/spy/v1/spy.proto"), | ||
out_dir.join("proto/gossip/v1/gossip.proto"), | ||
out_dir.join("proto/node/v1/node.proto"), | ||
out_dir.join("proto/publicrpc/v1/publicrpc.proto"), | ||
], | ||
&[out_dir.join("proto")], | ||
) | ||
.expect("failed to compile protobuf definitions"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,27 @@ | ||
use { | ||
clap::Args, | ||
libp2p::Multiaddr, | ||
solana_sdk::pubkey::Pubkey, | ||
}; | ||
|
||
const DEFAULT_LISTEN_ADDRS: &str = "/ip4/0.0.0.0/udp/30910/quic,/ip6/::/udp/30910/quic"; | ||
const DEFAULT_CONTRACT_ADDR: &str = "H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU"; | ||
const DEFAULT_NETWORK_ID: &str = "/wormhole/mainnet/2"; | ||
const DEFAULT_BOOTSTRAP_ADDRS: &str = concat![ | ||
"/dns4/wormhole-mainnet-v2-bootstrap.certus.one/udp/8999/quic/p2p/12D3KooWQp644DK27fd3d4Km3jr7gHiuJJ5ZGmy8hH4py7fP4FP7,", | ||
"/dns4/wormhole-v2-mainnet-bootstrap.xlabs.xyz/udp/8999/quic/p2p/12D3KooWNQ9tVrcb64tw6bNs2CaNrUGPM7yRrKvBBheQ5yCyPHKC", | ||
]; | ||
const DEFAULT_WORMHOLE_RPC_ADDR: &str = "grpc://127.0.0.1:7073"; | ||
|
||
#[derive(Args, Clone, Debug)] | ||
#[command(next_help_heading = "Wormhole Options")] | ||
#[group(id = "Wormhole")] | ||
pub struct Options { | ||
/// Multiaddresses for Wormhole bootstrap peers (separated by comma). | ||
/// | ||
/// Bootstraps can be found from the official Wormhole repository, note that these addresses | ||
/// are only used to bootstrap peer discovery and are not necessarily used for data transfer. | ||
/// Adding more peers will speed up P2P peer discovery. | ||
#[arg(long = "wormhole-bootstrap-addrs")] | ||
#[arg(value_delimiter = ',')] | ||
#[arg(default_value = DEFAULT_BOOTSTRAP_ADDRS)] | ||
#[arg(env = "WORMHOLE_BOOTSTRAP_ADDRS")] | ||
pub bootstrap_addrs: Vec<Multiaddr>, | ||
|
||
/// Address of the Wormhole contract on the target PythNet cluster. | ||
#[arg(long = "wormhole-contract-addr")] | ||
#[arg(default_value = DEFAULT_CONTRACT_ADDR)] | ||
#[arg(env = "WORMHOLE_CONTRACT_ADDR")] | ||
pub contract_addr: Pubkey, | ||
|
||
/// Multiaddresses to bind for Wormhole P2P (separated by comma) | ||
#[arg(long = "wormhole-listen-addrs")] | ||
#[arg(value_delimiter = ',')] | ||
#[arg(default_value = DEFAULT_LISTEN_ADDRS)] | ||
#[arg(env = "WORMHOLE_LISTEN_ADDRS")] | ||
pub listen_addrs: Vec<Multiaddr>, | ||
|
||
/// Network ID for Wormhole | ||
#[arg(long = "wormhole-network-id")] | ||
#[arg(default_value = DEFAULT_NETWORK_ID)] | ||
#[arg(env = "WORMHOLE_NETWORK_ID")] | ||
pub network_id: String, | ||
/// gRPC endpoint for a Wormhole node. | ||
/// | ||
/// This can either be a standard Wormhole node gRPC endpoint or a beacon endpoint if | ||
/// load-balancing is desired. | ||
#[arg(long = "wormhole-spy-rpc-addr")] | ||
#[arg(default_value = DEFAULT_WORMHOLE_RPC_ADDR)] | ||
#[arg(env = "WORMHOLE_RPC_ADDR")] | ||
pub spy_rpc_addr: String, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
pub mod p2p; | ||
pub mod pythnet; | ||
pub mod wormhole; |
Oops, something went wrong.