libp2p 2.8.7-ab014c0c0 → 2.8.8
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/README.md +0 -29
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +2 -2
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/typedoc-urls.json +21 -0
- package/package.json +10 -10
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -12,35 +12,6 @@
|
|
|
12
12
|
[](https://codecov.io/gh/libp2p/js-libp2p)
|
|
13
13
|
[](https://github.com/libp2p/js-libp2p/actions/workflows/main.yml?query=branch%3Amain)
|
|
14
14
|
|
|
15
|
-
# About
|
|
16
|
-
|
|
17
|
-
<!--
|
|
18
|
-
|
|
19
|
-
!IMPORTANT!
|
|
20
|
-
|
|
21
|
-
Everything in this README between "# About" and "# Install" is automatically
|
|
22
|
-
generated and will be overwritten the next time the doc generator is run.
|
|
23
|
-
|
|
24
|
-
To make changes to this section, please update the @packageDocumentation section
|
|
25
|
-
of src/index.js or src/index.ts
|
|
26
|
-
|
|
27
|
-
To experiment with formatting, please run "npm run docs" from the root of this
|
|
28
|
-
repo and examine the changes made.
|
|
29
|
-
|
|
30
|
-
-->
|
|
31
|
-
|
|
32
|
-
Use the `createLibp2p` function to create a libp2p node.
|
|
33
|
-
|
|
34
|
-
## Example
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
import { createLibp2p } from 'libp2p'
|
|
38
|
-
|
|
39
|
-
const node = await createLibp2p({
|
|
40
|
-
// ...other options
|
|
41
|
-
})
|
|
42
|
-
```
|
|
43
|
-
|
|
44
15
|
# Background
|
|
45
16
|
|
|
46
17
|
libp2p is the product of a long and arduous quest to understand the evolution of the Internet networking stack. In order to build P2P applications, devs have long had to make custom ad-hoc solutions to fit their needs, sometimes making some hard assumptions about their runtimes and the state of the network at the time of their development. Today, looking back more than 20 years, we see a clear pattern in the types of mechanisms built around the Internet Protocol, IP, which can be found throughout many layers of the OSI layer system, libp2p distils these mechanisms into flat categories and defines clear interfaces that once exposed, enable other protocols and applications to use and swap them, enabling upgradability and adaptability for the runtime, without breaking the API.
|
package/dist/index.min.js
CHANGED
|
@@ -17,7 +17,7 @@ ${[...e.errors.entries()].map(([s,i])=>`
|
|
|
17
17
|
`),e),e.log.trace('handle: responded with "%s" for "%s"',o,o),{stream:n.unwrap(),protocol:o};if(o==="ls"){let s=new Y(...t.map(i=>zi.single(L(`${i}
|
|
18
18
|
`))),L(`
|
|
19
19
|
`));e.log.trace('handle: respond with "%s" for %s',t,o),await Ar(n,s,e),e.log.trace('handle: responded with "%s" for %s',t,o);continue}e.log.trace('handle: respond with "na" for "%s"',o),await Ar(n,L(`na
|
|
20
|
-
`),e),e.log('handle: responded with "na" for "%s"',o)}}var Aw=500,iu=class{id;remoteAddr;remotePeer;direction;timeline;multiplexer;encryption;status;limits;log;tags;_newStream;_close;_abort;_getStreams;constructor(t){let{remoteAddr:e,remotePeer:n,newStream:o,close:s,abort:i,getStreams:a}=t;this.id=`${parseInt(String(Math.random()*1e9)).toString(36)}${Date.now()}`,this.remoteAddr=e,this.remotePeer=n,this.direction=t.direction,this.status="open",this.timeline=t.timeline,this.multiplexer=t.multiplexer,this.encryption=t.encryption,this.limits=t.limits,this.log=t.logger.forComponent(`libp2p:connection:${this.direction}:${this.id}`),this.remoteAddr.getPeerId()==null&&(this.remoteAddr=this.remoteAddr.encapsulate(`/p2p/${this.remotePeer}`)),this._newStream=o,this._close=s,this._abort=i,this._getStreams=a,this.tags=[]}[Symbol.toStringTag]="Connection";[lu]=!0;get streams(){return this._getStreams()}async newStream(t,e){if(this.status==="closing")throw new Po("the connection is being closed");if(this.status==="closed")throw new Pr("the connection is closed");if(Array.isArray(t)||(t=[t]),this.limits!=null&&e?.runOnLimitedConnection!==!0)throw new Dr("Cannot open protocol stream on limited connection");let n=await this._newStream(t,e);return n.direction="outbound",n}async close(t={}){if(!(this.status==="closed"||this.status==="closing")){if(this.log("closing connection to %a",this.remoteAddr),this.status="closing",t.signal==null){let e=AbortSignal.timeout(Aw);t={...t,signal:e}}try{this.log.trace("closing underlying transport"),await this._close(t),this.log.trace("updating timeline with close time"),this.status="closed",this.timeline.close=Date.now()}catch(e){this.log.error("error encountered during graceful close of connection to %a",this.remoteAddr,e),this.abort(e)}}}abort(t){this.status!=="closed"&&(this.log.error("aborting connection to %a due to error",this.remoteAddr,t),this.status="closing",this._abort(t),this.status="closed",this.timeline.close=Date.now())}};function Qh(r){return new iu(r)}function Iw(r,t){try{let{options:e}=t.getHandler(r);return e.maxInboundStreams}catch(e){if(e.name!=="UnhandledProtocolError")throw e}return tu}function Cw(r,t,e={}){try{let{options:n}=t.getHandler(r);if(n.maxOutboundStreams!=null)return n.maxOutboundStreams}catch(n){if(n.name!=="UnhandledProtocolError")throw n}return e.maxOutboundStreams??eu}function Jh(r,t,e){let n=0;return e.streams.forEach(o=>{o.direction===t&&o.protocol===r&&n++}),n}var Vi=class{components;connectionEncrypters;streamMuxers;inboundUpgradeTimeout;inboundStreamProtocolNegotiationTimeout;outboundStreamProtocolNegotiationTimeout;events;metrics;constructor(t,e){this.components=t,this.connectionEncrypters=new Map,e.connectionEncrypters.forEach(n=>{this.connectionEncrypters.set(n.protocol,n)}),this.streamMuxers=new Map,e.streamMuxers.forEach(n=>{this.streamMuxers.set(n.protocol,n)}),this.inboundUpgradeTimeout=e.inboundUpgradeTimeout??1e4,this.inboundStreamProtocolNegotiationTimeout=e.inboundStreamProtocolNegotiationTimeout??1e4,this.outboundStreamProtocolNegotiationTimeout=e.outboundStreamProtocolNegotiationTimeout??1e4,this.events=t.events,this.metrics={dials:t.metrics?.registerCounterGroup("libp2p_connection_manager_dials_total"),errors:t.metrics?.registerCounterGroup("libp2p_connection_manager_dial_errors_total")}}[Symbol.toStringTag]="@libp2p/upgrader";async shouldBlockConnection(t,...e){let n=this.components.connectionGater[t];if(n==null)return;if(await n.apply(this.components.connectionGater,e)===!0)throw new ni(`The multiaddr connection is blocked by gater.${t}`)}createInboundAbortSignal(t){let e=Pe([AbortSignal.timeout(this.inboundUpgradeTimeout),t]);return e}async upgradeInbound(t,e){let n=!1,o=this.createInboundAbortSignal(e.signal);try{if(this.metrics.dials?.increment({inbound:!0}),n=await this.components.connectionManager.acceptIncomingConnection(t),!n)throw new oi("Connection denied");await this.shouldBlockConnection("denyInboundConnection",t),await this._performUpgrade(t,"inbound",{...e,signal:o})}catch(s){throw this.metrics.errors?.increment({inbound:!0}),s}finally{o.clear(),n&&this.components.connectionManager.afterUpgradeInbound()}}async upgradeOutbound(t,e){try{this.metrics.dials?.increment({outbound:!0});let n=t.remoteAddr.getPeerId(),o;n!=null&&(o=fe(n),await this.shouldBlockConnection("denyOutboundConnection",o,t));let s="outbound";return e.initiator===!1&&(s="inbound"),await this._performUpgrade(t,s,e)}catch(n){throw this.metrics.errors?.increment({outbound:!0}),n}}async _performUpgrade(t,e,n){let o,s,i,a,c;this.components.metrics?.trackMultiaddrConnection(t),t.log.trace("starting the %s connection upgrade",e);let l=t;if(n?.skipProtection!==!0){let u=this.components.connectionProtector;u!=null&&(t.log("protecting the %s connection",e),l=await u.protect(t,n))}try{if(o=l,n?.skipEncryption!==!0){n?.onProgress?.(new dt(`upgrader:encrypt-${e}-connection`)),{conn:o,remotePeer:s,protocol:c,streamMuxer:a}=await(e==="inbound"?this._encryptInbound(l,n):this._encryptOutbound(l,n));let u={...l,...o};await this.shouldBlockConnection(e==="inbound"?"denyInboundEncryptedConnection":"denyOutboundEncryptedConnection",s,u)}else{let u=t.remoteAddr.getPeerId();if(u==null)throw new Te(`${e} connection that skipped encryption must have a peer id`);let f=fe(u);c="native",s=f}if(s.equals(this.components.peerId)){let u=new Tr("Can not dial self");throw t.abort(u),u}if(i=o,n?.muxerFactory!=null)a=n.muxerFactory;else if(a==null&&this.streamMuxers.size>0){n?.onProgress?.(new dt(`upgrader:multiplex-${e}-connection`));let u=await(e==="inbound"?this._multiplexInbound({...l,...o},this.streamMuxers,n):this._multiplexOutbound({...l,...o},this.streamMuxers,n));a=u.muxerFactory,i=u.stream}}catch(u){throw t.log.error("failed to upgrade inbound connection %s %a - %e",e==="inbound"?"from":"to",t.remoteAddr,u),u}return await this.shouldBlockConnection(e==="inbound"?"denyInboundUpgradedConnection":"denyOutboundUpgradedConnection",s,t),t.log("successfully upgraded %s connection",e),this._createConnection({cryptoProtocol:c,direction:e,maConn:t,upgradedConn:i,muxerFactory:a,remotePeer:s,limits:n?.limits})}_createConnection(t){let{cryptoProtocol:e,direction:n,maConn:o,upgradedConn:s,remotePeer:i,muxerFactory:a,limits:c}=t,l,u,f;a!=null&&(l=a.createStreamMuxer({direction:n,onIncomingStream:p=>{f!=null&&Promise.resolve().then(async()=>{let m=this.components.registrar.getProtocols(),w=AbortSignal.timeout(this.inboundStreamProtocolNegotiationTimeout);let{stream:v,protocol:C}=await So(p,m,{signal:w,log:p.log,yieldBytes:!1});if(f==null)return;f.log("incoming stream opened on %s",C);let x=Iw(C,this.components.registrar);if(Jh(C,"inbound",f)===x){let b=new Mo(`Too many inbound protocol streams for protocol "${C}" - limit ${x}`);throw p.abort(b),b}p.source=v.source,p.sink=v.sink,p.protocol=C,v.closeWrite!=null&&(p.closeWrite=v.closeWrite),v.closeRead!=null&&(p.closeRead=v.closeRead),v.close!=null&&(p.close=v.close),await this.components.peerStore.merge(i,{protocols:[C]}),this.components.metrics?.trackProtocolStream(p,f),this._onStream({connection:f,stream:p,protocol:C})}).catch(async m=>{f.log.error("error handling incoming stream id %s - %e",p.id,m),p.timeline.close==null&&await p.close()})}}),u=async(p,m={})=>{if(l==null)throw new Er("Connection is not multiplexed");f.log.trace("starting new stream for protocols %s",p);let w=await l.newStream();f.log.trace("started new stream %s for protocols %s",w.id,p);try{if(m.signal==null){w.log("no abort signal was passed while trying to negotiate protocols %s falling back to default timeout",p);let b=AbortSignal.timeout(this.outboundStreamProtocolNegotiationTimeout);m={...m,signal:b}}w.log.trace("selecting protocol from protocols %s",p);let{stream:v,protocol:C}=await Eo(w,p,{...m,log:w.log,yieldBytes:!0});w.log.trace("selected protocol %s",C);let x=Cw(C,this.components.registrar,m),h=Jh(C,"outbound",f);if(h>=x){let b=new Ro(`Too many outbound protocol streams for protocol "${C}" - ${h}/${x}`);throw w.abort(b),b}return await this.components.peerStore.merge(i,{protocols:[C]}),w.source=v.source,w.sink=v.sink,w.protocol=C,v.closeWrite!=null&&(w.closeWrite=v.closeWrite),v.closeRead!=null&&(w.closeRead=v.closeRead),v.close!=null&&(w.close=v.close),this.components.metrics?.trackProtocolStream(w,f),w}catch(v){throw f.log.error("could not create new outbound stream on connection %s %a for protocols %s - %e",n==="inbound"?"from":"to",t.maConn.remoteAddr,p,v),w.timeline.close==null&&w.abort(v),v}},Promise.all([l.sink(s.source),s.sink(l.source)]).catch(p=>{f.log.error("error piping data through muxer - %e",p)}));let d=o.timeline;o.timeline=new Proxy(d,{set:(...p)=>(p[1]==="close"&&p[2]!=null&&d.close==null&&(async()=>{try{f.status==="open"&&await f.close()}catch(m){f.log.error("error closing connection after timeline close %e",m)}finally{this.events.safeDispatchEvent("connection:close",{detail:f})}})().catch(m=>{f.log.error("error thrown while dispatching connection:close event %e",m)}),Reflect.set(...p))}),o.timeline.upgraded=Date.now();let g=()=>{throw new Er("Connection is not multiplexed")};return f=Qh({remoteAddr:o.remoteAddr,remotePeer:i,status:"open",direction:n,timeline:o.timeline,multiplexer:l?.protocol,encryption:e,limits:c,logger:this.components.logger,newStream:u??g,getStreams:()=>l?.streams??[],close:async p=>{await l?.close(p),await o.close(p)},abort:p=>{o.abort(p),l?.abort(p)}}),this.events.safeDispatchEvent("connection:open",{detail:f}),f.__maConnTimeline=d,f}_onStream(t){let{connection:e,stream:n,protocol:o}=t,{handler:s,options:i}=this.components.registrar.getHandler(o);if(e.limits!=null&&i.runOnLimitedConnection!==!0)throw new Dr("Cannot open protocol stream on limited connection");s({connection:e,stream:n})}async _encryptInbound(t,e){let n=Array.from(this.connectionEncrypters.keys());try{let{stream:o,protocol:s}=await So(t,n,{...e,log:t.log}),i=this.connectionEncrypters.get(s);if(i==null)throw new vr(`no crypto module found for ${s}`);return t.log("encrypting inbound connection to %a using %s",t.remoteAddr,s),{...await i.secureInbound(o,e),protocol:s}}catch(o){throw t.log.error("encrypting inbound connection from %a failed",t.remoteAddr,o),new vr(o.message)}}async _encryptOutbound(t,e){let n=Array.from(this.connectionEncrypters.keys());try{t.log.trace("selecting encrypter from %s",n);let{stream:o,protocol:s}=await Eo(t,n,{...e,log:t.log,yieldBytes:!0}),i=this.connectionEncrypters.get(s);if(i==null)throw new vr(`no crypto module found for ${s}`);return t.log("encrypting outbound connection to %a using %s",t.remoteAddr,s),{...await i.secureOutbound(o,e),protocol:s}}catch(o){throw t.log.error("encrypting outbound connection to %a failed",t.remoteAddr,o),new vr(o.message)}}async _multiplexOutbound(t,e,n){let o=Array.from(e.keys());t.log("outbound selecting muxer %s",o);try{t.log.trace("selecting stream muxer from %s",o);let{stream:s,protocol:i}=await Eo(t,o,{...n,log:t.log,yieldBytes:!0});t.log("selected %s as muxer protocol",i);let a=e.get(i);return{stream:s,muxerFactory:a}}catch(s){throw t.log.error("error multiplexing outbound connection",s),new Er(String(s))}}async _multiplexInbound(t,e,n){let o=Array.from(e.keys());t.log("inbound handling muxers %s",o);try{let{stream:s,protocol:i}=await So(t,o,{...n,log:t.log}),a=e.get(i);return{stream:s,muxerFactory:a}}catch(s){throw t.log.error("error multiplexing inbound connection",s),new Er(String(s))}}getConnectionEncrypters(){return this.connectionEncrypters}getStreamMuxers(){return this.streamMuxers}};var Hi="2.8.7-ab014c0c0",$i="js-libp2p";function ep(r,t){return`${r??$i}/${t??Hi} browser/${globalThis.navigator.userAgent}`}var Gi=class extends he{peerId;peerStore;contentRouting;peerRouting;metrics;services;logger;status;components;log;constructor(t){super(),this.status="stopped";let e=new he,n=e.dispatchEvent.bind(e);e.dispatchEvent=l=>{let u=n(l),f=this.dispatchEvent(new CustomEvent(l.type,{detail:l.detail}));return u||f},this.peerId=t.peerId,this.logger=t.logger??Ss(),this.log=this.logger.forComponent("libp2p"),this.services={};let o=t.nodeInfo?.name??$i,s=t.nodeInfo?.version??Hi,i=this.components=Ch({peerId:t.peerId,privateKey:t.privateKey,nodeInfo:{name:o,version:s,userAgent:t.nodeInfo?.userAgent??ep(o,s)},logger:this.logger,events:e,datastore:t.datastore??new Bs,connectionGater:Th(t.connectionGater),dns:t.dns});this.peerStore=this.configureComponent("peerStore",uh(i,{addressFilter:this.components.connectionGater.filterMultiaddrForPeer,...t.peerStore})),t.metrics!=null&&(this.metrics=this.configureComponent("metrics",t.metrics(this.components))),i.events.addEventListener("peer:update",l=>{if(l.detail.previous==null){let u={id:l.detail.peer.id,multiaddrs:l.detail.peer.addresses.map(f=>f.multiaddr)};i.events.safeDispatchEvent("peer:discovery",{detail:u})}}),t.connectionProtector!=null&&this.configureComponent("connectionProtector",t.connectionProtector(i)),this.components.upgrader=new Vi(this.components,{connectionEncrypters:(t.connectionEncrypters??[]).map((l,u)=>this.configureComponent(`connection-encryption-${u}`,l(this.components))),streamMuxers:(t.streamMuxers??[]).map((l,u)=>this.configureComponent(`stream-muxers-${u}`,l(this.components))),inboundUpgradeTimeout:t.connectionManager?.inboundUpgradeTimeout,inboundStreamProtocolNegotiationTimeout:t.connectionManager?.inboundStreamProtocolNegotiationTimeout??t.connectionManager?.protocolNegotiationTimeout,outboundStreamProtocolNegotiationTimeout:t.connectionManager?.outboundStreamProtocolNegotiationTimeout??t.connectionManager?.protocolNegotiationTimeout}),this.configureComponent("transportManager",new Mi(this.components,t.transportManager)),this.configureComponent("connectionManager",new vi(this.components,t.connectionManager)),t.connectionMonitor?.enabled!==!1&&this.configureComponent("connectionMonitor",new Ci(this.components,t.connectionMonitor)),this.configureComponent("registrar",new ki(this.components)),this.configureComponent("addressManager",new js(this.components,t.addresses));let a=(t.peerRouters??[]).map((l,u)=>this.configureComponent(`peer-router-${u}`,l(this.components)));this.peerRouting=this.components.peerRouting=this.configureComponent("peerRouting",new Li(this.components,{routers:a}));let c=(t.contentRouters??[]).map((l,u)=>this.configureComponent(`content-router-${u}`,l(this.components)));if(this.contentRouting=this.components.contentRouting=this.configureComponent("contentRouting",new Pi(this.components,{routers:c})),this.configureComponent("randomWalk",new Di(this.components)),(t.peerDiscovery??[]).forEach((l,u)=>{this.configureComponent(`peer-discovery-${u}`,l(this.components)).addEventListener("peer",d=>{this.#t(d)})}),t.transports?.forEach((l,u)=>{this.components.transportManager.add(this.configureComponent(`transport-${u}`,l(this.components)))}),t.services!=null)for(let l of Object.keys(t.services)){let u=t.services[l],f=u(this.components);if(f==null){this.log.error("service factory %s returned null or undefined instance",l);continue}this.services[l]=f,this.configureComponent(l,f),f[Wi]!=null&&(this.log("registering service %s for content routing",l),c.push(f[Wi])),f[Xi]!=null&&(this.log("registering service %s for peer routing",l),a.push(f[Xi])),f[ji]!=null&&(this.log("registering service %s for peer discovery",l),f[ji].addEventListener?.("peer",d=>{this.#t(d)}))}Ph(i)}configureComponent(t,e){return e==null&&this.log.error("component %s was null or undefined",t),this.components[t]=e,e}async start(){if(this.status==="stopped"){this.status="starting",this.log("libp2p is starting");try{await this.components.beforeStart?.(),await this.components.start(),await this.components.afterStart?.(),this.status="started",this.safeDispatchEvent("start",{detail:this}),this.log("libp2p has started")}catch(t){throw this.log.error("An error occurred starting libp2p",t),this.status="started",await this.stop(),t}}}async stop(){this.status==="started"&&(this.log("libp2p is stopping"),this.status="stopping",await this.components.beforeStop?.(),await this.components.stop(),await this.components.afterStop?.(),this.status="stopped",this.safeDispatchEvent("stop",{detail:this}),this.log("libp2p has stopped"))}getConnections(t){return this.components.connectionManager.getConnections(t)}getDialQueue(){return this.components.connectionManager.getDialQueue()}getPeers(){let t=new fr;for(let e of this.components.connectionManager.getConnections())t.add(e.remotePeer);return Array.from(t)}async dial(t,e={}){return this.components.connectionManager.openConnection(t,{priority:75,...e})}async dialProtocol(t,e,n={}){if(e==null)throw new M("no protocols were provided to open a stream");if(e=Array.isArray(e)?e:[e],e.length===0)throw new M("no protocols were provided to open a stream");return(await this.dial(t,n)).newStream(e,n)}getMultiaddrs(){return this.components.addressManager.getAddresses()}getProtocols(){return this.components.registrar.getProtocols()}async hangUp(t,e={}){Ke(t)&&(t=fe(t.getPeerId()??"")),await this.components.connectionManager.closeConnections(t,e)}async getPublicKey(t,e={}){if(this.log("getPublicKey %p",t),t.publicKey!=null)return t.publicKey;try{let i=await this.peerStore.get(t);if(i.id.publicKey!=null)return i.id.publicKey}catch(i){if(i.name!=="NotFoundError")throw i}let n=Tt([L("/pk/"),t.toMultihash().bytes]),o=await this.contentRouting.get(n,e),s=Wr(o);return await this.peerStore.patch(t,{publicKey:s}),s}async handle(t,e,n){Array.isArray(t)||(t=[t]),await Promise.all(t.map(async o=>{await this.components.registrar.handle(o,e,n)}))}async unhandle(t){Array.isArray(t)||(t=[t]),await Promise.all(t.map(async e=>{await this.components.registrar.unhandle(e)}))}async register(t,e){return this.components.registrar.register(t,e)}unregister(t){this.components.registrar.unregister(t)}async isDialable(t,e={}){return this.components.connectionManager.isDialable(t,e)}#t(t){let{detail:e}=t;if(e.id.toString()===this.peerId.toString()){this.log.error("peer discovery mechanism discovered self");return}this.components.peerStore.merge(e.id,{multiaddrs:e.multiaddrs}).catch(n=>{this.log.error(n)})}};async function Pw(r={}){r.privateKey??=await ld("Ed25519");let t=new Gi({...await Kd(r),peerId:hd(r.privateKey)});return r.start!==!1&&await t.start(),t}return fp(Tw);})();
|
|
20
|
+
`),e),e.log('handle: responded with "na" for "%s"',o)}}var Aw=500,iu=class{id;remoteAddr;remotePeer;direction;timeline;multiplexer;encryption;status;limits;log;tags;_newStream;_close;_abort;_getStreams;constructor(t){let{remoteAddr:e,remotePeer:n,newStream:o,close:s,abort:i,getStreams:a}=t;this.id=`${parseInt(String(Math.random()*1e9)).toString(36)}${Date.now()}`,this.remoteAddr=e,this.remotePeer=n,this.direction=t.direction,this.status="open",this.timeline=t.timeline,this.multiplexer=t.multiplexer,this.encryption=t.encryption,this.limits=t.limits,this.log=t.logger.forComponent(`libp2p:connection:${this.direction}:${this.id}`),this.remoteAddr.getPeerId()==null&&(this.remoteAddr=this.remoteAddr.encapsulate(`/p2p/${this.remotePeer}`)),this._newStream=o,this._close=s,this._abort=i,this._getStreams=a,this.tags=[]}[Symbol.toStringTag]="Connection";[lu]=!0;get streams(){return this._getStreams()}async newStream(t,e){if(this.status==="closing")throw new Po("the connection is being closed");if(this.status==="closed")throw new Pr("the connection is closed");if(Array.isArray(t)||(t=[t]),this.limits!=null&&e?.runOnLimitedConnection!==!0)throw new Dr("Cannot open protocol stream on limited connection");let n=await this._newStream(t,e);return n.direction="outbound",n}async close(t={}){if(!(this.status==="closed"||this.status==="closing")){if(this.log("closing connection to %a",this.remoteAddr),this.status="closing",t.signal==null){let e=AbortSignal.timeout(Aw);t={...t,signal:e}}try{this.log.trace("closing underlying transport"),await this._close(t),this.log.trace("updating timeline with close time"),this.status="closed",this.timeline.close=Date.now()}catch(e){this.log.error("error encountered during graceful close of connection to %a",this.remoteAddr,e),this.abort(e)}}}abort(t){this.status!=="closed"&&(this.log.error("aborting connection to %a due to error",this.remoteAddr,t),this.status="closing",this._abort(t),this.status="closed",this.timeline.close=Date.now())}};function Qh(r){return new iu(r)}function Iw(r,t){try{let{options:e}=t.getHandler(r);return e.maxInboundStreams}catch(e){if(e.name!=="UnhandledProtocolError")throw e}return tu}function Cw(r,t,e={}){try{let{options:n}=t.getHandler(r);if(n.maxOutboundStreams!=null)return n.maxOutboundStreams}catch(n){if(n.name!=="UnhandledProtocolError")throw n}return e.maxOutboundStreams??eu}function Jh(r,t,e){let n=0;return e.streams.forEach(o=>{o.direction===t&&o.protocol===r&&n++}),n}var Vi=class{components;connectionEncrypters;streamMuxers;inboundUpgradeTimeout;inboundStreamProtocolNegotiationTimeout;outboundStreamProtocolNegotiationTimeout;events;metrics;constructor(t,e){this.components=t,this.connectionEncrypters=new Map,e.connectionEncrypters.forEach(n=>{this.connectionEncrypters.set(n.protocol,n)}),this.streamMuxers=new Map,e.streamMuxers.forEach(n=>{this.streamMuxers.set(n.protocol,n)}),this.inboundUpgradeTimeout=e.inboundUpgradeTimeout??1e4,this.inboundStreamProtocolNegotiationTimeout=e.inboundStreamProtocolNegotiationTimeout??1e4,this.outboundStreamProtocolNegotiationTimeout=e.outboundStreamProtocolNegotiationTimeout??1e4,this.events=t.events,this.metrics={dials:t.metrics?.registerCounterGroup("libp2p_connection_manager_dials_total"),errors:t.metrics?.registerCounterGroup("libp2p_connection_manager_dial_errors_total")}}[Symbol.toStringTag]="@libp2p/upgrader";async shouldBlockConnection(t,...e){let n=this.components.connectionGater[t];if(n==null)return;if(await n.apply(this.components.connectionGater,e)===!0)throw new ni(`The multiaddr connection is blocked by gater.${t}`)}createInboundAbortSignal(t){let e=Pe([AbortSignal.timeout(this.inboundUpgradeTimeout),t]);return e}async upgradeInbound(t,e){let n=!1,o=this.createInboundAbortSignal(e.signal);try{if(this.metrics.dials?.increment({inbound:!0}),n=await this.components.connectionManager.acceptIncomingConnection(t),!n)throw new oi("Connection denied");await this.shouldBlockConnection("denyInboundConnection",t),await this._performUpgrade(t,"inbound",{...e,signal:o})}catch(s){throw this.metrics.errors?.increment({inbound:!0}),s}finally{o.clear(),n&&this.components.connectionManager.afterUpgradeInbound()}}async upgradeOutbound(t,e){try{this.metrics.dials?.increment({outbound:!0});let n=t.remoteAddr.getPeerId(),o;n!=null&&(o=fe(n),await this.shouldBlockConnection("denyOutboundConnection",o,t));let s="outbound";return e.initiator===!1&&(s="inbound"),await this._performUpgrade(t,s,e)}catch(n){throw this.metrics.errors?.increment({outbound:!0}),n}}async _performUpgrade(t,e,n){let o,s,i,a,c;this.components.metrics?.trackMultiaddrConnection(t),t.log.trace("starting the %s connection upgrade",e);let l=t;if(n?.skipProtection!==!0){let u=this.components.connectionProtector;u!=null&&(t.log("protecting the %s connection",e),l=await u.protect(t,n))}try{if(o=l,n?.skipEncryption!==!0){n?.onProgress?.(new dt(`upgrader:encrypt-${e}-connection`)),{conn:o,remotePeer:s,protocol:c,streamMuxer:a}=await(e==="inbound"?this._encryptInbound(l,n):this._encryptOutbound(l,n));let u={...l,...o};await this.shouldBlockConnection(e==="inbound"?"denyInboundEncryptedConnection":"denyOutboundEncryptedConnection",s,u)}else{let u=t.remoteAddr.getPeerId();if(u==null)throw new Te(`${e} connection that skipped encryption must have a peer id`);let f=fe(u);c="native",s=f}if(s.equals(this.components.peerId)){let u=new Tr("Can not dial self");throw t.abort(u),u}if(i=o,n?.muxerFactory!=null)a=n.muxerFactory;else if(a==null&&this.streamMuxers.size>0){n?.onProgress?.(new dt(`upgrader:multiplex-${e}-connection`));let u=await(e==="inbound"?this._multiplexInbound({...l,...o},this.streamMuxers,n):this._multiplexOutbound({...l,...o},this.streamMuxers,n));a=u.muxerFactory,i=u.stream}}catch(u){throw t.log.error("failed to upgrade inbound connection %s %a - %e",e==="inbound"?"from":"to",t.remoteAddr,u),u}return await this.shouldBlockConnection(e==="inbound"?"denyInboundUpgradedConnection":"denyOutboundUpgradedConnection",s,t),t.log("successfully upgraded %s connection",e),this._createConnection({cryptoProtocol:c,direction:e,maConn:t,upgradedConn:i,muxerFactory:a,remotePeer:s,limits:n?.limits})}_createConnection(t){let{cryptoProtocol:e,direction:n,maConn:o,upgradedConn:s,remotePeer:i,muxerFactory:a,limits:c}=t,l,u,f;a!=null&&(l=a.createStreamMuxer({direction:n,onIncomingStream:p=>{f!=null&&Promise.resolve().then(async()=>{let m=this.components.registrar.getProtocols(),w=AbortSignal.timeout(this.inboundStreamProtocolNegotiationTimeout);let{stream:v,protocol:C}=await So(p,m,{signal:w,log:p.log,yieldBytes:!1});if(f==null)return;f.log("incoming stream opened on %s",C);let x=Iw(C,this.components.registrar);if(Jh(C,"inbound",f)===x){let b=new Mo(`Too many inbound protocol streams for protocol "${C}" - limit ${x}`);throw p.abort(b),b}p.source=v.source,p.sink=v.sink,p.protocol=C,v.closeWrite!=null&&(p.closeWrite=v.closeWrite),v.closeRead!=null&&(p.closeRead=v.closeRead),v.close!=null&&(p.close=v.close),await this.components.peerStore.merge(i,{protocols:[C]}),this.components.metrics?.trackProtocolStream(p,f),this._onStream({connection:f,stream:p,protocol:C})}).catch(async m=>{f.log.error("error handling incoming stream id %s - %e",p.id,m),p.timeline.close==null&&await p.close()})}}),u=async(p,m={})=>{if(l==null)throw new Er("Connection is not multiplexed");f.log.trace("starting new stream for protocols %s",p);let w=await l.newStream();f.log.trace("started new stream %s for protocols %s",w.id,p);try{if(m.signal==null){w.log("no abort signal was passed while trying to negotiate protocols %s falling back to default timeout",p);let b=AbortSignal.timeout(this.outboundStreamProtocolNegotiationTimeout);m={...m,signal:b}}w.log.trace("selecting protocol from protocols %s",p);let{stream:v,protocol:C}=await Eo(w,p,{...m,log:w.log,yieldBytes:!0});w.log.trace("selected protocol %s",C);let x=Cw(C,this.components.registrar,m),h=Jh(C,"outbound",f);if(h>=x){let b=new Ro(`Too many outbound protocol streams for protocol "${C}" - ${h}/${x}`);throw w.abort(b),b}return await this.components.peerStore.merge(i,{protocols:[C]}),w.source=v.source,w.sink=v.sink,w.protocol=C,v.closeWrite!=null&&(w.closeWrite=v.closeWrite),v.closeRead!=null&&(w.closeRead=v.closeRead),v.close!=null&&(w.close=v.close),this.components.metrics?.trackProtocolStream(w,f),w}catch(v){throw f.log.error("could not create new outbound stream on connection %s %a for protocols %s - %e",n==="inbound"?"from":"to",t.maConn.remoteAddr,p,v),w.timeline.close==null&&w.abort(v),v}},Promise.all([l.sink(s.source),s.sink(l.source)]).catch(p=>{f.log.error("error piping data through muxer - %e",p)}));let d=o.timeline;o.timeline=new Proxy(d,{set:(...p)=>(p[1]==="close"&&p[2]!=null&&d.close==null&&(async()=>{try{f.status==="open"&&await f.close()}catch(m){f.log.error("error closing connection after timeline close %e",m)}finally{this.events.safeDispatchEvent("connection:close",{detail:f})}})().catch(m=>{f.log.error("error thrown while dispatching connection:close event %e",m)}),Reflect.set(...p))}),o.timeline.upgraded=Date.now();let g=()=>{throw new Er("Connection is not multiplexed")};return f=Qh({remoteAddr:o.remoteAddr,remotePeer:i,status:"open",direction:n,timeline:o.timeline,multiplexer:l?.protocol,encryption:e,limits:c,logger:this.components.logger,newStream:u??g,getStreams:()=>l?.streams??[],close:async p=>{await l?.close(p),await o.close(p)},abort:p=>{o.abort(p),l?.abort(p)}}),this.events.safeDispatchEvent("connection:open",{detail:f}),f.__maConnTimeline=d,f}_onStream(t){let{connection:e,stream:n,protocol:o}=t,{handler:s,options:i}=this.components.registrar.getHandler(o);if(e.limits!=null&&i.runOnLimitedConnection!==!0)throw new Dr("Cannot open protocol stream on limited connection");s({connection:e,stream:n})}async _encryptInbound(t,e){let n=Array.from(this.connectionEncrypters.keys());try{let{stream:o,protocol:s}=await So(t,n,{...e,log:t.log}),i=this.connectionEncrypters.get(s);if(i==null)throw new vr(`no crypto module found for ${s}`);return t.log("encrypting inbound connection to %a using %s",t.remoteAddr,s),{...await i.secureInbound(o,e),protocol:s}}catch(o){throw t.log.error("encrypting inbound connection from %a failed",t.remoteAddr,o),new vr(o.message)}}async _encryptOutbound(t,e){let n=Array.from(this.connectionEncrypters.keys());try{t.log.trace("selecting encrypter from %s",n);let{stream:o,protocol:s}=await Eo(t,n,{...e,log:t.log,yieldBytes:!0}),i=this.connectionEncrypters.get(s);if(i==null)throw new vr(`no crypto module found for ${s}`);return t.log("encrypting outbound connection to %a using %s",t.remoteAddr,s),{...await i.secureOutbound(o,e),protocol:s}}catch(o){throw t.log.error("encrypting outbound connection to %a failed",t.remoteAddr,o),new vr(o.message)}}async _multiplexOutbound(t,e,n){let o=Array.from(e.keys());t.log("outbound selecting muxer %s",o);try{t.log.trace("selecting stream muxer from %s",o);let{stream:s,protocol:i}=await Eo(t,o,{...n,log:t.log,yieldBytes:!0});t.log("selected %s as muxer protocol",i);let a=e.get(i);return{stream:s,muxerFactory:a}}catch(s){throw t.log.error("error multiplexing outbound connection",s),new Er(String(s))}}async _multiplexInbound(t,e,n){let o=Array.from(e.keys());t.log("inbound handling muxers %s",o);try{let{stream:s,protocol:i}=await So(t,o,{...n,log:t.log}),a=e.get(i);return{stream:s,muxerFactory:a}}catch(s){throw t.log.error("error multiplexing inbound connection",s),new Er(String(s))}}getConnectionEncrypters(){return this.connectionEncrypters}getStreamMuxers(){return this.streamMuxers}};var Hi="2.8.8",$i="js-libp2p";function ep(r,t){return`${r??$i}/${t??Hi} browser/${globalThis.navigator.userAgent}`}var Gi=class extends he{peerId;peerStore;contentRouting;peerRouting;metrics;services;logger;status;components;log;constructor(t){super(),this.status="stopped";let e=new he,n=e.dispatchEvent.bind(e);e.dispatchEvent=l=>{let u=n(l),f=this.dispatchEvent(new CustomEvent(l.type,{detail:l.detail}));return u||f},this.peerId=t.peerId,this.logger=t.logger??Ss(),this.log=this.logger.forComponent("libp2p"),this.services={};let o=t.nodeInfo?.name??$i,s=t.nodeInfo?.version??Hi,i=this.components=Ch({peerId:t.peerId,privateKey:t.privateKey,nodeInfo:{name:o,version:s,userAgent:t.nodeInfo?.userAgent??ep(o,s)},logger:this.logger,events:e,datastore:t.datastore??new Bs,connectionGater:Th(t.connectionGater),dns:t.dns});this.peerStore=this.configureComponent("peerStore",uh(i,{addressFilter:this.components.connectionGater.filterMultiaddrForPeer,...t.peerStore})),t.metrics!=null&&(this.metrics=this.configureComponent("metrics",t.metrics(this.components))),i.events.addEventListener("peer:update",l=>{if(l.detail.previous==null){let u={id:l.detail.peer.id,multiaddrs:l.detail.peer.addresses.map(f=>f.multiaddr)};i.events.safeDispatchEvent("peer:discovery",{detail:u})}}),t.connectionProtector!=null&&this.configureComponent("connectionProtector",t.connectionProtector(i)),this.components.upgrader=new Vi(this.components,{connectionEncrypters:(t.connectionEncrypters??[]).map((l,u)=>this.configureComponent(`connection-encryption-${u}`,l(this.components))),streamMuxers:(t.streamMuxers??[]).map((l,u)=>this.configureComponent(`stream-muxers-${u}`,l(this.components))),inboundUpgradeTimeout:t.connectionManager?.inboundUpgradeTimeout,inboundStreamProtocolNegotiationTimeout:t.connectionManager?.inboundStreamProtocolNegotiationTimeout??t.connectionManager?.protocolNegotiationTimeout,outboundStreamProtocolNegotiationTimeout:t.connectionManager?.outboundStreamProtocolNegotiationTimeout??t.connectionManager?.protocolNegotiationTimeout}),this.configureComponent("transportManager",new Mi(this.components,t.transportManager)),this.configureComponent("connectionManager",new vi(this.components,t.connectionManager)),t.connectionMonitor?.enabled!==!1&&this.configureComponent("connectionMonitor",new Ci(this.components,t.connectionMonitor)),this.configureComponent("registrar",new ki(this.components)),this.configureComponent("addressManager",new js(this.components,t.addresses));let a=(t.peerRouters??[]).map((l,u)=>this.configureComponent(`peer-router-${u}`,l(this.components)));this.peerRouting=this.components.peerRouting=this.configureComponent("peerRouting",new Li(this.components,{routers:a}));let c=(t.contentRouters??[]).map((l,u)=>this.configureComponent(`content-router-${u}`,l(this.components)));if(this.contentRouting=this.components.contentRouting=this.configureComponent("contentRouting",new Pi(this.components,{routers:c})),this.configureComponent("randomWalk",new Di(this.components)),(t.peerDiscovery??[]).forEach((l,u)=>{this.configureComponent(`peer-discovery-${u}`,l(this.components)).addEventListener("peer",d=>{this.#t(d)})}),t.transports?.forEach((l,u)=>{this.components.transportManager.add(this.configureComponent(`transport-${u}`,l(this.components)))}),t.services!=null)for(let l of Object.keys(t.services)){let u=t.services[l],f=u(this.components);if(f==null){this.log.error("service factory %s returned null or undefined instance",l);continue}this.services[l]=f,this.configureComponent(l,f),f[Wi]!=null&&(this.log("registering service %s for content routing",l),c.push(f[Wi])),f[Xi]!=null&&(this.log("registering service %s for peer routing",l),a.push(f[Xi])),f[ji]!=null&&(this.log("registering service %s for peer discovery",l),f[ji].addEventListener?.("peer",d=>{this.#t(d)}))}Ph(i)}configureComponent(t,e){return e==null&&this.log.error("component %s was null or undefined",t),this.components[t]=e,e}async start(){if(this.status==="stopped"){this.status="starting",this.log("libp2p is starting");try{await this.components.beforeStart?.(),await this.components.start(),await this.components.afterStart?.(),this.status="started",this.safeDispatchEvent("start",{detail:this}),this.log("libp2p has started")}catch(t){throw this.log.error("An error occurred starting libp2p",t),this.status="started",await this.stop(),t}}}async stop(){this.status==="started"&&(this.log("libp2p is stopping"),this.status="stopping",await this.components.beforeStop?.(),await this.components.stop(),await this.components.afterStop?.(),this.status="stopped",this.safeDispatchEvent("stop",{detail:this}),this.log("libp2p has stopped"))}getConnections(t){return this.components.connectionManager.getConnections(t)}getDialQueue(){return this.components.connectionManager.getDialQueue()}getPeers(){let t=new fr;for(let e of this.components.connectionManager.getConnections())t.add(e.remotePeer);return Array.from(t)}async dial(t,e={}){return this.components.connectionManager.openConnection(t,{priority:75,...e})}async dialProtocol(t,e,n={}){if(e==null)throw new M("no protocols were provided to open a stream");if(e=Array.isArray(e)?e:[e],e.length===0)throw new M("no protocols were provided to open a stream");return(await this.dial(t,n)).newStream(e,n)}getMultiaddrs(){return this.components.addressManager.getAddresses()}getProtocols(){return this.components.registrar.getProtocols()}async hangUp(t,e={}){Ke(t)&&(t=fe(t.getPeerId()??"")),await this.components.connectionManager.closeConnections(t,e)}async getPublicKey(t,e={}){if(this.log("getPublicKey %p",t),t.publicKey!=null)return t.publicKey;try{let i=await this.peerStore.get(t);if(i.id.publicKey!=null)return i.id.publicKey}catch(i){if(i.name!=="NotFoundError")throw i}let n=Tt([L("/pk/"),t.toMultihash().bytes]),o=await this.contentRouting.get(n,e),s=Wr(o);return await this.peerStore.patch(t,{publicKey:s}),s}async handle(t,e,n){Array.isArray(t)||(t=[t]),await Promise.all(t.map(async o=>{await this.components.registrar.handle(o,e,n)}))}async unhandle(t){Array.isArray(t)||(t=[t]),await Promise.all(t.map(async e=>{await this.components.registrar.unhandle(e)}))}async register(t,e){return this.components.registrar.register(t,e)}unregister(t){this.components.registrar.unregister(t)}async isDialable(t,e={}){return this.components.connectionManager.isDialable(t,e)}#t(t){let{detail:e}=t;if(e.id.toString()===this.peerId.toString()){this.log.error("peer discovery mechanism discovered self");return}this.components.peerStore.merge(e.id,{multiaddrs:e.multiaddrs}).catch(n=>{this.log.error(n)})}};async function Pw(r={}){r.privateKey??=await ld("Ed25519");let t=new Gi({...await Kd(r),peerId:hd(r.privateKey)});return r.start!==!1&&await t.start(),t}return fp(Tw);})();
|
|
21
21
|
/*! Bundled license information:
|
|
22
22
|
|
|
23
23
|
@noble/hashes/esm/utils.js:
|