diff --git a/Cargo.lock b/Cargo.lock index 1581d5b..d61a25b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1652,6 +1652,8 @@ dependencies = [ "config", "consensus", "execution", + "eyre", + "tokio", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 42bfb31..e199da1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,12 @@ execution = { path = "./execution" } [patch.crates-io] ethers = { git = "https://github.com/ncitron/ethers-rs", branch = "fix-retry" } +[dev-dependencies] +tokio = { version = "1", features = ["full"] } +eyre = "0.6.8" + +[[example]] +name = "checkpoints" +path = "examples/checkpoints.rs" +required-features = [] + diff --git a/README.md b/README.md index 1b33426..495886b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Helios converts an untrusted centralized RPC endpoint into a safe unmanipulable The entire size of Helios's binary is 13Mb and should be easy to compile into WebAssembly. This makes it a perfect target to embed directly inside wallets and dapps. + ## Installing First install `heliosup`, Helios's installer: @@ -18,6 +19,7 @@ curl https://raw.githubusercontent.com/a16z/helios/master/heliosup/install | bas To install Helios, run `heliosup`. + ## Usage To run Helios, run the below command, replacing `$ETH_RPC_URL` with an RPC provider URL such as Alchemy or Infura: @@ -30,10 +32,14 @@ helios --execution-rpc $ETH_RPC_URL Helios will now run a local RPC server at `http://127.0.0.1:8545`. +Helios also provides examples in the [`examples/`](./examples/) directory. To run an example, you can execute `cargo run --example ` from inside the helios repository. + + ### Warning Helios is still experimental software. While we hope you try it out, we do not suggest adding it as your main RPC in wallets yet. Sending high-value transactions from a wallet connected to Helios is discouraged. + ### Additional Options `--consensus-rpc` or `-c` can be used to set a custom consensus layer rpc endpoint. This must be a consenus node that supports the light client beaconchain api. We recommend using Nimbus for this. If no consensus rpc is supplied, it defaults to `https://www.lightclientdata.org` which is run by us. @@ -61,6 +67,7 @@ This can be run like so: `helios --load-external-fallback` (or `helios -l` with `--help` or `-h` prints the help message. + ### Configuration Files All configuration options can be set on a per-network level in `~/.helios/helios.toml`. Here is an example config file: @@ -77,6 +84,7 @@ execution_rpc = "https://eth-goerli.g.alchemy.com/v2/XXXXX" checkpoint = "0xb5c375696913865d7c0e166d87bc7c772b6210dc9edf149f4c7ddc6da0dd4495" ``` + ### Using Helios as a Library Helios can be imported into any Rust project. Helios requires the Rust nightly toolchain to compile. @@ -141,10 +149,12 @@ async fn main() -> Result<()> { All contributions to Helios are welcome. Before opening a PR, please submit an issue detailing the bug or feature. When opening a PR, please ensure that your contribution builds on the nightly rust toolchain, has been linted with `cargo fmt`, and contains tests when applicable. + ## Telegram If you are having trouble with Helios or are considering contributing, feel free to join our telegram [here](https://t.me/+IntDY_gZJSRkNTJj). + ## Disclaimer _This code is being provided as is. No guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the code. It has not been audited and as such there can be no assurance it will work as intended, and users may experience delays, failures, errors, omissions or loss of transmitted information. Nothing in this repo should be construed as investment advice or legal advice for any particular facts or circumstances and is not meant to replace competent counsel. It is strongly advised for you to contact a reputable attorney in your jurisdiction for any questions or concerns with respect thereto. a16z is not liable for any use of the foregoing, and users should proceed with caution and use at their own risk. See a16z.com/disclosures for more info._ diff --git a/config/src/checkpoints.rs b/config/src/checkpoints.rs index a77b21b..7aa4c1f 100644 --- a/config/src/checkpoints.rs +++ b/config/src/checkpoints.rs @@ -229,4 +229,12 @@ impl CheckpointFallback { .map(|service| service.endpoint.clone()) .collect() } + + /// Returns the raw checkpoint fallback service objects for a given network. + pub fn get_fallback_services( + &self, + network: &networks::Network, + ) -> &Vec { + self.services[network].as_ref() + } } diff --git a/examples/checkpoints.rs b/examples/checkpoints.rs new file mode 100644 index 0000000..e74a4f0 --- /dev/null +++ b/examples/checkpoints.rs @@ -0,0 +1,42 @@ +use eyre::Result; + +// From helios::config +use config::{checkpoints, networks}; + +#[tokio::main] +async fn main() -> Result<()> { + // Construct the checkpoint fallback services. + // The `build` method will fetch a list of [CheckpointFallbackService]s from a community-mainained list by ethPandaOps. + // This list is NOT guaranteed to be secure, but is provided in good faith. + // The raw list can be found here: https://github.com/ethpandaops/checkpoint-sync-health-checks/blob/master/_data/endpoints.yaml + let cf = checkpoints::CheckpointFallback::new() + .build() + .await + .unwrap(); + + // Fetch the latest goerli checkpoint + let goerli_checkpoint = cf + .fetch_latest_checkpoint(&networks::Network::GOERLI) + .await + .unwrap(); + println!("Fetched latest goerli checkpoint: {}", goerli_checkpoint); + + // Fetch the latest mainnet checkpoint + let mainnet_checkpoint = cf + .fetch_latest_checkpoint(&networks::Network::MAINNET) + .await + .unwrap(); + println!("Fetched latest mainnet checkpoint: {}", mainnet_checkpoint); + + // Let's get a list of all the fallback service endpoints for mainnet + let endpoints = cf.get_all_fallback_endpoints(&networks::Network::MAINNET); + println!("Fetched all mainnet fallback endpoints: {:?}", endpoints); + + // Since we built the checkpoint fallback services, we can also just get the raw checkpoint fallback services. + // The `get_fallback_services` method returns a reference to the internal list of CheckpointFallbackService objects + // for the given network. + let services = cf.get_fallback_services(&networks::Network::MAINNET); + println!("Fetched all mainnet fallback services: {:?}", services); + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index c46ab7f..914e9f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,55 @@ +#![warn(missing_debug_implementations, rust_2018_idioms, unreachable_pub)] +#![deny(rustdoc::broken_intra_doc_links)] +#![doc(test( + no_crate_inject, + attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) +))] + +//! # Ethereum light client written in Rust. +//! +//! > helios is a fully trustless, efficient, and portable Ethereum light client written in Rust. +//! +//! Helios converts an untrusted centralized RPC endpoint into a safe unmanipulable local RPC for its users. It syncs in seconds, requires no storage, and is lightweight enough to run on mobile devices. +//! +//! The entire size of Helios's binary is 13Mb and should be easy to compile into WebAssembly. This makes it a perfect target to embed directly inside wallets and dapps. +//! +//! ## Quickstart: `prelude` +//! +//! The prelude imports all the necessary data types and traits from helios. Use this to quickly bootstrap a new project. +//! +//! ```no_run +//! # #[allow(unused)] +//! use helios::prelude::*; +//! ``` +//! +//! Examples on how you can use the types imported by the prelude can be found in +//! the [`examples` directory of the repository](https://github.com/a16z/helios/tree/master/examples) +//! and in the `tests/` directories of each crate. +//! +//! ## Breakdown of exported helios modules +//! +//! ### `client` +//! +//! The `client` module exports three main types: `Client`, `ClientBuilder`, and `FileDB`. +//! +//! `ClientBuilder` is a builder for the `Client` type. It allows you to configure the client using the fluent builder pattern. +//! +//! `Client` serves Ethereum RPC endpoints locally that call a node on the backend. +//! +//! Finally, the `FileDB` type is a simple local database. It is used by the `Client` to store checkpoint data. +//! +//! ### `config` +//! +//! The `config` module provides the configuration types for all of helios. It is used by the `ClientBuilder` to configure the `Client`. +//! +//! ### `types` +//! +//! Generic types used across helios. +//! +//! ### `errors` +//! +//! Errors used across helios. + pub mod client { pub use client::{database::FileDB, Client, ClientBuilder}; } @@ -16,3 +68,10 @@ pub mod errors { pub use consensus::errors::*; pub use execution::errors::*; } + +pub mod prelude { + pub use crate::client::*; + pub use crate::config::*; + pub use crate::errors::*; + pub use crate::types::*; +}