├── .nycrc ├── .prettierignore ├── diagram ├── devp2p.png └── devp2p.drawio ├── prettier.config.js ├── test ├── index.ts ├── integration │ ├── index.ts │ ├── rlpx-simulator.ts │ ├── dpt-simulator.ts │ ├── util.ts │ ├── les-simulator.ts │ └── eth-simulator.ts ├── rlpx-mac.ts ├── dpt-message.ts ├── rlpx-ecies.ts └── testdata.json ├── codecov.yml ├── src ├── index.ts ├── rlpx │ ├── index.ts │ └── mac.ts ├── dpt │ ├── index.ts │ ├── ban-list.ts │ ├── kbucket.ts │ ├── dpt.ts │ ├── message.ts │ └── server.ts └── util.ts ├── docs ├── modules │ ├── _dpt_dpt_.md │ ├── _eth_index_.md │ ├── _rlpx_mac_.md │ ├── _rlpx_ecies_.md │ ├── _dpt_ban_list_.md │ ├── _dpt_kbucket_.md │ ├── _rlpx_rlpx_.md │ ├── _dpt_server_.md │ ├── _les_index_.md │ ├── _dpt_message_.md │ ├── _dpt_index_.md │ ├── _rlpx_peer_.md │ ├── _rlpx_index_.md │ ├── _util_.md │ └── _index_.md ├── interfaces │ ├── _index_.protocolconstructor.md │ ├── _rlpx_peer_.protocolconstructor.md │ ├── _rlpx_index_.protocolconstructor.md │ ├── _index_.kobj.md │ ├── _dpt_index_.kobj.md │ ├── _dpt_kbucket_.kobj.md │ ├── _index_.protocoldescriptor.md │ ├── _rlpx_peer_.protocoldescriptor.md │ ├── _rlpx_index_.protocoldescriptor.md │ ├── _index_.dptserveroptions.md │ ├── _dpt_index_.dptserveroptions.md │ ├── _dpt_server_.dptserveroptions.md │ ├── _index_.peerinfo.md │ ├── _index_.capabilities.md │ ├── _dpt_index_.peerinfo.md │ ├── _dpt_message_.peerinfo.md │ ├── _rlpx_peer_.capabilities.md │ ├── _rlpx_index_.capabilities.md │ ├── _index_.hello.md │ ├── _rlpx_peer_.hello.md │ ├── _rlpx_index_.hello.md │ ├── _index_.rlpxoptions.md │ ├── _rlpx_rlpx_.rlpxoptions.md │ ├── _rlpx_index_.rlpxoptions.md │ ├── _index_.les.status.md │ └── _les_index_.les.status.md ├── README.md ├── enums │ ├── _index_.prefixes.md │ ├── _rlpx_peer_.prefixes.md │ ├── _rlpx_index_.prefixes.md │ ├── _index_.eth.message_codes.md │ ├── _eth_index_.eth.message_codes.md │ ├── _index_.disconnect_reasons.md │ ├── _rlpx_peer_.disconnect_reasons.md │ ├── _rlpx_index_.disconnect_reasons.md │ ├── _index_.les.message_codes.md │ └── _les_index_.les.message_codes.md └── classes │ ├── _index_.banlist.md │ ├── _dpt_index_.banlist.md │ ├── _dpt_ban_list_.banlist.md │ ├── _util_.deferred.md │ ├── _index_.deferred.md │ ├── _index_.mac.md │ ├── _rlpx_mac_.mac.md │ └── _rlpx_index_.mac.md ├── .eslintrc.js ├── tsconfig.json ├── typedoc.json ├── tsconfig.prod.json ├── .github └── workflows │ └── build.yml ├── .gitignore ├── examples ├── simple.ts └── peer-communication-les.ts ├── package.json └── CHANGELOG.md /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@ethereumjs/config-coverage" 3 | } 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | package.json 4 | dist 5 | .nyc_output 6 | -------------------------------------------------------------------------------- /diagram/devp2p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereumjs/ethereumjs-devp2p/HEAD/diagram/devp2p.png -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@ethereumjs/eslint-config-defaults/prettier.config.js') -------------------------------------------------------------------------------- /test/index.ts: -------------------------------------------------------------------------------- 1 | import './dpt-message' 2 | import './rlpx-ecies' 3 | import './rlpx-mac' 4 | import './integration' 5 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | target: auto 6 | threshold: 2% 7 | base: auto -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dpt' 2 | export * from './eth' 3 | export * from './les' 4 | export * from './rlpx' 5 | export * from './util' 6 | -------------------------------------------------------------------------------- /src/rlpx/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | export * from './ecies' 4 | export * from './mac' 5 | export * from './peer' 6 | export * from './rlpx' 7 | -------------------------------------------------------------------------------- /test/integration/index.ts: -------------------------------------------------------------------------------- 1 | import './dpt-simulator' 2 | import './eth-simulator' 3 | import './les-simulator' 4 | import './rlpx-simulator' 5 | 6 | export * from './util' 7 | -------------------------------------------------------------------------------- /src/dpt/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | export * from './ban-list' 4 | export * from './dpt' 5 | export * from './kbucket' 6 | export * from './message' 7 | export * from './server' 8 | -------------------------------------------------------------------------------- /docs/modules/_dpt_dpt_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "dpt/dpt" 4 | 5 | # Module: "dpt/dpt" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [DPT](../classes/_dpt_dpt_.dpt.md) 12 | -------------------------------------------------------------------------------- /docs/modules/_eth_index_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "eth/index" 4 | 5 | # Module: "eth/index" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [ETH](../classes/_eth_index_.eth.md) 12 | -------------------------------------------------------------------------------- /docs/modules/_rlpx_mac_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "rlpx/mac" 4 | 5 | # Module: "rlpx/mac" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [MAC](../classes/_rlpx_mac_.mac.md) 12 | -------------------------------------------------------------------------------- /docs/modules/_rlpx_ecies_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "rlpx/ecies" 4 | 5 | # Module: "rlpx/ecies" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [ECIES](../classes/_rlpx_ecies_.ecies.md) 12 | -------------------------------------------------------------------------------- /docs/modules/_dpt_ban_list_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "dpt/ban-list" 4 | 5 | # Module: "dpt/ban-list" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [BanList](../classes/_dpt_ban_list_.banlist.md) 12 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@ethereumjs/eslint-config-defaults', 3 | parserOptions: { 4 | project: ['./tsconfig.json'] 5 | }, 6 | rules: { 7 | '@typescript-eslint/no-floating-promises': 'off', 8 | '@typescript-eslint/no-unnecessary-condition': 'off', 9 | 'no-redeclare': 'off' 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/modules/_dpt_kbucket_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "dpt/kbucket" 4 | 5 | # Module: "dpt/kbucket" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [KBucket](../classes/_dpt_kbucket_.kbucket.md) 12 | 13 | ### Interfaces 14 | 15 | * [KObj](../interfaces/_dpt_kbucket_.kobj.md) 16 | -------------------------------------------------------------------------------- /docs/modules/_rlpx_rlpx_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "rlpx/rlpx" 4 | 5 | # Module: "rlpx/rlpx" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [RLPx](../classes/_rlpx_rlpx_.rlpx.md) 12 | 13 | ### Interfaces 14 | 15 | * [RLPxOptions](../interfaces/_rlpx_rlpx_.rlpxoptions.md) 16 | -------------------------------------------------------------------------------- /docs/modules/_dpt_server_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "dpt/server" 4 | 5 | # Module: "dpt/server" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [Server](../classes/_dpt_server_.server.md) 12 | 13 | ### Interfaces 14 | 15 | * [DptServerOptions](../interfaces/_dpt_server_.dptserveroptions.md) 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@ethereumjs/config-typescript", 3 | "include": ["src/**/*.ts", "test/**/*.ts", "examples/**/*.ts"], 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "typeRoots": ["node_modules/@types"], 7 | "declaration": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "downlevelIteration": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFiles": ["src/index.ts"], 3 | "out": "docs", 4 | "mode": "library", 5 | "plugin": "typedoc-plugin-markdown", 6 | "readme": "none", 7 | "gitRevision": "master", 8 | "exclude": ["test/**/*.ts", "examples/*.ts"], 9 | "excludeNotExported": true, 10 | "excludeExternals": true, 11 | "excludePrivate": true, 12 | "excludeProtected": true 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@ethereumjs/config-typescript", 3 | "exclude": ["test", "examples", "node_modules", "dist"], 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist", 7 | "rootDir": "./src", 8 | "typeRoots": ["node_modules/@types"], 9 | "declaration": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "downlevelIteration": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/modules/_les_index_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "les/index" 4 | 5 | # Module: "les/index" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [LES](../classes/_les_index_.les.md) 12 | 13 | ### Variables 14 | 15 | * [DEFAULT\_ANNOUNCE\_TYPE](_les_index_.md#default_announce_type) 16 | 17 | ## Variables 18 | 19 | ### DEFAULT\_ANNOUNCE\_TYPE 20 | 21 | • `Const` **DEFAULT\_ANNOUNCE\_TYPE**: 1 = 1 22 | 23 | *Defined in [src/les/index.ts:11](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L11)* 24 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.protocolconstructor.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / ProtocolConstructor 4 | 5 | # Interface: ProtocolConstructor 6 | 7 | ## Hierarchy 8 | 9 | * **ProtocolConstructor** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_index_.protocolconstructor.md#constructor) 16 | 17 | ## Constructors 18 | 19 | ### constructor 20 | 21 | \+ **new ProtocolConstructor**(...`args`: any[]): any 22 | 23 | *Defined in [src/rlpx/peer.ts:58](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L58)* 24 | 25 | #### Parameters: 26 | 27 | Name | Type | 28 | ------ | ------ | 29 | `...args` | any[] | 30 | 31 | **Returns:** any 32 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_peer_.protocolconstructor.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/peer"](../modules/_rlpx_peer_.md) / ProtocolConstructor 4 | 5 | # Interface: ProtocolConstructor 6 | 7 | ## Hierarchy 8 | 9 | * **ProtocolConstructor** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_rlpx_peer_.protocolconstructor.md#constructor) 16 | 17 | ## Constructors 18 | 19 | ### constructor 20 | 21 | \+ **new ProtocolConstructor**(...`args`: any[]): any 22 | 23 | *Defined in [src/rlpx/peer.ts:58](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L58)* 24 | 25 | #### Parameters: 26 | 27 | Name | Type | 28 | ------ | ------ | 29 | `...args` | any[] | 30 | 31 | **Returns:** any 32 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_index_.protocolconstructor.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / ProtocolConstructor 4 | 5 | # Interface: ProtocolConstructor 6 | 7 | ## Hierarchy 8 | 9 | * **ProtocolConstructor** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_rlpx_index_.protocolconstructor.md#constructor) 16 | 17 | ## Constructors 18 | 19 | ### constructor 20 | 21 | \+ **new ProtocolConstructor**(...`args`: any[]): any 22 | 23 | *Defined in [src/rlpx/peer.ts:58](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L58)* 24 | 25 | #### Parameters: 26 | 27 | Name | Type | 28 | ------ | ------ | 29 | `...args` | any[] | 30 | 31 | **Returns:** any 32 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](README.md)** 2 | 3 | > Globals 4 | 5 | # ethereumjs-devp2p 6 | 7 | ## Index 8 | 9 | ### Modules 10 | 11 | * ["dpt/ban-list"](modules/_dpt_ban_list_.md) 12 | * ["dpt/dpt"](modules/_dpt_dpt_.md) 13 | * ["dpt/index"](modules/_dpt_index_.md) 14 | * ["dpt/kbucket"](modules/_dpt_kbucket_.md) 15 | * ["dpt/message"](modules/_dpt_message_.md) 16 | * ["dpt/server"](modules/_dpt_server_.md) 17 | * ["eth/index"](modules/_eth_index_.md) 18 | * ["index"](modules/_index_.md) 19 | * ["les/index"](modules/_les_index_.md) 20 | * ["rlpx/ecies"](modules/_rlpx_ecies_.md) 21 | * ["rlpx/index"](modules/_rlpx_index_.md) 22 | * ["rlpx/mac"](modules/_rlpx_mac_.md) 23 | * ["rlpx/peer"](modules/_rlpx_peer_.md) 24 | * ["rlpx/rlpx"](modules/_rlpx_rlpx_.md) 25 | * ["util"](modules/_util_.md) 26 | -------------------------------------------------------------------------------- /src/dpt/ban-list.ts: -------------------------------------------------------------------------------- 1 | import LRUCache from 'lru-cache' 2 | import { debug as createDebugLogger } from 'debug' 3 | import { KBucket } from './kbucket' 4 | import { formatLogId } from '../util' 5 | 6 | const debug = createDebugLogger('devp2p:dpt:ban-list') 7 | const verbose = createDebugLogger('verbose').enabled 8 | 9 | export class BanList { 10 | private lru: LRUCache 11 | constructor() { 12 | this.lru = new LRUCache({ max: 30000 }) // 10k should be enough (each peer obj can has 3 keys) 13 | } 14 | 15 | add(obj: any, maxAge?: number) { 16 | for (const key of KBucket.getKeys(obj)) { 17 | this.lru.set(key, true, maxAge) 18 | debug(`Added peer ${formatLogId(key, verbose)}, size: ${this.lru.length}`) 19 | } 20 | } 21 | 22 | has(obj: any): boolean { 23 | return KBucket.getKeys(obj).some((key: string) => Boolean(this.lru.get(key))) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.kobj.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / KObj 4 | 5 | # Interface: KObj 6 | 7 | ## Hierarchy 8 | 9 | * **KObj** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [address](_index_.kobj.md#address) 16 | * [id](_index_.kobj.md#id) 17 | * [port](_index_.kobj.md#port) 18 | 19 | ## Properties 20 | 21 | ### address 22 | 23 | • `Optional` **address**: undefined \| string 24 | 25 | *Defined in [src/dpt/kbucket.ts:10](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L10)* 26 | 27 | ___ 28 | 29 | ### id 30 | 31 | • `Optional` **id**: undefined \| string 32 | 33 | *Defined in [src/dpt/kbucket.ts:8](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L8)* 34 | 35 | ___ 36 | 37 | ### port 38 | 39 | • `Optional` **port**: undefined \| string 40 | 41 | *Defined in [src/dpt/kbucket.ts:9](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L9)* 42 | -------------------------------------------------------------------------------- /src/rlpx/mac.ts: -------------------------------------------------------------------------------- 1 | import { createCipheriv } from 'crypto' 2 | import createKeccakHash from 'keccak' 3 | import { xor } from '../util' 4 | 5 | export class MAC { 6 | _hash: any 7 | _secret: Buffer 8 | constructor(secret: Buffer) { 9 | this._hash = createKeccakHash('keccak256') 10 | this._secret = secret 11 | } 12 | 13 | update(data: Buffer | string) { 14 | this._hash.update(data) 15 | } 16 | 17 | updateHeader(data: Buffer | string) { 18 | const aes = createCipheriv('aes-256-ecb', this._secret, '') 19 | const encrypted = aes.update(this.digest()) 20 | this._hash.update(xor(encrypted, data)) 21 | } 22 | 23 | updateBody(data: Buffer | string) { 24 | this._hash.update(data) 25 | const prev = this.digest() 26 | const aes = createCipheriv('aes-256-ecb', this._secret, '') 27 | const encrypted = aes.update(prev) 28 | this._hash.update(xor(encrypted, prev)) 29 | } 30 | 31 | digest() { 32 | return this._hash 33 | ._clone() 34 | .digest() 35 | .slice(0, 16) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/interfaces/_dpt_index_.kobj.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/index"](../modules/_dpt_index_.md) / KObj 4 | 5 | # Interface: KObj 6 | 7 | ## Hierarchy 8 | 9 | * **KObj** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [address](_dpt_index_.kobj.md#address) 16 | * [id](_dpt_index_.kobj.md#id) 17 | * [port](_dpt_index_.kobj.md#port) 18 | 19 | ## Properties 20 | 21 | ### address 22 | 23 | • `Optional` **address**: undefined \| string 24 | 25 | *Defined in [src/dpt/kbucket.ts:10](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L10)* 26 | 27 | ___ 28 | 29 | ### id 30 | 31 | • `Optional` **id**: undefined \| string 32 | 33 | *Defined in [src/dpt/kbucket.ts:8](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L8)* 34 | 35 | ___ 36 | 37 | ### port 38 | 39 | • `Optional` **port**: undefined \| string 40 | 41 | *Defined in [src/dpt/kbucket.ts:9](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L9)* 42 | -------------------------------------------------------------------------------- /docs/interfaces/_dpt_kbucket_.kobj.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/kbucket"](../modules/_dpt_kbucket_.md) / KObj 4 | 5 | # Interface: KObj 6 | 7 | ## Hierarchy 8 | 9 | * **KObj** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [address](_dpt_kbucket_.kobj.md#address) 16 | * [id](_dpt_kbucket_.kobj.md#id) 17 | * [port](_dpt_kbucket_.kobj.md#port) 18 | 19 | ## Properties 20 | 21 | ### address 22 | 23 | • `Optional` **address**: undefined \| string 24 | 25 | *Defined in [src/dpt/kbucket.ts:10](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L10)* 26 | 27 | ___ 28 | 29 | ### id 30 | 31 | • `Optional` **id**: undefined \| string 32 | 33 | *Defined in [src/dpt/kbucket.ts:8](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L8)* 34 | 35 | ___ 36 | 37 | ### port 38 | 39 | • `Optional` **port**: undefined \| string 40 | 41 | *Defined in [src/dpt/kbucket.ts:9](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/kbucket.ts#L9)* 42 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.protocoldescriptor.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / ProtocolDescriptor 4 | 5 | # Interface: ProtocolDescriptor 6 | 7 | ## Hierarchy 8 | 9 | * **ProtocolDescriptor** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [length](_index_.protocoldescriptor.md#length) 16 | * [offset](_index_.protocoldescriptor.md#offset) 17 | * [protocol](_index_.protocoldescriptor.md#protocol) 18 | 19 | ## Properties 20 | 21 | ### length 22 | 23 | • `Optional` **length**: undefined \| number 24 | 25 | *Defined in [src/rlpx/peer.ts:55](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L55)* 26 | 27 | ___ 28 | 29 | ### offset 30 | 31 | • **offset**: number 32 | 33 | *Defined in [src/rlpx/peer.ts:54](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L54)* 34 | 35 | ___ 36 | 37 | ### protocol 38 | 39 | • `Optional` **protocol**: any 40 | 41 | *Defined in [src/rlpx/peer.ts:53](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L53)* 42 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - master 6 | tags: 7 | - '*' 8 | pull_request: 9 | types: [opened, reopened, synchronize] 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/setup-node@v1 15 | - uses: actions/checkout@v1 16 | - run: npm install 17 | - run: npm run lint 18 | 19 | coverage: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/setup-node@v1 23 | - uses: actions/checkout@v1 24 | - run: npm install 25 | - run: npm run coverage 26 | - uses: codecov/codecov-action@v1 27 | with: 28 | file: ./coverage/lcov.info 29 | 30 | test: 31 | runs-on: ubuntu-latest 32 | strategy: 33 | matrix: 34 | node-version: [10.x, 12.x, 13.x] 35 | steps: 36 | - name: Use Node.js ${{ matrix.node-version }} 37 | uses: actions/setup-node@v1 38 | with: 39 | node-version: ${{ matrix.node-version }} 40 | - uses: actions/checkout@v1 41 | - run: npm install 42 | - run: npm run test -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_peer_.protocoldescriptor.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/peer"](../modules/_rlpx_peer_.md) / ProtocolDescriptor 4 | 5 | # Interface: ProtocolDescriptor 6 | 7 | ## Hierarchy 8 | 9 | * **ProtocolDescriptor** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [length](_rlpx_peer_.protocoldescriptor.md#length) 16 | * [offset](_rlpx_peer_.protocoldescriptor.md#offset) 17 | * [protocol](_rlpx_peer_.protocoldescriptor.md#protocol) 18 | 19 | ## Properties 20 | 21 | ### length 22 | 23 | • `Optional` **length**: undefined \| number 24 | 25 | *Defined in [src/rlpx/peer.ts:55](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L55)* 26 | 27 | ___ 28 | 29 | ### offset 30 | 31 | • **offset**: number 32 | 33 | *Defined in [src/rlpx/peer.ts:54](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L54)* 34 | 35 | ___ 36 | 37 | ### protocol 38 | 39 | • `Optional` **protocol**: any 40 | 41 | *Defined in [src/rlpx/peer.ts:53](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L53)* 42 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_index_.protocoldescriptor.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / ProtocolDescriptor 4 | 5 | # Interface: ProtocolDescriptor 6 | 7 | ## Hierarchy 8 | 9 | * **ProtocolDescriptor** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [length](_rlpx_index_.protocoldescriptor.md#length) 16 | * [offset](_rlpx_index_.protocoldescriptor.md#offset) 17 | * [protocol](_rlpx_index_.protocoldescriptor.md#protocol) 18 | 19 | ## Properties 20 | 21 | ### length 22 | 23 | • `Optional` **length**: undefined \| number 24 | 25 | *Defined in [src/rlpx/peer.ts:55](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L55)* 26 | 27 | ___ 28 | 29 | ### offset 30 | 31 | • **offset**: number 32 | 33 | *Defined in [src/rlpx/peer.ts:54](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L54)* 34 | 35 | ___ 36 | 37 | ### protocol 38 | 39 | • `Optional` **protocol**: any 40 | 41 | *Defined in [src/rlpx/peer.ts:53](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L53)* 42 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.dptserveroptions.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / DptServerOptions 4 | 5 | # Interface: DptServerOptions 6 | 7 | ## Hierarchy 8 | 9 | * **DptServerOptions** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [createSocket](_index_.dptserveroptions.md#createsocket) 16 | * [endpoint](_index_.dptserveroptions.md#endpoint) 17 | * [timeout](_index_.dptserveroptions.md#timeout) 18 | 19 | ## Properties 20 | 21 | ### createSocket 22 | 23 | • `Optional` **createSocket**: Function 24 | 25 | *Defined in [src/dpt/server.ts:20](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L20)* 26 | 27 | ___ 28 | 29 | ### endpoint 30 | 31 | • `Optional` **endpoint**: [PeerInfo](_index_.peerinfo.md) 32 | 33 | *Defined in [src/dpt/server.ts:19](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L19)* 34 | 35 | ___ 36 | 37 | ### timeout 38 | 39 | • `Optional` **timeout**: undefined \| number 40 | 41 | *Defined in [src/dpt/server.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L18)* 42 | -------------------------------------------------------------------------------- /docs/enums/_index_.prefixes.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / PREFIXES 4 | 5 | # Enumeration: PREFIXES 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [DISCONNECT](_index_.prefixes.md#disconnect) 12 | * [HELLO](_index_.prefixes.md#hello) 13 | * [PING](_index_.prefixes.md#ping) 14 | * [PONG](_index_.prefixes.md#pong) 15 | 16 | ## Enumeration members 17 | 18 | ### DISCONNECT 19 | 20 | • **DISCONNECT**: = 1 21 | 22 | *Defined in [src/rlpx/peer.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L22)* 23 | 24 | ___ 25 | 26 | ### HELLO 27 | 28 | • **HELLO**: = 0 29 | 30 | *Defined in [src/rlpx/peer.ts:21](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L21)* 31 | 32 | ___ 33 | 34 | ### PING 35 | 36 | • **PING**: = 2 37 | 38 | *Defined in [src/rlpx/peer.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L23)* 39 | 40 | ___ 41 | 42 | ### PONG 43 | 44 | • **PONG**: = 3 45 | 46 | *Defined in [src/rlpx/peer.ts:24](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L24)* 47 | -------------------------------------------------------------------------------- /docs/interfaces/_dpt_index_.dptserveroptions.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/index"](../modules/_dpt_index_.md) / DptServerOptions 4 | 5 | # Interface: DptServerOptions 6 | 7 | ## Hierarchy 8 | 9 | * **DptServerOptions** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [createSocket](_dpt_index_.dptserveroptions.md#createsocket) 16 | * [endpoint](_dpt_index_.dptserveroptions.md#endpoint) 17 | * [timeout](_dpt_index_.dptserveroptions.md#timeout) 18 | 19 | ## Properties 20 | 21 | ### createSocket 22 | 23 | • `Optional` **createSocket**: Function 24 | 25 | *Defined in [src/dpt/server.ts:20](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L20)* 26 | 27 | ___ 28 | 29 | ### endpoint 30 | 31 | • `Optional` **endpoint**: [PeerInfo](_dpt_index_.peerinfo.md) 32 | 33 | *Defined in [src/dpt/server.ts:19](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L19)* 34 | 35 | ___ 36 | 37 | ### timeout 38 | 39 | • `Optional` **timeout**: undefined \| number 40 | 41 | *Defined in [src/dpt/server.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L18)* 42 | -------------------------------------------------------------------------------- /docs/interfaces/_dpt_server_.dptserveroptions.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/server"](../modules/_dpt_server_.md) / DptServerOptions 4 | 5 | # Interface: DptServerOptions 6 | 7 | ## Hierarchy 8 | 9 | * **DptServerOptions** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [createSocket](_dpt_server_.dptserveroptions.md#createsocket) 16 | * [endpoint](_dpt_server_.dptserveroptions.md#endpoint) 17 | * [timeout](_dpt_server_.dptserveroptions.md#timeout) 18 | 19 | ## Properties 20 | 21 | ### createSocket 22 | 23 | • `Optional` **createSocket**: Function 24 | 25 | *Defined in [src/dpt/server.ts:20](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L20)* 26 | 27 | ___ 28 | 29 | ### endpoint 30 | 31 | • `Optional` **endpoint**: [PeerInfo](_index_.peerinfo.md) 32 | 33 | *Defined in [src/dpt/server.ts:19](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L19)* 34 | 35 | ___ 36 | 37 | ### timeout 38 | 39 | • `Optional` **timeout**: undefined \| number 40 | 41 | *Defined in [src/dpt/server.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/server.ts#L18)* 42 | -------------------------------------------------------------------------------- /docs/enums/_rlpx_peer_.prefixes.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/peer"](../modules/_rlpx_peer_.md) / PREFIXES 4 | 5 | # Enumeration: PREFIXES 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [DISCONNECT](_rlpx_peer_.prefixes.md#disconnect) 12 | * [HELLO](_rlpx_peer_.prefixes.md#hello) 13 | * [PING](_rlpx_peer_.prefixes.md#ping) 14 | * [PONG](_rlpx_peer_.prefixes.md#pong) 15 | 16 | ## Enumeration members 17 | 18 | ### DISCONNECT 19 | 20 | • **DISCONNECT**: = 1 21 | 22 | *Defined in [src/rlpx/peer.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L22)* 23 | 24 | ___ 25 | 26 | ### HELLO 27 | 28 | • **HELLO**: = 0 29 | 30 | *Defined in [src/rlpx/peer.ts:21](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L21)* 31 | 32 | ___ 33 | 34 | ### PING 35 | 36 | • **PING**: = 2 37 | 38 | *Defined in [src/rlpx/peer.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L23)* 39 | 40 | ___ 41 | 42 | ### PONG 43 | 44 | • **PONG**: = 3 45 | 46 | *Defined in [src/rlpx/peer.ts:24](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L24)* 47 | -------------------------------------------------------------------------------- /docs/enums/_rlpx_index_.prefixes.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / PREFIXES 4 | 5 | # Enumeration: PREFIXES 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [DISCONNECT](_rlpx_index_.prefixes.md#disconnect) 12 | * [HELLO](_rlpx_index_.prefixes.md#hello) 13 | * [PING](_rlpx_index_.prefixes.md#ping) 14 | * [PONG](_rlpx_index_.prefixes.md#pong) 15 | 16 | ## Enumeration members 17 | 18 | ### DISCONNECT 19 | 20 | • **DISCONNECT**: = 1 21 | 22 | *Defined in [src/rlpx/peer.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L22)* 23 | 24 | ___ 25 | 26 | ### HELLO 27 | 28 | • **HELLO**: = 0 29 | 30 | *Defined in [src/rlpx/peer.ts:21](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L21)* 31 | 32 | ___ 33 | 34 | ### PING 35 | 36 | • **PING**: = 2 37 | 38 | *Defined in [src/rlpx/peer.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L23)* 39 | 40 | ___ 41 | 42 | ### PONG 43 | 44 | • **PONG**: = 3 45 | 46 | *Defined in [src/rlpx/peer.ts:24](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L24)* 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### App ### 2 | 3 | .cachedb 4 | 5 | 6 | # Created by https://www.gitignore.io/api/osx,node 7 | 8 | ### OSX ### 9 | .DS_Store 10 | .AppleDouble 11 | .LSOverride 12 | 13 | # Icon must end with two \r 14 | Icon 15 | 16 | 17 | # Thumbnails 18 | ._* 19 | 20 | # Files that might appear in the root of a volume 21 | .DocumentRevisions-V100 22 | .fseventsd 23 | .Spotlight-V100 24 | .TemporaryItems 25 | .Trashes 26 | .VolumeIcon.icns 27 | .idea 28 | 29 | # Directories potentially created on remote AFP share 30 | .AppleDB 31 | .AppleDesktop 32 | Network Trash Folder 33 | Temporary Items 34 | .apdisk 35 | 36 | 37 | ### Node ### 38 | # Logs 39 | logs 40 | *.log 41 | npm-debug.log* 42 | 43 | # Runtime data 44 | pids 45 | *.pid 46 | *.seed 47 | 48 | # Coverage directory used by tools like nyc 49 | coverage 50 | 51 | # nyc test coverage 52 | .nyc_output 53 | 54 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 55 | .grunt 56 | 57 | # node-waf configuration 58 | .lock-wscript 59 | 60 | # Compiled binary addons (http://nodejs.org/api/addons.html) 61 | build/Release 62 | 63 | # Dependency directory 64 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 65 | node_modules 66 | package-lock.json 67 | 68 | dist 69 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.peerinfo.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / PeerInfo 4 | 5 | # Interface: PeerInfo 6 | 7 | ## Hierarchy 8 | 9 | * **PeerInfo** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [address](_index_.peerinfo.md#address) 16 | * [id](_index_.peerinfo.md#id) 17 | * [tcpPort](_index_.peerinfo.md#tcpport) 18 | * [udpPort](_index_.peerinfo.md#udpport) 19 | 20 | ## Properties 21 | 22 | ### address 23 | 24 | • `Optional` **address**: undefined \| string 25 | 26 | *Defined in [src/dpt/message.ts:16](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L16)* 27 | 28 | ___ 29 | 30 | ### id 31 | 32 | • `Optional` **id**: Buffer 33 | 34 | *Defined in [src/dpt/message.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L15)* 35 | 36 | ___ 37 | 38 | ### tcpPort 39 | 40 | • `Optional` **tcpPort**: number \| null 41 | 42 | *Defined in [src/dpt/message.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L18)* 43 | 44 | ___ 45 | 46 | ### udpPort 47 | 48 | • `Optional` **udpPort**: number \| null 49 | 50 | *Defined in [src/dpt/message.ts:17](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L17)* 51 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.capabilities.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / Capabilities 4 | 5 | # Interface: Capabilities 6 | 7 | ## Hierarchy 8 | 9 | * **Capabilities** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [constructor](_index_.capabilities.md#constructor) 16 | * [length](_index_.capabilities.md#length) 17 | * [name](_index_.capabilities.md#name) 18 | * [version](_index_.capabilities.md#version) 19 | 20 | ## Properties 21 | 22 | ### constructor 23 | 24 | • **constructor**: [ProtocolConstructor](_index_.protocolconstructor.md) 25 | 26 | *Defined in [src/rlpx/peer.ts:66](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L66)* 27 | 28 | ___ 29 | 30 | ### length 31 | 32 | • **length**: number 33 | 34 | *Defined in [src/rlpx/peer.ts:65](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L65)* 35 | 36 | ___ 37 | 38 | ### name 39 | 40 | • **name**: string 41 | 42 | *Defined in [src/rlpx/peer.ts:63](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L63)* 43 | 44 | ___ 45 | 46 | ### version 47 | 48 | • **version**: number 49 | 50 | *Defined in [src/rlpx/peer.ts:64](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L64)* 51 | -------------------------------------------------------------------------------- /docs/interfaces/_dpt_index_.peerinfo.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/index"](../modules/_dpt_index_.md) / PeerInfo 4 | 5 | # Interface: PeerInfo 6 | 7 | ## Hierarchy 8 | 9 | * **PeerInfo** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [address](_dpt_index_.peerinfo.md#address) 16 | * [id](_dpt_index_.peerinfo.md#id) 17 | * [tcpPort](_dpt_index_.peerinfo.md#tcpport) 18 | * [udpPort](_dpt_index_.peerinfo.md#udpport) 19 | 20 | ## Properties 21 | 22 | ### address 23 | 24 | • `Optional` **address**: undefined \| string 25 | 26 | *Defined in [src/dpt/message.ts:16](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L16)* 27 | 28 | ___ 29 | 30 | ### id 31 | 32 | • `Optional` **id**: Buffer 33 | 34 | *Defined in [src/dpt/message.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L15)* 35 | 36 | ___ 37 | 38 | ### tcpPort 39 | 40 | • `Optional` **tcpPort**: number \| null 41 | 42 | *Defined in [src/dpt/message.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L18)* 43 | 44 | ___ 45 | 46 | ### udpPort 47 | 48 | • `Optional` **udpPort**: number \| null 49 | 50 | *Defined in [src/dpt/message.ts:17](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L17)* 51 | -------------------------------------------------------------------------------- /test/rlpx-mac.ts: -------------------------------------------------------------------------------- 1 | import test from 'tape' 2 | import { MAC } from '../src/rlpx/mac' 3 | 4 | const secret = Buffer.from( 5 | '4caf4671e713d083128973de159d02688dc86f51535a80178264631e193ed2ea', 6 | 'hex' 7 | ) 8 | 9 | test('digest should work on empty data', t => { 10 | const mac = new MAC(secret) 11 | t.equal(mac.digest().toString('hex'), 'c5d2460186f7233c927e7db2dcc703c0') 12 | t.end() 13 | }) 14 | 15 | test('#update', t => { 16 | const mac = new MAC(secret) 17 | mac.update('test') 18 | t.equal(mac.digest().toString('hex'), '9c22ff5f21f0b81b113e63f7db6da94f') 19 | t.end() 20 | }) 21 | 22 | test('#updateHeader', t => { 23 | const mac = new MAC(secret) 24 | mac.updateHeader('this is a header data struct') 25 | t.equal(mac.digest().toString('hex'), '52235ed491a4c9224d94788762ead6a6') 26 | t.end() 27 | }) 28 | 29 | test('#updateBody', t => { 30 | const mac = new MAC(secret) 31 | mac.updateBody('this is a body data struct') 32 | t.equal(mac.digest().toString('hex'), '134a755450b1ed9d3ff90ef5dcecdd7d') 33 | t.end() 34 | }) 35 | 36 | test('#updateHeader and #updateBody', t => { 37 | const mac = new MAC(secret) 38 | mac.updateHeader('this is a header data struct') 39 | mac.updateBody('this is a body data struct') 40 | t.equal(mac.digest().toString('hex'), '5d98967578ec8edbb45e1d75992f394c') 41 | t.end() 42 | }) 43 | -------------------------------------------------------------------------------- /docs/interfaces/_dpt_message_.peerinfo.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/message"](../modules/_dpt_message_.md) / PeerInfo 4 | 5 | # Interface: PeerInfo 6 | 7 | ## Hierarchy 8 | 9 | * **PeerInfo** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [address](_dpt_message_.peerinfo.md#address) 16 | * [id](_dpt_message_.peerinfo.md#id) 17 | * [tcpPort](_dpt_message_.peerinfo.md#tcpport) 18 | * [udpPort](_dpt_message_.peerinfo.md#udpport) 19 | 20 | ## Properties 21 | 22 | ### address 23 | 24 | • `Optional` **address**: undefined \| string 25 | 26 | *Defined in [src/dpt/message.ts:16](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L16)* 27 | 28 | ___ 29 | 30 | ### id 31 | 32 | • `Optional` **id**: Buffer 33 | 34 | *Defined in [src/dpt/message.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L15)* 35 | 36 | ___ 37 | 38 | ### tcpPort 39 | 40 | • `Optional` **tcpPort**: number \| null 41 | 42 | *Defined in [src/dpt/message.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L18)* 43 | 44 | ___ 45 | 46 | ### udpPort 47 | 48 | • `Optional` **udpPort**: number \| null 49 | 50 | *Defined in [src/dpt/message.ts:17](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L17)* 51 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_peer_.capabilities.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/peer"](../modules/_rlpx_peer_.md) / Capabilities 4 | 5 | # Interface: Capabilities 6 | 7 | ## Hierarchy 8 | 9 | * **Capabilities** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [constructor](_rlpx_peer_.capabilities.md#constructor) 16 | * [length](_rlpx_peer_.capabilities.md#length) 17 | * [name](_rlpx_peer_.capabilities.md#name) 18 | * [version](_rlpx_peer_.capabilities.md#version) 19 | 20 | ## Properties 21 | 22 | ### constructor 23 | 24 | • **constructor**: [ProtocolConstructor](_index_.protocolconstructor.md) 25 | 26 | *Defined in [src/rlpx/peer.ts:66](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L66)* 27 | 28 | ___ 29 | 30 | ### length 31 | 32 | • **length**: number 33 | 34 | *Defined in [src/rlpx/peer.ts:65](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L65)* 35 | 36 | ___ 37 | 38 | ### name 39 | 40 | • **name**: string 41 | 42 | *Defined in [src/rlpx/peer.ts:63](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L63)* 43 | 44 | ___ 45 | 46 | ### version 47 | 48 | • **version**: number 49 | 50 | *Defined in [src/rlpx/peer.ts:64](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L64)* 51 | -------------------------------------------------------------------------------- /docs/modules/_dpt_message_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "dpt/message" 4 | 5 | # Module: "dpt/message" 6 | 7 | ## Index 8 | 9 | ### Interfaces 10 | 11 | * [PeerInfo](../interfaces/_dpt_message_.peerinfo.md) 12 | 13 | ### Functions 14 | 15 | * [decode](_dpt_message_.md#decode) 16 | * [encode](_dpt_message_.md#encode) 17 | 18 | ## Functions 19 | 20 | ### decode 21 | 22 | ▸ **decode**(`buffer`: Buffer): object 23 | 24 | *Defined in [src/dpt/message.ts:188](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L188)* 25 | 26 | #### Parameters: 27 | 28 | Name | Type | 29 | ------ | ------ | 30 | `buffer` | Buffer | 31 | 32 | **Returns:** object 33 | 34 | Name | Type | 35 | ------ | ------ | 36 | `data` | any | 37 | `publicKey` | Buffer | 38 | `typename` | string \| number | 39 | 40 | ___ 41 | 42 | ### encode 43 | 44 | ▸ **encode**\(`typename`: string, `data`: T, `privateKey`: Buffer): Buffer 45 | 46 | *Defined in [src/dpt/message.ts:175](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L175)* 47 | 48 | #### Type parameters: 49 | 50 | Name | 51 | ------ | 52 | `T` | 53 | 54 | #### Parameters: 55 | 56 | Name | Type | 57 | ------ | ------ | 58 | `typename` | string | 59 | `data` | T | 60 | `privateKey` | Buffer | 61 | 62 | **Returns:** Buffer 63 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_index_.capabilities.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / Capabilities 4 | 5 | # Interface: Capabilities 6 | 7 | ## Hierarchy 8 | 9 | * **Capabilities** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [constructor](_rlpx_index_.capabilities.md#constructor) 16 | * [length](_rlpx_index_.capabilities.md#length) 17 | * [name](_rlpx_index_.capabilities.md#name) 18 | * [version](_rlpx_index_.capabilities.md#version) 19 | 20 | ## Properties 21 | 22 | ### constructor 23 | 24 | • **constructor**: [ProtocolConstructor](_index_.protocolconstructor.md) 25 | 26 | *Defined in [src/rlpx/peer.ts:66](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L66)* 27 | 28 | ___ 29 | 30 | ### length 31 | 32 | • **length**: number 33 | 34 | *Defined in [src/rlpx/peer.ts:65](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L65)* 35 | 36 | ___ 37 | 38 | ### name 39 | 40 | • **name**: string 41 | 42 | *Defined in [src/rlpx/peer.ts:63](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L63)* 43 | 44 | ___ 45 | 46 | ### version 47 | 48 | • **version**: number 49 | 50 | *Defined in [src/rlpx/peer.ts:64](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L64)* 51 | -------------------------------------------------------------------------------- /examples/simple.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk' 2 | import Common from '@ethereumjs/common' 3 | import { DPT } from '../src/index' 4 | 5 | const PRIVATE_KEY = 'd772e3d6a001a38064dd23964dd2836239fa0e6cec8b28972a87460a17210fe9' 6 | 7 | const config = new Common({ chain: 'mainnet' }) 8 | const bootstrapNodes = config.bootstrapNodes() 9 | const BOOTNODES = bootstrapNodes.map((node: any) => { 10 | return { 11 | address: node.ip, 12 | udpPort: node.port, 13 | tcpPort: node.port 14 | } 15 | }) 16 | 17 | const dpt = new DPT(Buffer.from(PRIVATE_KEY, 'hex'), { 18 | endpoint: { 19 | address: '0.0.0.0', 20 | udpPort: null, 21 | tcpPort: null 22 | } 23 | }) 24 | 25 | /* eslint-disable no-console */ 26 | dpt.on('error', err => console.error(chalk.red(err.stack || err))) 27 | 28 | dpt.on('peer:added', peer => { 29 | const info = `(${peer.id.toString('hex')},${peer.address},${peer.udpPort},${peer.tcpPort})` 30 | console.log(chalk.green(`New peer: ${info} (total: ${dpt.getPeers().length})`)) 31 | }) 32 | 33 | dpt.on('peer:removed', peer => { 34 | console.log( 35 | chalk.yellow(`Remove peer: ${peer.id.toString('hex')} (total: ${dpt.getPeers().length})`) 36 | ) 37 | }) 38 | 39 | // for accept incoming connections uncomment next line 40 | // dpt.bind(30303, '0.0.0.0') 41 | 42 | for (const bootnode of BOOTNODES) { 43 | dpt.bootstrap(bootnode).catch(err => console.error(chalk.bold.red(err.stack || err))) 44 | } 45 | -------------------------------------------------------------------------------- /docs/classes/_index_.banlist.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / BanList 4 | 5 | # Class: BanList 6 | 7 | ## Hierarchy 8 | 9 | * **BanList** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_index_.banlist.md#constructor) 16 | 17 | ### Methods 18 | 19 | * [add](_index_.banlist.md#add) 20 | * [has](_index_.banlist.md#has) 21 | 22 | ## Constructors 23 | 24 | ### constructor 25 | 26 | \+ **new BanList**(): [BanList](_index_.banlist.md) 27 | 28 | *Defined in [src/dpt/ban-list.ts:10](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L10)* 29 | 30 | **Returns:** [BanList](_index_.banlist.md) 31 | 32 | ## Methods 33 | 34 | ### add 35 | 36 | ▸ **add**(`obj`: any, `maxAge?`: undefined \| number): void 37 | 38 | *Defined in [src/dpt/ban-list.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L15)* 39 | 40 | #### Parameters: 41 | 42 | Name | Type | 43 | ------ | ------ | 44 | `obj` | any | 45 | `maxAge?` | undefined \| number | 46 | 47 | **Returns:** void 48 | 49 | ___ 50 | 51 | ### has 52 | 53 | ▸ **has**(`obj`: any): boolean 54 | 55 | *Defined in [src/dpt/ban-list.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L22)* 56 | 57 | #### Parameters: 58 | 59 | Name | Type | 60 | ------ | ------ | 61 | `obj` | any | 62 | 63 | **Returns:** boolean 64 | -------------------------------------------------------------------------------- /docs/classes/_dpt_index_.banlist.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/index"](../modules/_dpt_index_.md) / BanList 4 | 5 | # Class: BanList 6 | 7 | ## Hierarchy 8 | 9 | * **BanList** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_dpt_index_.banlist.md#constructor) 16 | 17 | ### Methods 18 | 19 | * [add](_dpt_index_.banlist.md#add) 20 | * [has](_dpt_index_.banlist.md#has) 21 | 22 | ## Constructors 23 | 24 | ### constructor 25 | 26 | \+ **new BanList**(): [BanList](_dpt_index_.banlist.md) 27 | 28 | *Defined in [src/dpt/ban-list.ts:10](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L10)* 29 | 30 | **Returns:** [BanList](_dpt_index_.banlist.md) 31 | 32 | ## Methods 33 | 34 | ### add 35 | 36 | ▸ **add**(`obj`: any, `maxAge?`: undefined \| number): void 37 | 38 | *Defined in [src/dpt/ban-list.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L15)* 39 | 40 | #### Parameters: 41 | 42 | Name | Type | 43 | ------ | ------ | 44 | `obj` | any | 45 | `maxAge?` | undefined \| number | 46 | 47 | **Returns:** void 48 | 49 | ___ 50 | 51 | ### has 52 | 53 | ▸ **has**(`obj`: any): boolean 54 | 55 | *Defined in [src/dpt/ban-list.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L22)* 56 | 57 | #### Parameters: 58 | 59 | Name | Type | 60 | ------ | ------ | 61 | `obj` | any | 62 | 63 | **Returns:** boolean 64 | -------------------------------------------------------------------------------- /docs/classes/_dpt_ban_list_.banlist.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["dpt/ban-list"](../modules/_dpt_ban_list_.md) / BanList 4 | 5 | # Class: BanList 6 | 7 | ## Hierarchy 8 | 9 | * **BanList** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_dpt_ban_list_.banlist.md#constructor) 16 | 17 | ### Methods 18 | 19 | * [add](_dpt_ban_list_.banlist.md#add) 20 | * [has](_dpt_ban_list_.banlist.md#has) 21 | 22 | ## Constructors 23 | 24 | ### constructor 25 | 26 | \+ **new BanList**(): [BanList](_dpt_ban_list_.banlist.md) 27 | 28 | *Defined in [src/dpt/ban-list.ts:10](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L10)* 29 | 30 | **Returns:** [BanList](_dpt_ban_list_.banlist.md) 31 | 32 | ## Methods 33 | 34 | ### add 35 | 36 | ▸ **add**(`obj`: any, `maxAge?`: undefined \| number): void 37 | 38 | *Defined in [src/dpt/ban-list.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L15)* 39 | 40 | #### Parameters: 41 | 42 | Name | Type | 43 | ------ | ------ | 44 | `obj` | any | 45 | `maxAge?` | undefined \| number | 46 | 47 | **Returns:** void 48 | 49 | ___ 50 | 51 | ### has 52 | 53 | ▸ **has**(`obj`: any): boolean 54 | 55 | *Defined in [src/dpt/ban-list.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/ban-list.ts#L22)* 56 | 57 | #### Parameters: 58 | 59 | Name | Type | 60 | ------ | ------ | 61 | `obj` | any | 62 | 63 | **Returns:** boolean 64 | -------------------------------------------------------------------------------- /docs/classes/_util_.deferred.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["util"](../modules/_util_.md) / Deferred 4 | 5 | # Class: Deferred\ 6 | 7 | ## Type parameters 8 | 9 | Name | 10 | ------ | 11 | `T` | 12 | 13 | ## Hierarchy 14 | 15 | * **Deferred** 16 | 17 | ## Index 18 | 19 | ### Constructors 20 | 21 | * [constructor](_util_.deferred.md#constructor) 22 | 23 | ### Properties 24 | 25 | * [promise](_util_.deferred.md#promise) 26 | 27 | ### Methods 28 | 29 | * [reject](_util_.deferred.md#reject) 30 | * [resolve](_util_.deferred.md#resolve) 31 | 32 | ## Constructors 33 | 34 | ### constructor 35 | 36 | \+ **new Deferred**(): [Deferred](_util_.deferred.md) 37 | 38 | *Defined in [src/util.ts:97](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L97)* 39 | 40 | **Returns:** [Deferred](_util_.deferred.md) 41 | 42 | ## Properties 43 | 44 | ### promise 45 | 46 | • **promise**: Promise\ 47 | 48 | *Defined in [src/util.ts:95](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L95)* 49 | 50 | ## Methods 51 | 52 | ### reject 53 | 54 | ▸ **reject**(): void 55 | 56 | *Defined in [src/util.ts:97](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L97)* 57 | 58 | **Returns:** void 59 | 60 | ___ 61 | 62 | ### resolve 63 | 64 | ▸ **resolve**(): void 65 | 66 | *Defined in [src/util.ts:96](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L96)* 67 | 68 | **Returns:** void 69 | -------------------------------------------------------------------------------- /docs/classes/_index_.deferred.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / Deferred 4 | 5 | # Class: Deferred\ 6 | 7 | ## Type parameters 8 | 9 | Name | 10 | ------ | 11 | `T` | 12 | 13 | ## Hierarchy 14 | 15 | * **Deferred** 16 | 17 | ## Index 18 | 19 | ### Constructors 20 | 21 | * [constructor](_index_.deferred.md#constructor) 22 | 23 | ### Properties 24 | 25 | * [promise](_index_.deferred.md#promise) 26 | 27 | ### Methods 28 | 29 | * [reject](_index_.deferred.md#reject) 30 | * [resolve](_index_.deferred.md#resolve) 31 | 32 | ## Constructors 33 | 34 | ### constructor 35 | 36 | \+ **new Deferred**(): [Deferred](_index_.deferred.md) 37 | 38 | *Defined in [src/util.ts:97](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L97)* 39 | 40 | **Returns:** [Deferred](_index_.deferred.md) 41 | 42 | ## Properties 43 | 44 | ### promise 45 | 46 | • **promise**: Promise\ 47 | 48 | *Defined in [src/util.ts:95](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L95)* 49 | 50 | ## Methods 51 | 52 | ### reject 53 | 54 | ▸ **reject**(): void 55 | 56 | *Defined in [src/util.ts:97](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L97)* 57 | 58 | **Returns:** void 59 | 60 | ___ 61 | 62 | ### resolve 63 | 64 | ▸ **resolve**(): void 65 | 66 | *Defined in [src/util.ts:96](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L96)* 67 | 68 | **Returns:** void 69 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.hello.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / Hello 4 | 5 | # Interface: Hello 6 | 7 | ## Hierarchy 8 | 9 | * **Hello** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [capabilities](_index_.hello.md#capabilities) 16 | * [clientId](_index_.hello.md#clientid) 17 | * [id](_index_.hello.md#id) 18 | * [port](_index_.hello.md#port) 19 | * [protocolVersion](_index_.hello.md#protocolversion) 20 | 21 | ## Properties 22 | 23 | ### capabilities 24 | 25 | • **capabilities**: [Capabilities](_index_.capabilities.md)[] 26 | 27 | *Defined in [src/rlpx/peer.ts:72](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L72)* 28 | 29 | ___ 30 | 31 | ### clientId 32 | 33 | • **clientId**: string 34 | 35 | *Defined in [src/rlpx/peer.ts:71](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L71)* 36 | 37 | ___ 38 | 39 | ### id 40 | 41 | • **id**: Buffer 42 | 43 | *Defined in [src/rlpx/peer.ts:74](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L74)* 44 | 45 | ___ 46 | 47 | ### port 48 | 49 | • **port**: number 50 | 51 | *Defined in [src/rlpx/peer.ts:73](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L73)* 52 | 53 | ___ 54 | 55 | ### protocolVersion 56 | 57 | • **protocolVersion**: number 58 | 59 | *Defined in [src/rlpx/peer.ts:70](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L70)* 60 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_peer_.hello.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/peer"](../modules/_rlpx_peer_.md) / Hello 4 | 5 | # Interface: Hello 6 | 7 | ## Hierarchy 8 | 9 | * **Hello** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [capabilities](_rlpx_peer_.hello.md#capabilities) 16 | * [clientId](_rlpx_peer_.hello.md#clientid) 17 | * [id](_rlpx_peer_.hello.md#id) 18 | * [port](_rlpx_peer_.hello.md#port) 19 | * [protocolVersion](_rlpx_peer_.hello.md#protocolversion) 20 | 21 | ## Properties 22 | 23 | ### capabilities 24 | 25 | • **capabilities**: [Capabilities](_index_.capabilities.md)[] 26 | 27 | *Defined in [src/rlpx/peer.ts:72](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L72)* 28 | 29 | ___ 30 | 31 | ### clientId 32 | 33 | • **clientId**: string 34 | 35 | *Defined in [src/rlpx/peer.ts:71](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L71)* 36 | 37 | ___ 38 | 39 | ### id 40 | 41 | • **id**: Buffer 42 | 43 | *Defined in [src/rlpx/peer.ts:74](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L74)* 44 | 45 | ___ 46 | 47 | ### port 48 | 49 | • **port**: number 50 | 51 | *Defined in [src/rlpx/peer.ts:73](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L73)* 52 | 53 | ___ 54 | 55 | ### protocolVersion 56 | 57 | • **protocolVersion**: number 58 | 59 | *Defined in [src/rlpx/peer.ts:70](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L70)* 60 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_index_.hello.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / Hello 4 | 5 | # Interface: Hello 6 | 7 | ## Hierarchy 8 | 9 | * **Hello** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [capabilities](_rlpx_index_.hello.md#capabilities) 16 | * [clientId](_rlpx_index_.hello.md#clientid) 17 | * [id](_rlpx_index_.hello.md#id) 18 | * [port](_rlpx_index_.hello.md#port) 19 | * [protocolVersion](_rlpx_index_.hello.md#protocolversion) 20 | 21 | ## Properties 22 | 23 | ### capabilities 24 | 25 | • **capabilities**: [Capabilities](_index_.capabilities.md)[] 26 | 27 | *Defined in [src/rlpx/peer.ts:72](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L72)* 28 | 29 | ___ 30 | 31 | ### clientId 32 | 33 | • **clientId**: string 34 | 35 | *Defined in [src/rlpx/peer.ts:71](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L71)* 36 | 37 | ___ 38 | 39 | ### id 40 | 41 | • **id**: Buffer 42 | 43 | *Defined in [src/rlpx/peer.ts:74](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L74)* 44 | 45 | ___ 46 | 47 | ### port 48 | 49 | • **port**: number 50 | 51 | *Defined in [src/rlpx/peer.ts:73](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L73)* 52 | 53 | ___ 54 | 55 | ### protocolVersion 56 | 57 | • **protocolVersion**: number 58 | 59 | *Defined in [src/rlpx/peer.ts:70](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L70)* 60 | -------------------------------------------------------------------------------- /docs/modules/_dpt_index_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "dpt/index" 4 | 5 | # Module: "dpt/index" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [BanList](../classes/_dpt_index_.banlist.md) 12 | * [DPT](../classes/_dpt_index_.dpt.md) 13 | * [KBucket](../classes/_dpt_index_.kbucket.md) 14 | * [Server](../classes/_dpt_index_.server.md) 15 | 16 | ### Interfaces 17 | 18 | * [DptServerOptions](../interfaces/_dpt_index_.dptserveroptions.md) 19 | * [KObj](../interfaces/_dpt_index_.kobj.md) 20 | * [PeerInfo](../interfaces/_dpt_index_.peerinfo.md) 21 | 22 | ### Functions 23 | 24 | * [decode](_dpt_index_.md#decode) 25 | * [encode](_dpt_index_.md#encode) 26 | 27 | ## Functions 28 | 29 | ### decode 30 | 31 | ▸ **decode**(`buffer`: Buffer): object 32 | 33 | *Defined in [src/dpt/message.ts:188](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L188)* 34 | 35 | #### Parameters: 36 | 37 | Name | Type | 38 | ------ | ------ | 39 | `buffer` | Buffer | 40 | 41 | **Returns:** object 42 | 43 | Name | Type | 44 | ------ | ------ | 45 | `data` | any | 46 | `publicKey` | Buffer | 47 | `typename` | string \| number | 48 | 49 | ___ 50 | 51 | ### encode 52 | 53 | ▸ **encode**\(`typename`: string, `data`: T, `privateKey`: Buffer): Buffer 54 | 55 | *Defined in [src/dpt/message.ts:175](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L175)* 56 | 57 | #### Type parameters: 58 | 59 | Name | 60 | ------ | 61 | `T` | 62 | 63 | #### Parameters: 64 | 65 | Name | Type | 66 | ------ | ------ | 67 | `typename` | string | 68 | `data` | T | 69 | `privateKey` | Buffer | 70 | 71 | **Returns:** Buffer 72 | -------------------------------------------------------------------------------- /docs/modules/_rlpx_peer_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "rlpx/peer" 4 | 5 | # Module: "rlpx/peer" 6 | 7 | ## Index 8 | 9 | ### Enumerations 10 | 11 | * [DISCONNECT\_REASONS](../enums/_rlpx_peer_.disconnect_reasons.md) 12 | * [PREFIXES](../enums/_rlpx_peer_.prefixes.md) 13 | 14 | ### Classes 15 | 16 | * [Peer](../classes/_rlpx_peer_.peer.md) 17 | 18 | ### Interfaces 19 | 20 | * [Capabilities](../interfaces/_rlpx_peer_.capabilities.md) 21 | * [Hello](../interfaces/_rlpx_peer_.hello.md) 22 | * [ProtocolConstructor](../interfaces/_rlpx_peer_.protocolconstructor.md) 23 | * [ProtocolDescriptor](../interfaces/_rlpx_peer_.protocoldescriptor.md) 24 | 25 | ### Type aliases 26 | 27 | * [HelloMsg](_rlpx_peer_.md#hellomsg) 28 | 29 | ### Variables 30 | 31 | * [BASE\_PROTOCOL\_LENGTH](_rlpx_peer_.md#base_protocol_length) 32 | * [BASE\_PROTOCOL\_VERSION](_rlpx_peer_.md#base_protocol_version) 33 | * [PING\_INTERVAL](_rlpx_peer_.md#ping_interval) 34 | 35 | ## Type aliases 36 | 37 | ### HelloMsg 38 | 39 | Ƭ **HelloMsg**: { 0: Buffer ; 1: Buffer ; 2: Buffer[][] ; 3: Buffer ; 4: Buffer ; length: 5 } 40 | 41 | *Defined in [src/rlpx/peer.ts:43](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L43)* 42 | 43 | #### Type declaration: 44 | 45 | Name | Type | 46 | ------ | ------ | 47 | `0` | Buffer | 48 | `1` | Buffer | 49 | `2` | Buffer[][] | 50 | `3` | Buffer | 51 | `4` | Buffer | 52 | `length` | 5 | 53 | 54 | ## Variables 55 | 56 | ### BASE\_PROTOCOL\_LENGTH 57 | 58 | • `Const` **BASE\_PROTOCOL\_LENGTH**: 16 = 16 59 | 60 | *Defined in [src/rlpx/peer.ts:16](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L16)* 61 | 62 | ___ 63 | 64 | ### BASE\_PROTOCOL\_VERSION 65 | 66 | • `Const` **BASE\_PROTOCOL\_VERSION**: 4 = 4 67 | 68 | *Defined in [src/rlpx/peer.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L15)* 69 | 70 | ___ 71 | 72 | ### PING\_INTERVAL 73 | 74 | • `Const` **PING\_INTERVAL**: number = ms('15s') 75 | 76 | *Defined in [src/rlpx/peer.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L18)* 77 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.rlpxoptions.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / RLPxOptions 4 | 5 | # Interface: RLPxOptions 6 | 7 | ## Hierarchy 8 | 9 | * **RLPxOptions** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [capabilities](_index_.rlpxoptions.md#capabilities) 16 | * [clientId](_index_.rlpxoptions.md#clientid) 17 | * [dpt](_index_.rlpxoptions.md#dpt) 18 | * [listenPort](_index_.rlpxoptions.md#listenport) 19 | * [maxPeers](_index_.rlpxoptions.md#maxpeers) 20 | * [remoteClientIdFilter](_index_.rlpxoptions.md#remoteclientidfilter) 21 | * [timeout](_index_.rlpxoptions.md#timeout) 22 | 23 | ## Properties 24 | 25 | ### capabilities 26 | 27 | • **capabilities**: [Capabilities](_index_.capabilities.md)[] 28 | 29 | *Defined in [src/rlpx/rlpx.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L23)* 30 | 31 | ___ 32 | 33 | ### clientId 34 | 35 | • `Optional` **clientId**: Buffer 36 | 37 | *Defined in [src/rlpx/rlpx.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L18)* 38 | 39 | ___ 40 | 41 | ### dpt 42 | 43 | • **dpt**: [DPT](../classes/_index_.dpt.md) 44 | 45 | *Defined in [src/rlpx/rlpx.ts:20](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L20)* 46 | 47 | ___ 48 | 49 | ### listenPort 50 | 51 | • **listenPort**: number \| null 52 | 53 | *Defined in [src/rlpx/rlpx.ts:24](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L24)* 54 | 55 | ___ 56 | 57 | ### maxPeers 58 | 59 | • **maxPeers**: number 60 | 61 | *Defined in [src/rlpx/rlpx.ts:21](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L21)* 62 | 63 | ___ 64 | 65 | ### remoteClientIdFilter 66 | 67 | • `Optional` **remoteClientIdFilter**: string[] 68 | 69 | *Defined in [src/rlpx/rlpx.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L22)* 70 | 71 | ___ 72 | 73 | ### timeout 74 | 75 | • `Optional` **timeout**: undefined \| number 76 | 77 | *Defined in [src/rlpx/rlpx.ts:19](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L19)* 78 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_rlpx_.rlpxoptions.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/rlpx"](../modules/_rlpx_rlpx_.md) / RLPxOptions 4 | 5 | # Interface: RLPxOptions 6 | 7 | ## Hierarchy 8 | 9 | * **RLPxOptions** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [capabilities](_rlpx_rlpx_.rlpxoptions.md#capabilities) 16 | * [clientId](_rlpx_rlpx_.rlpxoptions.md#clientid) 17 | * [dpt](_rlpx_rlpx_.rlpxoptions.md#dpt) 18 | * [listenPort](_rlpx_rlpx_.rlpxoptions.md#listenport) 19 | * [maxPeers](_rlpx_rlpx_.rlpxoptions.md#maxpeers) 20 | * [remoteClientIdFilter](_rlpx_rlpx_.rlpxoptions.md#remoteclientidfilter) 21 | * [timeout](_rlpx_rlpx_.rlpxoptions.md#timeout) 22 | 23 | ## Properties 24 | 25 | ### capabilities 26 | 27 | • **capabilities**: [Capabilities](_index_.capabilities.md)[] 28 | 29 | *Defined in [src/rlpx/rlpx.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L23)* 30 | 31 | ___ 32 | 33 | ### clientId 34 | 35 | • `Optional` **clientId**: Buffer 36 | 37 | *Defined in [src/rlpx/rlpx.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L18)* 38 | 39 | ___ 40 | 41 | ### dpt 42 | 43 | • **dpt**: [DPT](../classes/_index_.dpt.md) 44 | 45 | *Defined in [src/rlpx/rlpx.ts:20](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L20)* 46 | 47 | ___ 48 | 49 | ### listenPort 50 | 51 | • **listenPort**: number \| null 52 | 53 | *Defined in [src/rlpx/rlpx.ts:24](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L24)* 54 | 55 | ___ 56 | 57 | ### maxPeers 58 | 59 | • **maxPeers**: number 60 | 61 | *Defined in [src/rlpx/rlpx.ts:21](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L21)* 62 | 63 | ___ 64 | 65 | ### remoteClientIdFilter 66 | 67 | • `Optional` **remoteClientIdFilter**: string[] 68 | 69 | *Defined in [src/rlpx/rlpx.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L22)* 70 | 71 | ___ 72 | 73 | ### timeout 74 | 75 | • `Optional` **timeout**: undefined \| number 76 | 77 | *Defined in [src/rlpx/rlpx.ts:19](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L19)* 78 | -------------------------------------------------------------------------------- /docs/interfaces/_rlpx_index_.rlpxoptions.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / RLPxOptions 4 | 5 | # Interface: RLPxOptions 6 | 7 | ## Hierarchy 8 | 9 | * **RLPxOptions** 10 | 11 | ## Index 12 | 13 | ### Properties 14 | 15 | * [capabilities](_rlpx_index_.rlpxoptions.md#capabilities) 16 | * [clientId](_rlpx_index_.rlpxoptions.md#clientid) 17 | * [dpt](_rlpx_index_.rlpxoptions.md#dpt) 18 | * [listenPort](_rlpx_index_.rlpxoptions.md#listenport) 19 | * [maxPeers](_rlpx_index_.rlpxoptions.md#maxpeers) 20 | * [remoteClientIdFilter](_rlpx_index_.rlpxoptions.md#remoteclientidfilter) 21 | * [timeout](_rlpx_index_.rlpxoptions.md#timeout) 22 | 23 | ## Properties 24 | 25 | ### capabilities 26 | 27 | • **capabilities**: [Capabilities](_index_.capabilities.md)[] 28 | 29 | *Defined in [src/rlpx/rlpx.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L23)* 30 | 31 | ___ 32 | 33 | ### clientId 34 | 35 | • `Optional` **clientId**: Buffer 36 | 37 | *Defined in [src/rlpx/rlpx.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L18)* 38 | 39 | ___ 40 | 41 | ### dpt 42 | 43 | • **dpt**: [DPT](../classes/_index_.dpt.md) 44 | 45 | *Defined in [src/rlpx/rlpx.ts:20](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L20)* 46 | 47 | ___ 48 | 49 | ### listenPort 50 | 51 | • **listenPort**: number \| null 52 | 53 | *Defined in [src/rlpx/rlpx.ts:24](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L24)* 54 | 55 | ___ 56 | 57 | ### maxPeers 58 | 59 | • **maxPeers**: number 60 | 61 | *Defined in [src/rlpx/rlpx.ts:21](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L21)* 62 | 63 | ___ 64 | 65 | ### remoteClientIdFilter 66 | 67 | • `Optional` **remoteClientIdFilter**: string[] 68 | 69 | *Defined in [src/rlpx/rlpx.ts:22](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L22)* 70 | 71 | ___ 72 | 73 | ### timeout 74 | 75 | • `Optional` **timeout**: undefined \| number 76 | 77 | *Defined in [src/rlpx/rlpx.ts:19](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/rlpx.ts#L19)* 78 | -------------------------------------------------------------------------------- /src/dpt/kbucket.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from 'events' 2 | import _KBucket = require('k-bucket') 3 | 4 | const KBUCKET_SIZE = 16 5 | const KBUCKET_CONCURRENCY = 3 6 | 7 | export interface KObj { 8 | id?: string 9 | port?: string 10 | address?: string 11 | } 12 | 13 | export class KBucket extends EventEmitter { 14 | _peers: Map = new Map() 15 | _kbucket: _KBucket 16 | constructor(id: string | Buffer) { 17 | super() 18 | 19 | this._kbucket = new _KBucket({ 20 | localNodeId: typeof id === 'string' ? Buffer.from(id) : id, 21 | numberOfNodesPerKBucket: KBUCKET_SIZE, 22 | numberOfNodesToPing: KBUCKET_CONCURRENCY 23 | }) 24 | 25 | this._kbucket.on('added', (peer: any) => { 26 | KBucket.getKeys(peer).forEach(key => this._peers.set(key, peer)) 27 | this.emit('added', peer) 28 | }) 29 | 30 | this._kbucket.on('removed', (peer: any) => { 31 | KBucket.getKeys(peer).forEach(key => this._peers.delete(key)) 32 | this.emit('removed', peer) 33 | }) 34 | 35 | this._kbucket.on('ping', (...args: any[]) => this.emit('ping', ...args)) 36 | } 37 | 38 | static getKeys(obj: Buffer | string | KObj): string[] { 39 | if (Buffer.isBuffer(obj)) return [obj.toString('hex')] 40 | if (typeof obj === 'string') return [obj] 41 | 42 | const keys = [] 43 | if (Buffer.isBuffer(obj.id)) keys.push(obj.id.toString('hex')) 44 | if (obj.address && obj.port) keys.push(`${obj.address}:${obj.port}`) 45 | return keys 46 | } 47 | 48 | add(peer: any) { 49 | const isExists = KBucket.getKeys(peer).some(key => this._peers.has(key)) 50 | if (!isExists) this._kbucket.add(peer) 51 | } 52 | 53 | get(obj: Buffer | string | KObj) { 54 | for (const key of KBucket.getKeys(obj)) { 55 | const peer = this._peers.get(key) 56 | if (peer !== undefined) return peer 57 | } 58 | 59 | return null 60 | } 61 | 62 | getAll(): Array { 63 | return this._kbucket.toArray() 64 | } 65 | 66 | closest(id: string): any { 67 | return this._kbucket.closest(Buffer.from(id), KBUCKET_SIZE) 68 | } 69 | 70 | remove(obj: Buffer | string | KObj) { 71 | const peer = this.get(obj) 72 | if (peer !== null) this._kbucket.remove(peer.id) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /docs/modules/_rlpx_index_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "rlpx/index" 4 | 5 | # Module: "rlpx/index" 6 | 7 | ## Index 8 | 9 | ### Enumerations 10 | 11 | * [DISCONNECT\_REASONS](../enums/_rlpx_index_.disconnect_reasons.md) 12 | * [PREFIXES](../enums/_rlpx_index_.prefixes.md) 13 | 14 | ### Classes 15 | 16 | * [ECIES](../classes/_rlpx_index_.ecies.md) 17 | * [MAC](../classes/_rlpx_index_.mac.md) 18 | * [Peer](../classes/_rlpx_index_.peer.md) 19 | * [RLPx](../classes/_rlpx_index_.rlpx.md) 20 | 21 | ### Interfaces 22 | 23 | * [Capabilities](../interfaces/_rlpx_index_.capabilities.md) 24 | * [Hello](../interfaces/_rlpx_index_.hello.md) 25 | * [ProtocolConstructor](../interfaces/_rlpx_index_.protocolconstructor.md) 26 | * [ProtocolDescriptor](../interfaces/_rlpx_index_.protocoldescriptor.md) 27 | * [RLPxOptions](../interfaces/_rlpx_index_.rlpxoptions.md) 28 | 29 | ### Type aliases 30 | 31 | * [HelloMsg](_rlpx_index_.md#hellomsg) 32 | 33 | ### Variables 34 | 35 | * [BASE\_PROTOCOL\_LENGTH](_rlpx_index_.md#base_protocol_length) 36 | * [BASE\_PROTOCOL\_VERSION](_rlpx_index_.md#base_protocol_version) 37 | * [PING\_INTERVAL](_rlpx_index_.md#ping_interval) 38 | 39 | ## Type aliases 40 | 41 | ### HelloMsg 42 | 43 | Ƭ **HelloMsg**: { 0: Buffer ; 1: Buffer ; 2: Buffer[][] ; 3: Buffer ; 4: Buffer ; length: 5 } 44 | 45 | *Defined in [src/rlpx/peer.ts:43](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L43)* 46 | 47 | #### Type declaration: 48 | 49 | Name | Type | 50 | ------ | ------ | 51 | `0` | Buffer | 52 | `1` | Buffer | 53 | `2` | Buffer[][] | 54 | `3` | Buffer | 55 | `4` | Buffer | 56 | `length` | 5 | 57 | 58 | ## Variables 59 | 60 | ### BASE\_PROTOCOL\_LENGTH 61 | 62 | • `Const` **BASE\_PROTOCOL\_LENGTH**: 16 = 16 63 | 64 | *Defined in [src/rlpx/peer.ts:16](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L16)* 65 | 66 | ___ 67 | 68 | ### BASE\_PROTOCOL\_VERSION 69 | 70 | • `Const` **BASE\_PROTOCOL\_VERSION**: 4 = 4 71 | 72 | *Defined in [src/rlpx/peer.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L15)* 73 | 74 | ___ 75 | 76 | ### PING\_INTERVAL 77 | 78 | • `Const` **PING\_INTERVAL**: number = ms('15s') 79 | 80 | *Defined in [src/rlpx/peer.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L18)* 81 | -------------------------------------------------------------------------------- /docs/classes/_index_.mac.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / MAC 4 | 5 | # Class: MAC 6 | 7 | ## Hierarchy 8 | 9 | * **MAC** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_index_.mac.md#constructor) 16 | 17 | ### Properties 18 | 19 | * [\_hash](_index_.mac.md#_hash) 20 | * [\_secret](_index_.mac.md#_secret) 21 | 22 | ### Methods 23 | 24 | * [digest](_index_.mac.md#digest) 25 | * [update](_index_.mac.md#update) 26 | * [updateBody](_index_.mac.md#updatebody) 27 | * [updateHeader](_index_.mac.md#updateheader) 28 | 29 | ## Constructors 30 | 31 | ### constructor 32 | 33 | \+ **new MAC**(`secret`: Buffer): [MAC](_index_.mac.md) 34 | 35 | *Defined in [src/rlpx/mac.ts:7](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L7)* 36 | 37 | #### Parameters: 38 | 39 | Name | Type | 40 | ------ | ------ | 41 | `secret` | Buffer | 42 | 43 | **Returns:** [MAC](_index_.mac.md) 44 | 45 | ## Properties 46 | 47 | ### \_hash 48 | 49 | • **\_hash**: any 50 | 51 | *Defined in [src/rlpx/mac.ts:6](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L6)* 52 | 53 | ___ 54 | 55 | ### \_secret 56 | 57 | • **\_secret**: Buffer 58 | 59 | *Defined in [src/rlpx/mac.ts:7](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L7)* 60 | 61 | ## Methods 62 | 63 | ### digest 64 | 65 | ▸ **digest**(): any 66 | 67 | *Defined in [src/rlpx/mac.ts:31](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L31)* 68 | 69 | **Returns:** any 70 | 71 | ___ 72 | 73 | ### update 74 | 75 | ▸ **update**(`data`: Buffer \| string): void 76 | 77 | *Defined in [src/rlpx/mac.ts:13](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L13)* 78 | 79 | #### Parameters: 80 | 81 | Name | Type | 82 | ------ | ------ | 83 | `data` | Buffer \| string | 84 | 85 | **Returns:** void 86 | 87 | ___ 88 | 89 | ### updateBody 90 | 91 | ▸ **updateBody**(`data`: Buffer \| string): void 92 | 93 | *Defined in [src/rlpx/mac.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L23)* 94 | 95 | #### Parameters: 96 | 97 | Name | Type | 98 | ------ | ------ | 99 | `data` | Buffer \| string | 100 | 101 | **Returns:** void 102 | 103 | ___ 104 | 105 | ### updateHeader 106 | 107 | ▸ **updateHeader**(`data`: Buffer \| string): void 108 | 109 | *Defined in [src/rlpx/mac.ts:17](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L17)* 110 | 111 | #### Parameters: 112 | 113 | Name | Type | 114 | ------ | ------ | 115 | `data` | Buffer \| string | 116 | 117 | **Returns:** void 118 | -------------------------------------------------------------------------------- /docs/classes/_rlpx_mac_.mac.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/mac"](../modules/_rlpx_mac_.md) / MAC 4 | 5 | # Class: MAC 6 | 7 | ## Hierarchy 8 | 9 | * **MAC** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_rlpx_mac_.mac.md#constructor) 16 | 17 | ### Properties 18 | 19 | * [\_hash](_rlpx_mac_.mac.md#_hash) 20 | * [\_secret](_rlpx_mac_.mac.md#_secret) 21 | 22 | ### Methods 23 | 24 | * [digest](_rlpx_mac_.mac.md#digest) 25 | * [update](_rlpx_mac_.mac.md#update) 26 | * [updateBody](_rlpx_mac_.mac.md#updatebody) 27 | * [updateHeader](_rlpx_mac_.mac.md#updateheader) 28 | 29 | ## Constructors 30 | 31 | ### constructor 32 | 33 | \+ **new MAC**(`secret`: Buffer): [MAC](_rlpx_mac_.mac.md) 34 | 35 | *Defined in [src/rlpx/mac.ts:7](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L7)* 36 | 37 | #### Parameters: 38 | 39 | Name | Type | 40 | ------ | ------ | 41 | `secret` | Buffer | 42 | 43 | **Returns:** [MAC](_rlpx_mac_.mac.md) 44 | 45 | ## Properties 46 | 47 | ### \_hash 48 | 49 | • **\_hash**: any 50 | 51 | *Defined in [src/rlpx/mac.ts:6](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L6)* 52 | 53 | ___ 54 | 55 | ### \_secret 56 | 57 | • **\_secret**: Buffer 58 | 59 | *Defined in [src/rlpx/mac.ts:7](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L7)* 60 | 61 | ## Methods 62 | 63 | ### digest 64 | 65 | ▸ **digest**(): any 66 | 67 | *Defined in [src/rlpx/mac.ts:31](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L31)* 68 | 69 | **Returns:** any 70 | 71 | ___ 72 | 73 | ### update 74 | 75 | ▸ **update**(`data`: Buffer \| string): void 76 | 77 | *Defined in [src/rlpx/mac.ts:13](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L13)* 78 | 79 | #### Parameters: 80 | 81 | Name | Type | 82 | ------ | ------ | 83 | `data` | Buffer \| string | 84 | 85 | **Returns:** void 86 | 87 | ___ 88 | 89 | ### updateBody 90 | 91 | ▸ **updateBody**(`data`: Buffer \| string): void 92 | 93 | *Defined in [src/rlpx/mac.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L23)* 94 | 95 | #### Parameters: 96 | 97 | Name | Type | 98 | ------ | ------ | 99 | `data` | Buffer \| string | 100 | 101 | **Returns:** void 102 | 103 | ___ 104 | 105 | ### updateHeader 106 | 107 | ▸ **updateHeader**(`data`: Buffer \| string): void 108 | 109 | *Defined in [src/rlpx/mac.ts:17](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L17)* 110 | 111 | #### Parameters: 112 | 113 | Name | Type | 114 | ------ | ------ | 115 | `data` | Buffer \| string | 116 | 117 | **Returns:** void 118 | -------------------------------------------------------------------------------- /docs/classes/_rlpx_index_.mac.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / MAC 4 | 5 | # Class: MAC 6 | 7 | ## Hierarchy 8 | 9 | * **MAC** 10 | 11 | ## Index 12 | 13 | ### Constructors 14 | 15 | * [constructor](_rlpx_index_.mac.md#constructor) 16 | 17 | ### Properties 18 | 19 | * [\_hash](_rlpx_index_.mac.md#_hash) 20 | * [\_secret](_rlpx_index_.mac.md#_secret) 21 | 22 | ### Methods 23 | 24 | * [digest](_rlpx_index_.mac.md#digest) 25 | * [update](_rlpx_index_.mac.md#update) 26 | * [updateBody](_rlpx_index_.mac.md#updatebody) 27 | * [updateHeader](_rlpx_index_.mac.md#updateheader) 28 | 29 | ## Constructors 30 | 31 | ### constructor 32 | 33 | \+ **new MAC**(`secret`: Buffer): [MAC](_rlpx_index_.mac.md) 34 | 35 | *Defined in [src/rlpx/mac.ts:7](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L7)* 36 | 37 | #### Parameters: 38 | 39 | Name | Type | 40 | ------ | ------ | 41 | `secret` | Buffer | 42 | 43 | **Returns:** [MAC](_rlpx_index_.mac.md) 44 | 45 | ## Properties 46 | 47 | ### \_hash 48 | 49 | • **\_hash**: any 50 | 51 | *Defined in [src/rlpx/mac.ts:6](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L6)* 52 | 53 | ___ 54 | 55 | ### \_secret 56 | 57 | • **\_secret**: Buffer 58 | 59 | *Defined in [src/rlpx/mac.ts:7](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L7)* 60 | 61 | ## Methods 62 | 63 | ### digest 64 | 65 | ▸ **digest**(): any 66 | 67 | *Defined in [src/rlpx/mac.ts:31](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L31)* 68 | 69 | **Returns:** any 70 | 71 | ___ 72 | 73 | ### update 74 | 75 | ▸ **update**(`data`: Buffer \| string): void 76 | 77 | *Defined in [src/rlpx/mac.ts:13](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L13)* 78 | 79 | #### Parameters: 80 | 81 | Name | Type | 82 | ------ | ------ | 83 | `data` | Buffer \| string | 84 | 85 | **Returns:** void 86 | 87 | ___ 88 | 89 | ### updateBody 90 | 91 | ▸ **updateBody**(`data`: Buffer \| string): void 92 | 93 | *Defined in [src/rlpx/mac.ts:23](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L23)* 94 | 95 | #### Parameters: 96 | 97 | Name | Type | 98 | ------ | ------ | 99 | `data` | Buffer \| string | 100 | 101 | **Returns:** void 102 | 103 | ___ 104 | 105 | ### updateHeader 106 | 107 | ▸ **updateHeader**(`data`: Buffer \| string): void 108 | 109 | *Defined in [src/rlpx/mac.ts:17](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/mac.ts#L17)* 110 | 111 | #### Parameters: 112 | 113 | Name | Type | 114 | ------ | ------ | 115 | `data` | Buffer \| string | 116 | 117 | **Returns:** void 118 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ethereumjs-devp2p", 3 | "version": "3.0.3", 4 | "description": "A JavaScript implementation of ÐΞVp2p", 5 | "keywords": [ 6 | "ethereum", 7 | "p2p", 8 | "networking", 9 | "dpt", 10 | "rlpx", 11 | "eth", 12 | "eth62", 13 | "eth63", 14 | "les", 15 | "les2" 16 | ], 17 | "homepage": "https://github.com/ethereumjs/ethereumjs-devp2p", 18 | "bugs": { 19 | "url": "https://github.com/ethereumjs/ethereumjs-devp2p/issues" 20 | }, 21 | "license": "MIT", 22 | "contributors": [ 23 | "Alex Beregszaszi ", 24 | "Kirill Fomichev (https://github.com/fanatid)", 25 | "Martin Becze ", 26 | "Holger Drewes " 27 | ], 28 | "files": [ 29 | "dist/**/*.js", 30 | "dist/**/*.d.ts", 31 | "dist/**/*.map" 32 | ], 33 | "main": "dist/index.js", 34 | "husky": { 35 | "hooks": { 36 | "pre-push": "npm run lint" 37 | } 38 | }, 39 | "repository": { 40 | "type": "git", 41 | "url": "https://github.com/ethereumjs/ethereumjs-devp2p.git" 42 | }, 43 | "engines": { 44 | "node": ">=10.0" 45 | }, 46 | "scripts": { 47 | "build": "ethereumjs-config-ts-build", 48 | "prepublishOnly": "npm run test && npm run build", 49 | "coverage": "nyc --reporter=lcov npm run test", 50 | "docs:build": "typedoc", 51 | "format": "ethereumjs-config-format", 52 | "format:fix": "ethereumjs-config-format-fix", 53 | "tsc": "ethereumjs-config-tsc", 54 | "lint": "ethereumjs-config-lint", 55 | "lint:fix": "ethereumjs-config-lint-fix", 56 | "test": "node_modules/tape/bin/tape -r ts-node/register ./test/index.ts" 57 | }, 58 | "dependencies": { 59 | "@types/bl": "^2.1.0", 60 | "@types/k-bucket": "^5.0.0", 61 | "@types/lru-cache": "^5.1.0", 62 | "@ethereumjs/common": "^2.0.0-beta.2", 63 | "babel-runtime": "^6.11.6", 64 | "bl": "^1.1.2", 65 | "debug": "^2.2.0", 66 | "inherits": "^2.0.1", 67 | "ip": "^1.1.3", 68 | "k-bucket": "^5.0.0", 69 | "keccak": "^3.0.1", 70 | "lru-cache": "^5.1.1", 71 | "ms": "^0.7.1", 72 | "rlp": "^2.2.6", 73 | "secp256k1": "^4.0.2" 74 | }, 75 | "devDependencies": { 76 | "@ethereumjs/block": "^3.0.0-beta.1", 77 | "@ethereumjs/config-coverage": "^2.0.0", 78 | "@ethereumjs/config-typescript": "^2.0.0", 79 | "@ethereumjs/eslint-config-defaults": "^2.0.0", 80 | "@ethereumjs/tx": "^3.0.0-beta.1", 81 | "@types/async": "^2.4.1", 82 | "@types/chalk": "^2.2.0", 83 | "@types/debug": "^4.1.4", 84 | "@types/ip": "^1.1.0", 85 | "@types/keccak": "^3.0.1", 86 | "@types/ms": "^0.7.30", 87 | "@types/secp256k1": "^4.0.1", 88 | "@types/tape": "^4.2.33", 89 | "async": "^2.6.0", 90 | "chalk": "^2.4.2", 91 | "husky": "^2.1.0", 92 | "nyc": "^15.0.0", 93 | "prettier": "^1.17.0", 94 | "tape": "^4.5.1", 95 | "ts-node": "^8.1.0", 96 | "typedoc": "next", 97 | "typedoc-plugin-markdown": "^3.0.11", 98 | "typescript": "^3.9.7" 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /test/integration/rlpx-simulator.ts: -------------------------------------------------------------------------------- 1 | import async from 'async' 2 | import test from 'tape' 3 | import * as util from './util' 4 | import { DISCONNECT_REASONS } from '../../src/rlpx/peer' 5 | 6 | test('RLPX: add working node', async t => { 7 | const rlpxs = util.initTwoPeerRLPXSetup() 8 | 9 | rlpxs[0].on('peer:added', function(peer: any) { 10 | t.equal(peer._port, 30306, 'should have added peer on peer:added after successful handshake') 11 | t.equal(rlpxs[0].getPeers().length, 1, 'peer list length should be 1') 12 | t.equal(rlpxs[0]._getOpenSlots(), 9, 'should have maxPeers - 1 open slots left') 13 | util.destroyRLPXs(rlpxs) 14 | t.end() 15 | }) 16 | }) 17 | 18 | test('RLPX: ban node with missing tcp port', async t => { 19 | const rlpxs = util.initTwoPeerRLPXSetup() 20 | rlpxs[0].on('peer:added', function() { 21 | const peer = { 22 | id: Buffer.from('abcd', 'hex'), 23 | address: '127.0.0.1', 24 | udpPort: 30308, 25 | tcpPort: null 26 | } 27 | t.notOk(rlpxs[0]._dpt.banlist.has(peer), 'should not be in ban list before bad peer discovered') 28 | rlpxs[0]._dpt.emit('peer:new', peer) 29 | t.ok(rlpxs[0]._dpt.banlist.has(peer), 'should be in ban list after bad peer discovered') 30 | util.destroyRLPXs(rlpxs) 31 | t.end() 32 | }) 33 | }) 34 | 35 | test('RLPX: remove node', async t => { 36 | const rlpxs = util.initTwoPeerRLPXSetup() 37 | 38 | async.series( 39 | [ 40 | function(cb) { 41 | rlpxs[0].on('peer:added', function(peer: any) { 42 | rlpxs[0].disconnect(peer._remoteId) 43 | cb(null) 44 | }) 45 | }, 46 | function(cb) { 47 | rlpxs[0].on('peer:removed', function(peer: any, reason: any) { 48 | t.equal( 49 | reason, 50 | DISCONNECT_REASONS.CLIENT_QUITTING, 51 | 'should close with CLIENT_QUITTING disconnect reason' 52 | ) 53 | t.equal(rlpxs[0]._getOpenSlots(), 10, 'should have maxPeers open slots left') 54 | cb(null) 55 | }) 56 | } 57 | ], 58 | function(err) { 59 | if (err) { 60 | t.fail('An unexpected error occured.') 61 | } 62 | util.destroyRLPXs(rlpxs) 63 | t.end() 64 | } 65 | ) 66 | }) 67 | 68 | test('RLPX: test peer queue / refill connections', async t => { 69 | const rlpxs = util.getTestRLPXs(3, 1) 70 | 71 | const peer = { address: util.localhost, udpPort: util.basePort + 1, tcpPort: util.basePort + 1 } 72 | rlpxs[0]._dpt.addPeer(peer) 73 | 74 | async.series( 75 | [ 76 | function(cb) { 77 | rlpxs[0].once('peer:added', function() { 78 | t.equal(rlpxs[0]._peersQueue.length, 0, 'peers queue should contain no peers') 79 | const peer2 = { 80 | address: util.localhost, 81 | udpPort: util.basePort + 2, 82 | tcpPort: util.basePort + 2 83 | } 84 | rlpxs[0]._dpt.addPeer(peer2) 85 | cb(null) 86 | }) 87 | }, 88 | function(cb) { 89 | rlpxs[0].once('peer:added', function() { 90 | // FIXME: values not as expected 91 | // t.equal(rlpxs[0]._peersQueue.length, 1, 'peers queue should contain one peer') 92 | cb(null) 93 | }) 94 | } 95 | ], 96 | function(err) { 97 | if (err) { 98 | t.fail('An unexpected error occured.') 99 | } 100 | util.destroyRLPXs(rlpxs) 101 | t.end() 102 | } 103 | ) 104 | }) 105 | -------------------------------------------------------------------------------- /docs/enums/_index_.eth.message_codes.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / [ETH](../classes/_index_.eth.md) / MESSAGE\_CODES 4 | 5 | # Enumeration: MESSAGE\_CODES 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [BLOCK\_BODIES](_index_.eth.message_codes.md#block_bodies) 12 | * [BLOCK\_HEADERS](_index_.eth.message_codes.md#block_headers) 13 | * [GET\_BLOCK\_BODIES](_index_.eth.message_codes.md#get_block_bodies) 14 | * [GET\_BLOCK\_HEADERS](_index_.eth.message_codes.md#get_block_headers) 15 | * [GET\_NODE\_DATA](_index_.eth.message_codes.md#get_node_data) 16 | * [GET\_RECEIPTS](_index_.eth.message_codes.md#get_receipts) 17 | * [NEW\_BLOCK](_index_.eth.message_codes.md#new_block) 18 | * [NEW\_BLOCK\_HASHES](_index_.eth.message_codes.md#new_block_hashes) 19 | * [NODE\_DATA](_index_.eth.message_codes.md#node_data) 20 | * [RECEIPTS](_index_.eth.message_codes.md#receipts) 21 | * [STATUS](_index_.eth.message_codes.md#status) 22 | * [TX](_index_.eth.message_codes.md#tx) 23 | 24 | ## Enumeration members 25 | 26 | ### BLOCK\_BODIES 27 | 28 | • **BLOCK\_BODIES**: = 6 29 | 30 | *Defined in [src/eth/index.ts:199](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L199)* 31 | 32 | ___ 33 | 34 | ### BLOCK\_HEADERS 35 | 36 | • **BLOCK\_HEADERS**: = 4 37 | 38 | *Defined in [src/eth/index.ts:197](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L197)* 39 | 40 | ___ 41 | 42 | ### GET\_BLOCK\_BODIES 43 | 44 | • **GET\_BLOCK\_BODIES**: = 5 45 | 46 | *Defined in [src/eth/index.ts:198](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L198)* 47 | 48 | ___ 49 | 50 | ### GET\_BLOCK\_HEADERS 51 | 52 | • **GET\_BLOCK\_HEADERS**: = 3 53 | 54 | *Defined in [src/eth/index.ts:196](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L196)* 55 | 56 | ___ 57 | 58 | ### GET\_NODE\_DATA 59 | 60 | • **GET\_NODE\_DATA**: = 13 61 | 62 | *Defined in [src/eth/index.ts:203](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L203)* 63 | 64 | ___ 65 | 66 | ### GET\_RECEIPTS 67 | 68 | • **GET\_RECEIPTS**: = 15 69 | 70 | *Defined in [src/eth/index.ts:205](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L205)* 71 | 72 | ___ 73 | 74 | ### NEW\_BLOCK 75 | 76 | • **NEW\_BLOCK**: = 7 77 | 78 | *Defined in [src/eth/index.ts:200](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L200)* 79 | 80 | ___ 81 | 82 | ### NEW\_BLOCK\_HASHES 83 | 84 | • **NEW\_BLOCK\_HASHES**: = 1 85 | 86 | *Defined in [src/eth/index.ts:194](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L194)* 87 | 88 | ___ 89 | 90 | ### NODE\_DATA 91 | 92 | • **NODE\_DATA**: = 14 93 | 94 | *Defined in [src/eth/index.ts:204](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L204)* 95 | 96 | ___ 97 | 98 | ### RECEIPTS 99 | 100 | • **RECEIPTS**: = 16 101 | 102 | *Defined in [src/eth/index.ts:206](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L206)* 103 | 104 | ___ 105 | 106 | ### STATUS 107 | 108 | • **STATUS**: = 0 109 | 110 | *Defined in [src/eth/index.ts:193](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L193)* 111 | 112 | ___ 113 | 114 | ### TX 115 | 116 | • **TX**: = 2 117 | 118 | *Defined in [src/eth/index.ts:195](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L195)* 119 | -------------------------------------------------------------------------------- /docs/enums/_eth_index_.eth.message_codes.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["eth/index"](../modules/_eth_index_.md) / [ETH](../classes/_eth_index_.eth.md) / MESSAGE\_CODES 4 | 5 | # Enumeration: MESSAGE\_CODES 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [BLOCK\_BODIES](_eth_index_.eth.message_codes.md#block_bodies) 12 | * [BLOCK\_HEADERS](_eth_index_.eth.message_codes.md#block_headers) 13 | * [GET\_BLOCK\_BODIES](_eth_index_.eth.message_codes.md#get_block_bodies) 14 | * [GET\_BLOCK\_HEADERS](_eth_index_.eth.message_codes.md#get_block_headers) 15 | * [GET\_NODE\_DATA](_eth_index_.eth.message_codes.md#get_node_data) 16 | * [GET\_RECEIPTS](_eth_index_.eth.message_codes.md#get_receipts) 17 | * [NEW\_BLOCK](_eth_index_.eth.message_codes.md#new_block) 18 | * [NEW\_BLOCK\_HASHES](_eth_index_.eth.message_codes.md#new_block_hashes) 19 | * [NODE\_DATA](_eth_index_.eth.message_codes.md#node_data) 20 | * [RECEIPTS](_eth_index_.eth.message_codes.md#receipts) 21 | * [STATUS](_eth_index_.eth.message_codes.md#status) 22 | * [TX](_eth_index_.eth.message_codes.md#tx) 23 | 24 | ## Enumeration members 25 | 26 | ### BLOCK\_BODIES 27 | 28 | • **BLOCK\_BODIES**: = 6 29 | 30 | *Defined in [src/eth/index.ts:199](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L199)* 31 | 32 | ___ 33 | 34 | ### BLOCK\_HEADERS 35 | 36 | • **BLOCK\_HEADERS**: = 4 37 | 38 | *Defined in [src/eth/index.ts:197](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L197)* 39 | 40 | ___ 41 | 42 | ### GET\_BLOCK\_BODIES 43 | 44 | • **GET\_BLOCK\_BODIES**: = 5 45 | 46 | *Defined in [src/eth/index.ts:198](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L198)* 47 | 48 | ___ 49 | 50 | ### GET\_BLOCK\_HEADERS 51 | 52 | • **GET\_BLOCK\_HEADERS**: = 3 53 | 54 | *Defined in [src/eth/index.ts:196](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L196)* 55 | 56 | ___ 57 | 58 | ### GET\_NODE\_DATA 59 | 60 | • **GET\_NODE\_DATA**: = 13 61 | 62 | *Defined in [src/eth/index.ts:203](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L203)* 63 | 64 | ___ 65 | 66 | ### GET\_RECEIPTS 67 | 68 | • **GET\_RECEIPTS**: = 15 69 | 70 | *Defined in [src/eth/index.ts:205](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L205)* 71 | 72 | ___ 73 | 74 | ### NEW\_BLOCK 75 | 76 | • **NEW\_BLOCK**: = 7 77 | 78 | *Defined in [src/eth/index.ts:200](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L200)* 79 | 80 | ___ 81 | 82 | ### NEW\_BLOCK\_HASHES 83 | 84 | • **NEW\_BLOCK\_HASHES**: = 1 85 | 86 | *Defined in [src/eth/index.ts:194](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L194)* 87 | 88 | ___ 89 | 90 | ### NODE\_DATA 91 | 92 | • **NODE\_DATA**: = 14 93 | 94 | *Defined in [src/eth/index.ts:204](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L204)* 95 | 96 | ___ 97 | 98 | ### RECEIPTS 99 | 100 | • **RECEIPTS**: = 16 101 | 102 | *Defined in [src/eth/index.ts:206](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L206)* 103 | 104 | ___ 105 | 106 | ### STATUS 107 | 108 | • **STATUS**: = 0 109 | 110 | *Defined in [src/eth/index.ts:193](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L193)* 111 | 112 | ___ 113 | 114 | ### TX 115 | 116 | • **TX**: = 2 117 | 118 | *Defined in [src/eth/index.ts:195](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L195)* 119 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert' 2 | import { randomBytes } from 'crypto' 3 | import { privateKeyVerify, publicKeyConvert } from 'secp256k1' 4 | import createKeccakHash from 'keccak' 5 | import { decode } from 'rlp' 6 | 7 | export function keccak256(...buffers: Buffer[]) { 8 | const buffer = Buffer.concat(buffers) 9 | return createKeccakHash('keccak256') 10 | .update(buffer) 11 | .digest() 12 | } 13 | 14 | export function genPrivateKey(): Buffer { 15 | const privateKey = randomBytes(32) 16 | return privateKeyVerify(privateKey) ? privateKey : genPrivateKey() 17 | } 18 | 19 | export function pk2id(pk: Buffer): Buffer { 20 | if (pk.length === 33) { 21 | pk = Buffer.from(publicKeyConvert(pk, false)) 22 | } 23 | return pk.slice(1) 24 | } 25 | 26 | export function id2pk(id: Buffer): Buffer { 27 | return Buffer.concat([Buffer.from([0x04]), id]) 28 | } 29 | 30 | export function int2buffer(v: number): Buffer { 31 | let hex = v.toString(16) 32 | if (hex.length % 2 === 1) hex = '0' + hex 33 | return Buffer.from(hex, 'hex') 34 | } 35 | 36 | export function buffer2int(buffer: Buffer): number { 37 | if (buffer.length === 0) return NaN 38 | 39 | let n = 0 40 | for (let i = 0; i < buffer.length; ++i) n = n * 256 + buffer[i] 41 | return n 42 | } 43 | 44 | export function zfill(buffer: Buffer, size: number, leftpad: boolean = true): Buffer { 45 | if (buffer.length >= size) return buffer 46 | if (leftpad === undefined) leftpad = true 47 | const pad = Buffer.allocUnsafe(size - buffer.length).fill(0x00) 48 | return leftpad ? Buffer.concat([pad, buffer]) : Buffer.concat([buffer, pad]) 49 | } 50 | 51 | export function xor(a: Buffer, b: any): Buffer { 52 | const length = Math.min(a.length, b.length) 53 | const buffer = Buffer.allocUnsafe(length) 54 | for (let i = 0; i < length; ++i) buffer[i] = a[i] ^ b[i] 55 | return buffer 56 | } 57 | 58 | export function assertEq(expected: any, actual: any, msg: string, debug: any): void { 59 | let message 60 | if (Buffer.isBuffer(expected) && Buffer.isBuffer(actual)) { 61 | if (expected.equals(actual)) return 62 | message = `${msg}: ${expected.toString('hex')} / ${actual.toString('hex')}` 63 | debug(`[ERROR] ${message}`) 64 | throw new assert.AssertionError({ 65 | message: message 66 | }) 67 | } 68 | 69 | if (expected === actual) return 70 | message = `${msg}: ${expected} / ${actual}` 71 | debug(message) 72 | throw new assert.AssertionError({ 73 | message: message 74 | }) 75 | } 76 | 77 | export function formatLogId(id: string, verbose: boolean): string { 78 | const numChars = 7 79 | if (verbose) { 80 | return id 81 | } else { 82 | return `${id.substring(0, numChars)}` 83 | } 84 | } 85 | 86 | export function formatLogData(data: string, verbose: boolean): string { 87 | const maxChars = 60 88 | if (verbose || data.length <= maxChars) { 89 | return data 90 | } else { 91 | return `${data.substring(0, maxChars)}...` 92 | } 93 | } 94 | 95 | export class Deferred { 96 | promise: Promise 97 | resolve: (...args: any[]) => any = () => {} 98 | reject: (...args: any[]) => any = () => {} 99 | constructor() { 100 | this.promise = new Promise((resolve, reject) => { 101 | this.resolve = resolve 102 | this.reject = reject 103 | }) 104 | } 105 | } 106 | 107 | export function createDeferred(): Deferred { 108 | return new Deferred() 109 | } 110 | 111 | export function unstrictDecode(value: Buffer) { 112 | // rlp library throws on remainder.length !== 0 113 | // this utility function bypasses that 114 | return (decode(value, true) as any).data 115 | } 116 | -------------------------------------------------------------------------------- /docs/enums/_index_.disconnect_reasons.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / DISCONNECT\_REASONS 4 | 5 | # Enumeration: DISCONNECT\_REASONS 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [ALREADY\_CONNECTED](_index_.disconnect_reasons.md#already_connected) 12 | * [CLIENT\_QUITTING](_index_.disconnect_reasons.md#client_quitting) 13 | * [DISCONNECT\_REQUESTED](_index_.disconnect_reasons.md#disconnect_requested) 14 | * [INCOMPATIBLE\_VERSION](_index_.disconnect_reasons.md#incompatible_version) 15 | * [INVALID\_IDENTITY](_index_.disconnect_reasons.md#invalid_identity) 16 | * [NETWORK\_ERROR](_index_.disconnect_reasons.md#network_error) 17 | * [PROTOCOL\_ERROR](_index_.disconnect_reasons.md#protocol_error) 18 | * [SAME\_IDENTITY](_index_.disconnect_reasons.md#same_identity) 19 | * [SUBPROTOCOL\_ERROR](_index_.disconnect_reasons.md#subprotocol_error) 20 | * [TIMEOUT](_index_.disconnect_reasons.md#timeout) 21 | * [TOO\_MANY\_PEERS](_index_.disconnect_reasons.md#too_many_peers) 22 | * [UNEXPECTED\_IDENTITY](_index_.disconnect_reasons.md#unexpected_identity) 23 | * [USELESS\_PEER](_index_.disconnect_reasons.md#useless_peer) 24 | 25 | ## Enumeration members 26 | 27 | ### ALREADY\_CONNECTED 28 | 29 | • **ALREADY\_CONNECTED**: = 5 30 | 31 | *Defined in [src/rlpx/peer.ts:33](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L33)* 32 | 33 | ___ 34 | 35 | ### CLIENT\_QUITTING 36 | 37 | • **CLIENT\_QUITTING**: = 8 38 | 39 | *Defined in [src/rlpx/peer.ts:36](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L36)* 40 | 41 | ___ 42 | 43 | ### DISCONNECT\_REQUESTED 44 | 45 | • **DISCONNECT\_REQUESTED**: = 0 46 | 47 | *Defined in [src/rlpx/peer.ts:28](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L28)* 48 | 49 | ___ 50 | 51 | ### INCOMPATIBLE\_VERSION 52 | 53 | • **INCOMPATIBLE\_VERSION**: = 6 54 | 55 | *Defined in [src/rlpx/peer.ts:34](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L34)* 56 | 57 | ___ 58 | 59 | ### INVALID\_IDENTITY 60 | 61 | • **INVALID\_IDENTITY**: = 7 62 | 63 | *Defined in [src/rlpx/peer.ts:35](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L35)* 64 | 65 | ___ 66 | 67 | ### NETWORK\_ERROR 68 | 69 | • **NETWORK\_ERROR**: = 1 70 | 71 | *Defined in [src/rlpx/peer.ts:29](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L29)* 72 | 73 | ___ 74 | 75 | ### PROTOCOL\_ERROR 76 | 77 | • **PROTOCOL\_ERROR**: = 2 78 | 79 | *Defined in [src/rlpx/peer.ts:30](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L30)* 80 | 81 | ___ 82 | 83 | ### SAME\_IDENTITY 84 | 85 | • **SAME\_IDENTITY**: = 10 86 | 87 | *Defined in [src/rlpx/peer.ts:38](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L38)* 88 | 89 | ___ 90 | 91 | ### SUBPROTOCOL\_ERROR 92 | 93 | • **SUBPROTOCOL\_ERROR**: = 16 94 | 95 | *Defined in [src/rlpx/peer.ts:40](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L40)* 96 | 97 | ___ 98 | 99 | ### TIMEOUT 100 | 101 | • **TIMEOUT**: = 11 102 | 103 | *Defined in [src/rlpx/peer.ts:39](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L39)* 104 | 105 | ___ 106 | 107 | ### TOO\_MANY\_PEERS 108 | 109 | • **TOO\_MANY\_PEERS**: = 4 110 | 111 | *Defined in [src/rlpx/peer.ts:32](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L32)* 112 | 113 | ___ 114 | 115 | ### UNEXPECTED\_IDENTITY 116 | 117 | • **UNEXPECTED\_IDENTITY**: = 9 118 | 119 | *Defined in [src/rlpx/peer.ts:37](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L37)* 120 | 121 | ___ 122 | 123 | ### USELESS\_PEER 124 | 125 | • **USELESS\_PEER**: = 3 126 | 127 | *Defined in [src/rlpx/peer.ts:31](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L31)* 128 | -------------------------------------------------------------------------------- /docs/enums/_rlpx_peer_.disconnect_reasons.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/peer"](../modules/_rlpx_peer_.md) / DISCONNECT\_REASONS 4 | 5 | # Enumeration: DISCONNECT\_REASONS 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [ALREADY\_CONNECTED](_rlpx_peer_.disconnect_reasons.md#already_connected) 12 | * [CLIENT\_QUITTING](_rlpx_peer_.disconnect_reasons.md#client_quitting) 13 | * [DISCONNECT\_REQUESTED](_rlpx_peer_.disconnect_reasons.md#disconnect_requested) 14 | * [INCOMPATIBLE\_VERSION](_rlpx_peer_.disconnect_reasons.md#incompatible_version) 15 | * [INVALID\_IDENTITY](_rlpx_peer_.disconnect_reasons.md#invalid_identity) 16 | * [NETWORK\_ERROR](_rlpx_peer_.disconnect_reasons.md#network_error) 17 | * [PROTOCOL\_ERROR](_rlpx_peer_.disconnect_reasons.md#protocol_error) 18 | * [SAME\_IDENTITY](_rlpx_peer_.disconnect_reasons.md#same_identity) 19 | * [SUBPROTOCOL\_ERROR](_rlpx_peer_.disconnect_reasons.md#subprotocol_error) 20 | * [TIMEOUT](_rlpx_peer_.disconnect_reasons.md#timeout) 21 | * [TOO\_MANY\_PEERS](_rlpx_peer_.disconnect_reasons.md#too_many_peers) 22 | * [UNEXPECTED\_IDENTITY](_rlpx_peer_.disconnect_reasons.md#unexpected_identity) 23 | * [USELESS\_PEER](_rlpx_peer_.disconnect_reasons.md#useless_peer) 24 | 25 | ## Enumeration members 26 | 27 | ### ALREADY\_CONNECTED 28 | 29 | • **ALREADY\_CONNECTED**: = 5 30 | 31 | *Defined in [src/rlpx/peer.ts:33](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L33)* 32 | 33 | ___ 34 | 35 | ### CLIENT\_QUITTING 36 | 37 | • **CLIENT\_QUITTING**: = 8 38 | 39 | *Defined in [src/rlpx/peer.ts:36](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L36)* 40 | 41 | ___ 42 | 43 | ### DISCONNECT\_REQUESTED 44 | 45 | • **DISCONNECT\_REQUESTED**: = 0 46 | 47 | *Defined in [src/rlpx/peer.ts:28](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L28)* 48 | 49 | ___ 50 | 51 | ### INCOMPATIBLE\_VERSION 52 | 53 | • **INCOMPATIBLE\_VERSION**: = 6 54 | 55 | *Defined in [src/rlpx/peer.ts:34](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L34)* 56 | 57 | ___ 58 | 59 | ### INVALID\_IDENTITY 60 | 61 | • **INVALID\_IDENTITY**: = 7 62 | 63 | *Defined in [src/rlpx/peer.ts:35](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L35)* 64 | 65 | ___ 66 | 67 | ### NETWORK\_ERROR 68 | 69 | • **NETWORK\_ERROR**: = 1 70 | 71 | *Defined in [src/rlpx/peer.ts:29](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L29)* 72 | 73 | ___ 74 | 75 | ### PROTOCOL\_ERROR 76 | 77 | • **PROTOCOL\_ERROR**: = 2 78 | 79 | *Defined in [src/rlpx/peer.ts:30](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L30)* 80 | 81 | ___ 82 | 83 | ### SAME\_IDENTITY 84 | 85 | • **SAME\_IDENTITY**: = 10 86 | 87 | *Defined in [src/rlpx/peer.ts:38](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L38)* 88 | 89 | ___ 90 | 91 | ### SUBPROTOCOL\_ERROR 92 | 93 | • **SUBPROTOCOL\_ERROR**: = 16 94 | 95 | *Defined in [src/rlpx/peer.ts:40](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L40)* 96 | 97 | ___ 98 | 99 | ### TIMEOUT 100 | 101 | • **TIMEOUT**: = 11 102 | 103 | *Defined in [src/rlpx/peer.ts:39](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L39)* 104 | 105 | ___ 106 | 107 | ### TOO\_MANY\_PEERS 108 | 109 | • **TOO\_MANY\_PEERS**: = 4 110 | 111 | *Defined in [src/rlpx/peer.ts:32](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L32)* 112 | 113 | ___ 114 | 115 | ### UNEXPECTED\_IDENTITY 116 | 117 | • **UNEXPECTED\_IDENTITY**: = 9 118 | 119 | *Defined in [src/rlpx/peer.ts:37](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L37)* 120 | 121 | ___ 122 | 123 | ### USELESS\_PEER 124 | 125 | • **USELESS\_PEER**: = 3 126 | 127 | *Defined in [src/rlpx/peer.ts:31](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L31)* 128 | -------------------------------------------------------------------------------- /docs/enums/_rlpx_index_.disconnect_reasons.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["rlpx/index"](../modules/_rlpx_index_.md) / DISCONNECT\_REASONS 4 | 5 | # Enumeration: DISCONNECT\_REASONS 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [ALREADY\_CONNECTED](_rlpx_index_.disconnect_reasons.md#already_connected) 12 | * [CLIENT\_QUITTING](_rlpx_index_.disconnect_reasons.md#client_quitting) 13 | * [DISCONNECT\_REQUESTED](_rlpx_index_.disconnect_reasons.md#disconnect_requested) 14 | * [INCOMPATIBLE\_VERSION](_rlpx_index_.disconnect_reasons.md#incompatible_version) 15 | * [INVALID\_IDENTITY](_rlpx_index_.disconnect_reasons.md#invalid_identity) 16 | * [NETWORK\_ERROR](_rlpx_index_.disconnect_reasons.md#network_error) 17 | * [PROTOCOL\_ERROR](_rlpx_index_.disconnect_reasons.md#protocol_error) 18 | * [SAME\_IDENTITY](_rlpx_index_.disconnect_reasons.md#same_identity) 19 | * [SUBPROTOCOL\_ERROR](_rlpx_index_.disconnect_reasons.md#subprotocol_error) 20 | * [TIMEOUT](_rlpx_index_.disconnect_reasons.md#timeout) 21 | * [TOO\_MANY\_PEERS](_rlpx_index_.disconnect_reasons.md#too_many_peers) 22 | * [UNEXPECTED\_IDENTITY](_rlpx_index_.disconnect_reasons.md#unexpected_identity) 23 | * [USELESS\_PEER](_rlpx_index_.disconnect_reasons.md#useless_peer) 24 | 25 | ## Enumeration members 26 | 27 | ### ALREADY\_CONNECTED 28 | 29 | • **ALREADY\_CONNECTED**: = 5 30 | 31 | *Defined in [src/rlpx/peer.ts:33](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L33)* 32 | 33 | ___ 34 | 35 | ### CLIENT\_QUITTING 36 | 37 | • **CLIENT\_QUITTING**: = 8 38 | 39 | *Defined in [src/rlpx/peer.ts:36](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L36)* 40 | 41 | ___ 42 | 43 | ### DISCONNECT\_REQUESTED 44 | 45 | • **DISCONNECT\_REQUESTED**: = 0 46 | 47 | *Defined in [src/rlpx/peer.ts:28](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L28)* 48 | 49 | ___ 50 | 51 | ### INCOMPATIBLE\_VERSION 52 | 53 | • **INCOMPATIBLE\_VERSION**: = 6 54 | 55 | *Defined in [src/rlpx/peer.ts:34](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L34)* 56 | 57 | ___ 58 | 59 | ### INVALID\_IDENTITY 60 | 61 | • **INVALID\_IDENTITY**: = 7 62 | 63 | *Defined in [src/rlpx/peer.ts:35](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L35)* 64 | 65 | ___ 66 | 67 | ### NETWORK\_ERROR 68 | 69 | • **NETWORK\_ERROR**: = 1 70 | 71 | *Defined in [src/rlpx/peer.ts:29](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L29)* 72 | 73 | ___ 74 | 75 | ### PROTOCOL\_ERROR 76 | 77 | • **PROTOCOL\_ERROR**: = 2 78 | 79 | *Defined in [src/rlpx/peer.ts:30](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L30)* 80 | 81 | ___ 82 | 83 | ### SAME\_IDENTITY 84 | 85 | • **SAME\_IDENTITY**: = 10 86 | 87 | *Defined in [src/rlpx/peer.ts:38](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L38)* 88 | 89 | ___ 90 | 91 | ### SUBPROTOCOL\_ERROR 92 | 93 | • **SUBPROTOCOL\_ERROR**: = 16 94 | 95 | *Defined in [src/rlpx/peer.ts:40](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L40)* 96 | 97 | ___ 98 | 99 | ### TIMEOUT 100 | 101 | • **TIMEOUT**: = 11 102 | 103 | *Defined in [src/rlpx/peer.ts:39](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L39)* 104 | 105 | ___ 106 | 107 | ### TOO\_MANY\_PEERS 108 | 109 | • **TOO\_MANY\_PEERS**: = 4 110 | 111 | *Defined in [src/rlpx/peer.ts:32](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L32)* 112 | 113 | ___ 114 | 115 | ### UNEXPECTED\_IDENTITY 116 | 117 | • **UNEXPECTED\_IDENTITY**: = 9 118 | 119 | *Defined in [src/rlpx/peer.ts:37](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L37)* 120 | 121 | ___ 122 | 123 | ### USELESS\_PEER 124 | 125 | • **USELESS\_PEER**: = 3 126 | 127 | *Defined in [src/rlpx/peer.ts:31](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L31)* 128 | -------------------------------------------------------------------------------- /docs/interfaces/_index_.les.status.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / [LES](../classes/_index_.les.md) / Status 4 | 5 | # Interface: Status 6 | 7 | ## Hierarchy 8 | 9 | * **Status** 10 | 11 | ## Indexable 12 | 13 | ▪ [key: string]: Buffer \| number 14 | 15 | ## Index 16 | 17 | ### Properties 18 | 19 | * [announceType](_index_.les.status.md#announcetype) 20 | * [flowControl/BL](_index_.les.status.md#flowcontrol/bl) 21 | * [flowControl/MRC](_index_.les.status.md#flowcontrol/mrc) 22 | * [flowControl/MRR](_index_.les.status.md#flowcontrol/mrr) 23 | * [genesisHash](_index_.les.status.md#genesishash) 24 | * [headHash](_index_.les.status.md#headhash) 25 | * [headNum](_index_.les.status.md#headnum) 26 | * [headTd](_index_.les.status.md#headtd) 27 | * [networkId](_index_.les.status.md#networkid) 28 | * [protocolVersion](_index_.les.status.md#protocolversion) 29 | * [serveChainSince](_index_.les.status.md#servechainsince) 30 | * [serveHeaders](_index_.les.status.md#serveheaders) 31 | * [serveStateSince](_index_.les.status.md#servestatesince) 32 | * [txRelax](_index_.les.status.md#txrelax) 33 | 34 | ## Properties 35 | 36 | ### announceType 37 | 38 | • **announceType**: Buffer \| number 39 | 40 | *Defined in [src/les/index.ts:224](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L224)* 41 | 42 | ___ 43 | 44 | ### flowControl/BL 45 | 46 | • **flowControl/BL**: Buffer 47 | 48 | *Defined in [src/les/index.ts:221](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L221)* 49 | 50 | ___ 51 | 52 | ### flowControl/MRC 53 | 54 | • **flowControl/MRC**: Buffer 55 | 56 | *Defined in [src/les/index.ts:223](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L223)* 57 | 58 | ___ 59 | 60 | ### flowControl/MRR 61 | 62 | • **flowControl/MRR**: Buffer 63 | 64 | *Defined in [src/les/index.ts:222](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L222)* 65 | 66 | ___ 67 | 68 | ### genesisHash 69 | 70 | • **genesisHash**: Buffer 71 | 72 | *Defined in [src/les/index.ts:216](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L216)* 73 | 74 | ___ 75 | 76 | ### headHash 77 | 78 | • **headHash**: Buffer 79 | 80 | *Defined in [src/les/index.ts:214](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L214)* 81 | 82 | ___ 83 | 84 | ### headNum 85 | 86 | • **headNum**: Buffer 87 | 88 | *Defined in [src/les/index.ts:215](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L215)* 89 | 90 | ___ 91 | 92 | ### headTd 93 | 94 | • **headTd**: Buffer 95 | 96 | *Defined in [src/les/index.ts:213](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L213)* 97 | 98 | ___ 99 | 100 | ### networkId 101 | 102 | • **networkId**: Buffer \| number 103 | 104 | *Defined in [src/les/index.ts:212](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L212)* 105 | 106 | ___ 107 | 108 | ### protocolVersion 109 | 110 | • **protocolVersion**: Buffer 111 | 112 | *Defined in [src/les/index.ts:211](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L211)* 113 | 114 | ___ 115 | 116 | ### serveChainSince 117 | 118 | • **serveChainSince**: Buffer 119 | 120 | *Defined in [src/les/index.ts:218](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L218)* 121 | 122 | ___ 123 | 124 | ### serveHeaders 125 | 126 | • **serveHeaders**: Buffer 127 | 128 | *Defined in [src/les/index.ts:217](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L217)* 129 | 130 | ___ 131 | 132 | ### serveStateSince 133 | 134 | • **serveStateSince**: Buffer 135 | 136 | *Defined in [src/les/index.ts:219](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L219)* 137 | 138 | ___ 139 | 140 | ### txRelax 141 | 142 | • **txRelax**: Buffer 143 | 144 | *Defined in [src/les/index.ts:220](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L220)* 145 | -------------------------------------------------------------------------------- /docs/interfaces/_les_index_.les.status.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["les/index"](../modules/_les_index_.md) / [LES](../classes/_les_index_.les.md) / Status 4 | 5 | # Interface: Status 6 | 7 | ## Hierarchy 8 | 9 | * **Status** 10 | 11 | ## Indexable 12 | 13 | ▪ [key: string]: Buffer \| number 14 | 15 | ## Index 16 | 17 | ### Properties 18 | 19 | * [announceType](_les_index_.les.status.md#announcetype) 20 | * [flowControl/BL](_les_index_.les.status.md#flowcontrol/bl) 21 | * [flowControl/MRC](_les_index_.les.status.md#flowcontrol/mrc) 22 | * [flowControl/MRR](_les_index_.les.status.md#flowcontrol/mrr) 23 | * [genesisHash](_les_index_.les.status.md#genesishash) 24 | * [headHash](_les_index_.les.status.md#headhash) 25 | * [headNum](_les_index_.les.status.md#headnum) 26 | * [headTd](_les_index_.les.status.md#headtd) 27 | * [networkId](_les_index_.les.status.md#networkid) 28 | * [protocolVersion](_les_index_.les.status.md#protocolversion) 29 | * [serveChainSince](_les_index_.les.status.md#servechainsince) 30 | * [serveHeaders](_les_index_.les.status.md#serveheaders) 31 | * [serveStateSince](_les_index_.les.status.md#servestatesince) 32 | * [txRelax](_les_index_.les.status.md#txrelax) 33 | 34 | ## Properties 35 | 36 | ### announceType 37 | 38 | • **announceType**: Buffer \| number 39 | 40 | *Defined in [src/les/index.ts:224](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L224)* 41 | 42 | ___ 43 | 44 | ### flowControl/BL 45 | 46 | • **flowControl/BL**: Buffer 47 | 48 | *Defined in [src/les/index.ts:221](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L221)* 49 | 50 | ___ 51 | 52 | ### flowControl/MRC 53 | 54 | • **flowControl/MRC**: Buffer 55 | 56 | *Defined in [src/les/index.ts:223](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L223)* 57 | 58 | ___ 59 | 60 | ### flowControl/MRR 61 | 62 | • **flowControl/MRR**: Buffer 63 | 64 | *Defined in [src/les/index.ts:222](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L222)* 65 | 66 | ___ 67 | 68 | ### genesisHash 69 | 70 | • **genesisHash**: Buffer 71 | 72 | *Defined in [src/les/index.ts:216](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L216)* 73 | 74 | ___ 75 | 76 | ### headHash 77 | 78 | • **headHash**: Buffer 79 | 80 | *Defined in [src/les/index.ts:214](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L214)* 81 | 82 | ___ 83 | 84 | ### headNum 85 | 86 | • **headNum**: Buffer 87 | 88 | *Defined in [src/les/index.ts:215](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L215)* 89 | 90 | ___ 91 | 92 | ### headTd 93 | 94 | • **headTd**: Buffer 95 | 96 | *Defined in [src/les/index.ts:213](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L213)* 97 | 98 | ___ 99 | 100 | ### networkId 101 | 102 | • **networkId**: Buffer \| number 103 | 104 | *Defined in [src/les/index.ts:212](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L212)* 105 | 106 | ___ 107 | 108 | ### protocolVersion 109 | 110 | • **protocolVersion**: Buffer 111 | 112 | *Defined in [src/les/index.ts:211](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L211)* 113 | 114 | ___ 115 | 116 | ### serveChainSince 117 | 118 | • **serveChainSince**: Buffer 119 | 120 | *Defined in [src/les/index.ts:218](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L218)* 121 | 122 | ___ 123 | 124 | ### serveHeaders 125 | 126 | • **serveHeaders**: Buffer 127 | 128 | *Defined in [src/les/index.ts:217](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L217)* 129 | 130 | ___ 131 | 132 | ### serveStateSince 133 | 134 | • **serveStateSince**: Buffer 135 | 136 | *Defined in [src/les/index.ts:219](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L219)* 137 | 138 | ___ 139 | 140 | ### txRelax 141 | 142 | • **txRelax**: Buffer 143 | 144 | *Defined in [src/les/index.ts:220](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L220)* 145 | -------------------------------------------------------------------------------- /src/dpt/dpt.ts: -------------------------------------------------------------------------------- 1 | import ms from 'ms' 2 | import { EventEmitter } from 'events' 3 | import { publicKeyCreate } from 'secp256k1' 4 | import { randomBytes } from 'crypto' 5 | import { debug as createDebugLogger } from 'debug' 6 | import { pk2id } from '../util' 7 | import { KBucket } from './kbucket' 8 | import { BanList } from './ban-list' 9 | import { Server as DPTServer } from './server' 10 | 11 | const debug = createDebugLogger('devp2p:dpt') 12 | 13 | export class DPT extends EventEmitter { 14 | privateKey: Buffer 15 | banlist: BanList 16 | 17 | private _id: Buffer | undefined 18 | private _kbucket: KBucket 19 | private _server: DPTServer 20 | private _refreshIntervalId: NodeJS.Timeout 21 | 22 | constructor(privateKey: Buffer, options: any) { 23 | super() 24 | 25 | this.privateKey = Buffer.from(privateKey) 26 | this._id = pk2id(Buffer.from(publicKeyCreate(this.privateKey, false))) 27 | 28 | this.banlist = new BanList() 29 | 30 | this._kbucket = new KBucket(this._id) 31 | this._kbucket.on('added', peer => this.emit('peer:added', peer)) 32 | this._kbucket.on('removed', peer => this.emit('peer:removed', peer)) 33 | this._kbucket.on('ping', this._onKBucketPing) 34 | 35 | this._server = new DPTServer(this, this.privateKey, { 36 | createSocket: options.createSocket, 37 | timeout: options.timeout, 38 | endpoint: options.endpoint 39 | }) 40 | this._server.once('listening', () => this.emit('listening')) 41 | this._server.once('close', () => this.emit('close')) 42 | this._server.on('peers', peers => this._onServerPeers(peers)) 43 | this._server.on('error', err => this.emit('error', err)) 44 | 45 | const refreshInterval = options.refreshInterval || ms('60s') 46 | this._refreshIntervalId = setInterval(() => this.refresh(), refreshInterval) 47 | } 48 | 49 | bind(...args: any[]): void { 50 | this._server.bind(...args) 51 | } 52 | 53 | destroy(...args: any[]): void { 54 | clearInterval(this._refreshIntervalId) 55 | this._server.destroy(...args) 56 | } 57 | 58 | _onKBucketPing(oldPeers: any[], newPeer: any): void { 59 | if (this.banlist.has(newPeer)) return 60 | 61 | let count = 0 62 | let err: Error | null = null 63 | for (const peer of oldPeers) { 64 | this._server 65 | .ping(peer) 66 | .catch((_err: Error) => { 67 | this.banlist.add(peer, ms('5m')) 68 | this._kbucket.remove(peer) 69 | err = err || _err 70 | }) 71 | .then(() => { 72 | if (++count < oldPeers.length) return 73 | 74 | if (err === null) this.banlist.add(newPeer, ms('5m')) 75 | else this._kbucket.add(newPeer) 76 | }) 77 | } 78 | } 79 | 80 | _onServerPeers(peers: any[]): void { 81 | for (const peer of peers) this.addPeer(peer).catch(() => {}) 82 | } 83 | 84 | async bootstrap(peer: any): Promise { 85 | debug(`bootstrap with peer ${peer.address}:${peer.udpPort}`) 86 | 87 | peer = await this.addPeer(peer) 88 | if (!this._id) return 89 | this._server.findneighbours(peer, this._id) 90 | } 91 | 92 | async addPeer(obj: any): Promise { 93 | if (this.banlist.has(obj)) throw new Error('Peer is banned') 94 | debug(`attempt adding peer ${obj.address}:${obj.udpPort}`) 95 | 96 | // check k-bucket first 97 | const peer = this._kbucket.get(obj) 98 | if (peer !== null) return peer 99 | 100 | // check that peer is alive 101 | try { 102 | const peer = await this._server.ping(obj) 103 | this.emit('peer:new', peer) 104 | this._kbucket.add(peer) 105 | return peer 106 | } catch (err) { 107 | this.banlist.add(obj, ms('5m')) 108 | throw err 109 | } 110 | } 111 | 112 | getPeer(obj: any): any { 113 | return this._kbucket.get(obj) 114 | } 115 | 116 | getPeers(): any[] { 117 | return this._kbucket.getAll() 118 | } 119 | 120 | getClosestPeers(id: string): any { 121 | return this._kbucket.closest(id) 122 | } 123 | 124 | removePeer(obj: any) { 125 | this._kbucket.remove(obj) 126 | } 127 | 128 | banPeer(obj: any, maxAge?: number) { 129 | this.banlist.add(obj, maxAge) 130 | this._kbucket.remove(obj) 131 | } 132 | 133 | refresh(): void { 134 | const peers = this.getPeers() 135 | debug(`call .refresh (${peers.length} peers in table)`) 136 | 137 | for (const peer of peers) this._server.findneighbours(peer, randomBytes(64)) 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /test/dpt-message.ts: -------------------------------------------------------------------------------- 1 | import test from 'tape' 2 | import * as secp256k1 from 'secp256k1' 3 | import * as message from '../src/dpt/message' 4 | 5 | const privateKey = Buffer.from( 6 | 'b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291', 7 | 'hex' 8 | ) 9 | const publicKey = Buffer.from(secp256k1.publicKeyCreate(privateKey, false)) 10 | 11 | test('ping packet with version 4, additional list elements', t => { 12 | const buffer = Buffer.from( 13 | 'e9614ccfd9fc3e74360018522d30e1419a143407ffcce748de3e22116b7e8dc92ff74788c0b6663aaa3d67d641936511c8f8d6ad8698b820a7cf9e1be7155e9a241f556658c55428ec0563514365799a4be2be5a685a80971ddcfa80cb422cdd0101ec04cb847f000001820cfa8215a8d790000000000000000000000000000000018208ae820d058443b9a3550102', 14 | 'hex' 15 | ) 16 | const msg = message.decode(buffer) 17 | 18 | t.same(msg.typename, 'ping') 19 | t.same(msg.data.version, 4) 20 | t.same(msg.publicKey, publicKey) 21 | 22 | t.end() 23 | }) 24 | 25 | test('ping packet with version 555, additional list elements and additional random data:', t => { 26 | const buffer = Buffer.from( 27 | '577be4349c4dd26768081f58de4c6f375a7a22f3f7adda654d1428637412c3d7fe917cadc56d4e5e7ffae1dbe3efffb9849feb71b262de37977e7c7a44e677295680e9e38ab26bee2fcbae207fba3ff3d74069a50b902a82c9903ed37cc993c50001f83e82022bd79020010db83c4d001500000000abcdef12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba76023fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee1917084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c76d922dc3', 28 | 'hex' 29 | ) 30 | const msg = message.decode(buffer) 31 | 32 | t.same(msg.typename, 'ping') 33 | t.same(msg.data.version, 555) 34 | t.same(msg.publicKey, publicKey) 35 | 36 | t.end() 37 | }) 38 | 39 | test('pong packet with additional list elements and additional random data', t => { 40 | const buffer = Buffer.from( 41 | '09b2428d83348d27cdf7064ad9024f526cebc19e4958f0fdad87c15eb598dd61d08423e0bf66b2069869e1724125f820d851c136684082774f870e614d95a2855d000f05d1648b2d5945470bc187c2d2216fbe870f43ed0909009882e176a46b0102f846d79020010db885a308d313198a2e037073488208ae82823aa0fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c9548443b9a355c6010203c2040506a0c969a58f6f9095004c0177a6b47f451530cab38966a25cca5cb58f055542124e', 42 | 'hex' 43 | ) 44 | const msg = message.decode(buffer) 45 | 46 | t.same(msg.typename, 'pong') 47 | t.same(msg.publicKey, publicKey) 48 | 49 | t.end() 50 | }) 51 | 52 | test('findnode packet with additional list elements and additional random data', t => { 53 | const buffer = Buffer.from( 54 | 'c7c44041b9f7c7e41934417ebac9a8e1a4c6298f74553f2fcfdcae6ed6fe53163eb3d2b52e39fe91831b8a927bf4fc222c3902202027e5e9eb812195f95d20061ef5cd31d502e47ecb61183f74a504fe04c51e73df81f25c4d506b26db4517490103f84eb840ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be00812904767bf5ccd1fc7f8443b9a35582999983999999280dc62cc8255c73471e0a61da0c89acdc0e035e260add7fc0c04ad9ebf3919644c91cb247affc82b69bd2ca235c71eab8e49737c937a2c396', 55 | 'hex' 56 | ) 57 | const msg = message.decode(buffer) 58 | 59 | t.same(msg.typename, 'findneighbours') 60 | t.same(msg.publicKey, publicKey) 61 | 62 | t.end() 63 | }) 64 | 65 | test('neighbours packet with additional list elements and additional random data', t => { 66 | const buffer = Buffer.from( 67 | 'c679fc8fe0b8b12f06577f2e802d34f6fa257e6137a995f6f4cbfc9ee50ed3710faf6e66f932c4c8d81d64343f429651328758b47d3dbc02c4042f0fff6946a50f4a49037a72bb550f3a7872363a83e1b9ee6469856c24eb4ef80b7535bcf99c0004f9015bf90150f84d846321163782115c82115db8403155e1427f85f10a5c9a7755877748041af1bcd8d474ec065eb33df57a97babf54bfd2103575fa829115d224c523596b401065a97f74010610fce76382c0bf32f84984010203040101b840312c55512422cf9b8a4097e9a6ad79402e87a15ae909a4bfefa22398f03d20951933beea1e4dfa6f968212385e829f04c2d314fc2d4e255e0d3bc08792b069dbf8599020010db83c4d001500000000abcdef12820d05820d05b84038643200b172dcfef857492156971f0e6aa2c538d8b74010f8e140811d53b98c765dd2d96126051913f44582e8c199ad7c6d6819e9a56483f637feaac9448aacf8599020010db885a308d313198a2e037073488203e78203e8b8408dcab8618c3253b558d459da53bd8fa68935a719aff8b811197101a4b2b47dd2d47295286fc00cc081bb542d760717d1bdd6bec2c37cd72eca367d6dd3b9df738443b9a355010203b525a138aa34383fec3d2719a0', 68 | 'hex' 69 | ) 70 | const msg = message.decode(buffer) 71 | 72 | t.same(msg.typename, 'neighbours') 73 | t.same(msg.publicKey, publicKey) 74 | 75 | t.end() 76 | }) 77 | -------------------------------------------------------------------------------- /test/integration/dpt-simulator.ts: -------------------------------------------------------------------------------- 1 | import async from 'async' 2 | import test from 'tape' 3 | import * as util from './util' 4 | 5 | async function delay(ms: number) { 6 | await new Promise(resolve => setTimeout(resolve, ms)) 7 | } 8 | 9 | test('DPT: new working node', async t => { 10 | const dpts = util.initTwoPeerDPTSetup() 11 | 12 | dpts[0].on('peer:new', function(peer: any) { 13 | t.equal(peer.address, '127.0.0.1', 'should have added peer on peer:new') 14 | util.destroyDPTs(dpts) 15 | t.end() 16 | }) 17 | }) 18 | 19 | test('DPT: working node added', async t => { 20 | const dpts = util.initTwoPeerDPTSetup() 21 | 22 | dpts[0].on('peer:added', function() { 23 | t.equal(dpts[0].getPeers().length, 1, 'should have added peer to k-bucket on peer:added') 24 | util.destroyDPTs(dpts) 25 | t.end() 26 | }) 27 | }) 28 | 29 | test('DPT: remove node', async t => { 30 | const dpts = util.initTwoPeerDPTSetup() 31 | 32 | async.series( 33 | [ 34 | function(cb) { 35 | dpts[0].on('peer:added', function(peer: any) { 36 | dpts[0].removePeer(peer) 37 | cb(null) 38 | }) 39 | }, 40 | function(cb) { 41 | dpts[0].on('peer:removed', function() { 42 | t.equal( 43 | dpts[0].getPeers().length, 44 | 0, 45 | 'should have removed peer from k-bucket on peer:removed' 46 | ) 47 | cb(null) 48 | }) 49 | } 50 | ], 51 | function(err) { 52 | if (err) { 53 | t.fail('An unexpected error occured.') 54 | } 55 | util.destroyDPTs(dpts) 56 | t.end() 57 | } 58 | ) 59 | }) 60 | 61 | test('DPT: ban node', async t => { 62 | const dpts = util.initTwoPeerDPTSetup() 63 | 64 | async.series( 65 | [ 66 | function(cb) { 67 | dpts[0].on('peer:added', function(peer: any) { 68 | dpts[0].banPeer(peer) 69 | cb(null) 70 | }) 71 | }, 72 | function(cb) { 73 | dpts[0].on('peer:removed', function(peer: any) { 74 | t.equal(dpts[0].banlist.has(peer), true, 'ban-list should contain peer') 75 | t.equal( 76 | dpts[0].getPeers().length, 77 | 0, 78 | 'should have removed peer from k-bucket on peer:removed' 79 | ) 80 | cb(null) 81 | }) 82 | } 83 | ], 84 | function(err) { 85 | if (err) { 86 | t.fail('An unexpected error occured.') 87 | } 88 | util.destroyDPTs(dpts) 89 | t.end() 90 | } 91 | ) 92 | }) 93 | 94 | test('DPT: k-bucket ping', async t => { 95 | const dpts = util.initTwoPeerDPTSetup() 96 | 97 | async.series( 98 | [ 99 | function(cb) { 100 | dpts[0].on('peer:added', function(peer: any) { 101 | dpts[0]._onKBucketPing([peer], peer) 102 | setTimeout(function() { 103 | cb(null) 104 | }, 400) 105 | }) 106 | }, 107 | function(cb) { 108 | t.equal(dpts[0].getPeers().length, 1, 'should still have one peer in k-bucket') 109 | cb(null) 110 | } 111 | ], 112 | function(err) { 113 | if (err) { 114 | t.fail('An unexpected error occured.') 115 | } 116 | util.destroyDPTs(dpts) 117 | t.end() 118 | } 119 | ) 120 | }) 121 | 122 | test('DPT: add non-available node', async t => { 123 | const dpts = util.getTestDPTs(1) 124 | const peer = { address: util.localhost, udpPort: util.basePort + 1 } 125 | 126 | await dpts[0].addPeer(peer).catch((e: Error) => { 127 | t.equal(e.message, 'Timeout error: ping 127.0.0.1:30307', 'should throw Timeout error') 128 | util.destroyDPTs(dpts) 129 | t.end() 130 | }) 131 | }) 132 | 133 | test('DPT: simulate bootstrap', async t => { 134 | const numDPTs = 6 135 | const dpts = util.getTestDPTs(numDPTs) 136 | 137 | await delay(250) 138 | await dpts[0].addPeer({ address: util.localhost, udpPort: util.basePort + 1 }) 139 | await delay(100) 140 | 141 | for (const dpt of dpts.slice(2)) { 142 | await dpt.bootstrap({ address: util.localhost, udpPort: util.basePort + 1 }) 143 | } 144 | 145 | for (const dpt of dpts) { 146 | dpt.refresh() 147 | await delay(400) 148 | } 149 | 150 | await delay(250) 151 | util.destroyDPTs(dpts) 152 | 153 | // dpts.forEach((dpt, i) => console.log(`${i}:${dpt.getPeers().length}`)) 154 | for (const dpt of dpts) 155 | t.equal(dpt.getPeers().length, numDPTs, 'Peers should be distributed to all DPTs') 156 | 157 | t.end() 158 | }) 159 | -------------------------------------------------------------------------------- /test/integration/util.ts: -------------------------------------------------------------------------------- 1 | import { Test } from 'tape' 2 | import { DPT, ETH, RLPx, genPrivateKey } from '../../src' 3 | import Common from '@ethereumjs/common' 4 | 5 | export const localhost = '127.0.0.1' 6 | export const basePort = 30306 7 | 8 | export function getTestDPTs(numDPTs: any) { 9 | const dpts = [] 10 | 11 | for (let i = 0; i < numDPTs; ++i) { 12 | const dpt = new DPT(genPrivateKey(), { 13 | endpoint: { 14 | address: localhost, 15 | udpPort: basePort + i, 16 | tcpPort: basePort + i 17 | }, 18 | timeout: 100 19 | }) 20 | dpt.bind(basePort + i) 21 | dpts.push(dpt) 22 | } 23 | return dpts 24 | } 25 | 26 | export function initTwoPeerDPTSetup() { 27 | const dpts = getTestDPTs(2) 28 | const peer = { address: localhost, udpPort: basePort + 1 } 29 | dpts[0].addPeer(peer) 30 | return dpts 31 | } 32 | 33 | export function destroyDPTs(dpts: any) { 34 | for (const dpt of dpts) dpt.destroy() 35 | } 36 | 37 | export function getTestRLPXs( 38 | numRLPXs: number, 39 | maxPeers: number = 10, 40 | capabilities?: any, 41 | common?: Object | Common 42 | ) { 43 | const rlpxs = [] 44 | if (!capabilities) { 45 | capabilities = [ETH.eth64, ETH.eth63, ETH.eth62] 46 | } 47 | if (!common) { 48 | common = new Common({ chain: 'mainnet' }) 49 | } 50 | const dpts = getTestDPTs(numRLPXs) 51 | 52 | for (let i = 0; i < numRLPXs; ++i) { 53 | const rlpx = new RLPx(dpts[i].privateKey, { 54 | dpt: dpts[i], 55 | maxPeers: maxPeers, 56 | capabilities: capabilities, 57 | common: common.constructor === Array ? common[i] : (common as Common), 58 | listenPort: basePort + i 59 | }) 60 | rlpx.listen(basePort + i) 61 | rlpxs.push(rlpx) 62 | } 63 | return rlpxs 64 | } 65 | 66 | export function initTwoPeerRLPXSetup(maxPeers?: any, capabilities?: any, common?: Object | Common) { 67 | const rlpxs = getTestRLPXs(2, maxPeers, capabilities, common) 68 | const peer = { address: localhost, udpPort: basePort + 1, tcpPort: basePort + 1 } 69 | rlpxs[0]._dpt.addPeer(peer) 70 | return rlpxs 71 | } 72 | 73 | /** 74 | * @param {Test} t 75 | * @param {Array} capabilities Capabilities 76 | * @param {Object} opts 77 | * @param {Dictionary} opts.status0 Status values requested by protocol 78 | * @param {Dictionary} opts.status1 Status values requested by protocol 79 | * @param {Function} opts.onOnceStatus0 (rlpxs, protocol) Optional handler function 80 | * @param {Function} opts.onPeerError0 (err, rlpxs) Optional handler function 81 | * @param {Function} opts.onPeerError1 (err, rlpxs) Optional handler function 82 | * @param {Function} opts.onOnMsg0 (rlpxs, protocol, code, payload) Optional handler function 83 | * @param {Function} opts.onOnMsg1 (rlpxs, protocol, code, payload) Optional handler function 84 | */ 85 | export function twoPeerMsgExchange( 86 | t: Test, 87 | opts: any, 88 | capabilities?: any, 89 | common?: Object | Common 90 | ) { 91 | const rlpxs = initTwoPeerRLPXSetup(null, capabilities, common) 92 | rlpxs[0].on('peer:added', function(peer: any) { 93 | const protocol = peer.getProtocols()[0] 94 | protocol.sendStatus(opts.status0) // (1 ->) 95 | 96 | protocol.once('status', () => { 97 | if (opts.onOnceStatus0) opts.onOnceStatus0(rlpxs, protocol) 98 | }) // (-> 2) 99 | protocol.on('message', async (code: any, payload: any) => { 100 | if (opts.onOnMsg0) opts.onOnMsg0(rlpxs, protocol, code, payload) 101 | }) 102 | peer.on('error', (err: Error) => { 103 | if (opts.onPeerError0) { 104 | opts.onPeerError0(err, rlpxs) 105 | } else { 106 | t.fail(`Unexpected peer 0 error: ${err}`) 107 | } 108 | }) // (-> 2) 109 | }) 110 | 111 | rlpxs[1].on('peer:added', function(peer: any) { 112 | const protocol = peer.getProtocols()[0] 113 | protocol.on('message', async (code: any, payload: any) => { 114 | switch (code) { 115 | // Comfortability hack, use constants like devp2p.ETH.MESSAGE_CODES.STATUS 116 | // in production use 117 | case 0x00: // (-> 1) 118 | t.pass('should receive initial status message') 119 | protocol.sendStatus(opts.status1) // (2 ->) 120 | break 121 | } 122 | if (opts.onOnMsg1) opts.onOnMsg1(rlpxs, protocol, code, payload) 123 | }) 124 | peer.on('error', (err: any) => { 125 | if (opts.onPeerError1) { 126 | opts.onPeerError1(err, rlpxs) 127 | } else { 128 | t.fail(`Unexpected peer 1 error: ${err}`) 129 | } 130 | }) 131 | }) 132 | } 133 | 134 | export function destroyRLPXs(rlpxs: any) { 135 | for (const rlpx of rlpxs) { 136 | // FIXME: Call destroy() on dpt instance from the rlpx.destroy() method 137 | rlpx._dpt.destroy() 138 | rlpx.destroy() 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /test/rlpx-ecies.ts: -------------------------------------------------------------------------------- 1 | import { randomBytes } from 'crypto' 2 | import * as secp256k1 from 'secp256k1' 3 | import test, { Test } from 'tape' 4 | import * as util from '../src/util' 5 | import { ECIES } from '../src/rlpx/ecies' 6 | 7 | import testdata from './testdata.json' 8 | 9 | declare module 'tape' { 10 | export interface Test { 11 | context: any 12 | } 13 | } 14 | 15 | function randomBefore(fn: Function) { 16 | return (t: Test) => { 17 | const privateKey1 = util.genPrivateKey() 18 | const privateKey2 = util.genPrivateKey() 19 | const publicKey1 = Buffer.from(secp256k1.publicKeyCreate(privateKey1, false)) 20 | const publicKey2 = Buffer.from(secp256k1.publicKeyCreate(privateKey2, false)) 21 | t.context = { 22 | a: new ECIES(privateKey1, util.pk2id(publicKey1), util.pk2id(publicKey2)), 23 | b: new ECIES(privateKey2, util.pk2id(publicKey2), util.pk2id(publicKey1)) 24 | } 25 | 26 | fn(t) 27 | } 28 | } 29 | 30 | function testdataBefore(fn: Function) { 31 | return (t: Test) => { 32 | const v = testdata.eip8Values 33 | const keyA = Buffer.from(v.keyA, 'hex') 34 | const keyB = Buffer.from(v.keyB, 'hex') 35 | const pubA = Buffer.from(v.pubA, 'hex') 36 | const pubB = Buffer.from(v.pubB, 'hex') 37 | const h = testdata.eip8Handshakes 38 | 39 | t.context = { 40 | a: new ECIES(keyA, util.pk2id(pubA), util.pk2id(pubB)), 41 | b: new ECIES(keyB, util.pk2id(pubB), util.pk2id(pubA)), 42 | h0: { 43 | auth: Buffer.from(h[0].auth.join(''), 'hex'), 44 | ack: Buffer.from(h[0].ack.join(''), 'hex') 45 | }, 46 | h1: { 47 | auth: Buffer.from(h[1].auth.join(''), 'hex'), 48 | ack: Buffer.from(h[1].ack.join(''), 'hex') 49 | } 50 | } 51 | fn(t) 52 | } 53 | } 54 | 55 | test( 56 | 'Random: message encryption', 57 | randomBefore((t: Test) => { 58 | const message = Buffer.from('The Magic Words are Squeamish Ossifrage') 59 | const encrypted = t.context.a._encryptMessage(message) 60 | const decrypted = t.context.b._decryptMessage(encrypted) 61 | t.same(message, decrypted, 'encryptMessage -> decryptMessage should lead to same') 62 | t.end() 63 | }) 64 | ) 65 | 66 | test( 67 | 'Random: auth -> ack -> header -> body (old format/no EIP8)', 68 | randomBefore((t: Test) => { 69 | t.doesNotThrow(() => { 70 | const auth = t.context.a.createAuthNonEIP8() 71 | t.context.b._gotEIP8Auth = false 72 | t.context.b.parseAuthPlain(auth) 73 | }, 'should not throw on auth creation/parsing') 74 | 75 | t.doesNotThrow(() => { 76 | t.context.b._gotEIP8Ack = false 77 | const ack = t.context.b.createAckOld() 78 | t.context.a.parseAckPlain(ack) 79 | }, 'should not throw on ack creation/parsing') 80 | 81 | const body = randomBytes(600) 82 | const header = t.context.b.parseHeader(t.context.a.createHeader(body.length)) 83 | t.same(header, body.length, 'createHeader -> parseHeader should lead to same') 84 | 85 | const parsedBody = t.context.b.parseBody(t.context.a.createBody(body)) 86 | t.same(parsedBody, body, 'createBody -> parseBody should lead to same') 87 | 88 | t.end() 89 | }) 90 | ) 91 | 92 | test( 93 | 'Random: auth -> ack (EIP8)', 94 | randomBefore((t: Test) => { 95 | t.doesNotThrow(() => { 96 | const auth = t.context.a.createAuthEIP8() 97 | t.context.b._gotEIP8Auth = true 98 | t.context.b.parseAuthEIP8(auth) 99 | }, 'should not throw on auth creation/parsing') 100 | 101 | t.doesNotThrow(() => { 102 | const ack = t.context.b.createAckEIP8() 103 | t.context.a._gotEIP8Ack = true 104 | t.context.a.parseAckEIP8(ack) 105 | }, 'should not throw on ack creation/parsing') 106 | 107 | t.end() 108 | }) 109 | ) 110 | 111 | test( 112 | 'Testdata: auth -> ack (old format/no EIP8)', 113 | testdataBefore((t: Test) => { 114 | t.doesNotThrow(() => { 115 | t.context.b._gotEIP8Auth = false 116 | t.context.b.parseAuthPlain(t.context.h0.auth) 117 | t.context.a._initMsg = t.context.h0.auth 118 | }, 'should not throw on auth parsing') 119 | 120 | t.doesNotThrow(() => { 121 | t.context.a._gotEIP8Ack = false 122 | t.context.a.parseAckPlain(t.context.h0.ack) 123 | }, 'should not throw on ack parsing') 124 | 125 | t.end() 126 | }) 127 | ) 128 | 129 | test( 130 | 'Testdata: auth -> ack (EIP8)', 131 | testdataBefore((t: Test) => { 132 | t.doesNotThrow(() => { 133 | t.context.b._gotEIP8Auth = true 134 | t.context.b.parseAuthEIP8(t.context.h1.auth) 135 | t.context.a._initMsg = t.context.h1.auth 136 | }, 'should not throw on auth parsing') 137 | t.doesNotThrow(() => { 138 | t.context.a._gotEIP8Ack = true 139 | t.context.a.parseAckEIP8(t.context.h1.ack) 140 | }, 'should not throw on ack parsing') 141 | 142 | t.end() 143 | }) 144 | ) 145 | -------------------------------------------------------------------------------- /test/integration/les-simulator.ts: -------------------------------------------------------------------------------- 1 | import test from 'tape' 2 | import Common from '@ethereumjs/common' 3 | import * as devp2p from '../../src' 4 | import * as util from './util' 5 | 6 | const GENESIS_TD = 17179869184 7 | const GENESIS_HASH = Buffer.from( 8 | 'd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', 9 | 'hex' 10 | ) 11 | 12 | const capabilities = [devp2p.LES.les2] 13 | 14 | const status = { 15 | headTd: devp2p.int2buffer(GENESIS_TD), // total difficulty in genesis block 16 | headHash: GENESIS_HASH, 17 | headNum: devp2p.int2buffer(0), 18 | genesisHash: GENESIS_HASH 19 | } 20 | 21 | // FIXME: Handle unhandled promises directly 22 | process.on('unhandledRejection', () => {}) 23 | 24 | test('LES: send status message (successful)', async t => { 25 | const opts: any = {} 26 | opts.status0 = Object.assign({}, status) 27 | opts.status1 = Object.assign({}, status) 28 | opts.onOnceStatus0 = function(rlpxs: any) { 29 | t.pass('should receive echoing status message and welcome connection') 30 | util.destroyRLPXs(rlpxs) 31 | t.end() 32 | } 33 | util.twoPeerMsgExchange(t, opts, capabilities) 34 | }) 35 | 36 | test('LES: send status message (modified announceType)', async t => { 37 | const opts: any = {} 38 | opts.status0 = Object.assign({}, status) 39 | opts.status0['announceType'] = 0 40 | opts.status1 = Object.assign({}, status) 41 | opts.status1['announceType'] = 0 42 | opts.onOnceStatus0 = function(rlpxs: any) { 43 | t.pass('should receive echoing status message and welcome connection') 44 | util.destroyRLPXs(rlpxs) 45 | t.end() 46 | } 47 | util.twoPeerMsgExchange(t, opts, capabilities) 48 | }) 49 | 50 | test('LES: send status message (NetworkId mismatch)', async t => { 51 | const opts: any = {} 52 | opts.status0 = Object.assign({}, status) 53 | opts.status1 = Object.assign({}, status) 54 | opts.onPeerError0 = function(err: Error, rlpxs: any) { 55 | const msg = 'NetworkId mismatch: 01 / 03' 56 | t.equal(err.message, msg, `should emit error: ${msg}`) 57 | util.destroyRLPXs(rlpxs) 58 | t.end() 59 | } 60 | 61 | const c1 = new Common({ chain: 'mainnet' }) 62 | const c2 = new Common({ chain: 'ropsten' }) 63 | util.twoPeerMsgExchange(t, opts, capabilities, [c1, c2]) 64 | }) 65 | 66 | test('ETH: send status message (Genesis block mismatch)', async t => { 67 | const opts: any = {} 68 | opts.status0 = Object.assign({}, status) 69 | const status1 = Object.assign({}, status) 70 | status1['genesisHash'] = Buffer.alloc(32) 71 | opts.status1 = status1 72 | opts.onPeerError0 = function(err: Error, rlpxs: any) { 73 | const msg = 74 | 'Genesis block mismatch: d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3 / 0000000000000000000000000000000000000000000000000000000000000000' 75 | t.equal(err.message, msg, `should emit error: ${msg}`) 76 | util.destroyRLPXs(rlpxs) 77 | t.end() 78 | } 79 | util.twoPeerMsgExchange(t, opts, capabilities) 80 | }) 81 | 82 | test('LES: send valid message', async t => { 83 | const opts: any = {} 84 | opts.status0 = Object.assign({}, status) 85 | opts.status1 = Object.assign({}, status) 86 | opts.onOnceStatus0 = function(rlpxs: any, les: any) { 87 | t.equal(les.getVersion(), 2, 'should use les2 as protocol version') 88 | les.sendMessage(devp2p.LES.MESSAGE_CODES.GET_BLOCK_HEADERS, 1, [437000, 1, 0, 0]) 89 | t.pass('should send GET_BLOCK_HEADERS message') 90 | } 91 | opts.onOnMsg1 = function(rlpxs: any, eth: any, code: any) { 92 | if (code === devp2p.LES.MESSAGE_CODES.GET_BLOCK_HEADERS) { 93 | t.pass('should receive GET_BLOCK_HEADERS message') 94 | util.destroyRLPXs(rlpxs) 95 | t.end() 96 | } 97 | } 98 | util.twoPeerMsgExchange(t, opts, capabilities) 99 | }) 100 | 101 | test('LES: send unknown message code', async t => { 102 | const opts: any = {} 103 | opts.status0 = Object.assign({}, status) 104 | opts.status1 = Object.assign({}, status) 105 | opts.onOnceStatus0 = function(rlpxs: any, les: any) { 106 | try { 107 | les.sendMessage(0x55, 1, []) 108 | } catch (err) { 109 | const msg = 'Error: Unknown code 85' 110 | t.equal(err.toString(), msg, `should emit error: ${msg}`) 111 | util.destroyRLPXs(rlpxs) 112 | t.end() 113 | } 114 | } 115 | util.twoPeerMsgExchange(t, opts, capabilities) 116 | }) 117 | 118 | test('LES: invalid status send', async t => { 119 | const opts: any = {} 120 | opts.status0 = Object.assign({}, status) 121 | opts.status1 = Object.assign({}, status) 122 | opts.onOnceStatus0 = function(rlpxs: any, les: any) { 123 | try { 124 | les.sendMessage(devp2p.ETH.MESSAGE_CODES.STATUS, 1, []) 125 | } catch (err) { 126 | const msg = 'Error: Please send status message through .sendStatus' 127 | t.equal(err.toString(), msg, `should emit error: ${msg}`) 128 | util.destroyRLPXs(rlpxs) 129 | t.end() 130 | } 131 | } 132 | util.twoPeerMsgExchange(t, opts, capabilities) 133 | }) 134 | -------------------------------------------------------------------------------- /docs/modules/_util_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "util" 4 | 5 | # Module: "util" 6 | 7 | ## Index 8 | 9 | ### Classes 10 | 11 | * [Deferred](../classes/_util_.deferred.md) 12 | 13 | ### Functions 14 | 15 | * [assertEq](_util_.md#asserteq) 16 | * [buffer2int](_util_.md#buffer2int) 17 | * [createDeferred](_util_.md#createdeferred) 18 | * [formatLogData](_util_.md#formatlogdata) 19 | * [formatLogId](_util_.md#formatlogid) 20 | * [genPrivateKey](_util_.md#genprivatekey) 21 | * [id2pk](_util_.md#id2pk) 22 | * [int2buffer](_util_.md#int2buffer) 23 | * [keccak256](_util_.md#keccak256) 24 | * [pk2id](_util_.md#pk2id) 25 | * [xor](_util_.md#xor) 26 | * [zfill](_util_.md#zfill) 27 | 28 | ## Functions 29 | 30 | ### assertEq 31 | 32 | ▸ **assertEq**(`expected`: any, `actual`: any, `msg`: string, `debug`: any): void 33 | 34 | *Defined in [src/util.ts:57](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L57)* 35 | 36 | #### Parameters: 37 | 38 | Name | Type | 39 | ------ | ------ | 40 | `expected` | any | 41 | `actual` | any | 42 | `msg` | string | 43 | `debug` | any | 44 | 45 | **Returns:** void 46 | 47 | ___ 48 | 49 | ### buffer2int 50 | 51 | ▸ **buffer2int**(`buffer`: Buffer): number 52 | 53 | *Defined in [src/util.ts:35](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L35)* 54 | 55 | #### Parameters: 56 | 57 | Name | Type | 58 | ------ | ------ | 59 | `buffer` | Buffer | 60 | 61 | **Returns:** number 62 | 63 | ___ 64 | 65 | ### createDeferred 66 | 67 | ▸ **createDeferred**\(): [Deferred](../classes/_index_.deferred.md)\ 68 | 69 | *Defined in [src/util.ts:106](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L106)* 70 | 71 | #### Type parameters: 72 | 73 | Name | 74 | ------ | 75 | `T` | 76 | 77 | **Returns:** [Deferred](../classes/_index_.deferred.md)\ 78 | 79 | ___ 80 | 81 | ### formatLogData 82 | 83 | ▸ **formatLogData**(`data`: string, `verbose`: boolean): string 84 | 85 | *Defined in [src/util.ts:85](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L85)* 86 | 87 | #### Parameters: 88 | 89 | Name | Type | 90 | ------ | ------ | 91 | `data` | string | 92 | `verbose` | boolean | 93 | 94 | **Returns:** string 95 | 96 | ___ 97 | 98 | ### formatLogId 99 | 100 | ▸ **formatLogId**(`id`: string, `verbose`: boolean): string 101 | 102 | *Defined in [src/util.ts:76](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L76)* 103 | 104 | #### Parameters: 105 | 106 | Name | Type | 107 | ------ | ------ | 108 | `id` | string | 109 | `verbose` | boolean | 110 | 111 | **Returns:** string 112 | 113 | ___ 114 | 115 | ### genPrivateKey 116 | 117 | ▸ **genPrivateKey**(): Buffer 118 | 119 | *Defined in [src/util.ts:13](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L13)* 120 | 121 | **Returns:** Buffer 122 | 123 | ___ 124 | 125 | ### id2pk 126 | 127 | ▸ **id2pk**(`id`: Buffer): Buffer 128 | 129 | *Defined in [src/util.ts:25](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L25)* 130 | 131 | #### Parameters: 132 | 133 | Name | Type | 134 | ------ | ------ | 135 | `id` | Buffer | 136 | 137 | **Returns:** Buffer 138 | 139 | ___ 140 | 141 | ### int2buffer 142 | 143 | ▸ **int2buffer**(`v`: number): Buffer 144 | 145 | *Defined in [src/util.ts:29](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L29)* 146 | 147 | #### Parameters: 148 | 149 | Name | Type | 150 | ------ | ------ | 151 | `v` | number | 152 | 153 | **Returns:** Buffer 154 | 155 | ___ 156 | 157 | ### keccak256 158 | 159 | ▸ **keccak256**(...`buffers`: Buffer[]): Buffer 160 | 161 | *Defined in [src/util.ts:6](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L6)* 162 | 163 | #### Parameters: 164 | 165 | Name | Type | 166 | ------ | ------ | 167 | `...buffers` | Buffer[] | 168 | 169 | **Returns:** Buffer 170 | 171 | ___ 172 | 173 | ### pk2id 174 | 175 | ▸ **pk2id**(`pk`: Buffer): Buffer 176 | 177 | *Defined in [src/util.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L18)* 178 | 179 | #### Parameters: 180 | 181 | Name | Type | 182 | ------ | ------ | 183 | `pk` | Buffer | 184 | 185 | **Returns:** Buffer 186 | 187 | ___ 188 | 189 | ### xor 190 | 191 | ▸ **xor**(`a`: Buffer, `b`: any): Buffer 192 | 193 | *Defined in [src/util.ts:50](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L50)* 194 | 195 | #### Parameters: 196 | 197 | Name | Type | 198 | ------ | ------ | 199 | `a` | Buffer | 200 | `b` | any | 201 | 202 | **Returns:** Buffer 203 | 204 | ___ 205 | 206 | ### zfill 207 | 208 | ▸ **zfill**(`buffer`: Buffer, `size`: number, `leftpad?`: boolean): Buffer 209 | 210 | *Defined in [src/util.ts:43](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L43)* 211 | 212 | #### Parameters: 213 | 214 | Name | Type | Default value | 215 | ------ | ------ | ------ | 216 | `buffer` | Buffer | - | 217 | `size` | number | - | 218 | `leftpad` | boolean | true | 219 | 220 | **Returns:** Buffer 221 | -------------------------------------------------------------------------------- /diagram/devp2p.drawio: -------------------------------------------------------------------------------- 1 | 7V1bc+I4Fv41VCVblZTvmMdAYDLb6ZnUpLe696nLYAGeNjZrm1zm16/kC9i6+IZkA0k/dEA2sqxzdHTOdy4aqJPN22+BtV1/9W3gDhTJfhuo9wNFkTXdhH9Qy3vSYqpK0rAKHDu96dDw7PwD0kYpbd05NggLN0a+70bOtti48D0PLKJCmxUE/mvxtqXvFp+6tVaAaHheWC7Z+t2xo3XaKkvS4cIDcFbr9NGmnl7YWNnNaUO4tmz/NdekTgfqJPD9KPm0eZsAF01eNi/J72aMq/uBBcCL6vxg+PB9/m/nPzfjZ+V1/Dj/tpwZjzfmMOnmxXJ36Runo43esykI/J1nA9SLNFDHr2snAs9ba4GuvkKiw7Z1tHHhNxl+DKPA/wUmvusH8a/VualrurS/kk0ifP3x0nHd3J1LcwEWC9Tue1HKCTK6bxVYtgPf8t4JIIkd34MXPD9A/eyv5fqZzUbwH7xGzlA6aS8giMBbrimdsd+AvwFR8A5vSa8OzVHyk5R99YzurwdmULO2dY4PlFHaaKUMuNr3faAR/JCSqQHJtJFokpnKXDWMOiSzdWDaWgnJcveOR1PpTq8gJweS6UaRZBpJMV2hUExTRFFM4U0xfLYxqsxmM2UyodKPoPVsZkqSxFpIUz1eSIIplsl6NsE0jUIwQ9gSI8kDbLgrpF/Ri/sr37Pc6aF1XCTg4Z5H39+mZPsbRNF7SjdrF/nlRIXzGbz/QP3darKeNfwXXb6VpGHWcP+WPjL59p7/9gQCB84ICNJGJq1CfxcsQMmMZFuvFaxAVHKfmtyHpquU8gFwrch5KW6yNDqmP33yHTjkPceoepFlFHztJgNNf3XghrsgsN5zt23RDWHJc1Sj+Bwd22Ob3Q8/JCM4sOZ+Ttpzq9wLu+bZU9Xy7ClB9jQq2JOQQ1L8j7UMumfkUUeMrGGyb4gxcvJCHBgZ2xRHVYxcer8YRqZsi50wsn2HDAX4deFaYegsksaZ4zI1JCa3Hs2YohlOxiTnngE5S07Wc4QykDo8Fwaazc6VgfRRNwzEeo5QBhqqBANx3CiLm6SiV+6RVhBlnOX5HsjaUsaS6vEe/JaOzWzEieDNiX5kfcDPyaiHo/TrYdDoy3vuS/ebtWHy5v2jzIehNiDtPcON0kmO0aps/o3/7RAANEb4xzKmRK7JWKG/ABI4yDqAA0r6SK5R5d2jNQdukQkt11khq20BaYAIM0bWmbOw3Lv0wsax7UQcgtD5x5rH/SHqpesUdq6PB/p9LZFVurYIu3AP3qVPHeTxMZq9eCPdyoapJ79tK86yW/zlMgQRQXMeejmTC2znpUC1jOJwXqKblFR36N1iY1dJFpGE5v0mjCceXZSV7RvJLNkjwq3lUZ/RqJd5+y5s8LJVoIS8s7dRjnnn+CNgWzJWojmepWLrR5i4fRfB8X0cPeFl8gpJq+Uy33TEcK0Nwri8ebgtjqko7AqDavmw+6dv8NrV9AWKq+nGiaA8vOY857RB8+i6H2rMfT+CaoO1vbpmvyOVfg1WQbpU59bi1ypWuW7St4yX82p+peg6ukuBsljKf5auyTe4kvMjJVbA+ZLCsu0nAIISQkj15NhriqOiR8+RT6xUVvIljpIfPU0U8aAPjz6YU9h8IuBnylTU0wpV+K+aNbaOtyLXoUQ0TZWBaQxGCpODiKVMXdrd8P9P3/sy3i1+QXsyeb0+JSxJCV7LegvXdNhuE2zGM+dG/GcQQHPhKZ0e0Vs0KY4qV9NpNPGgEsEhUvVmw4RKkMlZ4cPMLFIXLOPBOq77J7zZiRCUIMeIhIvs2Cc4DLT2E2s0bhr7gQ2CDMNIkRHcKvX81AwuxyDqeymVIQZIUUIBZIPip9w3cgca9D7gTnyi2YhSe+CnKzeiwSApbzci4zli3YJGH9xR31ViW+F6LyxyOGa6ng8g5h4Z3aORDUBUJg927WiB3291IdwlayPsSSqbu4hf42It+3WVB5Kbz+ZolCzeQSqU+KQt1SWZ5r8QLKp8eEid6e5p+bdDezv8wZPvu7Hdh77E2MgHmYs26hHURerY3nTcg5P5rJdiG11xzzGzCIVeGZTUhP2O0UBru17b64iyXFdHlEXpiEaH8rWebUr3csGlBQnHhSlO8fUCsPFfLvkFt9UATbs1jV5nIMyZiTTYMBUCYmQCrvxDuUjIBJpI0EVJBFkm5rgPw0BACExXQXsYRTXcwBdkNmbPEWo20mLVc/KGcHOeClZW8Derd2GMHJZpSry1zdTnzEW5LRXR+Ew8p6/azKhpN54qKtyQ97TXE0M/sdaqNpV6s9gKDi2brFqjKUzG2vLgvhTG/MLquOUwqwiTbM/SVcX4mS4vzGKRDjbKoMLHlUOUt763umZxCItPRdpSaqWfuBvi+AfdqQ6r1fAItB7u0vHsP5AaMveLTpfaT/fwX3P1G+DaAuZHKML+FA+CACtP1+taecI8AbJoGK2NSeA6YQS8WnZBLygPa9wL1w/BmY25PEj0NMe8zft1a475wo1DbajXMg7FCRKzD+PwVFIoht0YkARMiGd9cTIgWc8R63eklRQQjVjtdbdfN/MdZjUQet3FuzbybzeBqyOwFogr/PnfqETGaWCNz5EfoNob/eH9BQc0D1mOLTYKzifTCg/gi5+fLG+E5Zw2kH9eqPwnxN6pFiWbMn0/7QtiV443xyrgxNJNEMNC55Z3g2yxzvdEnpAob7WhAFmMLe+xOEE9u+FEIjzlQQwfYQbWVnihAQiYDqLS4g9oOoi4Ujpnk5LfvKZD1yGEBh4kwjATK+1AoiNOVUZYAxZbNcSsqeUWxMcGhCE0P26jsIZs4+45m3oL3waxVJvB/22QfO1kIOK9TL3665r4Wk50iFQXzImOtdrZI37fxFxA/LdR3ay5je5tfu77aNYxRcoRuny5bWlitmV1MpWiMfOoq2g+Z1L83G1O1TQLPKLUMzmFFZnMKs9RGGRLJbLreOBmncsDjndvna2g77KGL+A9F8IAR7vDbyV3Jo65tDRPPrEWriCvVwVKl1kc0zew2bpWTPFNiEInLM9GOh8KsYF/ly7ULrOweQsxEziEGzULHGDBPYT0nSqD0XBgzihiOY78qZLB5LD2s4IhBv+iz5z06K9WcaiRZ23y+sq2xTJPpfVJL3KluA8MKZDuHkQq7AN4Ihm/ZV6h7fbmyE369sDr4JAHweJDgYLgSus5PaI6dqrwCqUvc5hXEqhuF9N3YZuwhufkUmoHjyjrU5iapimXC3dUus+1uvXaxOAnjSsM4lm5eAH9ZveLQTd07XIZSjR+NsRrkOIoJwP2IjoyccrjHXGK1zAZAxbLYb1UEciVj5ZkLKnbMFpVN6/KIa8fQVSovHlYAPnim6UxA5UCUNN6WgE1y0uTnIk7FhRIt+Ho8O/I9cA7qzw7A6I3pi4U7Jcq2LnnSq8d7PgnVqE1G/dHr80ZuPHlXqICznLm8pbWZ3FO/sU5/3p8QvUGmZlsl1VZU+hUwgs36Nd4IqTgKeQ2NfHoF9bWmjuuEzmgXTISYiZwu7qFf6ffHm5BtDYOuHCbXCsiw3HLuzod+/2+Wp61QhORos1Z4WzH91rPTrsVkDwhfTyKpanC/DrH/41j0H9Cebzs0nb4WQtK/wltGhlBmWDLaIe4+plwQuKsGMR1i64Jmp09uIkbb7SCg7SD0YT5GLWeoAKOYFR2qkVqoWXnWgzKDrXoDcAaqZiPueYxZ9Ud4ZHPnALAiOeo5ZBqxf1iAK9hORenQpdDwZMujPqGjC6XMnpb/OIIAEGrCSAMuQMILI7UCxyp14R6KzvSai45XlyezewHhTjqKb9FIES9ywdxfOIhn3hI70Z8WqTzw+AhKWTh2be3t8dY6bWaunzVu120vqIDDy3Gfrf4xa+zr0koPL8OH+D25PPrDh39gHpDFt+Tn3yuzxkVQ3jezZ8CP/IXqAoun/FyY6ya0Iik5T9TwJGfaEERVK5cRD0BN3LDuM0PhdTgkQhUpIYakWiKAgWyeuFnDAr0ZuDj5JQ19VZSc251o5bNQPr9R2qjfnnFr+AlEDS1dJgV94sx/7UuKyJPJ79Pn4VaD/XH8jUOYwfeInjfIpcBitu2ghDKtZyydfqJv0iTilXi35/MPiv3Nx324tcZjvoBWHbBJD7x8Y59+73haI/RH5It5nu69wryAxCbBC2pm7rnCysqr4nOQijIrbtJKwY8puAr/7fYbW0rAsl6ujoVCZAMCi2alkMijIiTX02GialGlMS9/cLppORetnQbpHY2TtmkrwJTmauGQbLKX49PP9hmIsU0uzDPq46llWQ95FjEpHCIML+rrlA4hLnSpLorLWcapZyAr0E0n8gozt15r0/Ne03QvGdhu5nPhFyaOi3tWtzSZMeJ1k2qVelJtd/WqPxDFFheuIXmL5La1nuM9UJLF77JKgDoBqSlY0FQCElJq1dg6vx+mzwgWEnSKsJ/4J/ddguCm+w5hz5yAVIokidaQ15areNPIJ79AOTtg0tN9tSHRe5TRwT3qZ3WYtXZlTTnVO6rUaRdimO14i0h3jKW1sZxk3TugzINl7mKlvgauC8AEYy4Mih1VxWuJaOMk0P9YGO5+8suQN6MmxABbghbo9xC12zyFx0o9Lx0rUm5Z8cX4+W1hF1mnXtgf8OrH9jFZ+d/zikZ1WRAmfR10325qJFcdFKrskIqQ2aXO11zw+K8mD6+nD99XUvG2WhFCGL6DiqrJwGjpCFf7r2h0p3TEh1xzBf/ZMV+WJF/5j1eTr99UdXuhfpwWAyqUylVK4YUPUYTJdQNmvkiCtJIooTjg8sHw3FDEnaIXGaHGyEOXLgOJPfvdk6FP70Bk1ZIYrigT8iBMLxvCiFdGGow1LB1N9JIZUqlLDxhZYgNdhniTwPiLAyI4YkbEENVw3i+ZwPCqDAg6ou8ie+Fu80xzq+SGKRmPy0b5jPCiRqdqJZvA2/wl+hIOlSHlM97NvTYoZBbuEQ2m50H5QQCsoo1Wft34fEvL4nnW+kj8tQfar6VsCCeTB880bJi2ZkSNULvTsawlKXeKpEdN9m1D8U40fGf41Fon0fldTfmNvxxYaaKgTk4NZOittGc4MLOCcgG0GVSHruyU1UpqbZJeUzSdR1oamRVvxpHluIl/vGOGKGk3JI3j488OvN8qyZpbdNvDxU6yGc6G7WL4Pg+PtPZyIfF/MjIZuOR5gV3wBCFQsRDQLDzDEFg/GjaL0lqpzvxLcXzx/T7z/Hjn5MvPx/unh8O4ezsPKlvP6rv+W36Let1enc//atGtw1zAhk3Ns4crDPVJ5LkdQbZXcpndlftSG+DVvGFGukt7AzRLCaKom/VljJyqz0fYzv1sAAKH5u4IwJ/7qPwOoovIu6NuGIFDnImsO4PLS+8CUHgLAflDgfi5afKwDQGozJpw4ZuW1vN9rsHpwcapS5iurBwSnKjx100bcq2GIb2RtsZmgEcDHW5dOkcvQBbJTfza3IQcz0luB0lD1sgnPQRZ3vhe2EU7BbRRwe/RnIxA2SYHdpQtcsK89Nnbh3u3heU3wmeLBRpgs6Bh3N2ZVuRdc1zLdXg9DgrL/6JP//7drtf55OOxyG46efa8iCb0yotXPR6Uopx83pW1K3KmyluPZWXJDivCm/Ny7Z3DiarvMBkvCPBYLLJrpHWxrEEaR/tKIV495k2jF33wuTBEDsZ0ZBUQh7QxIGwQ5lMnSAziNa3CDB5jkl2dXnFY4d6MbNj76fJC2WJQgVhkVkmu+7GvI6R+RmM2HcwoiyfejQiFldlGGQKX6fRiCOaYs+ENKXqSSO0g7mpo8qiNRJ3l+YCLBaUiV8Flo3iz++dIKklH2szAepnfw1DQrnsEpjWSME6VZqAErdNsKFOliXSAulM2p7h3oPq+CcZtoffBCDGtA4OA2SutQIJs7iiX8eEh85dPy5bs7bCdXzuwL6vTIC27jqWZlZydkHT6kO192rhacdk9CgXMWZiS4Pcu7stQGCyoy7mOLH4lqhI5Rvdk1yFYlVuUeer3mVx9vsALlJ6dnr8+IislJAU6kLaRFL7agKFWwROafVyIMQoO0psX6LfIFUOWiSdMEqopLXDWeeYzcwEkajUOWazmTKZsPWIJqoIB2LJRfWQUl5Eo52nIazAg8ouL3JcCMfhoCAL2RlOiPrykScsPa1Iuvoy3iFY+JpaNiQK4iS/pBbJ0omrhySJlfvfPyfnSsWDQHf8gSZs7gchvcekEEkCkIaxSYKgsPwJRqjTbRwBnTtjKZXe0tb3Vte3TIlfW6QkwWknLlNksyhTNMr2zwlPhV8DH7HOAVaD63/91bdRXMP0/w== -------------------------------------------------------------------------------- /docs/enums/_index_.les.message_codes.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["index"](../modules/_index_.md) / [LES](../classes/_index_.les.md) / MESSAGE\_CODES 4 | 5 | # Enumeration: MESSAGE\_CODES 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [ANNOUNCE](_index_.les.message_codes.md#announce) 12 | * [BLOCK\_BODIES](_index_.les.message_codes.md#block_bodies) 13 | * [BLOCK\_HEADERS](_index_.les.message_codes.md#block_headers) 14 | * [CONTRACT\_CODES](_index_.les.message_codes.md#contract_codes) 15 | * [GET\_BLOCK\_BODIES](_index_.les.message_codes.md#get_block_bodies) 16 | * [GET\_BLOCK\_HEADERS](_index_.les.message_codes.md#get_block_headers) 17 | * [GET\_CONTRACT\_CODES](_index_.les.message_codes.md#get_contract_codes) 18 | * [GET\_HEADER\_PROOFS](_index_.les.message_codes.md#get_header_proofs) 19 | * [GET\_HELPER\_TRIE\_PROOFS](_index_.les.message_codes.md#get_helper_trie_proofs) 20 | * [GET\_PROOFS](_index_.les.message_codes.md#get_proofs) 21 | * [GET\_PROOFS\_V2](_index_.les.message_codes.md#get_proofs_v2) 22 | * [GET\_RECEIPTS](_index_.les.message_codes.md#get_receipts) 23 | * [GET\_TX\_STATUS](_index_.les.message_codes.md#get_tx_status) 24 | * [HEADER\_PROOFS](_index_.les.message_codes.md#header_proofs) 25 | * [HELPER\_TRIE\_PROOFS](_index_.les.message_codes.md#helper_trie_proofs) 26 | * [PROOFS](_index_.les.message_codes.md#proofs) 27 | * [PROOFS\_V2](_index_.les.message_codes.md#proofs_v2) 28 | * [RECEIPTS](_index_.les.message_codes.md#receipts) 29 | * [SEND\_TX](_index_.les.message_codes.md#send_tx) 30 | * [SEND\_TX\_V2](_index_.les.message_codes.md#send_tx_v2) 31 | * [STATUS](_index_.les.message_codes.md#status) 32 | * [TX\_STATUS](_index_.les.message_codes.md#tx_status) 33 | 34 | ## Enumeration members 35 | 36 | ### ANNOUNCE 37 | 38 | • **ANNOUNCE**: = 1 39 | 40 | *Defined in [src/les/index.ts:230](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L230)* 41 | 42 | ___ 43 | 44 | ### BLOCK\_BODIES 45 | 46 | • **BLOCK\_BODIES**: = 5 47 | 48 | *Defined in [src/les/index.ts:234](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L234)* 49 | 50 | ___ 51 | 52 | ### BLOCK\_HEADERS 53 | 54 | • **BLOCK\_HEADERS**: = 3 55 | 56 | *Defined in [src/les/index.ts:232](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L232)* 57 | 58 | ___ 59 | 60 | ### CONTRACT\_CODES 61 | 62 | • **CONTRACT\_CODES**: = 11 63 | 64 | *Defined in [src/les/index.ts:240](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L240)* 65 | 66 | ___ 67 | 68 | ### GET\_BLOCK\_BODIES 69 | 70 | • **GET\_BLOCK\_BODIES**: = 4 71 | 72 | *Defined in [src/les/index.ts:233](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L233)* 73 | 74 | ___ 75 | 76 | ### GET\_BLOCK\_HEADERS 77 | 78 | • **GET\_BLOCK\_HEADERS**: = 2 79 | 80 | *Defined in [src/les/index.ts:231](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L231)* 81 | 82 | ___ 83 | 84 | ### GET\_CONTRACT\_CODES 85 | 86 | • **GET\_CONTRACT\_CODES**: = 10 87 | 88 | *Defined in [src/les/index.ts:239](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L239)* 89 | 90 | ___ 91 | 92 | ### GET\_HEADER\_PROOFS 93 | 94 | • **GET\_HEADER\_PROOFS**: = 13 95 | 96 | *Defined in [src/les/index.ts:241](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L241)* 97 | 98 | ___ 99 | 100 | ### GET\_HELPER\_TRIE\_PROOFS 101 | 102 | • **GET\_HELPER\_TRIE\_PROOFS**: = 17 103 | 104 | *Defined in [src/les/index.ts:248](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L248)* 105 | 106 | ___ 107 | 108 | ### GET\_PROOFS 109 | 110 | • **GET\_PROOFS**: = 8 111 | 112 | *Defined in [src/les/index.ts:237](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L237)* 113 | 114 | ___ 115 | 116 | ### GET\_PROOFS\_V2 117 | 118 | • **GET\_PROOFS\_V2**: = 15 119 | 120 | *Defined in [src/les/index.ts:246](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L246)* 121 | 122 | ___ 123 | 124 | ### GET\_RECEIPTS 125 | 126 | • **GET\_RECEIPTS**: = 6 127 | 128 | *Defined in [src/les/index.ts:235](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L235)* 129 | 130 | ___ 131 | 132 | ### GET\_TX\_STATUS 133 | 134 | • **GET\_TX\_STATUS**: = 20 135 | 136 | *Defined in [src/les/index.ts:251](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L251)* 137 | 138 | ___ 139 | 140 | ### HEADER\_PROOFS 141 | 142 | • **HEADER\_PROOFS**: = 14 143 | 144 | *Defined in [src/les/index.ts:242](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L242)* 145 | 146 | ___ 147 | 148 | ### HELPER\_TRIE\_PROOFS 149 | 150 | • **HELPER\_TRIE\_PROOFS**: = 18 151 | 152 | *Defined in [src/les/index.ts:249](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L249)* 153 | 154 | ___ 155 | 156 | ### PROOFS 157 | 158 | • **PROOFS**: = 9 159 | 160 | *Defined in [src/les/index.ts:238](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L238)* 161 | 162 | ___ 163 | 164 | ### PROOFS\_V2 165 | 166 | • **PROOFS\_V2**: = 16 167 | 168 | *Defined in [src/les/index.ts:247](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L247)* 169 | 170 | ___ 171 | 172 | ### RECEIPTS 173 | 174 | • **RECEIPTS**: = 7 175 | 176 | *Defined in [src/les/index.ts:236](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L236)* 177 | 178 | ___ 179 | 180 | ### SEND\_TX 181 | 182 | • **SEND\_TX**: = 12 183 | 184 | *Defined in [src/les/index.ts:243](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L243)* 185 | 186 | ___ 187 | 188 | ### SEND\_TX\_V2 189 | 190 | • **SEND\_TX\_V2**: = 19 191 | 192 | *Defined in [src/les/index.ts:250](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L250)* 193 | 194 | ___ 195 | 196 | ### STATUS 197 | 198 | • **STATUS**: = 0 199 | 200 | *Defined in [src/les/index.ts:229](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L229)* 201 | 202 | ___ 203 | 204 | ### TX\_STATUS 205 | 206 | • **TX\_STATUS**: = 21 207 | 208 | *Defined in [src/les/index.ts:252](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L252)* 209 | -------------------------------------------------------------------------------- /docs/enums/_les_index_.les.message_codes.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / ["les/index"](../modules/_les_index_.md) / [LES](../classes/_les_index_.les.md) / MESSAGE\_CODES 4 | 5 | # Enumeration: MESSAGE\_CODES 6 | 7 | ## Index 8 | 9 | ### Enumeration members 10 | 11 | * [ANNOUNCE](_les_index_.les.message_codes.md#announce) 12 | * [BLOCK\_BODIES](_les_index_.les.message_codes.md#block_bodies) 13 | * [BLOCK\_HEADERS](_les_index_.les.message_codes.md#block_headers) 14 | * [CONTRACT\_CODES](_les_index_.les.message_codes.md#contract_codes) 15 | * [GET\_BLOCK\_BODIES](_les_index_.les.message_codes.md#get_block_bodies) 16 | * [GET\_BLOCK\_HEADERS](_les_index_.les.message_codes.md#get_block_headers) 17 | * [GET\_CONTRACT\_CODES](_les_index_.les.message_codes.md#get_contract_codes) 18 | * [GET\_HEADER\_PROOFS](_les_index_.les.message_codes.md#get_header_proofs) 19 | * [GET\_HELPER\_TRIE\_PROOFS](_les_index_.les.message_codes.md#get_helper_trie_proofs) 20 | * [GET\_PROOFS](_les_index_.les.message_codes.md#get_proofs) 21 | * [GET\_PROOFS\_V2](_les_index_.les.message_codes.md#get_proofs_v2) 22 | * [GET\_RECEIPTS](_les_index_.les.message_codes.md#get_receipts) 23 | * [GET\_TX\_STATUS](_les_index_.les.message_codes.md#get_tx_status) 24 | * [HEADER\_PROOFS](_les_index_.les.message_codes.md#header_proofs) 25 | * [HELPER\_TRIE\_PROOFS](_les_index_.les.message_codes.md#helper_trie_proofs) 26 | * [PROOFS](_les_index_.les.message_codes.md#proofs) 27 | * [PROOFS\_V2](_les_index_.les.message_codes.md#proofs_v2) 28 | * [RECEIPTS](_les_index_.les.message_codes.md#receipts) 29 | * [SEND\_TX](_les_index_.les.message_codes.md#send_tx) 30 | * [SEND\_TX\_V2](_les_index_.les.message_codes.md#send_tx_v2) 31 | * [STATUS](_les_index_.les.message_codes.md#status) 32 | * [TX\_STATUS](_les_index_.les.message_codes.md#tx_status) 33 | 34 | ## Enumeration members 35 | 36 | ### ANNOUNCE 37 | 38 | • **ANNOUNCE**: = 1 39 | 40 | *Defined in [src/les/index.ts:230](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L230)* 41 | 42 | ___ 43 | 44 | ### BLOCK\_BODIES 45 | 46 | • **BLOCK\_BODIES**: = 5 47 | 48 | *Defined in [src/les/index.ts:234](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L234)* 49 | 50 | ___ 51 | 52 | ### BLOCK\_HEADERS 53 | 54 | • **BLOCK\_HEADERS**: = 3 55 | 56 | *Defined in [src/les/index.ts:232](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L232)* 57 | 58 | ___ 59 | 60 | ### CONTRACT\_CODES 61 | 62 | • **CONTRACT\_CODES**: = 11 63 | 64 | *Defined in [src/les/index.ts:240](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L240)* 65 | 66 | ___ 67 | 68 | ### GET\_BLOCK\_BODIES 69 | 70 | • **GET\_BLOCK\_BODIES**: = 4 71 | 72 | *Defined in [src/les/index.ts:233](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L233)* 73 | 74 | ___ 75 | 76 | ### GET\_BLOCK\_HEADERS 77 | 78 | • **GET\_BLOCK\_HEADERS**: = 2 79 | 80 | *Defined in [src/les/index.ts:231](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L231)* 81 | 82 | ___ 83 | 84 | ### GET\_CONTRACT\_CODES 85 | 86 | • **GET\_CONTRACT\_CODES**: = 10 87 | 88 | *Defined in [src/les/index.ts:239](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L239)* 89 | 90 | ___ 91 | 92 | ### GET\_HEADER\_PROOFS 93 | 94 | • **GET\_HEADER\_PROOFS**: = 13 95 | 96 | *Defined in [src/les/index.ts:241](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L241)* 97 | 98 | ___ 99 | 100 | ### GET\_HELPER\_TRIE\_PROOFS 101 | 102 | • **GET\_HELPER\_TRIE\_PROOFS**: = 17 103 | 104 | *Defined in [src/les/index.ts:248](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L248)* 105 | 106 | ___ 107 | 108 | ### GET\_PROOFS 109 | 110 | • **GET\_PROOFS**: = 8 111 | 112 | *Defined in [src/les/index.ts:237](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L237)* 113 | 114 | ___ 115 | 116 | ### GET\_PROOFS\_V2 117 | 118 | • **GET\_PROOFS\_V2**: = 15 119 | 120 | *Defined in [src/les/index.ts:246](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L246)* 121 | 122 | ___ 123 | 124 | ### GET\_RECEIPTS 125 | 126 | • **GET\_RECEIPTS**: = 6 127 | 128 | *Defined in [src/les/index.ts:235](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L235)* 129 | 130 | ___ 131 | 132 | ### GET\_TX\_STATUS 133 | 134 | • **GET\_TX\_STATUS**: = 20 135 | 136 | *Defined in [src/les/index.ts:251](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L251)* 137 | 138 | ___ 139 | 140 | ### HEADER\_PROOFS 141 | 142 | • **HEADER\_PROOFS**: = 14 143 | 144 | *Defined in [src/les/index.ts:242](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L242)* 145 | 146 | ___ 147 | 148 | ### HELPER\_TRIE\_PROOFS 149 | 150 | • **HELPER\_TRIE\_PROOFS**: = 18 151 | 152 | *Defined in [src/les/index.ts:249](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L249)* 153 | 154 | ___ 155 | 156 | ### PROOFS 157 | 158 | • **PROOFS**: = 9 159 | 160 | *Defined in [src/les/index.ts:238](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L238)* 161 | 162 | ___ 163 | 164 | ### PROOFS\_V2 165 | 166 | • **PROOFS\_V2**: = 16 167 | 168 | *Defined in [src/les/index.ts:247](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L247)* 169 | 170 | ___ 171 | 172 | ### RECEIPTS 173 | 174 | • **RECEIPTS**: = 7 175 | 176 | *Defined in [src/les/index.ts:236](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L236)* 177 | 178 | ___ 179 | 180 | ### SEND\_TX 181 | 182 | • **SEND\_TX**: = 12 183 | 184 | *Defined in [src/les/index.ts:243](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L243)* 185 | 186 | ___ 187 | 188 | ### SEND\_TX\_V2 189 | 190 | • **SEND\_TX\_V2**: = 19 191 | 192 | *Defined in [src/les/index.ts:250](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L250)* 193 | 194 | ___ 195 | 196 | ### STATUS 197 | 198 | • **STATUS**: = 0 199 | 200 | *Defined in [src/les/index.ts:229](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L229)* 201 | 202 | ___ 203 | 204 | ### TX\_STATUS 205 | 206 | • **TX\_STATUS**: = 21 207 | 208 | *Defined in [src/les/index.ts:252](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L252)* 209 | -------------------------------------------------------------------------------- /src/dpt/message.ts: -------------------------------------------------------------------------------- 1 | import { debug as createDebugLogger } from 'debug' 2 | import ip from 'ip' 3 | import * as rlp from 'rlp' 4 | import secp256k1 from 'secp256k1' 5 | import { keccak256, int2buffer, buffer2int, assertEq, unstrictDecode } from '../util' 6 | 7 | const debug = createDebugLogger('devp2p:dpt:server') 8 | 9 | function getTimestamp() { 10 | return (Date.now() / 1000) | 0 11 | } 12 | 13 | export interface PeerInfo { 14 | id?: Buffer 15 | address?: string 16 | udpPort?: number | null 17 | tcpPort?: number | null 18 | } 19 | 20 | const timestamp = { 21 | encode: function(value = getTimestamp() + 60) { 22 | const buffer = Buffer.allocUnsafe(4) 23 | buffer.writeUInt32BE(value, 0) 24 | return buffer 25 | }, 26 | decode: function(buffer: Buffer) { 27 | if (buffer.length !== 4) 28 | throw new RangeError(`Invalid timestamp buffer :${buffer.toString('hex')}`) 29 | return buffer.readUInt32BE(0) 30 | } 31 | } 32 | 33 | const address = { 34 | encode: function(value: string) { 35 | if (ip.isV4Format(value)) return ip.toBuffer(value) 36 | if (ip.isV6Format(value)) return ip.toBuffer(value) 37 | throw new Error(`Invalid address: ${value}`) 38 | }, 39 | decode: function(buffer: Buffer) { 40 | if (buffer.length === 4) return ip.toString(buffer) 41 | if (buffer.length === 16) return ip.toString(buffer) 42 | 43 | const str = buffer.toString() 44 | if (ip.isV4Format(str) || ip.isV6Format(str)) return str 45 | 46 | // also can be host, but skip it right now (because need async function for resolve) 47 | throw new Error(`Invalid address buffer: ${buffer.toString('hex')}`) 48 | } 49 | } 50 | 51 | const port = { 52 | encode: function(value: number | null): Buffer { 53 | if (value === null) return Buffer.allocUnsafe(0) 54 | if (value >>> 16 > 0) throw new RangeError(`Invalid port: ${value}`) 55 | return Buffer.from([(value >>> 8) & 0xff, (value >>> 0) & 0xff]) 56 | }, 57 | decode: function(buffer: Buffer): number | null { 58 | if (buffer.length === 0) return null 59 | // if (buffer.length !== 2) throw new RangeError(`Invalid port buffer: ${buffer.toString('hex')}`) 60 | return buffer2int(buffer) 61 | } 62 | } 63 | 64 | const endpoint = { 65 | encode: function(obj: PeerInfo): Buffer[] { 66 | return [ 67 | address.encode(obj.address!), 68 | port.encode(obj.udpPort || null), 69 | port.encode(obj.tcpPort || null) 70 | ] 71 | }, 72 | decode: function(payload: Buffer[]): PeerInfo { 73 | return { 74 | address: address.decode(payload[0]), 75 | udpPort: port.decode(payload[1]), 76 | tcpPort: port.decode(payload[2]) 77 | } 78 | } 79 | } 80 | 81 | type InPing = { [0]: Buffer; [1]: Buffer[]; [2]: Buffer[]; [3]: Buffer } 82 | type OutPing = { version: number; from: PeerInfo; to: PeerInfo; timestamp: number } 83 | const ping = { 84 | encode: function(obj: OutPing): InPing { 85 | return [ 86 | int2buffer(obj.version), 87 | endpoint.encode(obj.from), 88 | endpoint.encode(obj.to), 89 | timestamp.encode(obj.timestamp) 90 | ] 91 | }, 92 | decode: function(payload: InPing): OutPing { 93 | return { 94 | version: buffer2int(payload[0]), 95 | from: endpoint.decode(payload[1]), 96 | to: endpoint.decode(payload[2]), 97 | timestamp: timestamp.decode(payload[3]) 98 | } 99 | } 100 | } 101 | 102 | type OutPong = { to: PeerInfo; hash: Buffer; timestamp: number } 103 | type InPong = { [0]: Buffer[]; [1]: Buffer[]; [2]: Buffer } 104 | const pong = { 105 | encode: function(obj: OutPong) { 106 | return [endpoint.encode(obj.to), obj.hash, timestamp.encode(obj.timestamp)] 107 | }, 108 | decode: function(payload: InPong) { 109 | return { 110 | to: endpoint.decode(payload[0]), 111 | hash: payload[1], 112 | timestamp: timestamp.decode(payload[2]) 113 | } 114 | } 115 | } 116 | 117 | type OutFindMsg = { id: string; timestamp: number } 118 | type InFindMsg = { [0]: string; [1]: Buffer } 119 | const findneighbours = { 120 | encode: function(obj: OutFindMsg): InFindMsg { 121 | return [obj.id, timestamp.encode(obj.timestamp)] 122 | }, 123 | decode: function(payload: InFindMsg): OutFindMsg { 124 | return { 125 | id: payload[0], 126 | timestamp: timestamp.decode(payload[1]) 127 | } 128 | } 129 | } 130 | 131 | type InNeighborMsg = { peers: PeerInfo[]; timestamp: number } 132 | type OutNeighborMsg = { [0]: Buffer[][]; [1]: Buffer } 133 | const neighbours = { 134 | encode: function(obj: InNeighborMsg): OutNeighborMsg { 135 | return [ 136 | obj.peers.map((peer: PeerInfo) => endpoint.encode(peer).concat(peer.id!)), 137 | timestamp.encode(obj.timestamp) 138 | ] 139 | }, 140 | decode: function(payload: OutNeighborMsg): InNeighborMsg { 141 | return { 142 | peers: payload[0].map(data => { 143 | return { endpoint: endpoint.decode(data), id: data[3] } // hack for id 144 | }), 145 | timestamp: timestamp.decode(payload[1]) 146 | } 147 | } 148 | } 149 | 150 | const messages: any = { ping, pong, findneighbours, neighbours } 151 | 152 | type Types = { [index: string]: { [index: string]: number | string } } 153 | const types: Types = { 154 | byName: { 155 | ping: 0x01, 156 | pong: 0x02, 157 | findneighbours: 0x03, 158 | neighbours: 0x04 159 | }, 160 | byType: { 161 | 0x01: 'ping', 162 | 0x02: 'pong', 163 | 0x03: 'findneighbours', 164 | 0x04: 'neighbours' 165 | } 166 | } 167 | 168 | // [0, 32) data hash 169 | // [32, 96) signature 170 | // 96 recoveryId 171 | // 97 type 172 | // [98, length) data 173 | 174 | export function encode(typename: string, data: T, privateKey: Buffer) { 175 | const type: number = types.byName[typename] as number 176 | if (type === undefined) throw new Error(`Invalid typename: ${typename}`) 177 | const encodedMsg = messages[typename].encode(data) 178 | const typedata = Buffer.concat([Buffer.from([type]), rlp.encode(encodedMsg)]) 179 | 180 | const sighash = keccak256(typedata) 181 | const sig = secp256k1.ecdsaSign(sighash, privateKey) 182 | const hashdata = Buffer.concat([Buffer.from(sig.signature), Buffer.from([sig.recid]), typedata]) 183 | const hash = keccak256(hashdata) 184 | return Buffer.concat([hash, hashdata]) 185 | } 186 | 187 | export function decode(buffer: Buffer) { 188 | const hash = keccak256(buffer.slice(32)) 189 | assertEq(buffer.slice(0, 32), hash, 'Hash verification failed', debug) 190 | 191 | const typedata = buffer.slice(97) 192 | const type = typedata[0] 193 | const typename = types.byType[type] 194 | if (typename === undefined) throw new Error(`Invalid type: ${type}`) 195 | const data = messages[typename].decode(unstrictDecode(typedata.slice(1))) 196 | 197 | const sighash = keccak256(typedata) 198 | const signature = buffer.slice(32, 96) 199 | const recoverId = buffer[96] 200 | const publicKey = Buffer.from(secp256k1.ecdsaRecover(signature, recoverId, sighash, false)) 201 | 202 | return { typename, data, publicKey } 203 | } 204 | -------------------------------------------------------------------------------- /test/integration/eth-simulator.ts: -------------------------------------------------------------------------------- 1 | import test from 'tape' 2 | import * as devp2p from '../../src' 3 | import * as util from './util' 4 | import Common from '@ethereumjs/common' 5 | 6 | const GENESIS_TD = 17179869184 7 | const GENESIS_HASH = Buffer.from( 8 | 'd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', 9 | 'hex' 10 | ) 11 | 12 | const capabilities = [devp2p.ETH.eth63, devp2p.ETH.eth62] 13 | 14 | const status = { 15 | td: devp2p.int2buffer(GENESIS_TD), 16 | bestHash: GENESIS_HASH, 17 | genesisHash: GENESIS_HASH 18 | } 19 | 20 | // FIXME: Handle unhandled promises directly 21 | process.on('unhandledRejection', () => {}) 22 | 23 | test('ETH: send status message (successful)', async t => { 24 | const opts: any = {} 25 | opts.status0 = Object.assign({}, status) 26 | opts.status1 = Object.assign({}, status) 27 | opts.onOnceStatus0 = function(rlpxs: any) { 28 | t.pass('should receive echoing status message and welcome connection') 29 | util.destroyRLPXs(rlpxs) 30 | t.end() 31 | } 32 | util.twoPeerMsgExchange(t, opts, capabilities) 33 | }) 34 | 35 | test('ETH: send status message (NetworkId mismatch)', async t => { 36 | const opts: any = {} 37 | opts.status0 = Object.assign({}, status) 38 | opts.status1 = Object.assign({}, status) 39 | opts.onPeerError0 = function(err: Error, rlpxs: any) { 40 | const msg = 'NetworkId mismatch: 01 / 03' 41 | t.equal(err.message, msg, `should emit error: ${msg}`) 42 | util.destroyRLPXs(rlpxs) 43 | t.end() 44 | } 45 | 46 | const c1 = new Common({ chain: 'mainnet' }) 47 | const c2 = new Common({ chain: 'ropsten' }) 48 | util.twoPeerMsgExchange(t, opts, capabilities, [c1, c2]) 49 | }) 50 | 51 | test('ETH: send status message (Genesis block mismatch)', async t => { 52 | const opts: any = {} 53 | opts.status0 = Object.assign({}, status) 54 | const status1 = Object.assign({}, status) 55 | status1['genesisHash'] = Buffer.alloc(32) 56 | opts.status1 = status1 57 | opts.onPeerError0 = function(err: Error, rlpxs: any) { 58 | const msg = 59 | 'Genesis block mismatch: d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3 / 0000000000000000000000000000000000000000000000000000000000000000' 60 | t.equal(err.message, msg, `should emit error: ${msg}`) 61 | util.destroyRLPXs(rlpxs) 62 | t.end() 63 | } 64 | util.twoPeerMsgExchange(t, opts, capabilities) 65 | }) 66 | 67 | function sendWithProtocolVersion(t: test.Test, version: number, cap?: Object) { 68 | const opts: any = {} 69 | opts.status0 = Object.assign({}, status) 70 | opts.status1 = Object.assign({}, status) 71 | opts.onOnceStatus0 = function(rlpxs: any, eth: any) { 72 | t.equal(eth.getVersion(), version, `should use eth${version} as protocol version`) 73 | eth.sendMessage(devp2p.ETH.MESSAGE_CODES.NEW_BLOCK_HASHES, [437000, 1, 0, 0]) 74 | t.pass('should send NEW_BLOCK_HASHES message') 75 | } 76 | opts.onOnMsg1 = function(rlpxs: any, eth: any, code: any) { 77 | if (code === devp2p.ETH.MESSAGE_CODES.NEW_BLOCK_HASHES) { 78 | t.pass('should receive NEW_BLOCK_HASHES message') 79 | util.destroyRLPXs(rlpxs) 80 | t.end() 81 | } 82 | } 83 | util.twoPeerMsgExchange(t, opts, cap) 84 | } 85 | 86 | test('ETH: should use latest protocol version on default', async t => { 87 | sendWithProtocolVersion(t, 64) 88 | }) 89 | 90 | test('ETH: should work with allowed eth64', async t => { 91 | sendWithProtocolVersion(t, 64) 92 | }) 93 | 94 | test('ETH -> Eth64 -> sendStatus(): should throw on non-matching latest block provided', async t => { 95 | const cap = [devp2p.ETH.eth64] 96 | const common = new Common({ chain: 'mainnet', hardfork: 'byzantium' }) 97 | const status0: any = Object.assign({}, status) 98 | status0['latestBlock'] = 100000 // lower than Byzantium fork block 4370000 99 | 100 | const rlpxs = util.initTwoPeerRLPXSetup(null, cap, common) 101 | rlpxs[0].on('peer:added', function(peer: any) { 102 | const protocol = peer.getProtocols()[0] 103 | t.throws(() => { 104 | protocol.sendStatus(status0) 105 | }, /latest block provided is not matching the HF setting/) 106 | util.destroyRLPXs(rlpxs) 107 | t.end() 108 | }) 109 | }) 110 | 111 | test('ETH -> Eth64 -> ForkId validation 1a)', async t => { 112 | const opts: any = {} 113 | const cap = [devp2p.ETH.eth64] 114 | const common = new Common({ chain: 'mainnet', hardfork: 'byzantium' }) 115 | const status0: any = Object.assign({}, status) 116 | // Take a latest block > next mainnet fork block (constantinople) 117 | // to trigger validation condition 118 | status0['latestBlock'] = 9069000 119 | opts.status0 = status0 120 | opts.status1 = Object.assign({}, status) 121 | opts.onPeerError0 = function(err: Error, rlpxs: any) { 122 | const msg = 'Remote is advertising a future fork that passed locally' 123 | t.equal(err.message, msg, `should emit error: ${msg}`) 124 | util.destroyRLPXs(rlpxs) 125 | t.end() 126 | } 127 | 128 | util.twoPeerMsgExchange(t, opts, cap, common) 129 | }) 130 | 131 | test('ETH: should work with allowed eth63', async t => { 132 | const cap = [devp2p.ETH.eth63] 133 | sendWithProtocolVersion(t, 63, cap) 134 | }) 135 | 136 | test('ETH: should work with allowed eth63', async t => { 137 | const cap = [devp2p.ETH.eth63] 138 | sendWithProtocolVersion(t, 63, cap) 139 | }) 140 | 141 | test('ETH: work with allowed eth62', async t => { 142 | const cap = [devp2p.ETH.eth62] 143 | sendWithProtocolVersion(t, 62, cap) 144 | }) 145 | 146 | test('ETH: send not-allowed eth62', async t => { 147 | const cap = [devp2p.ETH.eth62] 148 | const opts: any = {} 149 | opts.status0 = Object.assign({}, status) 150 | opts.status1 = Object.assign({}, status) 151 | opts.onOnceStatus0 = function(rlpxs: any, eth: any) { 152 | try { 153 | eth.sendMessage(devp2p.ETH.MESSAGE_CODES.GET_NODE_DATA, []) 154 | } catch (err) { 155 | const msg = 'Error: Code 13 not allowed with version 62' 156 | t.equal(err.toString(), msg, `should emit error: ${msg}`) 157 | util.destroyRLPXs(rlpxs) 158 | t.end() 159 | } 160 | } 161 | util.twoPeerMsgExchange(t, opts, cap) 162 | }) 163 | 164 | test('ETH: send unknown message code', async t => { 165 | const opts: any = {} 166 | opts.status0 = Object.assign({}, status) 167 | opts.status1 = Object.assign({}, status) 168 | opts.onOnceStatus0 = function(rlpxs: any, eth: any) { 169 | try { 170 | eth.sendMessage(0x55, []) 171 | } catch (err) { 172 | const msg = 'Error: Unknown code 85' 173 | t.equal(err.toString(), msg, `should emit error: ${msg}`) 174 | util.destroyRLPXs(rlpxs) 175 | t.end() 176 | } 177 | } 178 | util.twoPeerMsgExchange(t, opts, capabilities) 179 | }) 180 | 181 | test('ETH: invalid status send', async t => { 182 | const opts: any = {} 183 | opts.status0 = Object.assign({}, status) 184 | opts.status1 = Object.assign({}, status) 185 | opts.onOnceStatus0 = function(rlpxs: any, eth: any) { 186 | try { 187 | eth.sendMessage(devp2p.ETH.MESSAGE_CODES.STATUS, []) 188 | } catch (err) { 189 | const msg = 'Error: Please send status message through .sendStatus' 190 | t.equal(err.toString(), msg, `should emit error: ${msg}`) 191 | util.destroyRLPXs(rlpxs) 192 | t.end() 193 | } 194 | } 195 | util.twoPeerMsgExchange(t, opts, capabilities) 196 | }) 197 | -------------------------------------------------------------------------------- /examples/peer-communication-les.ts: -------------------------------------------------------------------------------- 1 | import * as devp2p from '../src/index' 2 | import { LES, Peer } from '../src/index' 3 | import Common from '@ethereumjs/common' 4 | import { Transaction } from '@ethereumjs/tx' 5 | import { Block, BlockHeader } from '@ethereumjs/block' 6 | import ms from 'ms' 7 | import chalk from 'chalk' 8 | import assert from 'assert' 9 | import { randomBytes } from 'crypto' 10 | 11 | const PRIVATE_KEY = randomBytes(32) 12 | 13 | const GENESIS_TD = 1 14 | const GENESIS_HASH = Buffer.from( 15 | '6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177', 16 | 'hex' 17 | ) 18 | 19 | const common = new Common({ chain: 'rinkeby' }) 20 | const bootstrapNodes = common.bootstrapNodes() 21 | const BOOTNODES = bootstrapNodes.map((node: any) => { 22 | return { 23 | address: node.ip, 24 | udpPort: node.port, 25 | tcpPort: node.port 26 | } 27 | }) 28 | const REMOTE_CLIENTID_FILTER = [ 29 | 'go1.5', 30 | 'go1.6', 31 | 'go1.7', 32 | 'Geth/v1.7', 33 | 'quorum', 34 | 'pirl', 35 | 'ubiq', 36 | 'gmc', 37 | 'gwhale', 38 | 'prichain' 39 | ] 40 | 41 | const getPeerAddr = (peer: Peer) => `${peer._socket.remoteAddress}:${peer._socket.remotePort}` 42 | 43 | // DPT 44 | const dpt = new devp2p.DPT(PRIVATE_KEY, { 45 | refreshInterval: 30000, 46 | endpoint: { 47 | address: '0.0.0.0', 48 | udpPort: null, 49 | tcpPort: null 50 | } 51 | }) 52 | 53 | /* eslint-disable no-console */ 54 | dpt.on('error', err => console.error(chalk.red(`DPT error: ${err}`))) 55 | 56 | /* eslint-disable @typescript-eslint/no-use-before-define */ 57 | 58 | // RLPx 59 | const rlpx = new devp2p.RLPx(PRIVATE_KEY, { 60 | dpt: dpt, 61 | maxPeers: 25, 62 | capabilities: [devp2p.LES.les2], 63 | common: common, 64 | remoteClientIdFilter: REMOTE_CLIENTID_FILTER, 65 | listenPort: null 66 | }) 67 | 68 | rlpx.on('error', err => console.error(chalk.red(`RLPx error: ${err.stack || err}`))) 69 | 70 | rlpx.on('peer:added', peer => { 71 | const addr = getPeerAddr(peer) 72 | const les = peer.getProtocols()[0] 73 | const requests: { headers: BlockHeader[]; bodies: any[] } = { headers: [], bodies: [] } 74 | 75 | const clientId = peer.getHelloMessage().clientId 76 | console.log( 77 | chalk.green( 78 | `Add peer: ${addr} ${clientId} (les${les.getVersion()}) (total: ${rlpx.getPeers().length})` 79 | ) 80 | ) 81 | 82 | les.sendStatus({ 83 | headTd: devp2p.int2buffer(GENESIS_TD), 84 | headHash: GENESIS_HASH, 85 | headNum: Buffer.from([]), 86 | genesisHash: GENESIS_HASH 87 | }) 88 | 89 | les.once('status', (status: LES.Status) => { 90 | const msg = [devp2p.buffer2int(status['headNum']), 1, 0, 1] 91 | les.sendMessage(devp2p.LES.MESSAGE_CODES.GET_BLOCK_HEADERS, 1, msg) 92 | }) 93 | 94 | les.on('message', async (code: LES.MESSAGE_CODES, payload: any) => { 95 | switch (code) { 96 | case devp2p.LES.MESSAGE_CODES.BLOCK_HEADERS: { 97 | if (payload[2].length > 1) { 98 | console.log( 99 | `${addr} not more than one block header expected (received: ${payload[2].length})` 100 | ) 101 | break 102 | } 103 | const header = BlockHeader.fromValuesArray(payload[2][0], {}) 104 | 105 | setTimeout(() => { 106 | les.sendMessage(devp2p.LES.MESSAGE_CODES.GET_BLOCK_BODIES, 2, [header.hash()]) 107 | requests.bodies.push(header) 108 | }, ms('0.1s')) 109 | break 110 | } 111 | 112 | case devp2p.LES.MESSAGE_CODES.BLOCK_BODIES: { 113 | if (payload[2].length !== 1) { 114 | console.log( 115 | `${addr} not more than one block body expected (received: ${payload[2].length})` 116 | ) 117 | break 118 | } 119 | 120 | const header2 = requests.bodies.shift() 121 | const txs = payload[2][0][0] 122 | const uncleHeaders = payload[2][0][1] 123 | const block = Block.fromValuesArray([header2.raw(), txs, uncleHeaders]) 124 | const isValid = await isValidBlock(block) 125 | let isValidPayload = false 126 | if (isValid) { 127 | isValidPayload = true 128 | onNewBlock(block, peer) 129 | break 130 | } 131 | 132 | if (!isValidPayload) { 133 | console.log(`${addr} received wrong block body`) 134 | } 135 | break 136 | } 137 | } 138 | }) 139 | }) 140 | 141 | rlpx.on('peer:removed', (peer, reasonCode, disconnectWe) => { 142 | const who = disconnectWe ? 'we disconnect' : 'peer disconnect' 143 | const total = rlpx.getPeers().length 144 | console.log( 145 | chalk.yellow( 146 | `Remove peer: ${getPeerAddr(peer)} - ${who}, reason: ${peer.getDisconnectPrefix( 147 | reasonCode 148 | )} (${String(reasonCode)}) (total: ${total})` 149 | ) 150 | ) 151 | }) 152 | 153 | rlpx.on('peer:error', (peer, err) => { 154 | if (err.code === 'ECONNRESET') return 155 | 156 | if (err instanceof assert.AssertionError) { 157 | const peerId = peer.getId() 158 | if (peerId !== null) dpt.banPeer(peerId, ms('5m')) 159 | 160 | console.error(chalk.red(`Peer error (${getPeerAddr(peer)}): ${err.message}`)) 161 | return 162 | } 163 | 164 | console.error(chalk.red(`Peer error (${getPeerAddr(peer)}): ${err.stack || err}`)) 165 | }) 166 | 167 | // uncomment, if you want accept incoming connections 168 | // rlpx.listen(30303, '0.0.0.0') 169 | // dpt.bind(30303, '0.0.0.0') 170 | 171 | for (const bootnode of BOOTNODES) { 172 | dpt.bootstrap(bootnode).catch(err => { 173 | console.error(chalk.bold.red(`DPT bootstrap error: ${err.stack || err}`)) 174 | }) 175 | } 176 | 177 | // connect to local ethereum node (debug) 178 | /* 179 | dpt.addPeer({ address: '127.0.0.1', udpPort: 30303, tcpPort: 30303 }) 180 | .then((peer) => { 181 | return rlpx.connect({ 182 | id: peer.id, 183 | address: peer.address, 184 | port: peer.tcpPort 185 | }) 186 | }) 187 | .catch((err) => console.log(`error on connection to local node: ${err.stack || err}`)) */ 188 | 189 | function onNewBlock(block: Block, peer: Peer) { 190 | const blockHashHex = block.hash().toString('hex') 191 | const blockNumber = block.header.number.toNumber() 192 | 193 | console.log( 194 | `----------------------------------------------------------------------------------------------------------` 195 | ) 196 | console.log(`block ${blockNumber} received: ${blockHashHex} (from ${getPeerAddr(peer)})`) 197 | console.log( 198 | `----------------------------------------------------------------------------------------------------------` 199 | ) 200 | } 201 | 202 | function isValidTx(tx: Transaction) { 203 | return tx.validate() 204 | } 205 | 206 | async function isValidBlock(block: Block) { 207 | return ( 208 | block.validateUnclesHash() && 209 | block.transactions.every(isValidTx) && 210 | block.validateTransactionsTrie() 211 | ) 212 | } 213 | 214 | setInterval(() => { 215 | const peersCount = dpt.getPeers().length 216 | const openSlots = rlpx._getOpenSlots() 217 | const queueLength = rlpx._peersQueue.length 218 | const queueLength2 = rlpx._peersQueue.filter(o => o.ts <= Date.now()).length 219 | 220 | console.log( 221 | chalk.yellow( 222 | `Total nodes in DPT: ${peersCount}, open slots: ${openSlots}, queue: ${queueLength} / ${queueLength2}` 223 | ) 224 | ) 225 | }, ms('30s')) 226 | -------------------------------------------------------------------------------- /test/testdata.json: -------------------------------------------------------------------------------- 1 | { 2 | "eip8Values": { 3 | "keyA": "49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee", 4 | "keyB": "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291", 5 | "pubA": "fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877", 6 | "pubB": "ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be00812904767bf5ccd1fc7f", 7 | "ephKeyA": "869d6ecf5211f1cc60418a13b9d870b22959d0c16f02bec714c960dd2298a32d", 8 | "ephKeyB": "e238eb8e04fee6511ab04c6dd3c89ce097b11f25d584863ac2b6d5b35b1847e4", 9 | "ephPubA": "654d1044b69c577a44e5f01a1209523adb4026e70c62d1c13a067acabc09d2667a49821a0ad4b634554d330a15a58fe61f8a8e0544b310c6de7b0c8da7528a8d", 10 | "ephPubB": "b6d82fa3409da933dbf9cb0140c5dde89f4e64aec88d476af648880f4a10e1e49fe35ef3e69e93dd300b4797765a747c6384a6ecf5db9c2690398607a86181e4", 11 | "nonceA": "7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6", 12 | "nonceB": "559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd" 13 | }, 14 | "eip8Handshakes": [ 15 | { 16 | "auth": [ 17 | "048ca79ad18e4b0659fab4853fe5bc58eb83992980f4c9cc147d2aa31532efd29a3d3dc6a3d89eaf", 18 | "913150cfc777ce0ce4af2758bf4810235f6e6ceccfee1acc6b22c005e9e3a49d6448610a58e98744", 19 | "ba3ac0399e82692d67c1f58849050b3024e21a52c9d3b01d871ff5f210817912773e610443a9ef14", 20 | "2e91cdba0bd77b5fdf0769b05671fc35f83d83e4d3b0b000c6b2a1b1bba89e0fc51bf4e460df3105", 21 | "c444f14be226458940d6061c296350937ffd5e3acaceeaaefd3c6f74be8e23e0f45163cc7ebd7622", 22 | "0f0128410fd05250273156d548a414444ae2f7dea4dfca2d43c057adb701a715bf59f6fb66b2d1d2", 23 | "0f2c703f851cbf5ac47396d9ca65b6260bd141ac4d53e2de585a73d1750780db4c9ee4cd4d225173", 24 | "a4592ee77e2bd94d0be3691f3b406f9bba9b591fc63facc016bfa8" 25 | ], 26 | "ack": [ 27 | "049f8abcfa9c0dc65b982e98af921bc0ba6e4243169348a236abe9df5f93aa69d99cadddaa387662", 28 | "b0ff2c08e9006d5a11a278b1b3331e5aaabf0a32f01281b6f4ede0e09a2d5f585b26513cb794d963", 29 | "5a57563921c04a9090b4f14ee42be1a5461049af4ea7a7f49bf4c97a352d39c8d02ee4acc416388c", 30 | "1c66cec761d2bc1c72da6ba143477f049c9d2dde846c252c111b904f630ac98e51609b3b1f58168d", 31 | "dca6505b7196532e5f85b259a20c45e1979491683fee108e9660edbf38f3add489ae73e3dda2c71b", 32 | "d1497113d5c755e942d1" 33 | ], 34 | "authVersion": 4, 35 | "ackVersion": 4, 36 | "eip8Format": false 37 | }, 38 | { 39 | "auth": [ 40 | "01b304ab7578555167be8154d5cc456f567d5ba302662433674222360f08d5f1534499d3678b513b", 41 | "0fca474f3a514b18e75683032eb63fccb16c156dc6eb2c0b1593f0d84ac74f6e475f1b8d56116b84", 42 | "9634a8c458705bf83a626ea0384d4d7341aae591fae42ce6bd5c850bfe0b999a694a49bbbaf3ef6c", 43 | "da61110601d3b4c02ab6c30437257a6e0117792631a4b47c1d52fc0f8f89caadeb7d02770bf999cc", 44 | "147d2df3b62e1ffb2c9d8c125a3984865356266bca11ce7d3a688663a51d82defaa8aad69da39ab6", 45 | "d5470e81ec5f2a7a47fb865ff7cca21516f9299a07b1bc63ba56c7a1a892112841ca44b6e0034dee", 46 | "70c9adabc15d76a54f443593fafdc3b27af8059703f88928e199cb122362a4b35f62386da7caad09", 47 | "c001edaeb5f8a06d2b26fb6cb93c52a9fca51853b68193916982358fe1e5369e249875bb8d0d0ec3", 48 | "6f917bc5e1eafd5896d46bd61ff23f1a863a8a8dcd54c7b109b771c8e61ec9c8908c733c0263440e", 49 | "2aa067241aaa433f0bb053c7b31a838504b148f570c0ad62837129e547678c5190341e4f1693956c", 50 | "3bf7678318e2d5b5340c9e488eefea198576344afbdf66db5f51204a6961a63ce072c8926c" 51 | ], 52 | "ack": [ 53 | "01ea0451958701280a56482929d3b0757da8f7fbe5286784beead59d95089c217c9b917788989470", 54 | "b0e330cc6e4fb383c0340ed85fab836ec9fb8a49672712aeabbdfd1e837c1ff4cace34311cd7f4de", 55 | "05d59279e3524ab26ef753a0095637ac88f2b499b9914b5f64e143eae548a1066e14cd2f4bd7f814", 56 | "c4652f11b254f8a2d0191e2f5546fae6055694aed14d906df79ad3b407d94692694e259191cde171", 57 | "ad542fc588fa2b7333313d82a9f887332f1dfc36cea03f831cb9a23fea05b33deb999e85489e645f", 58 | "6aab1872475d488d7bd6c7c120caf28dbfc5d6833888155ed69d34dbdc39c1f299be1057810f34fb", 59 | "e754d021bfca14dc989753d61c413d261934e1a9c67ee060a25eefb54e81a4d14baff922180c395d", 60 | "3f998d70f46f6b58306f969627ae364497e73fc27f6d17ae45a413d322cb8814276be6ddd13b885b", 61 | "201b943213656cde498fa0e9ddc8e0b8f8a53824fbd82254f3e2c17e8eaea009c38b4aa0a3f306e8", 62 | "797db43c25d68e86f262e564086f59a2fc60511c42abfb3057c247a8a8fe4fb3ccbadde17514b7ac", 63 | "8000cdb6a912778426260c47f38919a91f25f4b5ffb455d6aaaf150f7e5529c100ce62d6d92826a7", 64 | "1778d809bdf60232ae21ce8a437eca8223f45ac37f6487452ce626f549b3b5fdee26afd2072e4bc7", 65 | "5833c2464c805246155289f4" 66 | ], 67 | "authVersion": 4, 68 | "ackVersion": 4, 69 | "eip8Format": true 70 | }, 71 | { 72 | "auth": [ 73 | "01b8044c6c312173685d1edd268aa95e1d495474c6959bcdd10067ba4c9013df9e40ff45f5bfd6f7", 74 | "2471f93a91b493f8e00abc4b80f682973de715d77ba3a005a242eb859f9a211d93a347fa64b597bf", 75 | "280a6b88e26299cf263b01b8dfdb712278464fd1c25840b995e84d367d743f66c0e54a586725b7bb", 76 | "f12acca27170ae3283c1073adda4b6d79f27656993aefccf16e0d0409fe07db2dc398a1b7e8ee93b", 77 | "cd181485fd332f381d6a050fba4c7641a5112ac1b0b61168d20f01b479e19adf7fdbfa0905f63352", 78 | "bfc7e23cf3357657455119d879c78d3cf8c8c06375f3f7d4861aa02a122467e069acaf513025ff19", 79 | "6641f6d2810ce493f51bee9c966b15c5043505350392b57645385a18c78f14669cc4d960446c1757", 80 | "1b7c5d725021babbcd786957f3d17089c084907bda22c2b2675b4378b114c601d858802a55345a15", 81 | "116bc61da4193996187ed70d16730e9ae6b3bb8787ebcaea1871d850997ddc08b4f4ea668fbf3740", 82 | "7ac044b55be0908ecb94d4ed172ece66fd31bfdadf2b97a8bc690163ee11f5b575a4b44e36e2bfb2", 83 | "f0fce91676fd64c7773bac6a003f481fddd0bae0a1f31aa27504e2a533af4cef3b623f4791b2cca6", 84 | "d490" 85 | ], 86 | "ack": [ 87 | "01f004076e58aae772bb101ab1a8e64e01ee96e64857ce82b1113817c6cdd52c09d26f7b90981cd7", 88 | "ae835aeac72e1573b8a0225dd56d157a010846d888dac7464baf53f2ad4e3d584531fa203658fab0", 89 | "3a06c9fd5e35737e417bc28c1cbf5e5dfc666de7090f69c3b29754725f84f75382891c561040ea1d", 90 | "dc0d8f381ed1b9d0d4ad2a0ec021421d847820d6fa0ba66eaf58175f1b235e851c7e2124069fbc20", 91 | "2888ddb3ac4d56bcbd1b9b7eab59e78f2e2d400905050f4a92dec1c4bdf797b3fc9b2f8e84a482f3", 92 | "d800386186712dae00d5c386ec9387a5e9c9a1aca5a573ca91082c7d68421f388e79127a5177d4f8", 93 | "590237364fd348c9611fa39f78dcdceee3f390f07991b7b47e1daa3ebcb6ccc9607811cb17ce51f1", 94 | "c8c2c5098dbdd28fca547b3f58c01a424ac05f869f49c6a34672ea2cbbc558428aa1fe48bbfd6115", 95 | "8b1b735a65d99f21e70dbc020bfdface9f724a0d1fb5895db971cc81aa7608baa0920abb0a565c9c", 96 | "436e2fd13323428296c86385f2384e408a31e104670df0791d93e743a3a5194ee6b076fb6323ca59", 97 | "3011b7348c16cf58f66b9633906ba54a2ee803187344b394f75dd2e663a57b956cb830dd7a908d4f", 98 | "39a2336a61ef9fda549180d4ccde21514d117b6c6fd07a9102b5efe710a32af4eeacae2cb3b1dec0", 99 | "35b9593b48b9d3ca4c13d245d5f04169b0b1" 100 | ], 101 | "authVersion": 56, 102 | "ackVersion": 57, 103 | "eip8Format": true 104 | } 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /src/dpt/server.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from 'events' 2 | import * as dgram from 'dgram' 3 | import ms from 'ms' 4 | import { debug as createDebugLogger } from 'debug' 5 | import LRUCache = require('lru-cache') 6 | import { encode, decode } from './message' 7 | import { keccak256, pk2id, createDeferred, formatLogId } from '../util' 8 | import { DPT } from './dpt' 9 | import { Socket as DgramSocket, RemoteInfo } from 'dgram' 10 | import { PeerInfo } from './message' 11 | 12 | const debug = createDebugLogger('devp2p:dpt:server') 13 | const verbose = createDebugLogger('verbose').enabled 14 | 15 | const VERSION = 0x04 16 | 17 | export interface DptServerOptions { 18 | timeout?: number 19 | endpoint?: PeerInfo 20 | createSocket?: Function 21 | } 22 | 23 | export class Server extends EventEmitter { 24 | _dpt: DPT 25 | _privateKey: Buffer 26 | _timeout: number 27 | _endpoint: PeerInfo 28 | _requests: Map 29 | _parityRequestMap: Map 30 | _requestsCache: LRUCache> 31 | _socket: DgramSocket | null 32 | 33 | constructor(dpt: DPT, privateKey: Buffer, options: DptServerOptions) { 34 | super() 35 | 36 | this._dpt = dpt 37 | this._privateKey = privateKey 38 | 39 | this._timeout = options.timeout || ms('10s') 40 | this._endpoint = options.endpoint || { address: '0.0.0.0', udpPort: null, tcpPort: null } 41 | this._requests = new Map() 42 | this._parityRequestMap = new Map() 43 | this._requestsCache = new LRUCache({ max: 1000, maxAge: ms('1s'), stale: false }) 44 | 45 | const createSocket = options.createSocket || dgram.createSocket.bind(null, { type: 'udp4' }) 46 | this._socket = createSocket() 47 | if (this._socket) { 48 | this._socket.once('listening', () => this.emit('listening')) 49 | this._socket.once('close', () => this.emit('close')) 50 | this._socket.on('error', err => this.emit('error', err)) 51 | this._socket.on('message', (msg: Buffer, rinfo: RemoteInfo) => { 52 | try { 53 | this._handler(msg, rinfo) 54 | } catch (err) { 55 | this.emit('error', err) 56 | } 57 | }) 58 | } 59 | } 60 | 61 | bind(...args: any[]) { 62 | this._isAliveCheck() 63 | debug('call .bind') 64 | 65 | if (this._socket) this._socket.bind(...args) 66 | } 67 | 68 | destroy(...args: any[]) { 69 | this._isAliveCheck() 70 | debug('call .destroy') 71 | 72 | if (this._socket) { 73 | this._socket.close(...args) 74 | this._socket = null 75 | } 76 | } 77 | 78 | async ping(peer: PeerInfo): Promise { 79 | this._isAliveCheck() 80 | 81 | const rckey = `${peer.address}:${peer.udpPort}` 82 | const promise = this._requestsCache.get(rckey) 83 | if (promise !== undefined) return promise 84 | 85 | const hash = this._send(peer, 'ping', { 86 | version: VERSION, 87 | from: this._endpoint, 88 | to: peer 89 | }) 90 | 91 | const deferred = createDeferred() 92 | const rkey = hash.toString('hex') 93 | this._requests.set(rkey, { 94 | peer, 95 | deferred, 96 | timeoutId: setTimeout(() => { 97 | if (this._requests.get(rkey) !== undefined) { 98 | debug( 99 | `ping timeout: ${peer.address}:${peer.udpPort} ${ 100 | peer.id ? formatLogId(peer.id.toString('hex'), verbose) : '-' 101 | }` 102 | ) 103 | this._requests.delete(rkey) 104 | deferred.reject(new Error(`Timeout error: ping ${peer.address}:${peer.udpPort}`)) 105 | } else { 106 | return deferred.promise 107 | } 108 | }, this._timeout) 109 | }) 110 | this._requestsCache.set(rckey, deferred.promise) 111 | return deferred.promise 112 | } 113 | 114 | findneighbours(peer: PeerInfo, id: Buffer) { 115 | this._isAliveCheck() 116 | this._send(peer, 'findneighbours', { id }) 117 | } 118 | 119 | _isAliveCheck() { 120 | if (this._socket === null) throw new Error('Server already destroyed') 121 | } 122 | 123 | _send(peer: PeerInfo, typename: string, data: any) { 124 | debug( 125 | `send ${typename} to ${peer.address}:${peer.udpPort} (peerId: ${ 126 | peer.id ? formatLogId(peer.id.toString('hex'), verbose) : '-' 127 | })` 128 | ) 129 | 130 | const msg = encode(typename, data, this._privateKey) 131 | // Parity hack 132 | // There is a bug in Parity up to at lease 1.8.10 not echoing the hash from 133 | // discovery spec (hash: sha3(signature || packet-type || packet-data)) 134 | // but just hashing the RLP-encoded packet data (see discovery.rs, on_ping()) 135 | // 2018-02-28 136 | if (typename === 'ping') { 137 | const rkeyParity = keccak256(msg.slice(98)).toString('hex') 138 | this._parityRequestMap.set(rkeyParity, msg.slice(0, 32).toString('hex')) 139 | setTimeout(() => { 140 | if (this._parityRequestMap.get(rkeyParity) !== undefined) { 141 | this._parityRequestMap.delete(rkeyParity) 142 | } 143 | }, this._timeout) 144 | } 145 | if (this._socket && peer.udpPort) 146 | this._socket.send(msg, 0, msg.length, peer.udpPort, peer.address) 147 | return msg.slice(0, 32) // message id 148 | } 149 | 150 | _handler(msg: Buffer, rinfo: RemoteInfo) { 151 | const info = decode(msg) 152 | const peerId = pk2id(info.publicKey) 153 | debug( 154 | `received ${info.typename} from ${rinfo.address}:${rinfo.port} (peerId: ${formatLogId( 155 | peerId.toString('hex'), 156 | verbose 157 | )})` 158 | ) 159 | 160 | // add peer if not in our table 161 | const peer = this._dpt.getPeer(peerId) 162 | if (peer === null && info.typename === 'ping' && info.data.from.udpPort !== null) { 163 | setTimeout(() => this.emit('peers', [info.data.from]), ms('100ms')) 164 | } 165 | 166 | switch (info.typename) { 167 | case 'ping': { 168 | const remote: PeerInfo = { 169 | id: peerId, 170 | udpPort: rinfo.port, 171 | address: rinfo.address 172 | } 173 | this._send(remote, 'pong', { 174 | to: { 175 | address: rinfo.address, 176 | udpPort: rinfo.port, 177 | tcpPort: info.data.from.tcpPort 178 | }, 179 | hash: msg.slice(0, 32) 180 | }) 181 | break 182 | } 183 | 184 | case 'pong': { 185 | let rkey = info.data.hash.toString('hex') 186 | const rkeyParity = this._parityRequestMap.get(rkey) 187 | if (rkeyParity) { 188 | rkey = rkeyParity 189 | this._parityRequestMap.delete(rkeyParity) 190 | } 191 | const request = this._requests.get(rkey) 192 | if (request) { 193 | this._requests.delete(rkey) 194 | request.deferred.resolve({ 195 | id: peerId, 196 | address: request.peer.address, 197 | udpPort: request.peer.udpPort, 198 | tcpPort: request.peer.tcpPort 199 | }) 200 | } 201 | break 202 | } 203 | case 'findneighbours': { 204 | const remote: PeerInfo = { 205 | id: peerId, 206 | udpPort: rinfo.port, 207 | address: rinfo.address 208 | } 209 | this._send(remote, 'neighbours', { 210 | peers: this._dpt.getClosestPeers(info.data.id) 211 | }) 212 | break 213 | } 214 | 215 | case 'neighbours': { 216 | this.emit( 217 | 'peers', 218 | info.data.peers.map((peer: any) => peer.endpoint) 219 | ) 220 | break 221 | } 222 | } 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 6 | (modification: no type change headlines) and this project adheres to 7 | [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 8 | 9 | ## [3.0.3] - 2020-09-29 10 | 11 | - Moved `TypeScript` type packages for `lru-cache` and `bl` from `devDependencies` to 12 | `dependencies`, PR [#90](https://github.com/ethereumjs/ethereumjs-devp2p/pull/90) 13 | 14 | [3.0.3]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v3.0.2...v3.0.3 15 | 16 | ## [3.0.2] - 2020-09-28 17 | 18 | - Fixed `TypeScript` import issue causing problems when integrating the library in a 19 | `TypeScript` project, PR [#88](https://github.com/ethereumjs/ethereumjs-devp2p/pull/88) 20 | - Updated `k-bucket` library to `v5`, added types from new `@types/k-bucket` package from 21 | @tomonari-t, PR [#88](https://github.com/ethereumjs/ethereumjs-devp2p/pull/88) 22 | 23 | [3.0.2]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v3.0.1...v3.0.2 24 | 25 | ## [3.0.1] - 2020-06-10 26 | 27 | This release focuses on improving the [debugging](https://github.com/ethereumjs/ethereumjs-devp2p#debugging) 28 | capabilities of the library. PR [#72](https://github.com/ethereumjs/ethereumjs-devp2p/pull/72) 29 | reduces the **verbosity** of the log output to cut on noise on everyday debugging. There is a new `verbose` 30 | logger to retain the more verbose output (e.g. with full message bodies) which can be used like this: 31 | 32 | ```shell 33 | DEBUG=devp2p:*,verbose node -r ts-node/register ./examples/peer-communication.ts 34 | ``` 35 | 36 | **Other Logging Improvements** 37 | 38 | Relevant PRs [#75](https://github.com/ethereumjs/ethereumjs-devp2p/pull/75) and 39 | [#73](https://github.com/ethereumjs/ethereumjs-devp2p/pull/73): 40 | 41 | - Added number of peers to `refillConnections()` debug message 42 | - Replaced try/catch logic for EIP-8 auth check to avoid side-effects and get rid of misleading _wrong-ecies-header_ debug output 43 | - Moved debug output in `BanList.add()` after the set operation to get the correct size output 44 | - Added debug message for `DISCONNECT` reason from peer (this was always some constant re-debug reason, and at the end it's mostly `TOO_MANY_PEERS`) 45 | - Internalize detached logger output from the `devp2p:util` logger 46 | 47 | **Other Changes** 48 | 49 | - Refactored `Peer` class for better code readability, PR [#77](https://github.com/ethereumjs/ethereumjs-devp2p/pull/77) 50 | 51 | There has also been a new [high-level diagram](https://github.com/ethereumjs/ethereumjs-devp2p#api) added to the `README` which can be used to get an overview on the structure, available loggers and the event flow of the library (PR [#76](https://github.com/ethereumjs/ethereumjs-devp2p/pull/76)). 52 | 53 | [3.0.1]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v3.0.0...v3.0.1 54 | 55 | ## [3.0.0] - 2020-05-25 56 | 57 | First `TypeScript` release of the library, see PR [#56](https://github.com/ethereumjs/ethereumjs-devp2p/pull/56) for all the changes and associated discussion. 58 | 59 | All source parts of the library have been ported to `TypeScript` and working with the library should now therefore be much more reliable due to the additional type safety features provided by the `TypeScript` language. The API of the library remains unchanged in a `JavaScript` context. 60 | 61 | **Noteworthy Changes from PR [#56](https://github.com/ethereumjs/ethereumjs-devp2p/pull/56):** 62 | 63 | - Type additions for all method signatures and class members of all protocol components (`dpt`, `eth`, `les`, `rlpx`) 64 | - Addition of various structuring interfaces (like [PeerInfo](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L10) for `DPT` message input) and `enum` constructs (like [MESSAGE_CODES](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/eth/index.ts#L186) from the `ETH` protocol) 65 | - Port of the [examples](https://github.com/ethereumjs/ethereumjs-devp2p/tree/master/examples) to `TypeScript` 66 | - Port of all the [test cases](https://github.com/ethereumjs/ethereumjs-devp2p/tree/master/test) to `TypeScript` 67 | - Integration of the library into the common [ethereumjs-config](https://github.com/ethereumjs/ethereumjs-config) EthereumJS configuration setup (`standard` -> `TSLint` linting, docs with `TypeDoc`, `TypeScript` compilation, `Prettier` formatting rules) 68 | - Lots of code cleanups and code part modernizations 69 | 70 | Thanks @dryajov for all the great work on this! ❤ 71 | 72 | **Other Updates:** 73 | 74 | - Added Node 12,13 support, upgrade from Travis to GitHub actions, PR [#57](https://github.com/ethereumjs/ethereumjs-devp2p/pull/57) 75 | - Updated `ethereumjs-common` dependency to `v1.5.1` for a bootnode update, PR [#67](https://github.com/ethereumjs/ethereumjs-devp2p/pull/67) 76 | - Removed Node 6, 8 support, updated `secp256k1` dependency to from `v3.1.0` to `v4.0.1`, PR [#68](https://github.com/ethereumjs/ethereumjs-devp2p/pull/68) 77 | - Updated `keccak` dependency to `v3.0.0`, PR [#64](https://github.com/ethereumjs/ethereumjs-devp2p/pull/64) 78 | - Some dependency cleanup, PRs [#62](https://github.com/ethereumjs/ethereumjs-devp2p/pull/62), [#65](https://github.com/ethereumjs/ethereumjs-devp2p/pull/65), [#58](https://github.com/ethereumjs/ethereumjs-devp2p/pull/58) 79 | 80 | [3.0.0]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.5.1...v3.0.0 81 | 82 | ## [2.5.1] - 2018-12-12 83 | 84 | - Fix connection error by ignoring `RLPX` peers with missing tcp port, PR [#45](https://github.com/ethereumjs/ethereumjs-devp2p/pull/45) 85 | 86 | [2.5.1]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.5.0...v2.5.1 87 | 88 | ## [2.5.0] - 2018-03-22 89 | 90 | - Light client protocol (`LES/2`) implementation, PR [#21](https://github.com/ethereumjs/ethereumjs-devp2p/pull/21) 91 | - `LES/2` usage example, see: `examples/peer-communication-les.js` 92 | - Better test coverage for upper-layer protocols (`ETH`, `LES/2`), PR [#34](https://github.com/ethereumjs/ethereumjs-devp2p/pull/34) 93 | 94 | [2.5.0]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.4.0...v2.5.0 95 | 96 | ## [2.4.0] - 2018-02-28 97 | 98 | - First release providing a reliable `ETH` connection 99 | - Fix Parity `DPT` ping echo hash bug preventing the library to connect 100 | to Parity clients, PR [#32](https://github.com/ethereumjs/ethereumjs-devp2p/pull/32) 101 | - Fixed a bug not setting weHello in peer after sent `HELLO` msg 102 | 103 | [2.4.0]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.3.0...v2.4.0 104 | 105 | ## [2.3.0] - 2018-02-27 106 | 107 | - Fix critical `RLPX` bug leading to not processing incoming `EIP-8` `Auth` or `Ack` messages, PR [#26](https://github.com/ethereumjs/ethereumjs-devp2p/pull/26) 108 | - Fix bug not forwarding `k-bucket` remove event through `DPT` (so `peer:removed` from 109 | `DPT` was not working), PR [#27](https://github.com/ethereumjs/ethereumjs-devp2p/pull/27) 110 | - Fix updating `ingressMac` with wrong `Auth` msg leading to diverging `Mac` hashes, PR [#29](https://github.com/ethereumjs/ethereumjs-devp2p/pull/29) 111 | - Fix bug not let first `ETH` `status` message emit a `message` event, PR [#30](https://github.com/ethereumjs/ethereumjs-devp2p/pull/30) 112 | - Large rework of the test setup, additional `DPT`, `RLPX` and `ETH` simulator tests, 113 | improving test coverage from 48% to 84%, PR [#25](https://github.com/ethereumjs/ethereumjs-devp2p/pull/25) 114 | 115 | [2.3.0]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.2.0...v2.3.0 116 | 117 | ## [2.2.0] - 2017-12-07 118 | 119 | - `EIP-8` compatibility 120 | - Improved debug messages 121 | - Fixes a bug on DPT ping timeout being triggered even if pong message is received 122 | - Only send connect event after both HELLO msgs are exchanged (fixes unreliable upper-protocol communication start) 123 | - Connection reliability improvements for `peer-communication` example 124 | - API documentation 125 | 126 | [2.2.0]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.1.3...v2.2.0 127 | 128 | ## [2.1.3] - 2017-11-09 129 | 130 | - Dependency updates 131 | - Improved README documentation 132 | 133 | [2.1.3]: https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.1.2...v2.1.3 134 | 135 | ## Older releases: 136 | 137 | - [2.1.2](https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.1.1...v2.1.2) - 2017-05-16 138 | - [2.1.1](https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.1.0...v2.1.1) - 2017-04-27 139 | - [2.1.0](https://github.com/ethereumjs/ethereumjs-devp2p/compare/v2.0.0...v2.1.0) - 2016-12-11 140 | - [2.0.0](https://github.com/ethereumjs/ethereumjs-devp2p/compare/v1.0.0...v2.0.0) - 2016-11-14 141 | - 1.0.0 - 2016-10-18 142 | -------------------------------------------------------------------------------- /docs/modules/_index_.md: -------------------------------------------------------------------------------- 1 | **[ethereumjs-devp2p](../README.md)** 2 | 3 | > [Globals](../README.md) / "index" 4 | 5 | # Module: "index" 6 | 7 | ## Index 8 | 9 | ### Enumerations 10 | 11 | * [DISCONNECT\_REASONS](../enums/_index_.disconnect_reasons.md) 12 | * [PREFIXES](../enums/_index_.prefixes.md) 13 | 14 | ### Classes 15 | 16 | * [BanList](../classes/_index_.banlist.md) 17 | * [DPT](../classes/_index_.dpt.md) 18 | * [Deferred](../classes/_index_.deferred.md) 19 | * [ECIES](../classes/_index_.ecies.md) 20 | * [ETH](../classes/_index_.eth.md) 21 | * [KBucket](../classes/_index_.kbucket.md) 22 | * [LES](../classes/_index_.les.md) 23 | * [MAC](../classes/_index_.mac.md) 24 | * [Peer](../classes/_index_.peer.md) 25 | * [RLPx](../classes/_index_.rlpx.md) 26 | * [Server](../classes/_index_.server.md) 27 | 28 | ### Interfaces 29 | 30 | * [Capabilities](../interfaces/_index_.capabilities.md) 31 | * [DptServerOptions](../interfaces/_index_.dptserveroptions.md) 32 | * [Hello](../interfaces/_index_.hello.md) 33 | * [KObj](../interfaces/_index_.kobj.md) 34 | * [PeerInfo](../interfaces/_index_.peerinfo.md) 35 | * [ProtocolConstructor](../interfaces/_index_.protocolconstructor.md) 36 | * [ProtocolDescriptor](../interfaces/_index_.protocoldescriptor.md) 37 | * [RLPxOptions](../interfaces/_index_.rlpxoptions.md) 38 | 39 | ### Type aliases 40 | 41 | * [HelloMsg](_index_.md#hellomsg) 42 | 43 | ### Variables 44 | 45 | * [BASE\_PROTOCOL\_LENGTH](_index_.md#base_protocol_length) 46 | * [BASE\_PROTOCOL\_VERSION](_index_.md#base_protocol_version) 47 | * [DEFAULT\_ANNOUNCE\_TYPE](_index_.md#default_announce_type) 48 | * [PING\_INTERVAL](_index_.md#ping_interval) 49 | 50 | ### Functions 51 | 52 | * [assertEq](_index_.md#asserteq) 53 | * [buffer2int](_index_.md#buffer2int) 54 | * [createDeferred](_index_.md#createdeferred) 55 | * [decode](_index_.md#decode) 56 | * [encode](_index_.md#encode) 57 | * [formatLogData](_index_.md#formatlogdata) 58 | * [formatLogId](_index_.md#formatlogid) 59 | * [genPrivateKey](_index_.md#genprivatekey) 60 | * [id2pk](_index_.md#id2pk) 61 | * [int2buffer](_index_.md#int2buffer) 62 | * [keccak256](_index_.md#keccak256) 63 | * [pk2id](_index_.md#pk2id) 64 | * [xor](_index_.md#xor) 65 | * [zfill](_index_.md#zfill) 66 | 67 | ## Type aliases 68 | 69 | ### HelloMsg 70 | 71 | Ƭ **HelloMsg**: { 0: Buffer ; 1: Buffer ; 2: Buffer[][] ; 3: Buffer ; 4: Buffer ; length: 5 } 72 | 73 | *Defined in [src/rlpx/peer.ts:43](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L43)* 74 | 75 | #### Type declaration: 76 | 77 | Name | Type | 78 | ------ | ------ | 79 | `0` | Buffer | 80 | `1` | Buffer | 81 | `2` | Buffer[][] | 82 | `3` | Buffer | 83 | `4` | Buffer | 84 | `length` | 5 | 85 | 86 | ## Variables 87 | 88 | ### BASE\_PROTOCOL\_LENGTH 89 | 90 | • `Const` **BASE\_PROTOCOL\_LENGTH**: 16 = 16 91 | 92 | *Defined in [src/rlpx/peer.ts:16](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L16)* 93 | 94 | ___ 95 | 96 | ### BASE\_PROTOCOL\_VERSION 97 | 98 | • `Const` **BASE\_PROTOCOL\_VERSION**: 4 = 4 99 | 100 | *Defined in [src/rlpx/peer.ts:15](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L15)* 101 | 102 | ___ 103 | 104 | ### DEFAULT\_ANNOUNCE\_TYPE 105 | 106 | • `Const` **DEFAULT\_ANNOUNCE\_TYPE**: 1 = 1 107 | 108 | *Defined in [src/les/index.ts:11](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/les/index.ts#L11)* 109 | 110 | ___ 111 | 112 | ### PING\_INTERVAL 113 | 114 | • `Const` **PING\_INTERVAL**: number = ms('15s') 115 | 116 | *Defined in [src/rlpx/peer.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/rlpx/peer.ts#L18)* 117 | 118 | ## Functions 119 | 120 | ### assertEq 121 | 122 | ▸ **assertEq**(`expected`: any, `actual`: any, `msg`: string, `debug`: any): void 123 | 124 | *Defined in [src/util.ts:57](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L57)* 125 | 126 | #### Parameters: 127 | 128 | Name | Type | 129 | ------ | ------ | 130 | `expected` | any | 131 | `actual` | any | 132 | `msg` | string | 133 | `debug` | any | 134 | 135 | **Returns:** void 136 | 137 | ___ 138 | 139 | ### buffer2int 140 | 141 | ▸ **buffer2int**(`buffer`: Buffer): number 142 | 143 | *Defined in [src/util.ts:35](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L35)* 144 | 145 | #### Parameters: 146 | 147 | Name | Type | 148 | ------ | ------ | 149 | `buffer` | Buffer | 150 | 151 | **Returns:** number 152 | 153 | ___ 154 | 155 | ### createDeferred 156 | 157 | ▸ **createDeferred**\(): [Deferred](../classes/_index_.deferred.md)\ 158 | 159 | *Defined in [src/util.ts:106](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L106)* 160 | 161 | #### Type parameters: 162 | 163 | Name | 164 | ------ | 165 | `T` | 166 | 167 | **Returns:** [Deferred](../classes/_index_.deferred.md)\ 168 | 169 | ___ 170 | 171 | ### decode 172 | 173 | ▸ **decode**(`buffer`: Buffer): object 174 | 175 | *Defined in [src/dpt/message.ts:188](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L188)* 176 | 177 | #### Parameters: 178 | 179 | Name | Type | 180 | ------ | ------ | 181 | `buffer` | Buffer | 182 | 183 | **Returns:** object 184 | 185 | Name | Type | 186 | ------ | ------ | 187 | `data` | any | 188 | `publicKey` | Buffer | 189 | `typename` | string \| number | 190 | 191 | ___ 192 | 193 | ### encode 194 | 195 | ▸ **encode**\(`typename`: string, `data`: T, `privateKey`: Buffer): Buffer 196 | 197 | *Defined in [src/dpt/message.ts:175](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/dpt/message.ts#L175)* 198 | 199 | #### Type parameters: 200 | 201 | Name | 202 | ------ | 203 | `T` | 204 | 205 | #### Parameters: 206 | 207 | Name | Type | 208 | ------ | ------ | 209 | `typename` | string | 210 | `data` | T | 211 | `privateKey` | Buffer | 212 | 213 | **Returns:** Buffer 214 | 215 | ___ 216 | 217 | ### formatLogData 218 | 219 | ▸ **formatLogData**(`data`: string, `verbose`: boolean): string 220 | 221 | *Defined in [src/util.ts:85](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L85)* 222 | 223 | #### Parameters: 224 | 225 | Name | Type | 226 | ------ | ------ | 227 | `data` | string | 228 | `verbose` | boolean | 229 | 230 | **Returns:** string 231 | 232 | ___ 233 | 234 | ### formatLogId 235 | 236 | ▸ **formatLogId**(`id`: string, `verbose`: boolean): string 237 | 238 | *Defined in [src/util.ts:76](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L76)* 239 | 240 | #### Parameters: 241 | 242 | Name | Type | 243 | ------ | ------ | 244 | `id` | string | 245 | `verbose` | boolean | 246 | 247 | **Returns:** string 248 | 249 | ___ 250 | 251 | ### genPrivateKey 252 | 253 | ▸ **genPrivateKey**(): Buffer 254 | 255 | *Defined in [src/util.ts:13](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L13)* 256 | 257 | **Returns:** Buffer 258 | 259 | ___ 260 | 261 | ### id2pk 262 | 263 | ▸ **id2pk**(`id`: Buffer): Buffer 264 | 265 | *Defined in [src/util.ts:25](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L25)* 266 | 267 | #### Parameters: 268 | 269 | Name | Type | 270 | ------ | ------ | 271 | `id` | Buffer | 272 | 273 | **Returns:** Buffer 274 | 275 | ___ 276 | 277 | ### int2buffer 278 | 279 | ▸ **int2buffer**(`v`: number): Buffer 280 | 281 | *Defined in [src/util.ts:29](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L29)* 282 | 283 | #### Parameters: 284 | 285 | Name | Type | 286 | ------ | ------ | 287 | `v` | number | 288 | 289 | **Returns:** Buffer 290 | 291 | ___ 292 | 293 | ### keccak256 294 | 295 | ▸ **keccak256**(...`buffers`: Buffer[]): Buffer 296 | 297 | *Defined in [src/util.ts:6](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L6)* 298 | 299 | #### Parameters: 300 | 301 | Name | Type | 302 | ------ | ------ | 303 | `...buffers` | Buffer[] | 304 | 305 | **Returns:** Buffer 306 | 307 | ___ 308 | 309 | ### pk2id 310 | 311 | ▸ **pk2id**(`pk`: Buffer): Buffer 312 | 313 | *Defined in [src/util.ts:18](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L18)* 314 | 315 | #### Parameters: 316 | 317 | Name | Type | 318 | ------ | ------ | 319 | `pk` | Buffer | 320 | 321 | **Returns:** Buffer 322 | 323 | ___ 324 | 325 | ### xor 326 | 327 | ▸ **xor**(`a`: Buffer, `b`: any): Buffer 328 | 329 | *Defined in [src/util.ts:50](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L50)* 330 | 331 | #### Parameters: 332 | 333 | Name | Type | 334 | ------ | ------ | 335 | `a` | Buffer | 336 | `b` | any | 337 | 338 | **Returns:** Buffer 339 | 340 | ___ 341 | 342 | ### zfill 343 | 344 | ▸ **zfill**(`buffer`: Buffer, `size`: number, `leftpad?`: boolean): Buffer 345 | 346 | *Defined in [src/util.ts:43](https://github.com/ethereumjs/ethereumjs-devp2p/blob/master/src/util.ts#L43)* 347 | 348 | #### Parameters: 349 | 350 | Name | Type | Default value | 351 | ------ | ------ | ------ | 352 | `buffer` | Buffer | - | 353 | `size` | number | - | 354 | `leftpad` | boolean | true | 355 | 356 | **Returns:** Buffer 357 | --------------------------------------------------------------------------------