Giter Club home page Giter Club logo

ethereumjs-devp2p's Introduction

ethereumjs-devp2p

NPM Status Actions Status Coverage Status Discord

This library bundles different components for lower-level peer-to-peer connection and message exchange:

  • Distributed Peer Table (DPT) / Node Discovery
  • RLPx Transport Protocol
  • Ethereum Wire Protocol (ETH)
  • Light Ethereum Subprotocol (LES/2)

The library is based on ethereumjs/node-devp2p as well as other sub-libraries (node-* named) (all outdated).

Run/Build

To build the dist/ directory, run:

npm run build

You can also use ts-node to run a script without first transpiling to js (you need to npm i --save-dev ts-node first):

node -r ts-node/register [YOUR_SCRIPT_TO_RUN.ts]

Usage/Examples

All components of this library are implemented as Node EventEmitter objects and make heavy use of the Node.js network stack.

You can react on events from the network like this:

dpt.on('peer:added', (peer) => {
  // Do something...
})

Basic example to connect to some bootstrap nodes and get basic peer info:

Communicate with peers to read new transaction and block information:

Run an example with:

DEBUG=devp2p:* node -r ts-node/register ./examples/peer-communication.ts

Distributed Peer Table (DPT) / Node Discovery

Maintain/manage a list of peers, see ./src/dpt/, also includes node discovery (./src/dpt/server.ts)

Usage

Create your peer table:

const dpt = new DPT(Buffer.from(PRIVATE_KEY, 'hex'), {
  endpoint: {
    address: '0.0.0.0',
    udpPort: null,
    tcpPort: null
  }
})

Add some bootstrap nodes (or some custom nodes with dpt.addPeer()):

dpt.bootstrap(bootnode).catch((err) => console.error('Something went wrong!'))

API

See the following diagram for a high level overview on the library.

DPT (extends EventEmitter)

Distributed Peer Table. Manages a Kademlia DHT K-bucket (Kbucket) for storing peer information and a BanList for keeping a list of bad peers. Server implements the node discovery (ping, pong, findNeighbours).

new DPT(privateKey, options)

Creates new DPT object

  • privateKey - Key for message encoding/signing.
  • options.refreshInterval - Interval in ms for refreshing (calling findNeighbours) the peer list (default: 60s).
  • options.createSocket - A datagram (dgram) createSocket function, passed to Server (default: dgram.createSocket.bind(null, 'udp4')).
  • options.timeout - Timeout in ms for server ping, passed to Server (default: 10s).
  • options.endpoint - Endpoint information to send with the server ping, passed to Server (default: { address: '0.0.0.0', udpPort: null, tcpPort: null }).

dpt.bootstrap(peer) (async)

Uses a peer as new bootstrap peer and calls findNeighbouts.

  • peer - Peer to be added, format { address: [ADDRESS], udpPort: [UDPPORT], tcpPort: [TCPPORT] }.

dpt.addPeer(object) (async)

Adds a new peer.

  • object - Peer to be added, format { address: [ADDRESS], udpPort: [UDPPORT], tcpPort: [TCPPORT] }.

For other utility functions like getPeer, getPeers see ./src/dpt/dpt.ts.

Events

Events emitted:

Event Description
peer:added Peer added to DHT bucket
peer:removed Peer removed from DHT bucket
peer:new New peer added
listening Forwarded from server
close Forwarded from server
error Forwarded from server

Reference

RLPx Transport Protocol

Connect to a peer, organize the communication, see ./src/rlpx/

Usage

Instantiate an @ethereumjs/common instance with the network you want to connect to:

const common = new Common({ chain: 'mainnet' })

Create your RLPx object, e.g.:

const rlpx = new devp2p.RLPx(PRIVATE_KEY, {
  dpt: dpt,
  maxPeers: 25,
  capabilities: [devp2p.ETH.eth63, devp2p.ETH.eth62],
  common: common,
  listenPort: null,
})

API

RLPx (extends EventEmitter)

Manages the handshake (ECIES) and the handling of the peer communication (Peer).

new RLPx(privateKey, options)

