Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Helios will now run a local RPC server at `http://127.0.0.1:8545`.

`--checkpoint` or `-w` can be used to set a custom weak subjectivity checkpoint. This must be equal to the first beacon block hash of an epoch. Weak subjectivity checkpoints are the root of trust in the system. If this is set to a malicious value, an attacker can cause the client to sync to the wrong chain. Helios sets a default value initially, then caches the most recent finalized block it has seen for later use.

`--network` or `-n` sets the network to sync to. Current valid options are `mainnet`, `sepolia`, and `holesky` however users can add custom networks in their configuration files.
`--network` or `-n` sets the network to sync to. Current valid options are `mainnet`, `sepolia`, and `hoodi` however users can add custom networks in their configuration files.

`--rpc-port` or `-p` sets the port that the local RPC should run on. The default value is `8545`.

Expand Down Expand Up @@ -114,23 +114,23 @@ Examples of running Helios as a rust library can be seen in the [examples](./exa

### Supported Ethereum Checkpoints <a id="supported-checkpoints"></a>

A checkpoint is a Beacon Chain Consensus Layer block hash rather than an Execution Layer block hash. An example of an Execution Layer block hash for Holesky is shown at https://holesky.etherscan.io/blocks
A checkpoint is a Beacon Chain Consensus Layer block hash rather than an Execution Layer block hash. An example of an Execution Layer block hash for Holesky is shown at https://hoodi.etherscan.io/blocks

Checkpoints may be obtained from the following links:
* Ethereum Mainnet https://beaconcha.in
* Holesky Testnet https://holesky.beaconcha.in
* Hoodi Testnet https://hoodi.beaconcha.in/

It is recommended to use a block hash as a checkpoint that is less than two weeks old, however you can actually use older checkpoints and it will still work but will give you a warning. Using a checkpoint that is less than two weeks old prevents a few attacks that are pretty hard to pull off.

For example, to obtain a recent checkpoint for Holesky Testnet go to https://holesky.beaconcha.in/ and get the block hash of the first block in any finalized epoch. At the time of writing, the [first block hash in epoch 78425](https://holesky.beaconcha.in/epoch/78425) is the [oldest slot 2509600](https://holesky.beaconcha.in/slot/2509600) that has a Block Root of 0x60409a013161b33c8c68c6183c7753e779ec6c24be2f3c50c6036c30e13b34a6 and is the latest checkpoint value to use.
For example, to obtain a recent checkpoint for Hoodi Testnet go to https://hoodi.beaconcha.in/ and get the block hash of the first block in any finalized epoch. At the time of writing, the [first block hash in epoch 78425](https://hoodi.beaconcha.in/epoch/78425) is the [oldest slot 2509600](https://hoodi.beaconcha.in/slot/2509600) that has a Block Root of 0x60409a013161b33c8c68c6183c7753e779ec6c24be2f3c50c6036c30e13b34a6 and is the latest checkpoint value to use.

This latest checkpoint may be provided as an [Additional CLI Option](#additional-cli-options) at the command line to run a Helios Light Client node on Ethereum Holesky Testnet:
```bash
helios ethereum \
--network holesky \
--consensus-rpc http://testing.holesky.beacon-api.nimbus.team \
--execution-rpc https://ethereum-holesky.g.allthatnode.com \
--checkpoint 0x60409a013161b33c8c68c6183c7753e779ec6c24be2f3c50c6036c30e13b34a6
--network hoodi \
--consensus-rpc http://testing.hoodi.beacon-api.nimbus.team \
--execution-rpc https://ethereum-hoodi-rpc.publicnode.com \
--checkpoint 0x3335028555f5fff431f82f978d2503ed59bc8da00a86217eea9befa9d486a049
```

For example, to obtain a recent checkpoint for Ethereum Mainnet go to https://beaconcha.in and get the block hash of the first block in any finalized epoch. At the time of writing the [first block hash in epoch 222705](https://beaconcha.in/epoch/222705) is the [oldest slot 7126560](https://beaconcha.in/slot/7126560) that has a Block Root of 0xe1912ca8ca3b45dac497cae7825bab055b0f60285533721b046e8fefb5b076f2 and is the latest checkpoint value to use.
Expand All @@ -140,7 +140,7 @@ This latest checkpoint may be provided as an [Additional CLI Option](#additional
helios ethereum \
--network mainnet \
--consensus-rpc https://www.lightclientdata.org \
--execution-rpc https://ethereum-mainnet.g.allthatnode.com \
--execution-rpc https://ethereum-rpc.publicnode.com \
--checkpoint 0xe1912ca8ca3b45dac497cae7825bab055b0f60285533721b046e8fefb5b076f2
```

Expand Down
2 changes: 1 addition & 1 deletion ethereum/src/config/checkpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl CheckpointFallback {
networks: vec![
networks::Network::Mainnet,
networks::Network::Sepolia,
networks::Network::Holesky,
networks::Network::Hoodi,
],
}
}
Expand Down
81 changes: 0 additions & 81 deletions ethereum/src/config/networks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use crate::config::types::ChainConfig;
pub enum Network {
Mainnet,
Sepolia,
Holesky,
Hoodi,
}

Expand All @@ -34,7 +33,6 @@ impl FromStr for Network {
match s {
"mainnet" => Ok(Self::Mainnet),
"sepolia" => Ok(Self::Sepolia),
"holesky" => Ok(Self::Holesky),
"hoodi" => Ok(Self::Hoodi),
_ => Err(eyre::eyre!("network not recognized")),
}
Expand All @@ -46,7 +44,6 @@ impl Display for Network {
let str = match self {
Self::Mainnet => "mainnet",
Self::Sepolia => "sepolia",
Self::Holesky => "holesky",
Self::Hoodi => "hoodi",
};

Expand All @@ -59,7 +56,6 @@ impl Network {
match self {
Self::Mainnet => mainnet(),
Self::Sepolia => sepolia(),
Self::Holesky => holesky(),
Self::Hoodi => hoodi(),
}
}
Expand All @@ -68,7 +64,6 @@ impl Network {
match id {
1 => Ok(Network::Mainnet),
11155111 => Ok(Network::Sepolia),
17000 => Ok(Network::Holesky),
560048 => Ok(Network::Hoodi),
_ => Err(eyre::eyre!("chain id not known")),
}
Expand Down Expand Up @@ -175,56 +170,6 @@ pub fn sepolia() -> BaseConfig {
}
}

pub fn holesky() -> BaseConfig {
BaseConfig {
default_checkpoint: b256!(
"e1f575f0b691404fe82cce68a09c2c98af197816de14ce53c0fe9f9bd02d2399"
),
rpc_port: 8545,
consensus_rpc: None,
chain: ChainConfig {
chain_id: 17000,
genesis_time: 1695902400,
genesis_root: b256!("9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"),
},
forks: Forks {
genesis: Fork {
epoch: 0,
fork_version: fixed_bytes!("01017000"),
},
altair: Fork {
epoch: 0,
fork_version: fixed_bytes!("02017000"),
},
bellatrix: Fork {
epoch: 0,
fork_version: fixed_bytes!("03017000"),
},
capella: Fork {
epoch: 256,
fork_version: fixed_bytes!("04017000"),
},
deneb: Fork {
epoch: 29696,
fork_version: fixed_bytes!("05017000"),
},
electra: Fork {
epoch: 115968,
fork_version: fixed_bytes!("06017000"),
},
fulu: Fork {
epoch: 165120,
fork_version: fixed_bytes!("07017000"),
},
},
execution_forks: EthereumForkSchedule::holesky(),
max_checkpoint_age: 1_209_600, // 14 days
#[cfg(not(target_arch = "wasm32"))]
data_dir: Some(data_dir(Network::Holesky)),
..std::default::Default::default()
}
}

pub fn hoodi() -> BaseConfig {
BaseConfig {
default_checkpoint: b256!(
Expand Down Expand Up @@ -338,32 +283,6 @@ impl EthereumForkSchedule {
}
}

fn holesky() -> ForkSchedule {
ForkSchedule {
frontier_timestamp: 1695902100,
homestead_timestamp: 1695902100,
dao_timestamp: 1695902100,
tangerine_timestamp: 1695902100,
spurious_dragon_timestamp: 1695902100,
byzantium_timestamp: 1695902100,
constantinople_timestamp: 1695902100,
petersburg_timestamp: 1695902100,
istanbul_timestamp: 1695902100,
muir_glacier_timestamp: 1695902100,
berlin_timestamp: 1695902100,
london_timestamp: 1695902100,
arrow_glacier_timestamp: 1695902100,
gray_glacier_timestamp: 1695902100,
paris_timestamp: 1695902100,
shanghai_timestamp: 1696000704,
cancun_timestamp: 1707305664,
prague_timestamp: 1740434112,
osaka_timestamp: 1759308480,

..Default::default()
}
}

fn hoodi() -> ForkSchedule {
ForkSchedule {
frontier_timestamp: 0,
Expand Down
16 changes: 6 additions & 10 deletions ethereum/tests/checkpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ async fn test_checkpoint_fallback() {

assert_eq!(cf.services.get(&networks::Network::Mainnet), None);
assert_eq!(cf.services.get(&networks::Network::Sepolia), None);
assert_eq!(cf.services.get(&networks::Network::Holesky), None);
assert_eq!(cf.services.get(&networks::Network::Hoodi), None);

assert_eq!(
cf.networks,
[
networks::Network::Mainnet,
networks::Network::Sepolia,
networks::Network::Holesky,
]
[networks::Network::Mainnet, networks::Network::Sepolia, networks::Network::Hoodi]
.to_vec()
);
}
Expand All @@ -29,7 +25,7 @@ async fn test_construct_checkpoints() {

assert!(cf.services[&networks::Network::Mainnet].len() > 1);
assert!(cf.services[&networks::Network::Sepolia].len() > 1);
assert!(cf.services[&networks::Network::Holesky].len() > 1);
assert!(cf.services[&networks::Network::Hoodi].len() > 1);
}

#[tokio::test]
Expand All @@ -44,7 +40,7 @@ async fn test_fetch_latest_checkpoints() {
.unwrap();
assert!(checkpoint != B256::ZERO);
let checkpoint = cf
.fetch_latest_checkpoint(&networks::Network::Holesky)
.fetch_latest_checkpoint(&networks::Network::Hoodi)
.await
.unwrap();
assert!(checkpoint != B256::ZERO);
Expand All @@ -65,7 +61,7 @@ async fn test_get_all_fallback_endpoints() {
assert!(!urls.is_empty());
let urls = cf.get_all_fallback_endpoints(&networks::Network::Sepolia);
assert!(!urls.is_empty());
let urls = cf.get_all_fallback_endpoints(&networks::Network::Holesky);
let urls = cf.get_all_fallback_endpoints(&networks::Network::Hoodi);
assert!(!urls.is_empty());
}

Expand All @@ -79,6 +75,6 @@ async fn test_get_healthy_fallback_endpoints() {
assert!(!urls.is_empty());
let urls = cf.get_healthy_fallback_endpoints(&networks::Network::Sepolia);
assert!(!urls.is_empty());
let urls = cf.get_healthy_fallback_endpoints(&networks::Network::Holesky);
let urls = cf.get_healthy_fallback_endpoints(&networks::Network::Hoodi);
assert!(!urls.is_empty());
}
8 changes: 4 additions & 4 deletions examples/checkpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ async fn main() -> Result<()> {
.unwrap();
println!("Fetched latest sepolia checkpoint: {sepolia_checkpoint}");

// Fetch the latest holesky checkpoint
let holesky_checkpoint = cf
.fetch_latest_checkpoint(&networks::Network::Holesky)
// Fetch the latest hoodi checkpoint
let hoodi_checkpoint = cf
.fetch_latest_checkpoint(&networks::Network::Hoodi)
.await
.unwrap();
println!("Fetched latest holesky checkpoint: {holesky_checkpoint}");
println!("Fetched latest hoodi checkpoint: {hoodi_checkpoint}");

// Fetch the latest mainnet checkpoint
let mainnet_checkpoint = cf
Expand Down
4 changes: 2 additions & 2 deletions helios-ts/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ export type Config = {
*
* @remarks
* Networks are organized by their network kind:
* - Ethereum networks: "mainnet", "sepolia", "holesky", "hoodi"
* - Ethereum networks: "mainnet", "sepolia", "hoodi"
* - OP Stack networks: "op-mainnet", "base", "worldchain", "zora", "unichain"
* - Linea networks: "linea", "linea-sepolia"
*
Expand All @@ -463,7 +463,7 @@ export type Network =
| "mainnet" // Ethereum mainnet (chain ID: 1)
| "goerli" // Goerli testnet (deprecated)
| "sepolia" // Sepolia testnet (chain ID: 11155111)
| "holesky" // Holesky testnet (chain ID: 17000)
| "holesky" // Holesky testnet (deprecated)
| "hoodi" // Hoodi testnet (chain ID: 560048)
// OP Stack networks
| "op-mainnet" // OP Mainnet (chain ID: 10)
Expand Down
2 changes: 1 addition & 1 deletion helios-ts/src/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl EthereumClient {
let base = match network.as_str() {
"mainnet" => networks::mainnet(),
"sepolia" => networks::sepolia(),
"holesky" => networks::holesky(),
"hoodi" => networks::hoodi(),
other => Err(JsError::new(&format!("invalid network: {other}")))?,
};

Expand Down