Coder Social home page Coder Social logo

eths's Introduction

Made with Rust

License MIT Rust 1.77

ETHS

(ETH HandShake) A simple Ethereum client for connecting to enodes through the RLPx protocol.
Relies on code from ParadigmXYZ's RLPx implementation, namely the ECIES encryption and decryption functions, and the RLPx packet encoding and decoding functions.
Those functions create the necessary secrets for stream transport, along with Ethereum's MAC custom encryption, and the RLP-encoded HelloMessage for the handshake.
The client is able to connect to an enode, perform the handshake, and check the matching capabilities (currently "supporting" ETH66 to ETH68, as a mock).

Details

The toolchain forces the nightly build of rust, due to the usage of experimental cargo fmt styling. However, this styling can be removed, and the stable rust version can be used.
The nodes to connect to are setup through a .csv file with no header, with the format:

enode_id,ip,port

Usage

This client requires at least Rust 1.76.0 due to an alloy-rpc-types-trace dependency, and optionally the nightly build for the cargo fmt styling.
Build has been tested on Debian 11 Bullseye and MacOS 14.0 M1 Max.
Please note that on MacOS, due to the usage of bindgen (and thus, stdlib.h) in blst crate, you might need to set the SDKROOT to the correct path, for example:

export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)

To run the client, you can try the --help argument:

cargo run -- --help

Usage: eths [--nodefile <nodefile>] [--timeout <timeout>]

ETH node handshake args.

Options:
  --nodefile        public nodes filename override
  --timeout         node timeout in ms
  --help            display usage information

By default, the node filename is set to nodes.csv (root of the project), and the timeout is set to 2500ms.

NOTE: Your cargo config might require git-fetch-with-cli, see: https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli

Output

Using the defaults:

cargo run

2024-04-05T20:29:00.282158Z  INFO eths: running with Config { nodes: [Node { id: "00022472a33bf4be92599db8d2a284599141dcbeea0610f88887e631e5531d90c926aeb1ca003dc4d99ecb1e43c3472d4d2006ebb0c38f51d7b7470c91f767b5", ip: "82.66.183.172", port: 30303 }, Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }], timeout: 2500 }
2024-04-05T20:29:00.283083Z  INFO eths::client: starting handshake to Node { id: "00022472a33bf4be92599db8d2a284599141dcbeea0610f88887e631e5531d90c926aeb1ca003dc4d99ecb1e43c3472d4d2006ebb0c38f51d7b7470c91f767b5", ip: "82.66.183.172", port: 30303 }
2024-04-05T20:29:00.283099Z  INFO eths::transport: connecting to Node { id: "00022472a33bf4be92599db8d2a284599141dcbeea0610f88887e631e5531d90c926aeb1ca003dc4d99ecb1e43c3472d4d2006ebb0c38f51d7b7470c91f767b5", ip: "82.66.183.172", port: 30303 }
2024-04-05T20:29:00.283147Z  INFO eths::client: starting handshake to Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.283236Z  INFO eths::transport: connecting to Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.520506Z  INFO eths::transport: connected to Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.533050Z  INFO eths::transport: connected to Node { id: "00022472a33bf4be92599db8d2a284599141dcbeea0610f88887e631e5531d90c926aeb1ca003dc4d99ecb1e43c3472d4d2006ebb0c38f51d7b7470c91f767b5", ip: "82.66.183.172", port: 30303 }
2024-04-05T20:29:00.751855Z  INFO eths::transport: sending message to Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.753044Z  INFO eths::client: received hello from Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.753072Z  INFO eths::client: hello message: HelloMessage { protocol_version: V5, client_version: "erigon/v2.59.2-a013ec25/linux-amd64/go1.21.5", capabilities: [Capability { name: "eth", version: 68 }], port: 0, id: 0x5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e }
2024-04-05T20:29:00.753109Z  INFO eths::transport: sending message to Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.753446Z  INFO eths::transport: no response expected from Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.753762Z  INFO eths::client: found shared capabilities: Ok(Eth68) with Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:29:00.753806Z  WARN eths::client: handshake failed for a node: transport error: ecies error: stream closed due to not being readable
2024-04-05T20:29:00.753830Z  INFO eths: handshake successful for peer: Peer { node: Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }, capabilities: [Capability { name: "eth", version: 68 }] }
2024-04-05T20:29:00.753848Z  INFO eths: handshake complete with 1 out of 2 nodes

The nodes currently setup in the repo, serve as an example of a single node that refuses to handshake, and another that successfully completes the handshake with an ETH66 capability.
When a node refuses to reply, the log will show something similar to the following:

2024-04-05T20:29:00.753806Z  WARN eths::client: handshake failed for a node: transport error: ecies error: stream closed due to not being readable

When a node successfully completes the handshake, the log will show the peer that replied and the capabilities it supports:

2024-04-05T20:46:56.781064Z  INFO eths::client: received hello from Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }
2024-04-05T20:46:56.781114Z  INFO eths::client: hello message: HelloMessage { protocol_version: V5, client_version: "erigon/v2.59.2-a013ec25/linux-amd64/go1.21.5", capabilities: [Capability { name: "eth", version: 68 }], port: 0, id: 0x5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e }

...

2024-04-05T20:29:00.753830Z  INFO eths: handshake successful for peer: Peer { node: Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 }, capabilities: [Capability { name: "eth", version: 68 }] }

However, a node can complete the handshake, but not support the expected capabilities, in which case the log will show the following:

2024-04-05T20:30:58.820437Z  WARN eths::client: no shared capabilities with Node { id: "5825b736bb359a0d52ab70867d880ab468ec2b29ff2a743d9d3d3d767869b772a6b455b142ff9339abebe348f2559d4f6dd1ba1219e598ce8e5935065211881e", ip: "95.216.64.51", port: 30303 } - they have [Capability { name: "eth", version: 68 }]

Tests

There are tests for the config file and the client handshake, you can run all of them with:

cargo test

Be mindful over several runs, as previously successful nodes might do some rate limiting/throttling, and the client test might fail.

eths's People

Contributors

patricionapoli avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.