Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
feat(providers): add a subset of admin namespace (#1880)
Browse files Browse the repository at this point in the history
* tell Geth to expose the admin namespace

* wip: add admin namespace support

 * add networking and peer related structs

* add rest of chain config fields

* add datadir to geth

* fix data dir ref

* add dev flag to geth

* set dev only if block_time is not set

* put mutually exclusive options in an enum

* make block_time use the devmode enum

* add p2p port to geth

* add basic impls for admin endpoints

* move from_int_or_hex to ethers-core utils

* fix nodeinfo protocol field

 * the type is better represented by a struct which can have either eth
   or snap

* add chain id and discovery toggle for Geth

* remove PeerEvent

 * should re-add when peer event endpoints are implemented

* simplify serde options for admin responses

* change signature for peer modification apis

 * these admin apis accept an enode, which _may_ be an enr, but could
   also be a legacy enode "v4" url.

* add note on where `ChainConfig` fields come from

* add note on PeerInfo about the source of fields

* add admin namespace support to CHANGELOG

* update pr number in changelog

* cargo fmt

* move chainconfig to genesis in utils

* accept genesis file in geth

* add genesis writing to geth spawn

* finally get geth nodes to connect

* import io::Read in provider tests

* fix PeerInfo and use enode id for provider test

* make clippy happy

* improve documentation for genesis module

* remove not(wasm) attributes on genesis module

* remove debugging printlns

* remove io::Read from provider tests

* add failing post merge test case

* add full mainnet nodeinfo for testing

* support deserializing json bignums to U256

 * the serde_json arbitrary_precision feature is necessary so the
   serde_json::Number variant of `IntOrHexOrBigNum` can be converted
   into a string and fed into U256::from_dec_string

* fix from_int_or_hex_opt doc string

* remove third variant from IntOrHex

 * unnecessary since serde_json::Number handles smaller ints as well

* add comments for ids

* fix enode id type in admin_peers provider test

* fix admin typo in Cargo.toml

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>

* add method to wait on a gethinstance adding a peer

* fix dial loop and wait_to_add_peer doc comments

* update geth

 * the build can be updated by changing the GETH_BUILD env var

* wait for geth to exit on drop

* remove unnecessary wait

* fix mid-handshake PeerInfo deserialization

* remove println

* make tests less flaky

* handle discovery with the rest of the non dev opts

* dump geth stderr to debug failing ci test

 * add method which dumps the unread stderr of the geth instance into a
   string

* remove call_raw debug println

 * bug is due to authrpc endpoint being in use

* use unused port when authrpc port is not specified

* remove dump_stderr from GethInstance

 * did not work properly anyways

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
  • Loading branch information
Rjected and gakonst authored Nov 30, 2022
1 parent 2d793ed commit 4b68562
Show file tree
Hide file tree
Showing 12 changed files with 1,126 additions and 44 deletions.
19 changes: 10 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ env:
ETHERSCAN_API_KEY_ETHEREUM: I5BXNZYP5GEDWFINGVEZKYIVU2695NPQZB
ETHERSCAN_API_KEY_CELO: B13XSMUT6Q3Q4WZ5DNQR8RXDBA2KNTMT4M
GOERLI_PRIVATE_KEY: "fa4a1a79e869a96fcb42727f75e3232d6865a82ea675bb95de967a7fe6a773b2"
GETH_BUILD: 1.10.26-e5eb32ac

jobs:
tests:
Expand All @@ -36,9 +37,9 @@ jobs:
- name: Install geth
run: |
mkdir -p "$HOME/bin"
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.23-8c2f2715.tar.gz
tar -xvf geth-linux-amd64-1.9.23-8c2f2715.tar.gz
mv geth-linux-amd64-1.9.23-8c2f2715/geth $HOME/bin/geth
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-$GETH_BUILD.tar.gz
tar -xvf geth-linux-amd64-$GETH_BUILD.tar.gz
mv geth-linux-amd64-$GETH_BUILD/geth $HOME/bin/geth
chmod u+x "$HOME/bin/geth"
export PATH=$HOME/bin:$PATH
geth version
Expand Down Expand Up @@ -79,9 +80,9 @@ jobs:
- name: Install geth
run: |
mkdir -p "$HOME/bin"
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.23-8c2f2715.tar.gz
tar -xvf geth-linux-amd64-1.9.23-8c2f2715.tar.gz
mv geth-linux-amd64-1.9.23-8c2f2715/geth $HOME/bin/geth
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-$GETH_BUILD.tar.gz
tar -xvf geth-linux-amd64-$GETH_BUILD.tar.gz
mv geth-linux-amd64-$GETH_BUILD/geth $HOME/bin/geth
chmod u+x "$HOME/bin/geth"
export PATH=$HOME/bin:$PATH
geth version
Expand Down Expand Up @@ -201,9 +202,9 @@ jobs:
- name: Install geth (for state overrides example)
run: |
mkdir -p "$HOME/bin"
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.23-8c2f2715.tar.gz
tar -xvf geth-linux-amd64-1.9.23-8c2f2715.tar.gz
mv geth-linux-amd64-1.9.23-8c2f2715/geth $HOME/bin/geth
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-$GETH_BUILD.tar.gz
tar -xvf geth-linux-amd64-$GETH_BUILD.tar.gz
mv geth-linux-amd64-$GETH_BUILD/geth $HOME/bin/geth
chmod u+x "$HOME/bin/geth"
export PATH=$HOME/bin:$PATH
geth version
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@

### Unreleased

- Add a subset of the `admin` namespace
[1880](https://github.com/gakonst/ethers-rs/pull/1880)
- Return String for net version
[1376](https://github.com/gakonst/ethers-rs/pull/1376)
- Stream of paginated logs that load logs in small pages
Expand Down
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ethers-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ tiny-keccak = { version = "2.0.2", default-features = false }
# misc
chrono = { version = "0.4", default-features = false }
serde = { version = "1.0.124", default-features = false, features = ["derive"] }
serde_json = { version = "1.0.64", default-features = false }
serde_json = { version = "1.0.64", default-features = false, features = ["arbitrary_precision"] }
thiserror = { version = "1.0", default-features = false }
bytes = { version = "1.3.0", features = ["serde"] }
hex = { version = "0.4.3", default-features = false, features = ["std"] }
Expand Down
22 changes: 2 additions & 20 deletions ethers-core/src/types/fee.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::str::FromStr;

use crate::types::U256;
use serde::{de::Deserializer, Deserialize, Serialize};
use crate::{types::U256, utils::from_int_or_hex};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
Expand All @@ -19,19 +17,3 @@ pub struct FeeHistory {
#[serde(default)]
pub reward: Vec<Vec<U256>>,
}

fn from_int_or_hex<'de, D>(deserializer: D) -> Result<U256, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum IntOrHex {
Int(u64),
Hex(String),
}
match IntOrHex::deserialize(deserializer)? {
IntOrHex::Int(n) => Ok(U256::from(n)),
IntOrHex::Hex(s) => U256::from_str(s.as_str()).map_err(serde::de::Error::custom),
}
}
170 changes: 170 additions & 0 deletions ethers-core/src/utils/genesis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
use std::collections::HashMap;

use crate::{
types::{Address, Bytes, H256, U256, U64},
utils::{from_int_or_hex, from_int_or_hex_opt},
};
use serde::{Deserialize, Serialize};

/// This represents the chain configuration, specifying the genesis block, header fields, and hard
/// fork switch blocks.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Genesis {
/// The fork configuration for this network.
pub config: ChainConfig,

/// The genesis header nonce.
pub nonce: U64,

/// The genesis header timestamp.
pub timestamp: U64,

/// The genesis header extra data.
pub extra_data: Bytes,

/// The genesis header gas limit.
pub gas_limit: U64,

/// The genesis header difficulty.
#[serde(deserialize_with = "from_int_or_hex")]
pub difficulty: U256,

/// The genesis header mix hash.
pub mix_hash: H256,

/// The genesis header coinbase address.
pub coinbase: Address,

/// The initial state of the genesis block.
pub alloc: HashMap<Address, GenesisAccount>,
}

