[hermes] Pass Wormhole arguments from command line or env. vars (#769)
* Format p2p.go * Pass Wormhole arguments from command line or env. vars * Remove forget calls and let memory be freed (also remove confusing comment) * Use proper types on command line arguments
This commit is contained in:
parent
9fea461174
commit
04b1a21dfe
|
@ -24,13 +24,22 @@ pub enum Options {
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
id_secp256k1: Option<PathBuf>,
|
id_secp256k1: Option<PathBuf>,
|
||||||
|
|
||||||
/// Multiaddress for a Wormhole bootstrap peer.
|
/// Network ID for Wormhole
|
||||||
#[structopt(long)]
|
#[structopt(long, env = "WORMHOLE_NETWORK_ID")]
|
||||||
wormhole_peer: Option<String>,
|
wh_network_id: String,
|
||||||
|
|
||||||
/// Multiaddress to bind Wormhole P2P to.
|
/// Multiaddresses for Wormhole bootstrap peers (separated by comma).
|
||||||
#[structopt(long)]
|
#[structopt(long, use_delimiter = true, env = "WORMHOLE_BOOTSTRAP_ADDRS")]
|
||||||
wormhole_addr: Option<Multiaddr>,
|
wh_bootstrap_addrs: Vec<Multiaddr>,
|
||||||
|
|
||||||
|
/// Multiaddresses to bind Wormhole P2P to (separated by comma)
|
||||||
|
#[structopt(
|
||||||
|
long,
|
||||||
|
use_delimiter = true,
|
||||||
|
default_value = "/ip4/0.0.0.0/udp/30910/quic,/ip6/::/udp/30910/quic",
|
||||||
|
env = "WORMHOLE_LISTEN_ADDRS"
|
||||||
|
)]
|
||||||
|
wh_listen_addrs: Vec<Multiaddr>,
|
||||||
|
|
||||||
/// The address to bind the RPC server to.
|
/// The address to bind the RPC server to.
|
||||||
#[structopt(long, default_value = "127.0.0.1:33999")]
|
#[structopt(long, default_value = "127.0.0.1:33999")]
|
||||||
|
|
|
@ -52,8 +52,9 @@ async fn init(_update_channel: Receiver<AccountUpdate>) -> Result<()> {
|
||||||
config::Options::Run {
|
config::Options::Run {
|
||||||
id: _,
|
id: _,
|
||||||
id_secp256k1: _,
|
id_secp256k1: _,
|
||||||
wormhole_addr: _,
|
wh_network_id,
|
||||||
wormhole_peer: _,
|
wh_bootstrap_addrs,
|
||||||
|
wh_listen_addrs,
|
||||||
rpc_addr,
|
rpc_addr,
|
||||||
p2p_addr,
|
p2p_addr,
|
||||||
p2p_peer: _,
|
p2p_peer: _,
|
||||||
|
@ -62,7 +63,13 @@ async fn init(_update_channel: Receiver<AccountUpdate>) -> Result<()> {
|
||||||
|
|
||||||
// Spawn the P2P layer.
|
// Spawn the P2P layer.
|
||||||
log::info!("Starting P2P server on {}", p2p_addr);
|
log::info!("Starting P2P server on {}", p2p_addr);
|
||||||
network::p2p::spawn(handle_message).await?;
|
network::p2p::spawn(
|
||||||
|
handle_message,
|
||||||
|
wh_network_id.to_string(),
|
||||||
|
wh_bootstrap_addrs,
|
||||||
|
wh_listen_addrs,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Spawn the RPC server.
|
// Spawn the RPC server.
|
||||||
log::info!("Starting RPC server on {}", rpc_addr);
|
log::info!("Starting RPC server on {}", rpc_addr);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
// #include <stdlib.h>
|
// #include <stdlib.h>
|
||||||
|
// #include <string.h>
|
||||||
//
|
//
|
||||||
// // A structure containing Wormhole VAA observations. This must match on both
|
// // A structure containing Wormhole VAA observations. This must match on both
|
||||||
// // the Go and Rust side.
|
// // the Go and Rust side.
|
||||||
|
@ -27,6 +28,7 @@ import "C"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
"github.com/libp2p/go-libp2p/core/crypto"
|
||||||
|
@ -45,16 +47,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
//export RegisterObservationCallback
|
//export RegisterObservationCallback
|
||||||
func RegisterObservationCallback(f C.callback_t) {
|
func RegisterObservationCallback(f C.callback_t, network_id, bootstrap_addrs, listen_addrs *C.char) {
|
||||||
|
networkID := C.GoString(network_id)
|
||||||
|
bootstrapAddrs := strings.Split(C.GoString(bootstrap_addrs), ",")
|
||||||
|
listenAddrs := strings.Split(C.GoString(listen_addrs), ",")
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
// Setup base network configuration.
|
// Setup base network configuration.
|
||||||
networkID := "/wormhole/mainnet/2"
|
|
||||||
priv, _, err := crypto.GenerateKeyPair(crypto.Ed25519, -1)
|
priv, _, err := crypto.GenerateKeyPair(crypto.Ed25519, -1)
|
||||||
bootstrapPeers := []string{
|
|
||||||
"/dns4/wormhole-mainnet-v2-bootstrap.certus.one/udp/8999/quic/p2p/12D3KooWQp644DK27fd3d4Km3jr7gHiuJJ5ZGmy8hH4py7fP4FP7",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup libp2p Connection Manager.
|
// Setup libp2p Connection Manager.
|
||||||
mgr, err := connmgr.NewConnManager(
|
mgr, err := connmgr.NewConnManager(
|
||||||
|
@ -72,16 +74,13 @@ func RegisterObservationCallback(f C.callback_t) {
|
||||||
// Setup libp2p Reactor.
|
// Setup libp2p Reactor.
|
||||||
h, err := libp2p.New(
|
h, err := libp2p.New(
|
||||||
libp2p.Identity(priv),
|
libp2p.Identity(priv),
|
||||||
libp2p.ListenAddrStrings(
|
libp2p.ListenAddrStrings(listenAddrs...),
|
||||||
"/ip4/0.0.0.0/udp/30910/quic",
|
|
||||||
"/ip6/::/udp/30910/quic",
|
|
||||||
),
|
|
||||||
libp2p.Security(libp2ptls.ID, libp2ptls.New),
|
libp2p.Security(libp2ptls.ID, libp2ptls.New),
|
||||||
libp2p.Transport(libp2pquic.NewTransport),
|
libp2p.Transport(libp2pquic.NewTransport),
|
||||||
libp2p.ConnectionManager(mgr),
|
libp2p.ConnectionManager(mgr),
|
||||||
libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
|
libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
|
||||||
bootstrappers := make([]peer.AddrInfo, 0)
|
bootstrappers := make([]peer.AddrInfo, 0)
|
||||||
for _, addr := range bootstrapPeers {
|
for _, addr := range bootstrapAddrs {
|
||||||
ma, err := multiaddr.NewMultiaddr(addr)
|
ma, err := multiaddr.NewMultiaddr(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -11,17 +11,29 @@
|
||||||
|
|
||||||
use {
|
use {
|
||||||
anyhow::Result,
|
anyhow::Result,
|
||||||
std::sync::{
|
libp2p::Multiaddr,
|
||||||
|
std::{
|
||||||
|
ffi::{
|
||||||
|
c_char,
|
||||||
|
CString,
|
||||||
|
},
|
||||||
|
sync::{
|
||||||
mpsc::{
|
mpsc::{
|
||||||
Receiver,
|
Receiver,
|
||||||
Sender,
|
Sender,
|
||||||
},
|
},
|
||||||
Mutex,
|
Mutex,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn RegisterObservationCallback(cb: extern "C" fn(o: ObservationC));
|
fn RegisterObservationCallback(
|
||||||
|
cb: extern "C" fn(o: ObservationC),
|
||||||
|
network_id: *const c_char,
|
||||||
|
bootstrap_addrs: *const c_char,
|
||||||
|
listen_addrs: *const c_char,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// An `Observation` C type passed back to us from Go.
|
// An `Observation` C type passed back to us from Go.
|
||||||
|
@ -64,22 +76,58 @@ extern "C" fn proxy(o: ObservationC) {
|
||||||
/// TODO: handle_message should be capable of handling more than just Observations. But we don't
|
/// TODO: handle_message should be capable of handling more than just Observations. But we don't
|
||||||
/// have our own P2P network, we pass it in to keep the code structure and read directly from the
|
/// have our own P2P network, we pass it in to keep the code structure and read directly from the
|
||||||
/// OBSERVATIONS channel in the RPC for now.
|
/// OBSERVATIONS channel in the RPC for now.
|
||||||
pub fn bootstrap<H>(_handle_message: H) -> Result<()>
|
pub fn bootstrap<H>(
|
||||||
|
_handle_message: H,
|
||||||
|
network_id: String,
|
||||||
|
wh_bootstrap_addrs: Vec<Multiaddr>,
|
||||||
|
wh_listen_addrs: Vec<Multiaddr>,
|
||||||
|
) -> Result<()>
|
||||||
where
|
where
|
||||||
H: Fn(Observation) -> Result<()> + 'static,
|
H: Fn(Observation) -> Result<()> + 'static,
|
||||||
{
|
{
|
||||||
|
let network_id_cstr = CString::new(network_id)?;
|
||||||
|
let wh_bootstrap_addrs_cstr = CString::new(
|
||||||
|
wh_bootstrap_addrs
|
||||||
|
.iter()
|
||||||
|
.map(|a| a.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(","),
|
||||||
|
)?;
|
||||||
|
let wh_listen_addrs_cstr = CString::new(
|
||||||
|
wh_listen_addrs
|
||||||
|
.iter()
|
||||||
|
.map(|a| a.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(","),
|
||||||
|
)?;
|
||||||
|
|
||||||
// Launch the Go LibP2P Reactor.
|
// Launch the Go LibP2P Reactor.
|
||||||
unsafe {
|
unsafe {
|
||||||
RegisterObservationCallback(proxy as extern "C" fn(o: ObservationC));
|
RegisterObservationCallback(
|
||||||
|
proxy as extern "C" fn(observation: ObservationC),
|
||||||
|
network_id_cstr.as_ptr(),
|
||||||
|
wh_bootstrap_addrs_cstr.as_ptr(),
|
||||||
|
wh_listen_addrs_cstr.as_ptr(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spawn's the P2P layer as a separate thread via Go.
|
// Spawn's the P2P layer as a separate thread via Go.
|
||||||
pub async fn spawn<H>(handle_message: H) -> Result<()>
|
pub async fn spawn<H>(
|
||||||
|
handle_message: H,
|
||||||
|
network_id: String,
|
||||||
|
wh_bootstrap_addrs: Vec<Multiaddr>,
|
||||||
|
wh_listen_addrs: Vec<Multiaddr>,
|
||||||
|
) -> Result<()>
|
||||||
where
|
where
|
||||||
H: Fn(Observation) -> Result<()> + Send + 'static,
|
H: Fn(Observation) -> Result<()> + Send + 'static,
|
||||||
{
|
{
|
||||||
bootstrap(handle_message)?;
|
bootstrap(
|
||||||
|
handle_message,
|
||||||
|
network_id,
|
||||||
|
wh_bootstrap_addrs,
|
||||||
|
wh_listen_addrs,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue