{"id":13307151,"url":"https://github.com/ivanbgd/ethereum-handshake","last_synced_at":"2026-05-10T16:01:59.055Z","repository":{"id":248938589,"uuid":"826512109","full_name":"ivanbgd/ethereum-handshake","owner":"ivanbgd","description":"Ethereum peer-to-peer handshake procedure","archived":false,"fork":false,"pushed_at":"2024-07-21T00:24:47.000Z","size":94,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-03T10:11:56.522Z","etag":null,"topics":["eth","ethereum","ethereum-blockchain","handshake","p2p","peer-to-peer","rlpx","rlpx-protocol"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivanbgd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-09T21:11:53.000Z","updated_at":"2024-07-21T00:24:51.000Z","dependencies_parsed_at":"2024-10-23T13:02:07.130Z","dependency_job_id":null,"html_url":"https://github.com/ivanbgd/ethereum-handshake","commit_stats":null,"previous_names":["ivanbgd/ethereum-handshake"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanbgd%2Fethereum-handshake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanbgd%2Fethereum-handshake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanbgd%2Fethereum-handshake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanbgd%2Fethereum-handshake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivanbgd","download_url":"https://codeload.github.com/ivanbgd/ethereum-handshake/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246117690,"owners_count":20726068,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eth","ethereum","ethereum-blockchain","handshake","p2p","peer-to-peer","rlpx","rlpx-protocol"],"created_at":"2024-07-29T17:59:34.516Z","updated_at":"2026-05-10T16:01:54.003Z","avatar_url":"https://github.com/ivanbgd.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ethereum Handshake Procedure\n\n[![CI](https://github.com/ivanbgd/ethereum-handshake/actions/workflows/ci.yml/badge.svg)](https://github.com/ivanbgd/ethereum-handshake/actions/workflows/ci.yml)\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)\n\n## Introduction\n\n- This is a client program that dials and connects to an Ethereum node.\n- The node's [enode](https://ethereum.org/en/developers/docs/networking-layer/network-addresses/#enode)\n  can be provided by the user through command line and/or through a text file\n  which consists of a list of enodes, with an enode per line of the text file.\n    - It should contain an IPv4 address, which is almost always the case with\n      Ethereum nodes.\n    - All valid enodes from command line and the file are included.\n    - Invalid enodes are simply skipped.\n- TODO: It can act as a receiver (a listener), as well,\n  not only as an initiator of the connection, making it bidirectional.\n- It implements the Ethereum handshake procedure, which is part of the\n  Ethereum's [RLPx](https://github.com/ethereum/devp2p/blob/master/rlpx.md)\n  transport protocol.\n    - We are basically implementing RLPx.\n- Peer-to-peer communication is assumed in the Ethereum network.\n- Since the purpose of this program is to implement the handshake procedure,\n  it doesn't use high-level crates that implement that functionality.\n- It instead works at a lower level, and uses lower-level crates.\n- Further communication, beyond a successful handshake, is not implemented.\n- We are also skipping the node discovery part.\n- We provide a configurable timeout for establishing a TCP connection,\n  and for completing a full handshake procedure.\n\n## Implementation\n\n- This program doesn't use high-level libraries such as\n  [libp2p](https://libp2p.io/) or [devp2p](https://github.com/ethereum/devp2p).\n- It uses cryptographic libraries,\n  which are necessary for the handshake procedure.\n- It also uses a library for\n  [RLP](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/),\n  which is Ethereum's serialization algorithm.\n- This project uses asynchrony for concurrent execution. We use the\n  [tokio](https://crates.io/crates/tokio) library for that.\n- We keep the main function minimal.\n- In case we add support for receiving calls and/or for supporting multiple\n  connections at once, the design/architecture of the project will probably\n  change, at least a little.\n    - The caveat is that each handshake should preferably complete as an atomic\n      operation, meaning it shouldn't be interrupted until it's complete.\n- Input validation is performed at a single place, which is at the program's\n  boundary at which the data (which is recipient's enode's) enters the application.\n\n## Development\n\n### Pre-Push Checks\n\nPre-push hooks are available in this repository.\n\nA Python package is required to use them. Install it by executing:\n\n`pip3 install pre-commit`\n\nInside the repository, run:\n\n`pre-commit install --hook-type pre-push`\n\nThe hooks will be run automatically before each push.\n\nWe can also run them manually like this:\n\n`pre-commit run --all-files`\n\n## Command Line Arguments\n\n### Arguments\n\nThere are no required arguments.\n\nTODO Level 1: If recipient isn't provided, the application will act only as a receiver.\nTODO Level 2: The application is bidirectional.\n\n### Options\n\n- `-t`, `--timeout \u003cTIMEOUT\u003e`: Handshake timeout in milliseconds, from 100 to 10000 [default: 1000]\n- `-r`, `--recipient-enode \u003cRECIPIENT_ENODE\u003e`: Recipient node's `enode` in the following form:  \n  `enode://\u003cnode_id\u003e@\u003cipv4_address\u003e:\u003cport\u003e`\n    - This is a list of `enode`s, so there can be more than one; just prepend\n      each with `-r`.\n- `-f`, `--file-path \u003cFILE_PATH\u003e`: Path to a text file with a list of\n  recipient `enode`s in the following form:  \n  `enode://\u003cnode_id\u003e@\u003cipv4_address\u003e:\u003cport\u003e`\n\n## Running\n\n- You can optionally set the `RUST_LOG` environment variable to `debug` or `trace` to\n  have more detailed log messaging.\n    - The log level is set to `info` by default.\n    - `export RUST_LOG=debug`\n    - `export RUST_LOG=trace`\n- In the following examples, substitute `\u003cRECIPIENT_ENODE\u003e` with\n  `enode://a3435a0155a3e837c02f5e7f5662a2f1fbc25b48e4dc232016e1c51b544cb5b4510ef633ea3278c0e970fa8ad8141e2d4d0f9f95456c537ff05fdf9b31c15072@178.128.136.233:30303`\n    - This is an Ethereum boot node running on the Holesky test network.\n    - Boot node addresses can be found at:  \n      https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go\n    - Boot nodes should be up and running all the time.\n- Alternatively, pick a node from:\n    - https://etherscan.io/nodetracker/nodes\n    - https://ethernodes.org/nodes\n    - Make sure to grab a full\n      [enode](https://ethereum.org/en/developers/docs/networking-layer/network-addresses/#enode).\n- Executables can be downloaded from the repository's\n  [Releases](https://github.com/ivanbgd/ethereum-handshake/releases) page.\n    - `ethereum-handshake [-t \u003cTIMEOUT\u003e] [-r \u003cRECIPIENT_ENODE\u003e] [-f FILE_PATH]`\n        - Example: `ethereum-handshake -t 2500 -r \u003cRECIPIENT_ENODE\u003e -f \u003cFILE_PATH\u003e -r \u003cRECIPIENT_ENODE\u003e`\n- Alternatively, by using `cargo`:\n    - `cargo run [--release] -- [-t \u003cTIMEOUT\u003e] [-r \u003cRECIPIENT_ENODE\u003e]`\n        - Example: `cargo run -- -r \u003cRECIPIENT_ENODE\u003e`\n        - Example: `cargo run -- -f \u003cFILE_PATH\u003e`\n\n## Testing\n\n- Unit tests are implemented.\n    - They can be performed by executing:  \n      `cargo test`\n- Manual testing can be performed by running the application from the CLI,\n  as described above.\n\n## References\n\n- [Networking Layer](https://ethereum.org/en/developers/docs/networking-layer/)\n    - [Network Addresses](https://ethereum.org/en/developers/docs/networking-layer/network-addresses/)\n- [Phase 0 - Networking: The P2P Interface](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md)\n- [Recursive-Length Prefix (RLP) Serialization](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/)\n- [The RLPx Transport Protocol (devp2p)](https://github.com/ethereum/devp2p/blob/master/rlpx.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanbgd%2Fethereum-handshake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivanbgd%2Fethereum-handshake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanbgd%2Fethereum-handshake/lists"}