Creates new RLPx object

  • privateKey - Key for message encoding/signing.
  • options.timeout - Peer ping timeout in ms (default: 10s).
  • options.maxPeers - Max number of peer connections (default: 10).
  • options.clientId - Client ID string (default example: ethereumjs-devp2p/v2.1.3/darwin-x64/nodejs).
  • options.remoteClientIdFilter - Optional list of client ID filter strings (e.g. ['go1.5', 'quorum']).
  • options.capabilities - Upper layer protocol capabilities, e.g. [devp2p.ETH.eth63, devp2p.ETH.eth62].
  • options.listenPort - The listening port for the server or null for default.
  • options.dpt - DPT object for the peers to connect to (default: null, no DPT peer management).

rlpx.connect(peer) (async)

Manually connect to peer without DPT.

  • peer - Peer to connect to, format { id: PEER_ID, address: PEER_ADDRESS, port: PEER_PORT }.

For other connection/utility functions like listen, getPeers see ./src/rlpx/rlpx.ts.

Events

Events emitted:

Event Description
peer:added Handshake with peer successful
peer:removed Disconnected from peer
peer:error Error connecting to peer
listening Forwarded from server
close Forwarded from server
error Forwarded from server

Reference

Ethereum Wire Protocol (ETH)

Upper layer protocol for exchanging Ethereum network data like block headers or transactions with a node, see ./src/eth/.

Usage

Send the initial status message with sendStatus(), then wait for the corresponding status message to arrive to start the communication.

eth.once('status', () => {
  // Send an initial message
  eth.sendMessage()
})

Wait for follow-up messages to arrive, send your responses.

eth.on('message', async (code, payload) => {
  if (code === devp2p.ETH.MESSAGE_CODES.NEW_BLOCK_HASHES) {
    // Do something with your new block hashes :-)
  }
})

See the peer-communication.ts example for a more detailed use case.

API

ETH (extends EventEmitter)

Handles the different message types like NEW_BLOCK_HASHES or GET_NODE_DATA (see MESSAGE_CODES) for a complete list. Currently protocol versions PV62 and PV63 are supported.

new ETH(privateKey, options)

Normally not instantiated directly but created as a SubProtocol in the Peer object.

  • version - The protocol version for communicating, e.g. 63.
  • peer - Peer object to communicate with.
  • send - Wrapped peer.sendMessage() function where the communication is routed to.

eth.sendStatus(status)

Send initial status message.

  • status - Status message to send, format {td: TOTAL_DIFFICULTY_BUFFER, bestHash: BEST_HASH_BUFFER, genesisHash: GENESIS_HASH_BUFFER }, networkId (respectively chainId) is taken from the Common instance

eth.sendMessage(code, payload)

Send initial status message.

  • code - The message code, see MESSAGE_CODES for available message types.
  • payload - Payload as a list, will be rlp-encoded.

Events

Events emitted:

Event Description
message Message received
status Status info received

Reference

Light Ethereum Subprotocol (LES)

Upper layer protocol used by light clients, see ./src/les/.

Usage

Send the initial status message with sendStatus(), then wait for the corresponding status message to arrive to start the communication.

les.once('status', () => {
  // Send an initial message
  les.sendMessage()
})

Wait for follow-up messages to arrive, send your responses.

les.on('message', async (code, payload) => {
  if (code === devp2p.LES.MESSAGE_CODES.BLOCK_HEADERS) {
    // Do something with your new block headers :-)
  }
})

See the peer-communication-les.ts example for a more detailed use case.

API

LES (extends EventEmitter)

Handles the different message types like BLOCK_HEADERS or GET_PROOFS_V2 (see MESSAGE_CODES) for a complete list. Currently protocol version LES/2 running in client-mode is supported.

new LES(privateKey, options)

Normally not instantiated directly but created as a SubProtocol in the Peer object.

  • version - The protocol version for communicating, e.g. 2.
  • peer - Peer object to communicate with.
  • send - Wrapped peer.sendMessage() function where the communication is routed to.

les.sendStatus(status)

