Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Reth node bindings #1092

Merged
merged 42 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4f6da99
generalize geth into node
zerosnacks Jul 19, 2024
328d124
add basic reth setup
zerosnacks Jul 19, 2024
96e2a01
basic spawning and capturing of ports works, shutdown does not
zerosnacks Jul 19, 2024
ab0bf72
add auth_port, p2p_port
zerosnacks Jul 19, 2024
6b71b8a
clean up
zerosnacks Jul 19, 2024
8c46894
fix geth tests
zerosnacks Jul 19, 2024
bae3bcb
simplify abstraction
zerosnacks Jul 19, 2024
20c183e
clean up
zerosnacks Jul 19, 2024
c3546e1
Merge branch 'main' into zerosnacks/add-reth-node-bindings
zerosnacks Jul 22, 2024
75bf22b
Merge branch 'main' into zerosnacks/add-reth-node-bindings
zerosnacks Sep 3, 2024
dd722fc
add explicit `dev` mode command, reth remains open
zerosnacks Sep 3, 2024
d09358c
--chain takes path or string, not id
zerosnacks Sep 3, 2024
9fd23ed
add support for UDP endpoint extraction from keys
zerosnacks Sep 3, 2024
15bcebd
clean up, add dev flag
zerosnacks Sep 3, 2024
22ae33c
tag as dev
zerosnacks Sep 3, 2024
883dfb5
add option to set block time
zerosnacks Sep 3, 2024
06c8b0e
add block time
zerosnacks Sep 3, 2024
360744f
disable peer persistence if discovery is disabled
zerosnacks Sep 3, 2024
594413a
update binaries
zerosnacks Sep 3, 2024
f42d495
add reth install in github workflow
zerosnacks Sep 3, 2024
011ee3d
fix build
zerosnacks Sep 3, 2024
f29a570
fix doctest
zerosnacks Sep 3, 2024
9c0add8
windows geth build is zipped
zerosnacks Sep 3, 2024
e6fc1e4
fix name
zerosnacks Sep 3, 2024
aa2b62a
fix path to reth binary
zerosnacks Sep 3, 2024
a7f1c07
tar is flat
zerosnacks Sep 3, 2024
9f4a4b7
fix url
zerosnacks Sep 3, 2024
a552d88
fix output path
zerosnacks Sep 3, 2024
46c30a9
reth is already extracted to the root
zerosnacks Sep 3, 2024
ed12666
reth renders via stdout
zerosnacks Sep 3, 2024
6a725f0
disable dev by default, enabling it with .dev()
zerosnacks Sep 4, 2024
c9cbfb6
make sure to exit when running into fatal error
zerosnacks Sep 4, 2024
768544a
add tests to cover the feature set
zerosnacks Sep 4, 2024
98781cf
try debugging windows
zerosnacks Sep 4, 2024
57a383b
run binary install in parallel
zerosnacks Sep 4, 2024
f3fd8a3
disable discovery on blocktime dev
zerosnacks Sep 4, 2024
30ca720
attempt to fix on windows by not using tempdir
zerosnacks Sep 4, 2024
8501af1
re-enable tempdir, attempt to get full error log on windows
zerosnacks Sep 4, 2024
7ad194a
ignore tests on windows, CI of Windows is not compatible:
zerosnacks Sep 4, 2024
970cb81
only install on linux
zerosnacks Sep 4, 2024
ef0462c
temporarily re-enable windows to test error catching
zerosnacks Sep 4, 2024
fb7b09e
revert
zerosnacks Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 33 additions & 12 deletions .github/scripts/install_test_binaries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
# Note: intended for use only with CI (x86_64 Ubuntu, MacOS or Windows)
set -e

GETH_BUILD=${GETH_BUILD:-"1.14.0-87246f3c"}
GETH_BUILD=${GETH_BUILD:-"1.14.8-a9523b64"}
RETH_BUILD=${RETH_BUILD:-"1.0.6"}

BIN_DIR=${BIN_DIR:-"$HOME/bin"}

Expand All @@ -22,25 +23,45 @@ main() {
echo ""
echo "Installed Geth:"
geth version

install_reth
zerosnacks marked this conversation as resolved.
Show resolved Hide resolved

echo ""
echo "Installed Reth:"
reth --version
}

# Installs geth from https://geth.ethereum.org/downloads
install_geth() {
case "$PLATFORM" in
linux|darwin)
name="geth-$PLATFORM-amd64-$GETH_BUILD"
curl -s "https://gethstore.blob.core.windows.net/builds/$name.tar.gz" | tar -xzf -
mv -f "$name/geth" ./
rm -rf "$name"
linux)
NAME="geth-$PLATFORM-amd64-$GETH_BUILD"
curl -sL "https://gethstore.blob.core.windows.net/builds/$NAME.tar.gz" | tar -xzf -
mv -f "$NAME/geth" ./
rm -rf "$NAME"
chmod +x geth
;;
*)
name="geth-windows-amd64-$GETH_BUILD"
zip="$name.zip"
curl -so "$zip" "https://gethstore.blob.core.windows.net/builds/$zip"
unzip "$zip"
mv -f "$name/geth.exe" ./
rm -rf "$name" "$zip"
NAME="geth-windows-amd64-$GETH_BUILD"
curl -so $NAME.zip "https://gethstore.blob.core.windows.net/builds/$NAME.zip"
unzip $NAME.zip
mv -f "$NAME/geth.exe" ./
rm -rf "$NAME" "$NAME.zip"
;;
esac
}

