# devp2p: the specifications behind Ethereum's peer-to-peer network

> devp2p is a specification repository, not an implementation, describing the node discovery, RLPx transport and application-level protocols that Ethereum clients use to find and talk to each other. The judgement is that its value is the interoperability contract it fixes, and that the specification-first rule with a working prototype requirement is what keeps a dozen implementations able to talk to each other.

**ethereum/devp2p** — Ethereum peer-to-peer networking specifications

- Repository: https://github.com/ethereum/devp2p
- Stars: 1,131 · Forks: 302
- Language: JavaScript
- License: not declared
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/ethereum-devp2p

## A repository of documents, not a library

devp2p is the Ethereum peer-to-peer networking specification repository. The contents are documents, not code, and the primary language reported for the repository is JavaScript only because the specification files and tooling that accompany them are written that way.

The set of documents is the whole product. At the low level there are the Ethereum Node Records, the DNS Node Lists, Node Discovery Protocol v4, Node Discovery Protocol v5, and the RLPx protocol. On top of RLPx sit the application-level protocols: the Ethereum Wire Protocol at eth/70, the Ethereum Snapshot Protocol at snap/2, the Light Ethereum Subprotocol at les/4, the Parity Light Protocol at pip/1, and the Ethereum Witness Protocol at wit/0.

The repository layout follows the specification structure. The root holds `enr.md`, `dnsdisc.md`, `discv4.md` and `rlpx.md`, with a `discv5/` directory holding the v5 specification, a `caps/` directory holding the capability documents for the application protocols, an `enr-entries/` directory for the node record entry types, a `.lint/` directory for specification linting, and a `.circleci/` directory for continuous integration. The `etherdog.png` image at the root is the project's mascot.

The issue tracker here is for discussions of protocol changes, and the README says it is also fine to open an issue just to ask a question. That is a small but meaningful detail: it means the tracker is a protocol discussion space, not only a bug queue.

## The two constraints that shape every specification

The mission section states two rules that explain most of the design decisions in the documents.

The first is implementability from the document alone. The protocols in devp2p should be easy to implement from scratch given only the specification, and must work within the limits of a consumer-grade Internet connection. That second clause is the one that shapes packet sizes, timeouts and the number of round trips, because a protocol that assumes a datacentre link does not survive on a home connection.

The second rule is the specification-first approach with a proof obligation attached. The project usually designs protocols in a specification-first way, but any specification proposed must be accompanied by a working prototype or be implementable within reasonable time. That is the mechanism that keeps the documents honest. A specification that describes an unbuildable design does not get merged.

The broader framing is that devp2p is not specific to a particular blockchain and should serve the needs of any networked application associated with the Ethereum umbrella. The aim is an integrated system of orthogonal parts, implemented in multiple programming environments, providing discovery of other participants throughout the Internet as well as secure communication with those participants.

Two of those words carry weight. Orthogonal means the parts should be composable rather than entangled, so discovery and transport and application protocol can be replaced independently. Multiple programming environments is not aspirational, it is the reason the repository is written the way it is.

## Discovery in two versions, plus node records and DNS lists

Before two nodes can exchange application messages they have to find each other, and devp2p specifies that path in four documents.

The Ethereum Node Records, in `enr.md`, define how a node describes itself. A node record carries a sequence of key-value entries, and the `enr-entries/` directory in the repository holds the specifications for those individual entry types, so the record format itself is extensible without changing the container.

Node Discovery Protocol v4 and Node Discovery Protocol v5 are separate specifications with separate files, `discv4.md` and `discv5/discv5.md`. The fact that both are maintained tells you something about the network's transition state, and it is a practical detail for anyone implementing a client: a node that speaks only one of them will find fewer peers than one that speaks both.

The DNS Node Lists, in `dnsdisc.md`, complete the picture. This is the fallback path where peers are published through DNS rather than found through the gossip-based discovery protocols, and it is what a node uses when the peer-to-peer discovery path is not working or is not available.

So the discovery story has three layers: a self-description format that carries capabilities and addresses, two gossip protocols for finding peers, and a DNS-published list as the fallback. A client implementation that only implements one of them will work in some environments and silently fail in others, which is exactly the kind of failure that looks like a network problem.

## RLPx is the transport, capability subprotocols are the payload

The RLPx protocol in `rlpx.md` is the transport layer, and it is where the security and framing rules live. It is the layer that every application protocol rides on.

Above it, the application-level protocols are negotiated as capabilities with version numbers, and the versions in the README are the current ones: eth/70, snap/2, les/4, pip/1 and wit/0. The naming convention itself, a short name followed by a slash and a version, is the mechanism by which a client advertises what it can do and a peer matches on it.

The split between the two categories is worth noting. The Wire Protocol at eth/70 carries the block and transaction data, while the Snapshot Protocol at snap/2 is a separate capability rather than a mode of the wire protocol, which is a design choice that lets a node serve snapshots without also serving everything else. The Light Ethereum Subprotocol at les/4 and the Parity Light Protocol at pip/1 are the light-client protocols, and the Witness Protocol at wit/0 is a newer one.

Each of these has its own document under `caps/`, which is where the message formats, the request and response shapes, and the validity rules for that particular protocol are written. The `caps/` directory naming is deliberate: these are capabilities, and the transport does not need to know what any of them mean.