Send initial status message.

  • status - Status message to send, format { headTd: TOTAL_DIFFICULTY_BUFFER, headHash: HEAD_HASH_BUFFER, headNum: HEAD_NUM_BUFFER, genesisHash: GENESIS_HASH_BUFFER }, networkId (respectively chainId) is taken from the Common instance

les.sendMessage(code, reqId, payload)

Send initial status message.

  • code - The message code, see MESSAGE_CODES for available message types.
  • reqId - Request ID, will be echoed back on response.
  • payload - Payload as a list, will be rlp-encoded.

Events

Events emitted:

Event Description
message Message received
status Status info received

Reference

Tests

There are unit tests in the test/ directory which can be run with:

npm run test

Debugging

This library uses debug debugging utility package.

For the debugging output to show up, set the DEBUG environment variable (e.g. in Linux/Mac OS: export DEBUG=*,-babel).

Use the DEBUG environment variable to active the logger output you are interested in, e.g.:

DEBUG=devp2p:dpt:*,devp2p:eth node -r ts-node/register [YOUR_SCRIPT_TO_RUN.ts]

For more verbose output on logging (e.g. to output the entire msg payload) use the verbose logger in addition:

DEBUG=devp2p:dpt:*,devp2p:eth,verbose node -r ts-node/register [YOUR_SCRIPT_TO_RUN.ts]

Exemplary logging output:

Add peer: 52.3.158.184:30303 Geth/v1.7.3-unstable-479aa61f/linux-amd64/go1.9 (eth63) (total: 2)
  devp2p:rlpx:peer Received body 52.169.42.101:30303 01c110 +133ms
  devp2p:rlpx:peer Message code: 1 - 0 = 1 +0ms
  devp2p:rlpx refill connections.. queue size: 0, open slots: 20 +1ms
  devp2p:rlpx 52.169.42.101:30303 disconnect, reason: 16 +1ms
Remove peer: 52.169.42.101:30303 (peer disconnect, reason code: 16) (total: 1)

Docs

For a complete API reference see the generated documentation.

Developer

Diagram Updates

To update the structure diagram files in the root folder open the devp2p.drawio file in draw.io, make your changes, and open a PR with the updated files. Export svg and png with border width=20 and transparency=false. For png go to "Advanced" and select 300 DPI.

General References

Other Implementations

The following is a list of major implementations of the devp2p stack in other languages:

Links

License

MIT

ethereumjs-devp2p's People

Contributors

dryajov avatar fanatid avatar holgerd77 avatar jochem-brouwer avatar ryanio avatar vpulim avatar whymarrh avatar ya7ya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ethereumjs-devp2p's Issues

EIP 8 Compliance

EIP 8 compliance for this library is needed in order to being usable again. At the moment, EIP 8 (forwards compatibility) changes aren't implemented, and the library can't build up connection to more or less any up-to-date node.

This behavior can be observed by e.g. running the peer-communication example.

There are three parts to this EIP:

Changes to the devp2p Wire Protocol

(Probably) implemented

Changes to the RLPx Discovery Protocol

(Probably) implemented

Changes to the RLPx TCP Handshake

At least the RLPx TCP Handshake part isn't implemented and has to be added to Auth and Ack encoding/decoding in rlpx/peer.js and rlpx/ecies.js.

At least the Ack receival part is necessary to build a robust network with peers from the DPT.

The implementation in the pydevp2p library is well-structured and can serve as a basis and for orientation.

Note:
There are some basic unit tests on EIP 8, these tests are not doing much though and doesn't hint to EIP 8 being already implemented.

Where is ./lib Folder?

@fanatid
When installing via npm I get a lib folder but I can't seem to find it in this repo, so is this the main version or Am I missing something here ?

package.json snippet

"gitHead": "696617ffa36b6abe87bc37698e9c927dd17cbf1c",
"homepage": "https://github.com/fanatid/ethereumjs-devp2p",
"main": "./lib/index.js",

Uncaught "Connection timeout" promise rejection

The DPT sometimes emits a peer:new event for a peer that isn't listening on a tcp port (only a udp port for discovery). This causes the following uncaught promise rejection when the RLPx server tries to connect to that peer on the missing tcp port.

