From d0a9fada32677ee3b810d5c2fb8d5e2c4f5a9fef Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Fri, 20 Nov 2020 15:14:01 +0100 Subject: [PATCH] feat: custom and store self agent version + store self protocol version (#800) * feat: custom and store self protocol and agent version * fix: do not enable custom protocolVersion --- doc/API.md | 1 + src/config.js | 4 ++ src/identify/index.js | 14 ++++++- test/identify/index.spec.js | 78 ++++++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 12 deletions(-) diff --git a/doc/API.md b/doc/API.md index d277ba87c4..f059741721 100644 --- a/doc/API.md +++ b/doc/API.md @@ -92,6 +92,7 @@ Creates an instance of Libp2p. | options.modules | [`Array`](./CONFIGURATION.md#modules) | libp2p [modules](./CONFIGURATION.md#modules) to use | | [options.addresses] | `{ listen: Array, announce: Array, noAnnounce: Array }` | Addresses for transport listening and to advertise to the network | | [options.config] | `object` | libp2p modules configuration and core configuration | +| [options.host] | `{ agentVersion: string }` | libp2p host options | | [options.connectionManager] | [`object`](./CONFIGURATION.md#configuring-connection-manager) | libp2p Connection Manager [configuration](./CONFIGURATION.md#configuring-connection-manager) | | [options.transportManager] | [`object`](./CONFIGURATION.md#configuring-transport-manager) | libp2p transport manager [configuration](./CONFIGURATION.md#configuring-transport-manager) | | [options.datastore] | `object` | must implement [ipfs/interface-datastore](https://github.com/ipfs/interface-datastore) (in memory datastore will be used if not provided) | diff --git a/src/config.js b/src/config.js index 1cc0f097b4..6e0997938d 100644 --- a/src/config.js +++ b/src/config.js @@ -4,6 +4,7 @@ const mergeOptions = require('merge-options') const { dnsaddrResolver } = require('multiaddr/src/resolvers') const Constants = require('./constants') +const { AGENT_VERSION } = require('./identify/consts') const { FaultTolerance } = require('./transport-manager') @@ -27,6 +28,9 @@ const DefaultConfig = { dnsaddr: dnsaddrResolver } }, + host: { + agentVersion: AGENT_VERSION + }, metrics: { enabled: false }, diff --git a/src/identify/index.js b/src/identify/index.js index f42a8b6f94..f39f95f03e 100644 --- a/src/identify/index.js +++ b/src/identify/index.js @@ -83,6 +83,16 @@ class IdentifyService { this._protocols = protocols this.handleMessage = this.handleMessage.bind(this) + + // Store self host metadata + this._host = { + agentVersion: AGENT_VERSION, + protocolVersion: PROTOCOL_VERSION, + ...libp2p._options.host + } + + this.peerStore.metadataBook.set(this.peerId, 'AgentVersion', uint8ArrayFromString(this._host.agentVersion)) + this.peerStore.metadataBook.set(this.peerId, 'ProtocolVersion', uint8ArrayFromString(this._host.protocolVersion)) } /** @@ -246,8 +256,8 @@ class IdentifyService { const signedPeerRecord = await this._getSelfPeerRecord() const message = Message.encode({ - protocolVersion: PROTOCOL_VERSION, - agentVersion: AGENT_VERSION, + protocolVersion: this._host.protocolVersion, + agentVersion: this._host.agentVersion, publicKey, listenAddrs: this._libp2p.multiaddrs.map((ma) => ma.bytes), signedPeerRecord, diff --git a/test/identify/index.spec.js b/test/identify/index.spec.js index 1ccbf67122..74394dd158 100644 --- a/test/identify/index.spec.js +++ b/test/identify/index.spec.js @@ -53,7 +53,8 @@ describe('Identify', () => { peerId: localPeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: localPeer }), - multiaddrs: listenMaddrs + multiaddrs: listenMaddrs, + _options: { host: {} } }, protocols }) @@ -63,7 +64,8 @@ describe('Identify', () => { peerId: remotePeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: remotePeer }), - multiaddrs: listenMaddrs + multiaddrs: listenMaddrs, + _options: { host: {} } }, protocols }) @@ -106,7 +108,8 @@ describe('Identify', () => { peerId: localPeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: localPeer }), - multiaddrs: listenMaddrs + multiaddrs: listenMaddrs, + _options: { host: {} } }, protocols }) @@ -116,7 +119,8 @@ describe('Identify', () => { peerId: remotePeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: remotePeer }), - multiaddrs: listenMaddrs + multiaddrs: listenMaddrs, + _options: { host: {} } }, protocols }) @@ -165,7 +169,8 @@ describe('Identify', () => { peerId: localPeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: localPeer }), - multiaddrs: [] + multiaddrs: [], + _options: { host: {} } }, protocols }) @@ -174,7 +179,8 @@ describe('Identify', () => { peerId: remotePeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: remotePeer }), - multiaddrs: [] + multiaddrs: [], + _options: { host: {} } }, protocols }) @@ -201,6 +207,36 @@ describe('Identify', () => { .and.to.have.property('code', Errors.ERR_INVALID_PEER) }) + it('should store host data and protocol version into metadataBook', () => { + const agentVersion = 'js-project/1.0.0' + const peerStore = new PeerStore({ peerId: localPeer }) + + sinon.spy(peerStore.metadataBook, 'set') + + new IdentifyService({ // eslint-disable-line no-new + libp2p: { + peerId: localPeer, + connectionManager: new EventEmitter(), + peerStore, + multiaddrs: listenMaddrs, + _options: { + host: { + agentVersion + } + } + }, + protocols + }) + + expect(peerStore.metadataBook.set.callCount).to.eql(2) + + const storedAgentVersion = peerStore.metadataBook.getValue(localPeer, 'AgentVersion') + const storedProtocolVersion = peerStore.metadataBook.getValue(localPeer, 'ProtocolVersion') + + expect(agentVersion).to.eql(unit8ArrayToString(storedAgentVersion)) + expect(storedProtocolVersion).to.exist() + }) + describe('push', () => { it('should be able to push identify updates to another peer', async () => { const connectionManager = new EventEmitter() @@ -211,7 +247,8 @@ describe('Identify', () => { peerId: localPeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: localPeer }), - multiaddrs: listenMaddrs + multiaddrs: listenMaddrs, + _options: { host: {} } }, protocols: new Map([ [multicodecs.IDENTIFY], @@ -224,7 +261,8 @@ describe('Identify', () => { peerId: remotePeer, connectionManager, peerStore: new PeerStore({ peerId: remotePeer }), - multiaddrs: [] + multiaddrs: [], + _options: { host: {} } } }) @@ -272,7 +310,8 @@ describe('Identify', () => { peerId: localPeer, connectionManager: new EventEmitter(), peerStore: new PeerStore({ peerId: localPeer }), - multiaddrs: listenMaddrs + multiaddrs: listenMaddrs, + _options: { host: {} } }, protocols: new Map([ [multicodecs.IDENTIFY], @@ -285,7 +324,8 @@ describe('Identify', () => { peerId: remotePeer, connectionManager, peerStore: new PeerStore({ peerId: remotePeer }), - multiaddrs: [] + multiaddrs: [], + _options: { host: {} } } }) @@ -404,5 +444,23 @@ describe('Identify', () => { // Verify the streams close await pWaitFor(() => connection.streams.length === 0) }) + + it('should store host data and protocol version into metadataBook', () => { + const agentVersion = 'js-project/1.0.0' + + libp2p = new Libp2p({ + ...baseOptions, + peerId, + host: { + agentVersion + } + }) + + const storedAgentVersion = libp2p.peerStore.metadataBook.getValue(localPeer, 'AgentVersion') + const storedProtocolVersion = libp2p.peerStore.metadataBook.getValue(localPeer, 'ProtocolVersion') + + expect(agentVersion).to.eql(unit8ArrayToString(storedAgentVersion)) + expect(storedProtocolVersion).to.exist() + }) }) })