For an implementer, the practical sequence is discovery, then RLPx handshake and framing, then capability negotiation, then the subprotocol's own message set. The specifications are written so each of those stages can be implemented separately, which is the orthogonality the mission section asks for.

## Sixteen client implementations and one wire format

The value of a specification is only realised if independent implementations agree on it, and the implementation list in the README is long enough to demonstrate that this has happened.

The listed implementations span a wide range of languages. In C# there is Nethermind, in C++ Aleth, in C Breadwallet, in Elixir Exthereum, in Go go-ethereum or geth, in Java the Tuweni RLPx library and Besu, in JavaScript EthereumJS, in Kotlin the Tuweni Discovery library, in Nim the nim-eth implementation from status-im, in Python Trinity, in Ruby Ciri and ruby-devp2p, and in Rust rust-devp2p, openethereum and reth.

The distribution matters as much as the count. The Go and Java clients are the ones most users meet, but the list also covers languages that would not be obvious candidates for a peer-to-peer stack, which is a direct consequence of the requirement that the protocols be implementable from the specification alone. A Go developer cannot borrow code from a Rust implementation, so the document has to be precise enough to work twice.

The same applies to the debugging story. There are Wireshark dissectors available, linked from the README, so traffic on the wire can be decoded with a tool that is not tied to any single client. That is the kind of tooling that only becomes possible when a protocol is publicly specified rather than implied by an implementation.

Note what the list does not say. It does not rank implementations, does not say which is canonical, and does not claim any of them is a reference implementation. The specification is the reference.

## devp2p and libp2p, and where security issues go

The README devotes a section to the relationship with libp2p, which tells you the question comes up often enough to be worth answering in writing.

The libp2p project was started at about the same time as devp2p and seeks to be a collection of modules for assembling a peer-to-peer network from modular components. The stated reason they are hard to compare is that they have different scope and were designed with different goals. devp2p is described as an integrated system definition that wants to serve Ethereum's needs well, even if it might fit other applications too, while libp2p is a collection of programming library parts serving no single application in particular.

The two are also converging in one direction: both projects are very similar in spirit, and devp2p is slowly adopting parts of libp2p as they mature. So the practical difference is one of starting point. If you are building something for Ethereum, you are implementing the devp2p specification, and the specification-first requirement plus the shared cross-implementation test is the hard part. If you are building a general peer-to-peer application with no Ethereum requirements, the libp2p module collection gives you working parts instead of a document.

The security process is short and clear. Protocol level security issues are described as valuable, and serious issues should be reported responsibly through the Ethereum Foundation Bounty Program. The repository does not describe a private disclosure channel of its own, which is a difference from most application security processes, and the bounty program is the route to use instead.

There are no GitHub releases for this repository, which is consistent with it being a document set. The last push was on 2026-08-27, so the specifications are still changing, and the `.lint/` directory suggests the documents are checked mechanically as well as by review.

## Conclusion

devp2p fits a developer implementing an Ethereum node, writing a custom RLPx subprotocol, or debugging why two clients fail to interoperate, because the discovery, handshake and capability negotiation rules are written down in one place and are shared by every client in the ecosystem. It does not fit a developer who wants a working peer-to-peer stack to link against, since the repository contains specifications and no library, and it does not fit a project whose networking needs stop at ordinary TCP or WebSocket traffic. Verify first which discovery version your peers actually speak, since v4 and v5 are separate specifications, that the capability versions you negotiate are the ones listed in the README, such as eth/70 or snap/2, and that the RLPx framing rules in `rlpx.md` match what the peer you are debugging implements, because a mismatch there shows up as a connection that opens and then goes quiet.

## FAQ

### What is the devp2p repository and what does it contain?

It is the specification repository for Ethereum's peer-to-peer networking protocols. It holds the Ethereum Node Records, DNS Node Lists, Node Discovery Protocol v4 and v5, the RLPx protocol, and the RLPx-based application protocols eth/70, snap/2, les/4, pip/1 and wit/0.

### How does devp2p differ from libp2p?

They have different scope and goals. devp2p is an integrated system definition serving Ethereum's needs, while libp2p is a collection of library modules serving no single application. The README notes devp2p is slowly adopting parts of libp2p as they mature.

### Which clients implement the devp2p protocols?

The README lists implementations including Nethermind in C#, Aleth in C++, go-ethereum in Go, Besu and the Tuweni libraries in Java, EthereumJS in JavaScript, Trinity in Python, Ciri in Ruby, and rust-devp2p, openethereum and reth in Rust.

### Where should I report a security issue in the Ethereum devp2p protocols?

Serious protocol level security issues should be reported responsibly through the Ethereum Foundation Bounty Program. The issue tracker in the repository is for protocol change discussions and questions.

### How do I propose a change to a devp2p protocol?

Open an issue on the repository, which is where protocol change discussions take place. Any specification proposed must be accompanied by a working prototype or be implementable within reasonable time, and the protocols have to work within the limits of a consumer-grade Internet connection.

## Sources

- [ethereum/devp2p on GitHub](https://github.com/ethereum/devp2p)
- [Issues](https://github.com/ethereum/devp2p/issues)
- [README](https://github.com/ethereum/devp2p/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ethereum-devp2p