(node:87414) UnhandledPromiseRejectionWarning: Error: Connection timeout
    at Socket.<anonymous> (/Users/vpulim/dev/ethereumjs-devp2p/lib/rlpx/index.js:147:32)

These peers should be ignored or banned.

esModuleInterop issue on client integration

Have now locally linked the devp2p library to the client library to fix the issues from ethereumjs/ethereumjs-client#143

I will now fix the issues like

Module '"/ethereumjs-devp2p/node_modules/@types/lru-cache/index"' can only be default-imported using the 'esModuleInterop' flag

by switching to import = syntax as suggested here and push later the day.

Let me know if this fix is not adequate, solution is directly taken from the TypeScript GitHub (might be wrong context though) and esModuleInterop is activated both on the client and the devp2p library.

Prepare for migration to the VM Monorepo

Those are some of the requirements to move this lib to the VM monorepo:

  • Migrate to TypeScript (rename lib to src in the process)
  • Update @ethereumjs/config to v2.0.0, see #91
  • Remove coveralls configuration, replacing by Codecov
  • Remove github workflows, replacing by the ones in the monorepo format
  • Remove Babel configuration (to be replaced by Typescript build)
  • Unify Readme and package.json with the monorepo standards

Docs Auto-Generation / Integrate API docs from old repos

The documentation from the old node-devp2p-* repositories didn't completely make it into the new repository.

The following docs should be checked and missing information / API description should be added to this repo:

barbel Unknown plugin "transform-runtime"

Hi I am getting this plugin error

Alreadt tried this command

npm install babel-plugin-transform-class-properties --save

npm run build

ReferenceError: Unknown plugin "transform-runtime" specified in "/Users/Documents/ethereum-research/ethereumjs-devp2p/.babelrc" at 1, attempted to resolve relative to "/Users/Documents/ethereum-research/ethereumjs-devp2p"

Installation breaks on Node v12+

Installation on the library breaks using Node 12 (v12.15.0) or 13 (v13.13.0) (Mac OS Mojave 10.14.1), following output:

$ npm install

> [email protected] install /ethereumjs-devp2p/node_modules/sha3
> node-gyp rebuild

  CXX(target) Release/obj.target/sha3/src/addon.o
In file included from ../src/addon.cpp:4:
In file included from ../../nan/nan.h:192:
../../nan/nan_maybe_43_inl.h:112:15: error: no member named 'ForceSet' in 'v8::Object'
  return obj->ForceSet(isolate->GetCurrentContext(), key, value, attribs);
         ~~~  ^
In file included from ../src/addon.cpp:4:
In file included from ../../nan/nan.h:197:
In file included from ../../nan/nan_converters.h:67:
../../nan/nan_converters_43_inl.h:22:1: error: no viable conversion from 'Local<v8::Context>' to 'v8::Isolate *'
X(Boolean)
^~~~~~~~~~
../../nan/nan_converters_43_inl.h:18:23: note: expanded from macro 'X'
      val->To ## TYPE(v8::Isolate::GetCurrent()->GetCurrentContext())          \
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Caches/node-gyp/13.13.0/include/node/v8.h:2762:37: note: passing argument to parameter 'isolate' here
  Local<Boolean> ToBoolean(Isolate* isolate) const;
                                    ^
In file included from ../src/addon.cpp:4:
In file included from ../../nan/nan.h:197:
In file included from ../../nan/nan_converters.h:67:
../../nan/nan_converters_43_inl.h:40:1: error: no viable conversion from 'Local<v8::Context>' to 'v8::Isolate *'
X(bool, Boolean)
^~~~~~~~~~~~~~~~
 
[ MORE STUFF ]

