@aztec/p2p 0.38.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +3 -1
- package/dest/config.d.ts +5 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +4 -2
- package/dest/service/data_store.d.ts +27 -0
- package/dest/service/data_store.d.ts.map +1 -0
- package/dest/service/data_store.js +188 -0
- package/dest/service/discV5_service.d.ts +8 -6
- package/dest/service/discV5_service.d.ts.map +1 -1
- package/dest/service/discV5_service.js +35 -21
- package/dest/service/dummy_service.d.ts +3 -1
- package/dest/service/dummy_service.d.ts.map +1 -1
- package/dest/service/dummy_service.js +11 -1
- package/dest/service/libp2p_service.d.ts +28 -17
- package/dest/service/libp2p_service.d.ts.map +1 -1
- package/dest/service/libp2p_service.js +101 -174
- package/dest/service/peer_manager.d.ts +12 -0
- package/dest/service/peer_manager.d.ts.map +1 -0
- package/dest/service/peer_manager.js +22 -0
- package/dest/service/service.d.ts +5 -0
- package/dest/service/service.d.ts.map +1 -1
- package/dest/service/service.js +6 -2
- package/dest/service/tx_messages.d.ts +11 -57
- package/dest/service/tx_messages.d.ts.map +1 -1
- package/dest/service/tx_messages.js +14 -89
- package/package.json +29 -21
- package/src/bootstrap/bootstrap.ts +2 -0
- package/src/config.ts +9 -0
- package/src/service/data_store.ts +235 -0
- package/src/service/discV5_service.ts +37 -20
- package/src/service/dummy_service.ts +8 -1
- package/src/service/libp2p_service.ts +130 -194
- package/src/service/peer_manager.ts +26 -0
- package/src/service/service.ts +7 -0
- package/src/service/tx_messages.ts +18 -93
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../src/service/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../src/service/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,6BAA6B,CAAC;AAI9E,OAAO,KAAK,EAAsB,MAAM,EAAE,MAAM,EAAU,MAAM,mBAAmB,CAAC;AACpF,OAAO,iBAAiB,CAAC;AAMzB,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAEnD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGrE,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;KACjC,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS7E;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,UAAU;IAM5C,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,MAAM;IAZhB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,WAAW,CAAc;gBAEvB,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,YAAY,EAClB,oBAAoB,EAAE,oBAAoB,EAC1C,SAAS,EAAE,cAAc,EACzB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,gBAAgB,GAAE,MAAM,EAAO,EAC/B,MAAM,yCAA4C;IAM5D;;;OAGG;IACU,KAAK;IAqDlB;;;OAGG;IACU,IAAI;IAQjB;;;;;OAKG;WACiB,GAAG,CACrB,MAAM,EAAE,SAAS,EACjB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,YAAY;IA4ErB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;;;;OAKG;YACW,cAAc;IAS5B;;;;OAIG;YACW,sBAAsB;IAUpC;;;OAGG;IACI,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI;IAIhC;;;OAGG;IACI,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;YAI7B,OAAO;YAsCP,kBAAkB;YAelB,oBAAoB;YAYpB,mBAAmB;YASnB,iBAAiB;YAOjB,aAAa;IAO3B,OAAO,CAAC,eAAe;CAGxB"}
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
2
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
|
|
3
4
|
import { ENR } from '@chainsafe/enr';
|
|
5
|
+
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
4
6
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
5
7
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
6
8
|
import { identify } from '@libp2p/identify';
|
|
7
9
|
import '@libp2p/kad-dht';
|
|
8
10
|
import { mplex } from '@libp2p/mplex';
|
|
9
11
|
import { peerIdFromString } from '@libp2p/peer-id';
|
|
10
|
-
import { createFromJSON, createSecp256k1PeerId
|
|
12
|
+
import { createFromJSON, createSecp256k1PeerId } from '@libp2p/peer-id-factory';
|
|
11
13
|
import { tcp } from '@libp2p/tcp';
|
|
12
14
|
import { pipe } from 'it-pipe';
|
|
13
15
|
import { createLibp2p } from 'libp2p';
|
|
16
|
+
import { AztecDatastore } from './data_store.js';
|
|
14
17
|
import { KnownTxLookup } from './known_txs.js';
|
|
18
|
+
import { PeerManager } from './peer_manager.js';
|
|
15
19
|
import { AztecPeerDb } from './peer_store.js';
|
|
16
|
-
import {
|
|
20
|
+
import { AztecTxMessageCreator, fromTxMessage } from './tx_messages.js';
|
|
17
21
|
/**
|
|
18
22
|
* Create a libp2p peer ID from the private key if provided, otherwise creates a new random ID.
|
|
19
23
|
* @param privateKey - Optional peer ID private key as hex string
|
|
@@ -29,14 +33,6 @@ export async function createLibP2PPeerId(privateKey) {
|
|
|
29
33
|
privKey: base64,
|
|
30
34
|
});
|
|
31
35
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Exports a given peer id to a string representation.
|
|
34
|
-
* @param peerId - The peerId instance to be converted.
|
|
35
|
-
* @returns The peer id as a string.
|
|
36
|
-
*/
|
|
37
|
-
export function exportLibP2PPeerIdToString(peerId) {
|
|
38
|
-
return Buffer.from(exportToProtobuf(peerId)).toString('hex');
|
|
39
|
-
}
|
|
40
36
|
/**
|
|
41
37
|
* Lib P2P implementation of the P2PService interface.
|
|
42
38
|
*/
|
|
@@ -52,6 +48,8 @@ export class LibP2PService {
|
|
|
52
48
|
this.logger = logger;
|
|
53
49
|
this.jobQueue = new SerialQueue();
|
|
54
50
|
this.knownTxLookup = new KnownTxLookup();
|
|
51
|
+
this.messageCreator = new AztecTxMessageCreator(config.txGossipVersion);
|
|
52
|
+
this.peerManager = new PeerManager(node, peerDiscoveryService, config, logger);
|
|
55
53
|
}
|
|
56
54
|
/**
|
|
57
55
|
* Starts the LibP2P service.
|
|
@@ -73,23 +71,18 @@ export class LibP2PService {
|
|
|
73
71
|
this.peerDiscoveryService.on('peer:discovered', async (enr) => {
|
|
74
72
|
await this.addPeer(enr);
|
|
75
73
|
});
|
|
76
|
-
this.node.addEventListener('peer:
|
|
77
|
-
const peerId = evt.detail.id;
|
|
78
|
-
if (this.isBootstrapPeer(peerId)) {
|
|
79
|
-
this.logger.verbose(`Discovered bootstrap peer ${peerId.toString()}`);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
this.node.addEventListener('peer:connect', evt => {
|
|
74
|
+
this.node.addEventListener('peer:connect', async (evt) => {
|
|
83
75
|
const peerId = evt.detail;
|
|
84
|
-
this.handleNewConnection(peerId);
|
|
76
|
+
await this.handleNewConnection(peerId);
|
|
85
77
|
});
|
|
86
|
-
this.node.addEventListener('peer:disconnect', evt => {
|
|
78
|
+
this.node.addEventListener('peer:disconnect', async (evt) => {
|
|
87
79
|
const peerId = evt.detail;
|
|
88
80
|
if (this.isBootstrapPeer(peerId)) {
|
|
89
81
|
this.logger.verbose(`Disconnect from bootstrap peer ${peerId.toString()}`);
|
|
90
82
|
}
|
|
91
83
|
else {
|
|
92
84
|
this.logger.verbose(`Disconnected from transaction peer ${peerId.toString()}`);
|
|
85
|
+
await this.peerManager.updateDiscoveryService();
|
|
93
86
|
}
|
|
94
87
|
});
|
|
95
88
|
this.jobQueue.start();
|
|
@@ -97,6 +90,14 @@ export class LibP2PService {
|
|
|
97
90
|
await this.node.start();
|
|
98
91
|
await this.node.handle(this.protocolId, (incoming) => this.jobQueue.put(() => Promise.resolve(this.handleProtocolDial(incoming))));
|
|
99
92
|
this.logger.info(`Started P2P client with Peer ID ${this.node.peerId.toString()}`);
|
|
93
|
+
// Subscribe to standard topics by default
|
|
94
|
+
this.subscribeToTopic(this.messageCreator.getTopic());
|
|
95
|
+
// add gossipsub listener
|
|
96
|
+
this.node.services.pubsub.addEventListener('gossipsub:message', async (e) => {
|
|
97
|
+
const { msg } = e.detail;
|
|
98
|
+
this.logger.debug(`Received PUBSUB message.`);
|
|
99
|
+
await this.handleNewGossipMessage(msg.topic, msg.data);
|
|
100
|
+
});
|
|
100
101
|
}
|
|
101
102
|
/**
|
|
102
103
|
* Stops the LibP2P service.
|
|
@@ -116,26 +117,8 @@ export class LibP2PService {
|
|
|
116
117
|
* @returns The new service.
|
|
117
118
|
*/
|
|
118
119
|
static async new(config, peerDiscoveryService, peerId, txPool, store) {
|
|
119
|
-
const { tcpListenIp, tcpListenPort, minPeerCount, maxPeerCount } = config;
|
|
120
|
-
const
|
|
121
|
-
start: false,
|
|
122
|
-
peerId,
|
|
123
|
-
addresses: {
|
|
124
|
-
listen: [`/ip4/${tcpListenIp}/tcp/${tcpListenPort}`],
|
|
125
|
-
},
|
|
126
|
-
transports: [tcp()],
|
|
127
|
-
streamMuxers: [yamux(), mplex()],
|
|
128
|
-
connectionEncryption: [noise()],
|
|
129
|
-
connectionManager: {
|
|
130
|
-
minConnections: minPeerCount,
|
|
131
|
-
maxConnections: maxPeerCount,
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
const services = {
|
|
135
|
-
identify: identify({
|
|
136
|
-
protocolPrefix: 'aztec',
|
|
137
|
-
}),
|
|
138
|
-
};
|
|
120
|
+
const { tcpListenIp, tcpListenPort, minPeerCount, maxPeerCount, dataDirectory, transactionProtocol: protocolId, } = config;
|
|
121
|
+
const bindAddrTcp = `/ip4/${tcpListenIp}/tcp/${tcpListenPort}`;
|
|
139
122
|
// The autonat service seems quite problematic in that using it seems to cause a lot of attempts
|
|
140
123
|
// to dial ephemeral ports. I suspect that it works better if you can get the uPNPnat service to
|
|
141
124
|
// work as then you would have a permanent port to be dialled.
|
|
@@ -149,11 +132,40 @@ export class LibP2PService {
|
|
|
149
132
|
// });
|
|
150
133
|
// services.uPnPNAT = uPnPNATService();
|
|
151
134
|
// }
|
|
135
|
+
const datastore = new AztecDatastore(AztecLmdbStore.open(dataDirectory));
|
|
152
136
|
const node = await createLibp2p({
|
|
153
|
-
|
|
154
|
-
|
|
137
|
+
start: false,
|
|
138
|
+
peerId,
|
|
139
|
+
addresses: {
|
|
140
|
+
listen: [bindAddrTcp],
|
|
141
|
+
},
|
|
142
|
+
transports: [
|
|
143
|
+
tcp({
|
|
144
|
+
maxConnections: config.maxPeerCount,
|
|
145
|
+
}),
|
|
146
|
+
],
|
|
147
|
+
datastore,
|
|
148
|
+
streamMuxers: [yamux(), mplex()],
|
|
149
|
+
connectionEncryption: [noise()],
|
|
150
|
+
connectionManager: {
|
|
151
|
+
minConnections: minPeerCount,
|
|
152
|
+
maxConnections: maxPeerCount,
|
|
153
|
+
},
|
|
154
|
+
services: {
|
|
155
|
+
identify: identify({
|
|
156
|
+
protocolPrefix: 'aztec',
|
|
157
|
+
}),
|
|
158
|
+
pubsub: gossipsub({
|
|
159
|
+
allowPublishToZeroTopicPeers: true,
|
|
160
|
+
D: 6,
|
|
161
|
+
Dlo: 4,
|
|
162
|
+
Dhi: 12,
|
|
163
|
+
heartbeatInterval: 1000,
|
|
164
|
+
mcacheLength: 5,
|
|
165
|
+
mcacheGossip: 3,
|
|
166
|
+
}),
|
|
167
|
+
},
|
|
155
168
|
});
|
|
156
|
-
const protocolId = config.transactionProtocol;
|
|
157
169
|
// Create an LMDB peer store
|
|
158
170
|
const peerDb = new AztecPeerDb(store);
|
|
159
171
|
// extract bootstrap node peer IDs
|
|
@@ -163,6 +175,42 @@ export class LibP2PService {
|
|
|
163
175
|
}
|
|
164
176
|
return new LibP2PService(config, node, peerDiscoveryService, peerDb, protocolId, txPool, bootstrapPeerIds);
|
|
165
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Subscribes to a topic.
|
|
180
|
+
* @param topic - The topic to subscribe to.
|
|
181
|
+
*/
|
|
182
|
+
subscribeToTopic(topic) {
|
|
183
|
+
if (!this.node.services.pubsub) {
|
|
184
|
+
throw new Error('Pubsub service not available.');
|
|
185
|
+
}
|
|
186
|
+
void this.node.services.pubsub.subscribe(topic);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Publishes data to a topic.
|
|
190
|
+
* @param topic - The topic to publish to.
|
|
191
|
+
* @param data - The data to publish.
|
|
192
|
+
* @returns The number of recipients the data was sent to.
|
|
193
|
+
*/
|
|
194
|
+
async publishToTopic(topic, data) {
|
|
195
|
+
if (!this.node.services.pubsub) {
|
|
196
|
+
throw new Error('Pubsub service not available.');
|
|
197
|
+
}
|
|
198
|
+
const result = await this.node.services.pubsub.publish(topic, data);
|
|
199
|
+
return result.recipients.length;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Handles a new gossip message that was received by the client.
|
|
203
|
+
* @param topic - The message's topic.
|
|
204
|
+
* @param data - The message data
|
|
205
|
+
*/
|
|
206
|
+
async handleNewGossipMessage(topic, data) {
|
|
207
|
+
if (topic !== this.messageCreator.getTopic()) {
|
|
208
|
+
// Invalid TX Topic, ignore
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const tx = fromTxMessage(Buffer.from(data));
|
|
212
|
+
await this.processTxFromPeer(tx);
|
|
213
|
+
}
|
|
166
214
|
/**
|
|
167
215
|
* Propagates the provided transaction to peers.
|
|
168
216
|
* @param tx - The transaction to propagate.
|
|
@@ -193,7 +241,7 @@ export class LibP2PService {
|
|
|
193
241
|
const hasPeer = await this.node.peerStore.has(peerId);
|
|
194
242
|
// add to peer store if not already known
|
|
195
243
|
if (!hasPeer) {
|
|
196
|
-
this.logger.info(`Discovered peer ${
|
|
244
|
+
this.logger.info(`Discovered peer ${peerIdStr}. Adding to libp2p peer list`);
|
|
197
245
|
let stream;
|
|
198
246
|
try {
|
|
199
247
|
stream = await this.node.dialProtocol(peerMultiAddr, this.protocolId);
|
|
@@ -218,7 +266,7 @@ export class LibP2PService {
|
|
|
218
266
|
if (!message.length) {
|
|
219
267
|
this.logger.verbose(`Ignoring 0 byte message from peer${peer.toString()}`);
|
|
220
268
|
}
|
|
221
|
-
await this.
|
|
269
|
+
// await this.processTransactionMessage(message, peer);
|
|
222
270
|
}
|
|
223
271
|
catch (err) {
|
|
224
272
|
this.logger.error(`Failed to handle received message from peer ${incomingStreamData.connection.remotePeer.toString()}`, err);
|
|
@@ -235,150 +283,29 @@ export class LibP2PService {
|
|
|
235
283
|
await incomingStreamData.stream.close();
|
|
236
284
|
return { message: buffer, peer: incomingStreamData.connection.remotePeer };
|
|
237
285
|
}
|
|
238
|
-
handleNewConnection(peerId) {
|
|
286
|
+
async handleNewConnection(peerId) {
|
|
239
287
|
if (this.isBootstrapPeer(peerId)) {
|
|
240
288
|
this.logger.verbose(`Connected to bootstrap peer ${peerId.toString()}`);
|
|
241
289
|
}
|
|
242
290
|
else {
|
|
243
291
|
this.logger.verbose(`Connected to transaction peer ${peerId.toString()}`);
|
|
244
|
-
|
|
245
|
-
void this.jobQueue.put(async () => {
|
|
246
|
-
await this.sendTxHashesMessageToPeer(peerId);
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
async processMessage(message, peerId) {
|
|
251
|
-
const type = message.readUInt32BE(0);
|
|
252
|
-
const encodedMessage = getEncodedMessage(message);
|
|
253
|
-
switch (type) {
|
|
254
|
-
case Messages.POOLED_TRANSACTIONS:
|
|
255
|
-
await this.processReceivedTxs(encodedMessage, peerId);
|
|
256
|
-
return;
|
|
257
|
-
case Messages.POOLED_TRANSACTION_HASHES:
|
|
258
|
-
await this.processReceivedTxHashes(encodedMessage, peerId);
|
|
259
|
-
return;
|
|
260
|
-
case Messages.GET_TRANSACTIONS:
|
|
261
|
-
await this.processReceivedGetTransactionsRequest(encodedMessage, peerId);
|
|
262
|
-
return;
|
|
292
|
+
await this.peerManager.updateDiscoveryService();
|
|
263
293
|
}
|
|
264
|
-
throw new Error(`Unknown message type ${type}`);
|
|
265
294
|
}
|
|
266
|
-
async
|
|
267
|
-
try {
|
|
268
|
-
const txHashes = decodeTransactionHashesMessage(encodedMessage);
|
|
269
|
-
this.logger.debug(`Received tx hash messages from ${peerId.toString()}`);
|
|
270
|
-
// we send a message requesting the transactions that we don't have from the set of received hashes
|
|
271
|
-
const requiredHashes = txHashes.filter(hash => !this.txPool.hasTx(hash));
|
|
272
|
-
if (!requiredHashes.length) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
await this.sendGetTransactionsMessageToPeer(txHashes, peerId);
|
|
276
|
-
}
|
|
277
|
-
catch (err) {
|
|
278
|
-
this.logger.error(`Failed to process received tx hashes`, err);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
async processReceivedGetTransactionsRequest(encodedMessage, peerId) {
|
|
282
|
-
try {
|
|
283
|
-
this.logger.debug(`Received get txs messages from ${peerId.toString()}`);
|
|
284
|
-
// get the transactions in the list that we have and return them
|
|
285
|
-
const removeUndefined = (value) => value != undefined;
|
|
286
|
-
const txHashes = decodeGetTransactionsRequestMessage(encodedMessage);
|
|
287
|
-
const txs = txHashes.map(x => this.txPool.getTxByHash(x)).filter(removeUndefined);
|
|
288
|
-
if (!txs.length) {
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
await this.sendTransactionsMessageToPeer(txs, peerId);
|
|
292
|
-
}
|
|
293
|
-
catch (err) {
|
|
294
|
-
this.logger.error(`Failed to process get txs request`, err);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
async processReceivedTxs(encodedMessage, peerId) {
|
|
298
|
-
try {
|
|
299
|
-
const txs = decodeTransactionsMessage(encodedMessage);
|
|
300
|
-
// Could optimize here and process all txs at once
|
|
301
|
-
// Propagation would need to filter and send custom tx set per peer
|
|
302
|
-
for (const tx of txs) {
|
|
303
|
-
await this.processTxFromPeer(tx, peerId);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
catch (err) {
|
|
307
|
-
this.logger.error(`Failed to process pooled transactions message`, err);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
async processTxFromPeer(tx, peerId) {
|
|
295
|
+
async processTxFromPeer(tx) {
|
|
311
296
|
const txHash = tx.getTxHash();
|
|
312
297
|
const txHashString = txHash.toString();
|
|
313
|
-
this.
|
|
314
|
-
this.logger.debug(`Received tx ${txHashString} from peer ${peerId.toString()}`);
|
|
298
|
+
this.logger.debug(`Received tx ${txHashString} from external peer.`);
|
|
315
299
|
await this.txPool.addTxs([tx]);
|
|
316
|
-
this.propagateTx(tx);
|
|
317
300
|
}
|
|
318
301
|
async sendTxToPeers(tx) {
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
const txHashString = txHash.toString();
|
|
324
|
-
for (const peer of peers) {
|
|
325
|
-
try {
|
|
326
|
-
if (this.knownTxLookup.hasPeerSeenTx(peer, txHashString)) {
|
|
327
|
-
this.logger.debug(`Not sending tx ${txHashString} to peer ${peer.toString()} as they have already seen it`);
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
this.logger.debug(`Sending tx ${txHashString} to peer ${peer.toString()}`);
|
|
331
|
-
await this.sendRawMessageToPeer(payload, peer);
|
|
332
|
-
this.knownTxLookup.addPeerForTx(peer, txHashString);
|
|
333
|
-
}
|
|
334
|
-
catch (err) {
|
|
335
|
-
this.logger.error(`Failed to send txs to peer ${peer.toString()}`, err);
|
|
336
|
-
continue;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
async sendTxHashesMessageToPeer(peer) {
|
|
341
|
-
try {
|
|
342
|
-
const hashes = this.txPool.getAllTxHashes();
|
|
343
|
-
if (!hashes.length) {
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
const message = createTransactionHashesMessage(hashes);
|
|
347
|
-
await this.sendRawMessageToPeer(new Uint8Array(message), peer);
|
|
348
|
-
}
|
|
349
|
-
catch (err) {
|
|
350
|
-
this.logger.error(`Failed to send tx hashes to peer ${peer.toString()}`, err);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
async sendGetTransactionsMessageToPeer(hashes, peer) {
|
|
354
|
-
try {
|
|
355
|
-
const message = createGetTransactionsRequestMessage(hashes);
|
|
356
|
-
await this.sendRawMessageToPeer(new Uint8Array(message), peer);
|
|
357
|
-
}
|
|
358
|
-
catch (err) {
|
|
359
|
-
this.logger.error(`Failed to send tx request to peer ${peer.toString()}`, err);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
async sendTransactionsMessageToPeer(txs, peer) {
|
|
363
|
-
// don't filter out any transactions based on what we think the peer has seen,
|
|
364
|
-
// we have been explicitly asked for these transactions
|
|
365
|
-
const message = createTransactionsMessage(txs);
|
|
366
|
-
await this.sendRawMessageToPeer(message, peer);
|
|
367
|
-
for (const tx of txs) {
|
|
368
|
-
const hash = tx.getTxHash();
|
|
369
|
-
this.knownTxLookup.addPeerForTx(peer, hash.toString());
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
async sendRawMessageToPeer(message, peer) {
|
|
373
|
-
const stream = await this.node.dialProtocol(peer, this.protocolId);
|
|
374
|
-
await pipe([message], stream);
|
|
375
|
-
await stream.close();
|
|
376
|
-
}
|
|
377
|
-
getTxPeers() {
|
|
378
|
-
return this.node.getPeers().filter(peer => !this.isBootstrapPeer(peer));
|
|
302
|
+
const { data: txData } = this.messageCreator.createTxMessage(tx);
|
|
303
|
+
this.logger.debug(`Sending tx ${tx.getTxHash().toString()} to peers`);
|
|
304
|
+
const recipientsNum = await this.publishToTopic(this.messageCreator.getTopic(), txData);
|
|
305
|
+
this.logger.debug(`Sent tx ${tx.getTxHash().toString()} to ${recipientsNum} peers`);
|
|
379
306
|
}
|
|
380
307
|
isBootstrapPeer(peer) {
|
|
381
308
|
return this.bootstrapPeerIds.some(bootstrapPeer => bootstrapPeer.equals(peer));
|
|
382
309
|
}
|
|
383
310
|
}
|
|
384
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHMUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRzVDLE9BQU8saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsY0FBYyxFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbEcsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQy9CLE9BQU8sRUFBMkQsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBSS9GLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUF1QixNQUFNLGlCQUFpQixDQUFDO0FBRW5FLE9BQU8sRUFDTCxRQUFRLEVBQ1IsbUNBQW1DLEVBQ25DLDhCQUE4QixFQUM5Qix5QkFBeUIsRUFDekIsbUNBQW1DLEVBQ25DLDhCQUE4QixFQUM5Qix5QkFBeUIsRUFDekIsaUJBQWlCLEdBQ2xCLE1BQU0sa0JB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
|
|
311
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXRELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLEVBQXdCLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzlFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsY0FBYyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQy9CLE9BQU8sRUFBZSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFJbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FB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
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Libp2p } from 'libp2p';
|
|
2
|
+
import { type P2PConfig } from '../config.js';
|
|
3
|
+
import { type PeerDiscoveryService } from './service.js';
|
|
4
|
+
export declare class PeerManager {
|
|
5
|
+
private libP2PNode;
|
|
6
|
+
private discV5Node;
|
|
7
|
+
private config;
|
|
8
|
+
private logger;
|
|
9
|
+
constructor(libP2PNode: Libp2p, discV5Node: PeerDiscoveryService, config: P2PConfig, logger?: import("@aztec/foundation/log").Logger);
|
|
10
|
+
updateDiscoveryService(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=peer_manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../src/service/peer_manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,oBAAoB,EAAsB,MAAM,cAAc,CAAC;AAE7E,qBAAa,WAAW;IAEpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;gBAHN,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,SAAS,EACjB,MAAM,yCAA8C;IAGxD,sBAAsB;CAU7B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { PeerDiscoveryState } from './service.js';
|
|
3
|
+
export class PeerManager {
|
|
4
|
+
constructor(libP2PNode, discV5Node, config, logger = createDebugLogger('aztec:p2p:peer_manager')) {
|
|
5
|
+
this.libP2PNode = libP2PNode;
|
|
6
|
+
this.discV5Node = discV5Node;
|
|
7
|
+
this.config = config;
|
|
8
|
+
this.logger = logger;
|
|
9
|
+
}
|
|
10
|
+
async updateDiscoveryService() {
|
|
11
|
+
const peerCount = this.libP2PNode.getPeers().length;
|
|
12
|
+
if (peerCount >= this.config.maxPeerCount && this.discV5Node.getStatus() === PeerDiscoveryState.RUNNING) {
|
|
13
|
+
this.logger.debug('Max peer count reached, stopping discovery service');
|
|
14
|
+
await this.discV5Node.stop();
|
|
15
|
+
}
|
|
16
|
+
else if (peerCount <= this.config.minPeerCount && this.discV5Node.getStatus() === PeerDiscoveryState.STOPPED) {
|
|
17
|
+
this.logger.debug('Min peer count reached, starting discovery service');
|
|
18
|
+
await this.discV5Node.start();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2UvcGVlcl9tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBSzFELE9BQU8sRUFBNkIsa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFN0UsTUFBTSxPQUFPLFdBQVc7SUFDdEIsWUFDVSxVQUFrQixFQUNsQixVQUFnQyxFQUNoQyxNQUFpQixFQUNqQixTQUFTLGlCQUFpQixDQUFDLHdCQUF3QixDQUFDO1FBSHBELGVBQVUsR0FBVixVQUFVLENBQVE7UUFDbEIsZUFBVSxHQUFWLFVBQVUsQ0FBc0I7UUFDaEMsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUNqQixXQUFNLEdBQU4sTUFBTSxDQUE4QztJQUMzRCxDQUFDO0lBRUosS0FBSyxDQUFDLHNCQUFzQjtRQUMxQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUNwRCxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3hHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7WUFDeEUsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQy9CLENBQUM7YUFBTSxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQy9HLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7WUFDeEUsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0NBQ0YifQ==
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import type { Tx, TxHash } from '@aztec/circuit-types';
|
|
3
3
|
import type { ENR } from '@chainsafe/enr';
|
|
4
4
|
import type EventEmitter from 'events';
|
|
5
|
+
export declare enum PeerDiscoveryState {
|
|
6
|
+
RUNNING = "running",
|
|
7
|
+
STOPPED = "stopped"
|
|
8
|
+
}
|
|
5
9
|
/**
|
|
6
10
|
* The interface for a P2P service implementation.
|
|
7
11
|
*/
|
|
@@ -49,5 +53,6 @@ export interface PeerDiscoveryService extends EventEmitter {
|
|
|
49
53
|
*/
|
|
50
54
|
on(event: 'peer:discovered', listener: (enr: ENR) => void): this;
|
|
51
55
|
emit(event: 'peer:discovered', enr: ENR): boolean;
|
|
56
|
+
getStatus(): PeerDiscoveryState;
|
|
52
57
|
}
|
|
53
58
|
//# sourceMappingURL=service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IAE1B;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;SAEK;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;SAEK;IACL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,IAAI,GAAG,EAAE,CAAC;IAErB;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IAE1B;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;SAEK;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;SAEK;IACL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,IAAI,GAAG,EAAE,CAAC;IAErB;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;IAElD,SAAS,IAAI,kBAAkB,CAAC;CACjC"}
|
package/dest/service/service.js
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export var PeerDiscoveryState;
|
|
2
|
+
(function (PeerDiscoveryState) {
|
|
3
|
+
PeerDiscoveryState["RUNNING"] = "running";
|
|
4
|
+
PeerDiscoveryState["STOPPED"] = "stopped";
|
|
5
|
+
})(PeerDiscoveryState || (PeerDiscoveryState = {}));
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS0EsTUFBTSxDQUFOLElBQVksa0JBR1g7QUFIRCxXQUFZLGtCQUFrQjtJQUM1Qix5Q0FBbUIsQ0FBQTtJQUNuQix5Q0FBbUIsQ0FBQTtBQUNyQixDQUFDLEVBSFcsa0JBQWtCLEtBQWxCLGtCQUFrQixRQUc3QiJ9
|
|
@@ -1,68 +1,22 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import { Tx
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
import { Tx } from '@aztec/circuit-types';
|
|
3
|
+
import { type SemVer } from 'semver';
|
|
4
|
+
export declare const TX_MESSAGE_TOPIC = "";
|
|
5
|
+
export declare class AztecTxMessageCreator {
|
|
6
|
+
private readonly topic;
|
|
7
|
+
constructor(version: SemVer);
|
|
8
|
+
createTxMessage(tx: Tx): {
|
|
9
|
+
topic: string;
|
|
10
|
+
data: Buffer;
|
|
11
|
+
};
|
|
12
|
+
getTopic(): string;
|
|
10
13
|
}
|
|
11
|
-
/**
|
|
12
|
-
* Create a P2P message from the message type and message data.
|
|
13
|
-
* @param type - The type of the message.
|
|
14
|
-
* @param messageData - The binary message data.
|
|
15
|
-
* @returns The encoded message.
|
|
16
|
-
*/
|
|
17
|
-
export declare function createMessage(type: Messages, messageData: Buffer): Buffer;
|
|
18
|
-
/**
|
|
19
|
-
* Create a POOLED_TRANSACTIONS message from an array of transactions.
|
|
20
|
-
* @param txs - The transactions to encoded into a message.
|
|
21
|
-
* @returns The encoded message.
|
|
22
|
-
*/
|
|
23
|
-
export declare function createTransactionsMessage(txs: Tx[]): Buffer;
|
|
24
14
|
/**
|
|
25
15
|
* Decode a POOLED_TRANSACTIONS message into the original transaction objects.
|
|
26
16
|
* @param message - The binary message to be decoded.
|
|
27
17
|
* @returns - The array of transactions originally encoded into the message.
|
|
28
18
|
*/
|
|
29
19
|
export declare function decodeTransactionsMessage(message: Buffer): Tx[];
|
|
30
|
-
/**
|
|
31
|
-
* Create a POOLED_TRANSACTION_HASHES message.
|
|
32
|
-
* @param hashes - The transaction hashes to be sent.
|
|
33
|
-
* @returns The encoded message.
|
|
34
|
-
*/
|
|
35
|
-
export declare function createTransactionHashesMessage(hashes: TxHash[]): Buffer;
|
|
36
|
-
/**
|
|
37
|
-
* Decode a POOLED_TRANSACTION_HASHESs message ito the original transaction hash objects.
|
|
38
|
-
* @param message - The binary message to be decoded.
|
|
39
|
-
* @returns - The array of transaction hashes originally encoded into the message.
|
|
40
|
-
*/
|
|
41
|
-
export declare function decodeTransactionHashesMessage(message: Buffer): TxHash[];
|
|
42
|
-
/**
|
|
43
|
-
* Create a GET_TRANSACTIONS message from an array of transaction hashes.
|
|
44
|
-
* @param hashes - The hashes of the transactions to be requested.
|
|
45
|
-
* @returns The encoded message.
|
|
46
|
-
*/
|
|
47
|
-
export declare function createGetTransactionsRequestMessage(hashes: TxHash[]): Buffer;
|
|
48
|
-
/**
|
|
49
|
-
* Decode a GET_TRANSACTIONS message into the original transaction hash objects.
|
|
50
|
-
* @param message - The binary message to be decoded.
|
|
51
|
-
* @returns - The array of transaction hashes originally encoded into the message.
|
|
52
|
-
*/
|
|
53
|
-
export declare function decodeGetTransactionsRequestMessage(message: Buffer): TxHash[];
|
|
54
|
-
/**
|
|
55
|
-
* Decode the message type from a received message.
|
|
56
|
-
* @param message - The received message.
|
|
57
|
-
* @returns The decoded MessageType.
|
|
58
|
-
*/
|
|
59
|
-
export declare function decodeMessageType(message: Buffer): number;
|
|
60
|
-
/**
|
|
61
|
-
* Return the encoded message (minus the header) from received message buffer.
|
|
62
|
-
* @param message - The complete received message.
|
|
63
|
-
* @returns The encoded message, without the header.
|
|
64
|
-
*/
|
|
65
|
-
export declare function getEncodedMessage(message: Buffer): Buffer;
|
|
66
20
|
/**
|
|
67
21
|
* Creates a tx 'message' for sending to a peer.
|
|
68
22
|
* @param tx - The transaction to convert to a message.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tx_messages.d.ts","sourceRoot":"","sources":["../../src/service/tx_messages.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqB,EAAE,
|
|
1
|
+
{"version":3,"file":"tx_messages.d.ts","sourceRoot":"","sources":["../../src/service/tx_messages.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqB,EAAE,EAAuB,MAAM,sBAAsB,CAAC;AAIlF,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBACnB,OAAO,EAAE,MAAM;IAI3B,eAAe,CAAC,EAAE,EAAE,EAAE;;;;IAMtB,QAAQ;CAGT;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,QAWxD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CA6B1C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,EAAE,CAoDhD"}
|