/// An account in the state of the genesis block.
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct GenesisAccount {
#[serde(skip_serializing_if = "Option::is_none")]
pub nonce: Option<u64>,
pub balance: U256,
#[serde(skip_serializing_if = "Option::is_none")]
pub code: Option<Bytes>,
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub storage: Option<HashMap<H256, H256>>,
}

/// Represents a node's chain configuration.
///
/// See [geth's `ChainConfig`
/// struct](https://github.com/ethereum/go-ethereum/blob/64dccf7aa411c5c7cd36090c3d9b9892945ae813/params/config.go#L349)
/// for the source of each field.
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct ChainConfig {
/// The network's chain ID.
pub chain_id: u64,

/// The homestead switch block (None = no fork, 0 = already homestead).
#[serde(skip_serializing_if = "Option::is_none")]
pub homestead_block: Option<u64>,

/// The DAO fork switch block (None = no fork).
#[serde(skip_serializing_if = "Option::is_none")]
pub dao_fork_block: Option<u64>,

/// Whether or not the node supports the DAO hard-fork.
pub dao_fork_support: bool,

/// The EIP-150 hard fork block (None = no fork).
#[serde(skip_serializing_if = "Option::is_none")]
pub eip150_block: Option<u64>,

/// The EIP-150 hard fork hash.
#[serde(skip_serializing_if = "Option::is_none")]
pub eip150_hash: Option<H256>,

/// The EIP-155 hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub eip155_block: Option<u64>,

/// The EIP-158 hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub eip158_block: Option<u64>,

/// The Byzantium hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub byzantium_block: Option<u64>,

/// The Constantinople hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub constantinople_block: Option<u64>,

/// The Petersburg hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub petersburg_block: Option<u64>,

/// The Istanbul hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub istanbul_block: Option<u64>,

/// The Muir Glacier hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub muir_glacier_block: Option<u64>,

/// The Berlin hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub berlin_block: Option<u64>,

/// The London hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub london_block: Option<u64>,

/// The Arrow Glacier hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub arrow_glacier_block: Option<u64>,

/// The Gray Glacier hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub gray_glacier_block: Option<u64>,

/// Virtual fork after the merge to use as a network splitter.
#[serde(skip_serializing_if = "Option::is_none")]
pub merge_netsplit_block: Option<u64>,

/// The Shanghai hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub shanghai_block: Option<u64>,

/// The Cancun hard fork block.
#[serde(skip_serializing_if = "Option::is_none")]
pub cancun_block: Option<u64>,

/// Total difficulty reached that triggers the merge consensus upgrade.
#[serde(skip_serializing_if = "Option::is_none", deserialize_with = "from_int_or_hex_opt")]
pub terminal_total_difficulty: Option<U256>,

/// A flag specifying that the network already passed the terminal total difficulty. Its
/// purpose is to disable legacy sync without having seen the TTD locally.
pub terminal_total_difficulty_passed: bool,

/// Ethash parameters.
#[serde(skip_serializing_if = "Option::is_none")]
pub ethash: Option<EthashConfig>,

/// Clique parameters.
#[serde(skip_serializing_if = "Option::is_none")]
pub clique: Option<CliqueConfig>,
}

/// Empty consensus configuration for proof-of-work networks.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct EthashConfig {}

/// Consensus configuration for Clique.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CliqueConfig {
/// Number of seconds between blocks to enforce.
pub period: u64,

/// Epoch length to reset votes and checkpoints.
pub epoch: u64,
}
Loading

0 comments on commit 4b68562

Please sign in to comment.