@libp2p/interface-compliance-tests 0.0.0 → 0.2.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/LICENSE +4 -0
- package/README.md +25 -0
- package/dist/src/connection/connection.d.ts +5 -0
- package/dist/src/connection/connection.d.ts.map +1 -0
- package/dist/src/connection/connection.js +148 -0
- package/dist/src/connection/connection.js.map +1 -0
- package/dist/src/connection/index.d.ts +5 -0
- package/dist/src/connection/index.d.ts.map +1 -0
- package/dist/src/connection/index.js +5 -0
- package/dist/src/connection/index.js.map +1 -0
- package/dist/src/crypto/index.d.ts +5 -0
- package/dist/src/crypto/index.d.ts.map +1 -0
- package/dist/src/crypto/index.js +78 -0
- package/dist/src/crypto/index.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/peer-discovery/index.d.ts +6 -0
- package/dist/src/peer-discovery/index.d.ts.map +1 -0
- package/dist/src/peer-discovery/index.js +63 -0
- package/dist/src/peer-discovery/index.js.map +1 -0
- package/dist/src/pubsub/api.d.ts +6 -0
- package/dist/src/pubsub/api.d.ts.map +1 -0
- package/dist/src/pubsub/api.js +65 -0
- package/dist/src/pubsub/api.js.map +1 -0
- package/dist/src/pubsub/connection-handlers.d.ts +6 -0
- package/dist/src/pubsub/connection-handlers.d.ts.map +1 -0
- package/dist/src/pubsub/connection-handlers.js +279 -0
- package/dist/src/pubsub/connection-handlers.js.map +1 -0
- package/dist/src/pubsub/emit-self.d.ts +6 -0
- package/dist/src/pubsub/emit-self.d.ts.map +1 -0
- package/dist/src/pubsub/emit-self.js +51 -0
- package/dist/src/pubsub/emit-self.js.map +1 -0
- package/dist/src/pubsub/index.d.ts +6 -0
- package/dist/src/pubsub/index.d.ts.map +1 -0
- package/dist/src/pubsub/index.js +17 -0
- package/dist/src/pubsub/index.js.map +1 -0
- package/dist/src/pubsub/messages.d.ts +6 -0
- package/dist/src/pubsub/messages.d.ts.map +1 -0
- package/dist/src/pubsub/messages.js +93 -0
- package/dist/src/pubsub/messages.js.map +1 -0
- package/dist/src/pubsub/multiple-nodes.d.ts +6 -0
- package/dist/src/pubsub/multiple-nodes.d.ts.map +1 -0
- package/dist/src/pubsub/multiple-nodes.js +283 -0
- package/dist/src/pubsub/multiple-nodes.js.map +1 -0
- package/dist/src/pubsub/two-nodes.d.ts +6 -0
- package/dist/src/pubsub/two-nodes.d.ts.map +1 -0
- package/dist/src/pubsub/two-nodes.js +127 -0
- package/dist/src/pubsub/two-nodes.js.map +1 -0
- package/dist/src/pubsub/utils.d.ts +3 -0
- package/dist/src/pubsub/utils.d.ts.map +1 -0
- package/dist/src/pubsub/utils.js +11 -0
- package/dist/src/pubsub/utils.js.map +1 -0
- package/dist/src/record/index.d.ts +5 -0
- package/dist/src/record/index.d.ts.map +1 -0
- package/dist/src/record/index.js +25 -0
- package/dist/src/record/index.js.map +1 -0
- package/dist/src/stream-muxer/base-test.d.ts +5 -0
- package/dist/src/stream-muxer/base-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/base-test.js +123 -0
- package/dist/src/stream-muxer/base-test.js.map +1 -0
- package/dist/src/stream-muxer/close-test.d.ts +5 -0
- package/dist/src/stream-muxer/close-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/close-test.js +103 -0
- package/dist/src/stream-muxer/close-test.js.map +1 -0
- package/dist/src/stream-muxer/index.d.ts +5 -0
- package/dist/src/stream-muxer/index.d.ts.map +1 -0
- package/dist/src/stream-muxer/index.js +13 -0
- package/dist/src/stream-muxer/index.js.map +1 -0
- package/dist/src/stream-muxer/mega-stress-test.d.ts +5 -0
- package/dist/src/stream-muxer/mega-stress-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/mega-stress-test.js +8 -0
- package/dist/src/stream-muxer/mega-stress-test.js.map +1 -0
- package/dist/src/stream-muxer/spawner.d.ts +4 -0
- package/dist/src/stream-muxer/spawner.d.ts.map +1 -0
- package/dist/src/stream-muxer/spawner.js +32 -0
- package/dist/src/stream-muxer/spawner.js.map +1 -0
- package/dist/src/stream-muxer/stress-test.d.ts +5 -0
- package/dist/src/stream-muxer/stress-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/stress-test.js +21 -0
- package/dist/src/stream-muxer/stress-test.js.map +1 -0
- package/dist/src/topology/multicodec-topology.d.ts +5 -0
- package/dist/src/topology/multicodec-topology.d.ts.map +1 -0
- package/dist/src/topology/multicodec-topology.js +109 -0
- package/dist/src/topology/multicodec-topology.js.map +1 -0
- package/dist/src/topology/topology.d.ts +5 -0
- package/dist/src/topology/topology.d.ts.map +1 -0
- package/dist/src/topology/topology.js +29 -0
- package/dist/src/topology/topology.js.map +1 -0
- package/dist/src/transport/dial-test.d.ts +5 -0
- package/dist/src/transport/dial-test.d.ts.map +1 -0
- package/dist/src/transport/dial-test.js +78 -0
- package/dist/src/transport/dial-test.js.map +1 -0
- package/dist/src/transport/filter-test.d.ts +5 -0
- package/dist/src/transport/filter-test.d.ts.map +1 -0
- package/dist/src/transport/filter-test.js +19 -0
- package/dist/src/transport/filter-test.js.map +1 -0
- package/dist/src/transport/index.d.ts +18 -0
- package/dist/src/transport/index.d.ts.map +1 -0
- package/dist/src/transport/index.js +11 -0
- package/dist/src/transport/index.js.map +1 -0
- package/dist/src/transport/listen-test.d.ts +5 -0
- package/dist/src/transport/listen-test.d.ts.map +1 -0
- package/dist/src/transport/listen-test.js +116 -0
- package/dist/src/transport/listen-test.js.map +1 -0
- package/dist/src/transport/utils/index.d.ts +8 -0
- package/dist/src/transport/utils/index.d.ts.map +1 -0
- package/dist/src/transport/utils/index.js +104 -0
- package/dist/src/transport/utils/index.js.map +1 -0
- package/dist/src/utils/peers.d.ts +7 -0
- package/dist/src/utils/peers.d.ts.map +1 -0
- package/dist/src/utils/peers.js +26 -0
- package/dist/src/utils/peers.js.map +1 -0
- package/dist/test/connection/index.spec.d.ts +2 -0
- package/dist/test/connection/index.spec.d.ts.map +1 -0
- package/dist/test/connection/index.spec.js +71 -0
- package/dist/test/connection/index.spec.js.map +1 -0
- package/dist/test/crypto/index.spec.d.ts +2 -0
- package/dist/test/crypto/index.spec.d.ts.map +1 -0
- package/dist/test/crypto/index.spec.js +11 -0
- package/dist/test/crypto/index.spec.js.map +1 -0
- package/dist/test/crypto/mock-crypto.d.ts +4 -0
- package/dist/test/crypto/mock-crypto.d.ts.map +1 -0
- package/dist/test/crypto/mock-crypto.js +93 -0
- package/dist/test/crypto/mock-crypto.js.map +1 -0
- package/dist/test/peer-discovery/index.spec.d.ts +2 -0
- package/dist/test/peer-discovery/index.spec.d.ts.map +1 -0
- package/dist/test/peer-discovery/index.spec.js +18 -0
- package/dist/test/peer-discovery/index.spec.js.map +1 -0
- package/dist/test/peer-discovery/mock-discovery.d.ts +20 -0
- package/dist/test/peer-discovery/mock-discovery.d.ts.map +1 -0
- package/dist/test/peer-discovery/mock-discovery.js +39 -0
- package/dist/test/peer-discovery/mock-discovery.js.map +1 -0
- package/dist/test/topology/mock-peer-store.d.ts +12 -0
- package/dist/test/topology/mock-peer-store.d.ts.map +1 -0
- package/dist/test/topology/mock-peer-store.js +18 -0
- package/dist/test/topology/mock-peer-store.js.map +1 -0
- package/dist/test/topology/multicodec-topology.spec.d.ts +2 -0
- package/dist/test/topology/multicodec-topology.spec.d.ts.map +1 -0
- package/dist/test/topology/multicodec-topology.spec.js +45 -0
- package/dist/test/topology/multicodec-topology.spec.js.map +1 -0
- package/dist/test/topology/topology.spec.d.ts +2 -0
- package/dist/test/topology/topology.spec.d.ts.map +1 -0
- package/dist/test/topology/topology.spec.js +21 -0
- package/dist/test/topology/topology.spec.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +120 -4
- package/src/connection/README.md +256 -0
- package/src/connection/connection.ts +178 -0
- package/src/connection/index.ts +7 -0
- package/src/crypto/index.ts +104 -0
- package/src/index.ts +5 -0
- package/src/peer-discovery/index.ts +87 -0
- package/src/pubsub/api.ts +89 -0
- package/src/pubsub/connection-handlers.ts +356 -0
- package/src/pubsub/emit-self.ts +67 -0
- package/src/pubsub/index.ts +20 -0
- package/src/pubsub/messages.ts +111 -0
- package/src/pubsub/multiple-nodes.ts +353 -0
- package/src/pubsub/two-nodes.ts +175 -0
- package/src/pubsub/utils.ts +13 -0
- package/src/record/index.ts +32 -0
- package/src/stream-muxer/base-test.ts +154 -0
- package/src/stream-muxer/close-test.ts +124 -0
- package/src/stream-muxer/index.ts +15 -0
- package/src/stream-muxer/mega-stress-test.ts +11 -0
- package/src/stream-muxer/spawner.ts +52 -0
- package/src/stream-muxer/stress-test.ts +24 -0
- package/src/topology/multicodec-topology.ts +136 -0
- package/src/topology/topology.ts +38 -0
- package/src/transport/dial-test.ts +98 -0
- package/src/transport/filter-test.ts +26 -0
- package/src/transport/index.ts +29 -0
- package/src/transport/listen-test.ts +152 -0
- package/src/transport/utils/index.ts +123 -0
- package/src/utils/peers.ts +25 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# libp2p-interfaces-compliance-tests <!-- omit in toc -->
|
|
2
|
+
|
|
3
|
+
> Contains test suites you should use to implement the various components of libp2p
|
|
4
|
+
|
|
5
|
+
## Table of contents <!-- omit in toc -->
|
|
6
|
+
|
|
7
|
+
- [Usage](#usage)
|
|
8
|
+
- [Contribute](#contribute)
|
|
9
|
+
- [License](#license)
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Each [interface](../interfaces) has its documentation on how to use the compliance tests and should be used as the source of truth.
|
|
14
|
+
|
|
15
|
+
## Contribute
|
|
16
|
+
|
|
17
|
+
The libp2p implementation in JavaScript is a work in progress. As such, there are a few things you can do right now to help out:
|
|
18
|
+
|
|
19
|
+
- Go through the modules and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS/libp2p may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically.
|
|
20
|
+
- **Perform code reviews**. More eyes will help a) speed the project along b) ensure quality and c) reduce possible future bugs.
|
|
21
|
+
- **Add tests**. There can never be enough tests.
|
|
22
|
+
|
|
23
|
+
## License
|
|
24
|
+
|
|
25
|
+
[Apache-2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT) © Protocol Labs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/connection/connection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;+BAEzC,UAAU,UAAU,CAAC;AAA3C,wBA4KC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { expect } from 'aegir/utils/chai.js';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
export default (test) => {
|
|
4
|
+
describe('connection', () => {
|
|
5
|
+
describe('open connection', () => {
|
|
6
|
+
let connection;
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
connection = await test.setup();
|
|
9
|
+
});
|
|
10
|
+
afterEach(async () => {
|
|
11
|
+
await connection.close();
|
|
12
|
+
await test.teardown();
|
|
13
|
+
});
|
|
14
|
+
it('should have properties set', () => {
|
|
15
|
+
expect(connection.id).to.exist();
|
|
16
|
+
expect(connection.localPeer).to.exist();
|
|
17
|
+
expect(connection.remotePeer).to.exist();
|
|
18
|
+
expect(connection.localAddr).to.exist();
|
|
19
|
+
expect(connection.remoteAddr).to.exist();
|
|
20
|
+
expect(connection.stat.status).to.equal('OPEN');
|
|
21
|
+
expect(connection.stat.timeline.open).to.exist();
|
|
22
|
+
expect(connection.stat.timeline.upgraded).to.exist();
|
|
23
|
+
expect(connection.stat.timeline.close).to.not.exist();
|
|
24
|
+
expect(connection.stat.direction).to.exist();
|
|
25
|
+
expect(connection.streams).to.eql([]);
|
|
26
|
+
expect(connection.tags).to.eql([]);
|
|
27
|
+
});
|
|
28
|
+
it('should get the metadata of an open connection', () => {
|
|
29
|
+
const stat = connection.stat;
|
|
30
|
+
expect(stat.status).to.equal('OPEN');
|
|
31
|
+
expect(stat.direction).to.exist();
|
|
32
|
+
expect(stat.timeline.open).to.exist();
|
|
33
|
+
expect(stat.timeline.upgraded).to.exist();
|
|
34
|
+
expect(stat.timeline.close).to.not.exist();
|
|
35
|
+
});
|
|
36
|
+
it('should return an empty array of streams', () => {
|
|
37
|
+
const streams = connection.streams;
|
|
38
|
+
expect(streams).to.eql([]);
|
|
39
|
+
});
|
|
40
|
+
it('should be able to create a new stream', async () => {
|
|
41
|
+
const protocolToUse = '/echo/0.0.1';
|
|
42
|
+
const { stream, protocol } = await connection.newStream([protocolToUse]);
|
|
43
|
+
expect(protocol).to.equal(protocolToUse);
|
|
44
|
+
const connStreams = await connection.streams;
|
|
45
|
+
expect(stream).to.exist();
|
|
46
|
+
expect(connStreams).to.exist();
|
|
47
|
+
expect(connStreams).to.have.lengthOf(1);
|
|
48
|
+
expect(connStreams[0]).to.equal(stream);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe('close connection', () => {
|
|
52
|
+
let connection;
|
|
53
|
+
let timelineProxy;
|
|
54
|
+
const proxyHandler = {
|
|
55
|
+
set() {
|
|
56
|
+
// @ts-expect-error - TS fails to infer here
|
|
57
|
+
return Reflect.set(...arguments);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
beforeEach(async () => {
|
|
61
|
+
timelineProxy = new Proxy({
|
|
62
|
+
open: Date.now() - 10,
|
|
63
|
+
upgraded: Date.now()
|
|
64
|
+
}, proxyHandler);
|
|
65
|
+
connection = await test.setup({
|
|
66
|
+
stat: {
|
|
67
|
+
timeline: timelineProxy,
|
|
68
|
+
direction: 'outbound',
|
|
69
|
+
encryption: '/crypto/1.0.0',
|
|
70
|
+
multiplexer: '/muxer/1.0.0'
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
afterEach(async () => {
|
|
75
|
+
await test.teardown();
|
|
76
|
+
});
|
|
77
|
+
it('should be able to close the connection after being created', async () => {
|
|
78
|
+
expect(connection.stat.timeline.close).to.not.exist();
|
|
79
|
+
await connection.close();
|
|
80
|
+
expect(connection.stat.timeline.close).to.exist();
|
|
81
|
+
expect(connection.stat.status).to.equal('CLOSED');
|
|
82
|
+
});
|
|
83
|
+
it('should be able to close the connection after opening a stream', async () => {
|
|
84
|
+
// Open stream
|
|
85
|
+
const protocol = '/echo/0.0.1';
|
|
86
|
+
await connection.newStream([protocol]);
|
|
87
|
+
// Close connection
|
|
88
|
+
expect(connection.stat.timeline.close).to.not.exist();
|
|
89
|
+
await connection.close();
|
|
90
|
+
expect(connection.stat.timeline.close).to.exist();
|
|
91
|
+
expect(connection.stat.status).to.equal('CLOSED');
|
|
92
|
+
});
|
|
93
|
+
it('should properly track streams', async () => {
|
|
94
|
+
// Open stream
|
|
95
|
+
const protocol = '/echo/0.0.1';
|
|
96
|
+
const { stream } = await connection.newStream([protocol]);
|
|
97
|
+
const trackedStream = connection.registry.get(stream.id);
|
|
98
|
+
expect(trackedStream).to.have.property('protocol', protocol);
|
|
99
|
+
// Close stream
|
|
100
|
+
await stream.close();
|
|
101
|
+
expect(connection.registry.get(stream.id)).to.not.exist();
|
|
102
|
+
});
|
|
103
|
+
it('should support a proxy on the timeline', async () => {
|
|
104
|
+
sinon.spy(proxyHandler, 'set');
|
|
105
|
+
expect(connection.stat.timeline.close).to.not.exist();
|
|
106
|
+
await connection.close();
|
|
107
|
+
// @ts-expect-error - fails to infer callCount
|
|
108
|
+
expect(proxyHandler.set.callCount).to.equal(1);
|
|
109
|
+
// @ts-expect-error - fails to infer getCall
|
|
110
|
+
const [obj, key, value] = proxyHandler.set.getCall(0).args;
|
|
111
|
+
expect(obj).to.eql(connection.stat.timeline);
|
|
112
|
+
expect(key).to.equal('close');
|
|
113
|
+
expect(value).to.be.a('number').that.equals(connection.stat.timeline.close);
|
|
114
|
+
});
|
|
115
|
+
it('should fail to create a new stream if the connection is closing', async () => {
|
|
116
|
+
expect(connection.stat.timeline.close).to.not.exist();
|
|
117
|
+
const p = connection.close();
|
|
118
|
+
try {
|
|
119
|
+
const protocol = '/echo/0.0.1';
|
|
120
|
+
await connection.newStream([protocol]);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
expect(err).to.exist();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
await p;
|
|
128
|
+
}
|
|
129
|
+
throw new Error('should fail to create a new stream if the connection is closing');
|
|
130
|
+
});
|
|
131
|
+
it('should fail to create a new stream if the connection is closed', async () => {
|
|
132
|
+
expect(connection.stat.timeline.close).to.not.exist();
|
|
133
|
+
await connection.close();
|
|
134
|
+
try {
|
|
135
|
+
const protocol = '/echo/0.0.1';
|
|
136
|
+
await connection.newStream([protocol]);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
expect(err).to.exist();
|
|
140
|
+
expect(err.code).to.equal('ERR_CONNECTION_CLOSED');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
throw new Error('should fail to create a new stream if the connection is closing');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/connection/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/connection/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;+BAEzC,UAAU,UAAU,CAAC;AAA3C,wBAEC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/connection/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,iBAAiB,CAAA;AAI7C,eAAe,CAAC,IAA2B,EAAE,EAAE;IAC7C,eAAe,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;iCAG/B,UAAU,MAAM,CAAC;AAAzC,wBA0FC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { expect } from 'aegir/utils/chai.js';
|
|
2
|
+
// @ts-expect-error no types
|
|
3
|
+
import duplexPair from 'it-pair/duplex.js';
|
|
4
|
+
import { pipe } from 'it-pipe';
|
|
5
|
+
import * as PeerIdFactory from '@libp2p/peer-id-factory';
|
|
6
|
+
import { collect } from 'streaming-iterables';
|
|
7
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
|
|
8
|
+
import peers from '../utils/peers.js';
|
|
9
|
+
import { UnexpectedPeerError } from '@libp2p/interfaces/crypto/errors';
|
|
10
|
+
export default (common) => {
|
|
11
|
+
describe('interface-crypto compliance tests', () => {
|
|
12
|
+
let crypto;
|
|
13
|
+
let localPeer;
|
|
14
|
+
let remotePeer;
|
|
15
|
+
let mitmPeer;
|
|
16
|
+
before(async () => {
|
|
17
|
+
[
|
|
18
|
+
crypto,
|
|
19
|
+
localPeer,
|
|
20
|
+
remotePeer,
|
|
21
|
+
mitmPeer
|
|
22
|
+
] = await Promise.all([
|
|
23
|
+
common.setup(),
|
|
24
|
+
PeerIdFactory.createFromJSON(peers[0]),
|
|
25
|
+
PeerIdFactory.createFromJSON(peers[1]),
|
|
26
|
+
PeerIdFactory.createFromJSON(peers[2])
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
after(async () => {
|
|
30
|
+
await common.teardown();
|
|
31
|
+
});
|
|
32
|
+
it('has a protocol string', () => {
|
|
33
|
+
expect(crypto.protocol).to.exist();
|
|
34
|
+
expect(crypto.protocol).to.be.a('string');
|
|
35
|
+
});
|
|
36
|
+
it('it wraps the provided duplex connection', async () => {
|
|
37
|
+
const [localConn, remoteConn] = duplexPair();
|
|
38
|
+
const [inboundResult, outboundResult] = await Promise.all([
|
|
39
|
+
crypto.secureInbound(remotePeer, localConn),
|
|
40
|
+
crypto.secureOutbound(localPeer, remoteConn, remotePeer)
|
|
41
|
+
]);
|
|
42
|
+
// Echo server
|
|
43
|
+
pipe(inboundResult.conn, inboundResult.conn);
|
|
44
|
+
// Send some data and collect the result
|
|
45
|
+
const input = uint8ArrayFromString('data to encrypt');
|
|
46
|
+
const result = await pipe([input], outboundResult.conn,
|
|
47
|
+
// Convert BufferList to Buffer via slice
|
|
48
|
+
(source) => (async function* toBuffer() {
|
|
49
|
+
for await (const chunk of source) {
|
|
50
|
+
yield chunk.slice();
|
|
51
|
+
}
|
|
52
|
+
})(), collect);
|
|
53
|
+
expect(result).to.eql([input]);
|
|
54
|
+
});
|
|
55
|
+
it('should return the remote peer id', async () => {
|
|
56
|
+
const [localConn, remoteConn] = duplexPair();
|
|
57
|
+
const [inboundResult, outboundResult] = await Promise.all([
|
|
58
|
+
crypto.secureInbound(remotePeer, localConn),
|
|
59
|
+
crypto.secureOutbound(localPeer, remoteConn, remotePeer)
|
|
60
|
+
]);
|
|
61
|
+
// Inbound should return the initiator (local) peer
|
|
62
|
+
expect(inboundResult.remotePeer.toBytes()).to.equalBytes(localPeer.toBytes());
|
|
63
|
+
// Outbound should return the receiver (remote) peer
|
|
64
|
+
expect(outboundResult.remotePeer.toBytes()).to.equalBytes(remotePeer.toBytes());
|
|
65
|
+
});
|
|
66
|
+
it('inbound connections should verify peer integrity if known', async () => {
|
|
67
|
+
const [localConn, remoteConn] = duplexPair();
|
|
68
|
+
await Promise.all([
|
|
69
|
+
crypto.secureInbound(remotePeer, localConn, mitmPeer),
|
|
70
|
+
crypto.secureOutbound(localPeer, remoteConn, remotePeer)
|
|
71
|
+
]).then(() => expect.fail(), (err) => {
|
|
72
|
+
expect(err).to.exist();
|
|
73
|
+
expect(err).to.have.property('code', UnexpectedPeerError.code);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,EAAE;IAC1C,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IACvC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TestSetup } from '../index.js';
|
|
2
|
+
import type { PeerDiscovery } from '@libp2p/interfaces/peer-discovery';
|
|
3
|
+
import type { Startable } from '@libp2p/interfaces';
|
|
4
|
+
declare const _default: (common: TestSetup<PeerDiscovery & Startable>) => void;
|
|
5
|
+
export default _default;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/peer-discovery/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;iCAE3B,UAAU,aAAa,GAAG,SAAS,CAAC;AAA5D,wBA8EC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { expect } from 'aegir/utils/chai.js';
|
|
2
|
+
import { Multiaddr } from '@multiformats/multiaddr';
|
|
3
|
+
import delay from 'delay';
|
|
4
|
+
import pDefer from 'p-defer';
|
|
5
|
+
export default (common) => {
|
|
6
|
+
describe('interface-peer-discovery compliance tests', () => {
|
|
7
|
+
let discovery;
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
discovery = await common.setup();
|
|
10
|
+
});
|
|
11
|
+
afterEach('ensure discovery was stopped', async () => {
|
|
12
|
+
await discovery.stop();
|
|
13
|
+
discovery.removeAllListeners();
|
|
14
|
+
await common.teardown();
|
|
15
|
+
});
|
|
16
|
+
it('can start the service', async () => {
|
|
17
|
+
await discovery.start();
|
|
18
|
+
});
|
|
19
|
+
it('can start and stop the service', async () => {
|
|
20
|
+
await discovery.start();
|
|
21
|
+
await discovery.stop();
|
|
22
|
+
});
|
|
23
|
+
it('should not fail to stop the service if it was not started', async () => {
|
|
24
|
+
await discovery.stop();
|
|
25
|
+
});
|
|
26
|
+
it('should not fail to start the service if it is already started', async () => {
|
|
27
|
+
await discovery.start();
|
|
28
|
+
await discovery.start();
|
|
29
|
+
});
|
|
30
|
+
it('should emit a peer event after start', async () => {
|
|
31
|
+
const defer = pDefer();
|
|
32
|
+
await discovery.start();
|
|
33
|
+
discovery.on('peer', ({ id, multiaddrs }) => {
|
|
34
|
+
expect(id).to.exist();
|
|
35
|
+
expect(id).to.have.property('type').that.is.oneOf(['RSA', 'Ed25519', 'secp256k1']);
|
|
36
|
+
expect(multiaddrs).to.exist();
|
|
37
|
+
multiaddrs.forEach((m) => expect(Multiaddr.isMultiaddr(m)).to.eql(true));
|
|
38
|
+
defer.resolve();
|
|
39
|
+
});
|
|
40
|
+
await defer.promise;
|
|
41
|
+
});
|
|
42
|
+
it('should not receive a peer event before start', async () => {
|
|
43
|
+
discovery.on('peer', () => {
|
|
44
|
+
throw new Error('should not receive a peer event before start');
|
|
45
|
+
});
|
|
46
|
+
await delay(2000);
|
|
47
|
+
});
|
|
48
|
+
it('should not receive a peer event after stop', async () => {
|
|
49
|
+
const deferStart = pDefer();
|
|
50
|
+
await discovery.start();
|
|
51
|
+
discovery.on('peer', () => {
|
|
52
|
+
deferStart.resolve();
|
|
53
|
+
});
|
|
54
|
+
await deferStart.promise;
|
|
55
|
+
await discovery.stop();
|
|
56
|
+
discovery.on('peer', () => {
|
|
57
|
+
throw new Error('should not receive a peer event after stop');
|
|
58
|
+
});
|
|
59
|
+
await delay(2000);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/peer-discovery/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TestSetup } from '../index.js';
|
|
2
|
+
import type { PubSub } from '@libp2p/interfaces/pubsub';
|
|
3
|
+
import type { Startable } from '@libp2p/interfaces';
|
|
4
|
+
declare const _default: (common: TestSetup<PubSub & Startable>) => void;
|
|
5
|
+
export default _default;
|
|
6
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/pubsub/api.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,2BAA2B,CAAA;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;iCAK3B,UAAU,MAAM,GAAG,SAAS,CAAC;AAArD,wBA4EC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { expect } from 'aegir/utils/chai.js';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
import pDefer from 'p-defer';
|
|
4
|
+
import pWaitFor from 'p-wait-for';
|
|
5
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
|
|
6
|
+
const topic = 'foo';
|
|
7
|
+
const data = uint8ArrayFromString('bar');
|
|
8
|
+
export default (common) => {
|
|
9
|
+
describe('pubsub api', () => {
|
|
10
|
+
let pubsub;
|
|
11
|
+
// Create pubsub router
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
pubsub = await common.setup();
|
|
14
|
+
});
|
|
15
|
+
afterEach(async () => {
|
|
16
|
+
sinon.restore();
|
|
17
|
+
await pubsub.stop();
|
|
18
|
+
await common.teardown();
|
|
19
|
+
});
|
|
20
|
+
it('can start correctly', async () => {
|
|
21
|
+
sinon.spy(pubsub.registrar, 'register');
|
|
22
|
+
await pubsub.start();
|
|
23
|
+
expect(pubsub.started).to.eql(true);
|
|
24
|
+
expect(pubsub.registrar.register).to.have.property('callCount', 1);
|
|
25
|
+
});
|
|
26
|
+
it('can stop correctly', async () => {
|
|
27
|
+
sinon.spy(pubsub.registrar, 'unregister');
|
|
28
|
+
await pubsub.start();
|
|
29
|
+
await pubsub.stop();
|
|
30
|
+
expect(pubsub.started).to.eql(false);
|
|
31
|
+
expect(pubsub.registrar.unregister).to.have.property('callCount', 1);
|
|
32
|
+
});
|
|
33
|
+
it('can subscribe and unsubscribe correctly', async () => {
|
|
34
|
+
const handler = () => {
|
|
35
|
+
throw new Error('a message should not be received');
|
|
36
|
+
};
|
|
37
|
+
await pubsub.start();
|
|
38
|
+
pubsub.subscribe(topic);
|
|
39
|
+
pubsub.on('topic', handler);
|
|
40
|
+
await pWaitFor(() => {
|
|
41
|
+
const topics = pubsub.getTopics();
|
|
42
|
+
return topics.length === 1 && topics[0] === topic;
|
|
43
|
+
});
|
|
44
|
+
pubsub.unsubscribe(topic);
|
|
45
|
+
await pWaitFor(() => pubsub.getTopics().length === 0);
|
|
46
|
+
// Publish to guarantee the handler is not called
|
|
47
|
+
await pubsub.publish(topic, data);
|
|
48
|
+
await pubsub.stop();
|
|
49
|
+
});
|
|
50
|
+
it('can subscribe and publish correctly', async () => {
|
|
51
|
+
const defer = pDefer();
|
|
52
|
+
const handler = (msg) => {
|
|
53
|
+
expect(msg).to.not.eql(undefined);
|
|
54
|
+
defer.resolve();
|
|
55
|
+
};
|
|
56
|
+
await pubsub.start();
|
|
57
|
+
pubsub.subscribe(topic);
|
|
58
|
+
pubsub.on(topic, handler);
|
|
59
|
+
await pubsub.publish(topic, data);
|
|
60
|
+
await defer.promise;
|
|
61
|
+
await pubsub.stop();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/pubsub/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TestSetup } from '../index.js';
|
|
2
|
+
import type { PubSub } from '@libp2p/interfaces/pubsub';
|
|
3
|
+
import type { Startable } from '@libp2p/interfaces';
|
|
4
|
+
declare const _default: (common: TestSetup<PubSub & Startable>) => void;
|
|
5
|
+
export default _default;
|
|
6
|
+
//# sourceMappingURL=connection-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-handlers.d.ts","sourceRoot":"","sources":["../../../src/pubsub/connection-handlers.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,2BAA2B,CAAA;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;iCAE3B,UAAU,MAAM,GAAG,SAAS,CAAC;AAArD,wBAwVC"}
|