fatal error: too many errors emitted, stopping now [-ferror-limit=]
5 warnings and 20 errors generated.
make: *** [Release/obj.target/sha3/src/addon.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/.nvm/versions/node/v13.13.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:315:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
gyp ERR! System Darwin 18.2.0
gyp ERR! command "/.nvm/versions/node/v13.13.0/bin/node" "/.nvm/versions/node/v13.13.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Documents/DEV/EthereumJS/ethereumjs-devp2p/node_modules/sha3
gyp ERR! node -v v13.13.0
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok
npm WARN [email protected] requires a peer of request@^2.34 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of request@^2.34 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of tslint@^5.1.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of tslint@^5.11.0 but none is installed. You must install peer dependencies yourself.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /.npm/_logs/2020-04-20T15_21_21_194Z-debug.log

@PhilippLgh Is this something you can reproduce on your machine locally and if so can you please have a look at it before we release?

Loglevel support / Logger adoption for client

This library currently uses the debug library for logging output. The output can be activated by setting the DEBUG environment variable, see #debugging. The output can be filtered by topics/loggers, but there is no support for logging verbosity setting (log levels).

This is needed though for integration in an ethereumjs-client project.

Issue should be worked on in conjunction with: ethereumjs/ethereumjs-client#3

v3.0.0 Release Planning

The v3.0.0 release for this library is imminent, introducing a TypeScript based version of the library and building upon the work from @dryajov done in #56.

It is encouraged to test the current master branch of the library (this needs the bootnode update from the TODOs to work). If you have got comments on the release please drop here.

TODOs:

  • Release v1.5.1 of the common library on the VM monorepo side with the updated bootnodes and integrate here (via explicit PR separate from the release PR) //cc @evertonfraga
  • Update keccak dependency to v3.0.0
  • Move ethereumjs-tx dependency to devDependencies (used for examples)
  • Move examples out of the src directory
  • Eventually update secp2561 dependency to v4.0.0 (careful, breaking changes, see ethereumjs/ethereumjs-util#228 for context, only if not causing too much side-hazzle)
  • Test, eventually fix and test the npm pack command to have a working release bundled

LES/2 Protocol Implementation

Currently as upper-layer communication protocols the Ethereum Wire Protocols V62 and V63 are supported (see eth/index.js). For a possible future light client roadmap the implementation of the LES protocol would be needed.

The following reference implementations for orientation are available:

Also this Devcon3 talk might be useful.

Could you please add more guides for the Run/Build in the Readme.MD?

To make command "npm run build" work, I have to run "npm install --save-dev babel-cli" to solve the error in the "babel src -d lib" command, and have to run "npm install babel-plugin-transform-class-properties --save" to solve the error of 'ReferenceError: Unknown plugin "transform-class-properties" specified in .babelrc at 0'. It costed me hours searching online to solve these issues.
It will be very appreciated if you can add more guides for these errors.

RLPX Question: Shouldn't peer be removed from this._peers once it closes ?

hey @fanatid , regarding RLPX peer close event, Shouldn't the peer be removed form the this._peers Map once the event is triggered ? not removing the peer means this._getOpenSlots() will return actual open slots + the peer that just closed.

the fix is simple

// rlpx/index.js - in peer.once('close') event handler
let peerKey = peer.getId().toString('hex')
this._peers.delete(peerKey)

Thanks for your help, I appreciate it. ๐Ÿ‘

Node version?

Could you mention in README.md or elsewhere in docs which node version you expect? Async is used in code, introduced in 7.6; https://nodejs.org/en/ says newest features are in 8.6, recommended stable is 6.11.3 LTS. Which version are you using? Which one would you recommend?

Finishing up TypeScript transition work

TODO List and discussion for finishing up on the TypeScript transition PR at #51.

  • Updated TypeScript config on ethereumjs-config and/or in the repo
  • Test run on supported Node versions 8, 10, 11 (12 optional)
  • Integration test on ethereumjs-client repository, basic benchmarking (2-5 min run comparisons on different protocols)
  • Examples test run working confirmation
  • Update README (examples, URLs, method signatures)
  • Decision on TypeScript definition files (definitions folder), keep or not?

Subprotocol error: network mismatch

Sometimes I get connections, but most of the times I'm seeing the network mismatch error messages. It pretty much looks like here: #12 (comment).

I'm opening a new issue as the other one is closed and two years old.

No Parity client connections possible

Currently the library is not connecting to any Parity nodes.

This can be tested by trying to connect to one of the bootnodes from the Parity foundation.json configuration file.

This is due to the pong msg on node discovery (see dpt/server.js) from a Parity client is returing a different msg hash then the one sent.

This can be debugged by using export DEBUG=devp2p:dpt:server.

Remove src files from npm package

The following is the output on npm packaging. The src files should be removed from the package on publication to reduce package size.

npm notice
npm notice ๐Ÿ“ฆ  [email protected]
npm notice === Tarball Contents ===
npm notice 2.2kB  package.json
npm notice 3.4kB  CHANGELOG.md
npm notice 12.5kB README.md
npm notice 1.2kB  lib/dpt/ban-list.js
npm notice 6.0kB  lib/dpt/index.js
npm notice 2.4kB  lib/dpt/kbucket.js
npm notice 5.2kB  lib/dpt/message.js
npm notice 6.1kB  lib/dpt/server.js
npm notice 5.3kB  lib/eth/index.js
npm notice 180B   lib/index.js
npm notice 7.0kB  lib/les/index.js
npm notice 11.6kB lib/rlpx/ecies.js
npm notice 8.4kB  lib/rlpx/index.js
npm notice 896B   lib/rlpx/mac.js
npm notice 14.9kB lib/rlpx/peer.js
npm notice 2.5kB  lib/util.js
npm notice 596B   src/dpt/ban-list.js
npm notice 3.5kB  src/dpt/index.js
npm notice 1.7kB  src/dpt/kbucket.js
npm notice 5.0kB  src/dpt/message.js
npm notice 5.5kB  src/dpt/server.js
npm notice 5.1kB  src/eth/index.js
npm notice 161B   src/index.js
npm notice 6.8kB  src/les/index.js
npm notice 11.6kB src/rlpx/ecies.js
npm notice 7.2kB  src/rlpx/index.js
npm notice 803B   src/rlpx/mac.js
npm notice 11.9kB src/rlpx/peer.js
npm notice 2.4kB  src/util.js
npm notice === Tarball Details ===
npm notice name:          ethereumjs-devp2p
npm notice version:       2.5.1
npm notice package size:  34.6 kB
npm notice unpacked size: 152.0 kB
npm notice shasum:        da079c9a56ba358b6bd9bd3789c8707632d6324f
npm notice integrity:     sha512-xVizqoB44UqEa[...]5YSc1ZDmMPvDA==
npm notice total files:   29
npm notice

replace node-devp2p?

The original node-devp2p is out-of-data. Should we just depreciate it and use this instead? Also would you be would it be ok to move this to ethereumjs?

Add eth64 support

From Ethereum Wire Protocol documentation:

eth/64 ([EIP-2364], November 2019)

Version 64 changed the Status message to include the EIP-2124 ForkID. This allows peers
to determine mutual compatibility of chain execution rules without synchronizing the
blockchain.

Supporting eth64 would remove the need to fork-verify new peers and reduce the complexity of application code.

Example not working with updated bootnodes

Just injected the new bootnodes from ethereumjs/ethereumjs-monorepo#718 manually to the current master version of the library.

The peer-communication.ts example is still not working, would want to wait with merging the bootnode update until we find the root cause here.

Running the example with the following command:

DEBUG='*devp2p*' node -r ts-node/register ./src/examples/peer-communication.ts

This leads to the following output:

  devp2p:rlpx refill connections.. queue size: 0, open slots: 25 +0ms
  devp2p:rlpx refill connections.. queue size: 0, open slots: 25 +10s
  devp2p:dpt call .refresh (0 peers in table) +10s
Total nodes in DPT: 0, open slots: 25, queue: 0 / 0
  devp2p:rlpx refill connections.. queue size: 0, open slots: 25 +11ms
  devp2p:rlpx refill connections.. queue size: 0, open slots: 25 +10s
  devp2p:rlpx refill connections.. queue size: 0, open slots: 25 +10s

So there are no new peers added during connection build up.

Normally the output should be much more diverse, there is the debug package used for this (thus the DEBUG='*devp2p*' appendix on the example command, there should be actually some more explicit explanation in the README on how to adopt here).

I tried to switch to DEBUG=*, output still remains limited. Normally there should be output from various loggers, e.g. devp2p:rlpx:peer. Not sure, didn't give this much time to test.

This issue is for having a place to debug this and reporting on the progress.

Catch annoying timeout error for bootstrap nodes on startup

When starting the example, there are always errors like:

DPT bootstrap error: Error: Timeout error: ping 5.1.83.226:30303
    at Timeout._onTimeout (/Users/hdrewes/Documents/DEV/EthereumJS/ethereumjs-client/node_modules/ethereumjs-devp2p/lib/dpt/server.js:97:29)
    at ontimeout (timers.js:469:11)
    at tryOnTimeout (timers.js:304:5)
    at Timer.listOnTimeout (timers.js:264:5)

for unavailable bootstrap nodes. These should be caught and replaced with a proper logging output msg instead.

Node discovery v5

Introduction

Node discovery v5 is on it's way, which should make it a lot easier to discover suitable nodes. Though not standardized yet, it would be good to have some early experimentation/draft implementation to get closer to a feeling how the protocol (could) behave it would be good to have this library updated with a working implementation to support the practical usage in terms of a light client implementation.

Here are some draft documents on this. Also valuable in this regard: Talk from Felix at Devcon3.

Current py-evm implementation work: ethereum/py-evm#209

Current Situation

Currently the library supports Node discovery v4 implemented in src/dpt, where kbucket.js manages the list of peers in a Kademlia-like DHT, message.js implements the different message types like ping, pong or neighbours to discover new peers and server.js sets up a server to handle the discovery communication.

There are static tests for the message types in ./test/dpt-message.js, the integrated communication process is tested in ./test/integration/dpt-simulator.js as well as the corresponding eth and les files.

With the two peer-communication example scripts in the examples folder both ETH and LES (so full- and light client wire) communication can be tested in a real-world scenario by connecting to an actual network of in-production clients.

Task Description

Node discovery v5 updated the structure of Node records, brings changes to the communication flow by adding new packet types and introduces the concept of topics for exchanging on the capability of peers.

A first step into this task would be to work out some concept/idea where these additional/changed components fit into the existing v4 implementation and where current files/classes can be extended and where additional structures have to be set up. Since network communication implementation is very error-prone it will probably ease implementation to early on think along how to extend existing tests and add new tests for added functionality.

Goals

Though being still marked as "experimental" Geth has a working v5 discovery implementation for some time. Sufficient requirement for this issue to be completed is a working peer-communication example where it is possible to set the discovery to v5 - e.g. by CL parameter or example internal constant - and get a working LES and/or (optimally both) ETH connection (working means here: e.g. LES packets are actually passed through) in a reasonable amount of time (repeatedly < 5 min until first connection occurs).

Necessary side goals are:

  • An extended code base which...
    • follows the style principles and coding best practices of the existing code base
    • is readable/maintainable for other developers
    • introduces no or minimal code repetitions
  • An extended test suite which keeps code coverage for the DHT on more-or-less the current level
  • Some additions to the README docs which gives some usage guides and reflect the API changes

Required Skills

Everyone is invited to join and take on this task. Since this an advanced task requiring deeper knowledge of the Ethereum networking stack it is probably more likely that you succeed if you bring along skills/experience in the following fields:

  • Experience with working on larger code bases in Node.js/modern ES6 Javascript
  • Experience with the Node.js toolchain / ecosystem
  • Knowledge/understanding of generic p2p networking concepts
  • Some understanding of the Ethereum networking mechanics
  • Experience with assuring code quality/testing

Guidance

For questions helping to understand the existing code base and the scope of this issue you will get active guidance by the creator of this issue (@holgerd77, EthereumJS team).

Most peer connections get closed shortly after connection

Many peer connections directly close again after getting a connection, this can be tested by e.g. running the peer-communication example with:

node -r babel-register examples/peer-communication.js

Most of the connections are closed with reason code16 (see DISCONNECT_REASONS, which is disconnect reason SUBPROTOCOL_ERROR.

This issue was initially thought to be connected to #11. This wasn't be the case though.

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.