# Install reth from https://github.com/paradigmxyz/reth/releases
install_reth() {
case "$PLATFORM" in
linux)
NAME="reth-v$RETH_BUILD-x86_64-unknown-linux-gnu"
curl -sL "https://github.com/paradigmxyz/reth/releases/download/v$RETH_BUILD/$NAME.tar.gz" | tar -xzf -
chmod +x reth
;;
*)
NAME="reth-v$RETH_BUILD-x86_64-pc-windows-gnu"
curl -sL "https://github.com/paradigmxyz/reth/releases/download/v$RETH_BUILD/$NAME.tar.gz" | tar -xzf -
;;
esac
}
Expand Down
32 changes: 15 additions & 17 deletions crates/node-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,35 @@ extern crate tracing;

use alloy_primitives::U256;

pub mod anvil;
pub use anvil::{Anvil, AnvilInstance};
pub mod nodes;
pub use nodes::{
anvil::{self, Anvil, AnvilInstance},
geth::{self, Geth, GethInstance},
reth::{self, Reth, RethInstance},
};

pub mod geth;
pub use geth::{Geth, GethInstance};
mod node;
pub use node::*;

mod utils;
use utils::*;

/// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei
pub const WEI_IN_ETHER: U256 = U256::from_limbs([0x0de0b6b3a7640000, 0x0, 0x0, 0x0]);

/// The number of blocks from the past for which the fee rewards are fetched for fee estimation.
pub const EIP1559_FEE_ESTIMATION_PAST_BLOCKS: u64 = 10;

/// The default percentile of gas premiums that are fetched for fee estimation.
pub const EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE: f64 = 5.0;

/// The default max priority fee per gas, used in case the base fee is within a threshold.
pub const EIP1559_FEE_ESTIMATION_DEFAULT_PRIORITY_FEE: u64 = 3_000_000_000;

/// The threshold for base fee below which we use the default priority fee, and beyond which we
/// estimate an appropriate value for priority fee.
pub const EIP1559_FEE_ESTIMATION_PRIORITY_FEE_TRIGGER: u64 = 100_000_000_000;

/// The threshold max change/difference (in %) at which we will ignore the fee history values
/// under it.
pub const EIP1559_FEE_ESTIMATION_THRESHOLD_MAX_CHANGE: i64 = 200;

/// A bit of hack to find an unused TCP port.
///
/// Does not guarantee that the given port is unused after the function exists, just that it was
/// unused before the function started (i.e., it does not reserve a port).
fn unused_port() -> u16 {
let listener = std::net::TcpListener::bind("127.0.0.1:0")
.expect("Failed to create TCP listener to find unused port");

let local_addr =
listener.local_addr().expect("Failed to read TCP listener local_addr to find unused port");
local_addr.port()
}
106 changes: 106 additions & 0 deletions crates/node-bindings/src/node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//! Node-related types and constants.

use std::time::Duration;
use thiserror::Error;

/// How long we will wait for the node to indicate that it is ready.
pub const NODE_STARTUP_TIMEOUT: Duration = Duration::from_secs(10);

/// Timeout for waiting for the node to add a peer.
pub const NODE_DIAL_LOOP_TIMEOUT: Duration = Duration::from_secs(20);

/// Errors that can occur when working with a node instance.
#[derive(Debug)]
pub enum NodeInstanceError {
/// Timed out waiting for a message from node's stderr.
Timeout(String),

/// A line could not be read from the node's stderr.
ReadLineError(std::io::Error),

/// The child node process's stderr was not captured.
NoStderr,

/// The child node process's stdout was not captured.
NoStdout,
}

/// Errors that can occur when working with the node.
#[derive(Debug, Error)]
pub enum NodeError {
/// The chain id was not set.
#[error("the chain ID was not set")]
ChainIdNotSet,
/// Could not create the data directory.
#[error("could not create directory: {0}")]
CreateDirError(std::io::Error),
/// No stderr was captured from the child process.
#[error("no stderr was captured from the process")]
NoStderr,
/// No stdout was captured from the child process.
#[error("no stdout was captured from the process")]
NoStdout,
/// Timed out waiting for the node to start.
#[error("timed out waiting for node to spawn; is the node binary installed?")]
Timeout,
/// Encountered a fatal error.
#[error("fatal error: {0}")]
Fatal(String),
/// A line could not be read from the node stderr.
#[error("could not read line from node stderr: {0}")]
ReadLineError(std::io::Error),
/// Genesis error
#[error("genesis error occurred: {0}")]
GenesisError(String),
/// Node init error
#[error("node init error occurred")]
InitError,
/// Spawn node error
#[error("could not spawn node: {0}")]
SpawnError(std::io::Error),
/// Wait error
#[error("could not wait for node to exit: {0}")]
WaitError(std::io::Error),

/// Clique private key error
#[error("clique address error: {0}")]
CliqueAddressError(String),
}

/// Whether or not node is in `dev` mode and configuration options that depend on the mode.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NodeMode {
/// Options that can be set in dev mode
Dev(DevOptions),
/// Options that cannot be set in dev mode
NonDev(PrivateNetOptions),
}

impl Default for NodeMode {
fn default() -> Self {
Self::Dev(Default::default())
}
}

/// Configuration options that can be set in dev mode.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DevOptions {
/// The interval at which the dev chain will mine new blocks.
pub block_time: Option<u64>,
}

/// Configuration options that cannot be set in dev mode.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PrivateNetOptions {
/// The p2p port to use.
pub p2p_port: Option<u16>,

/// Whether or not peer discovery is enabled.
pub discovery: bool,
}

impl Default for PrivateNetOptions {
fn default() -> Self {
Self { p2p_port: None, discovery: true }
}
}
Loading
Loading