Skip to content

Commit

Permalink
Add admin_peer RPC endpoint (#3570)
Browse files Browse the repository at this point in the history
* add initial implementation of admin_peers

* add more fields

* fix versions

* add test
  • Loading branch information
acolytec3 authored Aug 8, 2024
1 parent 12eb962 commit f9788a1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
37 changes: 34 additions & 3 deletions packages/client/src/rpc/modules/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { middleware } from '../validation.js'

import type { Chain } from '../../blockchain/index.js'
import type { EthereumClient } from '../../client.js'
import type { RlpxPeer } from '../../net/peer/rlpxpeer.js'
import type { Service } from '../../service/index.js'

/**
Expand All @@ -28,14 +29,14 @@ export class Admin {
this._rpcDebug = rpcDebug

this.nodeInfo = middleware(callWithStackTrace(this.nodeInfo.bind(this), this._rpcDebug), 0, [])
this.peers = middleware(callWithStackTrace(this.peers.bind(this), this._rpcDebug), 0, [])
}

/**
* Returns information about the currently running node.
* see for reference: https://geth.ethereum.org/docs/rpc/ns-admin#admin_nodeinfo
* @param params An empty array
* see for reference: https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-admin#admin_peers
*/
async nodeInfo(_params: []) {
async nodeInfo() {
const rlpxInfo = this._client.config.server!.getRlpxInfo()
const { enode, id, ip, listenAddr, ports } = rlpxInfo
const { discovery, listener } = ports
Expand Down Expand Up @@ -68,4 +69,34 @@ export class Admin {
}
return nodeInfo
}

/**
* Returns information about currently connected peers
* @returns an array of objects containing information about peers (including id, eth protocol versions supported, client name, etc.)
*/
async peers() {
const peers = this._client.services.filter((serv) => serv.name === 'eth')[0]?.pool
.peers as RlpxPeer[]

return peers?.map((peer) => {
return {
id: peer.id,
// Typescript complains about the typing of `_hello` if we make rlpxPeer possibly null
name: (peer.rlpxPeer as any)['_hello'].clientId ?? null,
protocols: {
eth: {
head: peer.eth?.updatedBestHeader
? bytesToHex(peer.eth.updatedBestHeader?.hash())
: bytesToHex(peer.eth?.status.bestHash),
difficulty: peer.eth?.status.td.toString(10),
version: peer.eth?.['versions'].slice(-1)[0] ?? null,
},
},
caps: peer.eth?.['versions'].map((ver) => 'eth/' + ver),
network: {
remoteAddress: peer.address,
},
}
})
}
}
38 changes: 38 additions & 0 deletions packages/client/test/rpc/admin/peers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { randomBytes } from 'crypto'
import { assert, describe, it } from 'vitest'

import { createClient, createManager, getRpcClient, startRPC } from '../helpers.js'

const method = 'admin_peers'

describe(method, () => {
it('works', async () => {
const manager = createManager(await createClient({ opened: true, noPeers: true }))
const rpc = getRpcClient(startRPC(manager.getMethods()))

console.log(manager['_client'].services[0].pool)
//@ts-ignore
manager['_client'].services[0].pool.peers = [
{
id: 'abcd',
eth: {
versions: ['68'],
status: {
td: 1n,
bestHash: randomBytes(32),
},
},
rlpxPeer: {
_hello: {
clientId: 'fakeClient',
},
},
address: '127.0.0.1:8545',
},
]
const res = await rpc.request(method, [])
const { result } = res
console.log(res)
assert.notEqual(result, undefined, 'admin_peers returns a value')
})
})

0 comments on commit f9788a1

Please sign in to comment.