From c420f30885f831826b6ce508808685011892c786 Mon Sep 17 00:00:00 2001 From: Gerald Nash Date: Thu, 15 Nov 2018 01:00:38 -0500 Subject: [PATCH] Add net_version and net_listening RPC methods --- lib/rpc/modules/index.js | 2 +- lib/rpc/modules/net.js | 22 +++++ test/rpc/net/listening.js | 81 +++++++++++++++++++ test/rpc/net/version.js | 166 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 lib/rpc/modules/net.js create mode 100644 test/rpc/net/listening.js create mode 100644 test/rpc/net/version.js diff --git a/lib/rpc/modules/index.js b/lib/rpc/modules/index.js index 1fceb8f..d238de8 100644 --- a/lib/rpc/modules/index.js +++ b/lib/rpc/modules/index.js @@ -1,4 +1,4 @@ -const moduleList = ['eth', 'web3'] +const moduleList = ['eth', 'web3', 'net'] moduleList.forEach(mod => { module.exports[mod] = require(`./${mod}`) diff --git a/lib/rpc/modules/net.js b/lib/rpc/modules/net.js new file mode 100644 index 0000000..e566803 --- /dev/null +++ b/lib/rpc/modules/net.js @@ -0,0 +1,22 @@ +const { middleware } = require('../validation') + +class Net { + constructor (node) { + const service = node.services.find(s => s.name === 'eth') + this._chain = service.chain + this._node = node + + this.version = middleware(this.version.bind(this), 0, []) + this.listening = middleware(this.listening.bind(this), 0, []) + } + + version (params, cb) { + cb(null, `${this._node.common.chainId()}`) + } + + listening (params, cb) { + cb(null, this._node.opened) + } +} + +module.exports = Net diff --git a/test/rpc/net/listening.js b/test/rpc/net/listening.js new file mode 100644 index 0000000..4321e52 --- /dev/null +++ b/test/rpc/net/listening.js @@ -0,0 +1,81 @@ +const test = require('tape') + +const request = require('supertest') +const Common = require('ethereumjs-common') +const { startRPC, closeRPC, createManager } = require('../helpers') +const blockChain = require('../blockChainStub.js') +const Chain = require('../../../lib/blockchain/chain.js') + +function createNode (opened, commonChain = new Common('mainnet')) { + let chain = new Chain({ blockchain: blockChain({}) }) + chain.opened = true + return { + services: [{ name: 'eth', chain: chain }], + common: commonChain, + opened + } +} + +test('call net_listening while listening', t => { + const manager = createManager(createNode(true)) + const server = startRPC(manager.getMethods()) + + const req = { + jsonrpc: '2.0', + method: 'net_listening', + params: [], + id: 1 + } + + request(server) + .post('/') + .set('Content-Type', 'application/json') + .send(req) + .expect(200) + .expect(res => { + const { result } = res.body + if (typeof result !== 'boolean') { + throw new Error('Result should be a boolean, but is not') + } + + if (result !== true) { + throw new Error('Not listening, when it should be') + } + }) + .end((err, res) => { + closeRPC(server) + t.end(err) + }) +}) + +test('call net_listening while not listening', t => { + const manager = createManager(createNode(false)) + const server = startRPC(manager.getMethods()) + + const req = { + jsonrpc: '2.0', + method: 'net_listening', + params: [], + id: 1 + } + + request(server) + .post('/') + .set('Content-Type', 'application/json') + .send(req) + .expect(200) + .expect(res => { + const { result } = res.body + if (typeof result !== 'boolean') { + throw new Error('Result should be a boolean, but is not') + } + + if (result !== false) { + throw new Error('Listening, when it not should be') + } + }) + .end((err, res) => { + closeRPC(server) + t.end(err) + }) +}) diff --git a/test/rpc/net/version.js b/test/rpc/net/version.js new file mode 100644 index 0000000..13ea5c9 --- /dev/null +++ b/test/rpc/net/version.js @@ -0,0 +1,166 @@ +const test = require('tape') + +const request = require('supertest') +const Common = require('ethereumjs-common') +const { startRPC, closeRPC, createManager } = require('../helpers') +const blockChain = require('../blockChainStub.js') +const Chain = require('../../../lib/blockchain/chain.js') + +function createNode (commonChain = new Common('mainnet')) { + let chain = new Chain({ blockchain: blockChain({}) }) + chain.opened = true + return { + services: [{ name: 'eth', chain: chain }], + common: commonChain + } +} + +test('call net_version on ropsten', t => { + const manager = createManager(createNode(new Common('ropsten'))) + const server = startRPC(manager.getMethods()) + + const req = { + jsonrpc: '2.0', + method: 'net_version', + params: [], + id: 1 + } + + request(server) + .post('/') + .set('Content-Type', 'application/json') + .send(req) + .expect(200) + .expect(res => { + const { result } = res.body + + if (typeof result !== 'string') { + throw new Error('Result should be a string, but is not') + } + + if (result.length === 0) { + throw new Error('Empty result string') + } + + if (result !== '3') { + throw new Error(`Incorrect chain ID. Expected: 3, Received: ${result}`) + } + }) + .end((err, res) => { + closeRPC(server) + t.end(err) + }) +}) + +test('call net_version on mainnet', t => { + const manager = createManager(createNode()) + const server = startRPC(manager.getMethods()) + + const req = { + jsonrpc: '2.0', + method: 'net_version', + params: [], + id: 1 + } + + request(server) + .post('/') + .set('Content-Type', 'application/json') + .send(req) + .expect(200) + .expect(res => { + const { result } = res.body + + if (typeof result !== 'string') { + throw new Error('Result should be a string, but is not') + } + + if (result.length === 0) { + throw new Error('Empty result string') + } + + if (result !== '1') { + throw new Error(`Incorrect chain ID. Expected: 1, Received: ${result}`) + } + }) + .end((err, res) => { + closeRPC(server) + t.end(err) + }) +}) + +test('call net_version on rinkeby', t => { + const manager = createManager(createNode(new Common('rinkeby'))) + const server = startRPC(manager.getMethods()) + + const req = { + jsonrpc: '2.0', + method: 'net_version', + params: [], + id: 1 + } + + request(server) + .post('/') + .set('Content-Type', 'application/json') + .send(req) + .expect(200) + .expect(res => { + const { result } = res.body + + if (typeof result !== 'string') { + throw new Error('Result should be a string, but is not') + } + + if (result.length === 0) { + throw new Error('Empty result string') + } + + if (result !== '4') { + throw new Error(`Incorrect chain ID. Expected: 4, Received: ${result}`) + } + }) + .end((err, res) => { + closeRPC(server) + t.end(err) + }) +}) + +test('call net_version on kovan', t => { + const manager = createManager(createNode(new Common('kovan'))) + const server = startRPC(manager.getMethods()) + + const req = { + jsonrpc: '2.0', + method: 'net_version', + params: [], + id: 1 + } + + request(server) + .post('/') + .set('Content-Type', 'application/json') + .send(req) + .expect(200) + .expect(res => { + const { result } = res.body + + if (typeof result !== 'string') { + throw new Error('Result should be a string, but is not') + } + + if (result.length === 0) { + throw new Error('Empty result string') + } + + if (result !== '42') { + throw new Error( + `Incorrect chain ID. Expected: 42, Received: ${result}` + ) + } + }) + .end((err, res) => { + closeRPC(server) + t.end(err) + }) +})