Full Code of libp2p/go-libp2p for AI

master 062200be7aa1 cached
657 files
3.7 MB
999.3k tokens
5856 symbols
1 requests
Download .txt
Showing preview only (3,982K chars total). Download the full file or copy to clipboard to get everything.
Repository: libp2p/go-libp2p
Branch: master
Commit: 062200be7aa1
Files: 657
Total size: 3.7 MB

Directory structure:
gitextract_smkgriw_/

├── .codecov.yml
├── .githooks/
│   ├── README.md
│   └── pre-commit
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.md
│   │   ├── config.yml
│   │   ├── doc.md
│   │   ├── enhancement.md
│   │   ├── feature.md
│   │   ├── question.md
│   │   └── release.md
│   ├── actions/
│   │   ├── go-check-setup/
│   │   │   └── action.yml
│   │   └── go-test-setup/
│   │       └── action.yml
│   └── workflows/
│       ├── generated-pr.yml
│       ├── go-check-config.json
│       ├── go-check.yml
│       ├── go-test-config.json
│       ├── go-test-template.yml
│       ├── go-test.yml
│       ├── interop-test.yml
│       ├── link-check.yml
│       ├── markdown-links-config.json
│       ├── release-check.yml
│       ├── releaser.yml
│       ├── stale.yml
│       ├── tagpush.yml
│       └── upstream.yml
├── .gitignore
├── .golangci.yml
├── CHANGELOG.md
├── FUNDING.json
├── LICENSE
├── README.md
├── SECURITY.md
├── config/
│   ├── config.go
│   ├── config_test.go
│   ├── host.go
│   └── quic.go
├── core/
│   ├── alias.go
│   ├── connmgr/
│   │   ├── decay.go
│   │   ├── gater.go
│   │   ├── manager.go
│   │   ├── null.go
│   │   └── presets.go
│   ├── control/
│   │   └── disconnect.go
│   ├── crypto/
│   │   ├── bench_test.go
│   │   ├── ecdsa.go
│   │   ├── ecdsa_test.go
│   │   ├── ed25519.go
│   │   ├── ed25519_test.go
│   │   ├── fixture_test.go
│   │   ├── key.go
│   │   ├── key_test.go
│   │   ├── key_to_stdlib.go
│   │   ├── pb/
│   │   │   ├── crypto.pb.go
│   │   │   └── crypto.proto
│   │   ├── rsa_common.go
│   │   ├── rsa_go.go
│   │   ├── rsa_test.go
│   │   ├── secp256k1.go
│   │   ├── secp256k1_test.go
│   │   └── test_data/
│   │       ├── 0.priv
│   │       ├── 0.pub
│   │       ├── 0.sig
│   │       ├── 2.priv
│   │       ├── 2.pub
│   │       ├── 2.sig
│   │       ├── 3.priv
│   │       ├── 3.pub
│   │       └── 3.sig
│   ├── discovery/
│   │   ├── discovery.go
│   │   └── options.go
│   ├── event/
│   │   ├── addrs.go
│   │   ├── bus.go
│   │   ├── dht.go
│   │   ├── doc.go
│   │   ├── identify.go
│   │   ├── nattype.go
│   │   ├── network.go
│   │   ├── protocol.go
│   │   └── reachability.go
│   ├── host/
│   │   ├── helpers.go
│   │   └── host.go
│   ├── internal/
│   │   └── catch/
│   │       ├── catch.go
│   │       └── catch_test.go
│   ├── metrics/
│   │   ├── bandwidth.go
│   │   ├── bandwidth_test.go
│   │   └── reporter.go
│   ├── network/
│   │   ├── conn.go
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── errors.go
│   │   ├── mocks/
│   │   │   ├── mock_conn_management_scope.go
│   │   │   ├── mock_peer_scope.go
│   │   │   ├── mock_protocol_scope.go
│   │   │   ├── mock_resource_manager.go
│   │   │   ├── mock_resource_scope_span.go
│   │   │   ├── mock_stream_management_scope.go
│   │   │   └── network.go
│   │   ├── mux.go
│   │   ├── nattype.go
│   │   ├── network.go
│   │   ├── notifee.go
│   │   ├── notifee_test.go
│   │   ├── rcmgr.go
│   │   └── stream.go
│   ├── peer/
│   │   ├── addrinfo.go
│   │   ├── addrinfo_serde.go
│   │   ├── addrinfo_test.go
│   │   ├── pb/
│   │   │   ├── peer_record.pb.go
│   │   │   └── peer_record.proto
│   │   ├── peer.go
│   │   ├── peer_serde.go
│   │   ├── peer_serde_test.go
│   │   ├── peer_test.go
│   │   ├── record.go
│   │   └── record_test.go
│   ├── peerstore/
│   │   ├── helpers.go
│   │   └── peerstore.go
│   ├── pnet/
│   │   ├── codec.go
│   │   ├── codec_test.go
│   │   ├── env.go
│   │   ├── error.go
│   │   ├── error_test.go
│   │   └── protector.go
│   ├── protocol/
│   │   ├── id.go
│   │   └── switch.go
│   ├── record/
│   │   ├── envelope.go
│   │   ├── envelope_test.go
│   │   ├── pb/
│   │   │   ├── envelope.pb.go
│   │   │   └── envelope.proto
│   │   ├── record.go
│   │   └── record_test.go
│   ├── routing/
│   │   ├── options.go
│   │   ├── query.go
│   │   ├── query_serde.go
│   │   ├── query_test.go
│   │   └── routing.go
│   ├── sec/
│   │   └── security.go
│   ├── test/
│   │   ├── addrs.go
│   │   ├── crypto.go
│   │   ├── errors.go
│   │   ├── mockclock.go
│   │   ├── mockclock_test.go
│   │   └── peer.go
│   └── transport/
│       └── transport.go
├── dashboards/
│   ├── README.md
│   ├── autonat/
│   │   └── autonat.json
│   ├── autonatv2/
│   │   └── autonatv2.json
│   ├── autorelay/
│   │   └── autorelay.json
│   ├── dashboard.yml
│   ├── datasources.yml
│   ├── docker-compose-linux.yml
│   ├── docker-compose.base.yml
│   ├── eventbus/
│   │   └── eventbus.json
│   ├── holepunch/
│   │   └── holepunch.json
│   ├── host-addrs/
│   │   └── host-addrs.json
│   ├── identify/
│   │   └── identify.json
│   ├── prometheus.yml
│   ├── relaysvc/
│   │   └── relaysvc.json
│   ├── resource-manager/
│   │   ├── README.md
│   │   └── resource-manager.json
│   └── swarm/
│       └── swarm.json
├── defaults.go
├── docs/
│   └── flaky-tests.md
├── examples/
│   ├── README.md
│   ├── go.mod
│   ├── go.sum
│   ├── ipfs-camp-2019/
│   │   ├── README.md
│   │   ├── go.mod
│   │   └── go.sum
│   ├── metrics-and-dashboards/
│   │   ├── README.md
│   │   ├── compose.yml
│   │   ├── go-libp2p-node.Dockerfile
│   │   ├── main.go
│   │   └── prometheus.yml
│   ├── pubsub/
│   │   ├── README.md
│   │   └── basic-chat-with-rendezvous/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── go.mod
│   │       ├── go.sum
│   │       └── main.go
│   └── testutils/
│       ├── logharness.go
│       └── net.go
├── fx_options_test.go
├── go.mod
├── go.sum
├── gologshim/
│   ├── gologshim.go
│   └── gologshim_test.go
├── leaky_tests/
│   ├── README.md
│   └── leaky_test.go
├── libp2p.go
├── libp2p_test.go
├── limits.go
├── options.go
├── options_filter.go
├── p2p/
│   ├── canonicallog/
│   │   ├── canonicallog.go
│   │   └── canonicallog_test.go
│   ├── discovery/
│   │   ├── backoff/
│   │   │   ├── backoff.go
│   │   │   ├── backoff_test.go
│   │   │   ├── backoffcache.go
│   │   │   ├── backoffcache_test.go
│   │   │   ├── backoffconnector.go
│   │   │   └── backoffconnector_test.go
│   │   ├── mdns/
│   │   │   ├── mdns.go
│   │   │   └── mdns_test.go
│   │   ├── mocks/
│   │   │   └── mocks.go
│   │   ├── routing/
│   │   │   ├── routing.go
│   │   │   └── routing_test.go
│   │   └── util/
│   │       └── util.go
│   ├── host/
│   │   ├── autonat/
│   │   │   ├── autonat.go
│   │   │   ├── autonat_test.go
│   │   │   ├── client.go
│   │   │   ├── dialpolicy.go
│   │   │   ├── dialpolicy_test.go
│   │   │   ├── interface.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── notify.go
│   │   │   ├── options.go
│   │   │   ├── pb/
│   │   │   │   ├── autonat.pb.go
│   │   │   │   └── autonat.proto
│   │   │   ├── proto.go
│   │   │   ├── svc.go
│   │   │   ├── svc_test.go
│   │   │   └── test/
│   │   │       ├── autonat_test.go
│   │   │       └── dummy.go
│   │   ├── autorelay/
│   │   │   ├── addrsplosion.go
│   │   │   ├── addrsplosion_test.go
│   │   │   ├── autorelay.go
│   │   │   ├── autorelay_test.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_noalloc_test.go
│   │   │   ├── options.go
│   │   │   └── relay_finder.go
│   │   ├── basic/
│   │   │   ├── addrs_manager.go
│   │   │   ├── addrs_manager_test.go
│   │   │   ├── addrs_metrics.go
│   │   │   ├── addrs_metrics_test.go
│   │   │   ├── addrs_reachability_tracker.go
│   │   │   ├── addrs_reachability_tracker_test.go
│   │   │   ├── basic_host.go
│   │   │   ├── basic_host_synctest_test.go
│   │   │   ├── basic_host_test.go
│   │   │   ├── mock_nat_test.go
│   │   │   ├── mocks.go
│   │   │   ├── natmgr.go
│   │   │   └── natmgr_test.go
│   │   ├── blank/
│   │   │   └── blank.go
│   │   ├── eventbus/
│   │   │   ├── basic.go
│   │   │   ├── basic_metrics.go
│   │   │   ├── basic_metrics_test.go
│   │   │   ├── basic_test.go
│   │   │   └── opts.go
│   │   ├── observedaddrs/
│   │   │   ├── manager.go
│   │   │   ├── manager_glass_test.go
│   │   │   └── manager_test.go
│   │   ├── peerstore/
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── peerstore.go
│   │   │   ├── pstoreds/
│   │   │   │   ├── addr_book.go
│   │   │   │   ├── addr_book_gc.go
│   │   │   │   ├── addr_book_gc_test.go
│   │   │   │   ├── cache.go
│   │   │   │   ├── cyclic_batch.go
│   │   │   │   ├── deprecate.go
│   │   │   │   ├── ds_test.go
│   │   │   │   ├── keybook.go
│   │   │   │   ├── metadata.go
│   │   │   │   ├── pb/
│   │   │   │   │   ├── pstore.pb.go
│   │   │   │   │   └── pstore.proto
│   │   │   │   ├── peerstore.go
│   │   │   │   └── protobook.go
│   │   │   ├── pstoremem/
│   │   │   │   ├── addr_book.go
│   │   │   │   ├── addr_book_test.go
│   │   │   │   ├── inmem_test.go
│   │   │   │   ├── keybook.go
│   │   │   │   ├── metadata.go
│   │   │   │   ├── peerstore.go
│   │   │   │   ├── peerstore_test.go
│   │   │   │   ├── protobook.go
│   │   │   │   ├── sorting.go
│   │   │   │   └── sorting_test.go
│   │   │   └── test/
│   │   │       ├── addr_book_suite.go
│   │   │       ├── benchmarks_suite.go
│   │   │       ├── keybook_suite.go
│   │   │       ├── peerstore_suite.go
│   │   │       └── utils.go
│   │   ├── pstoremanager/
│   │   │   ├── mock_peerstore_test.go
│   │   │   ├── pstoremanager.go
│   │   │   └── pstoremanager_test.go
│   │   ├── relaysvc/
│   │   │   ├── relay.go
│   │   │   └── relay_test.go
│   │   ├── resource-manager/
│   │   │   ├── README.md
│   │   │   ├── allowlist.go
│   │   │   ├── allowlist_test.go
│   │   │   ├── conn_limiter.go
│   │   │   ├── conn_limiter_test.go
│   │   │   ├── conn_rate_limiter.go
│   │   │   ├── docs/
│   │   │   │   └── allowlist.md
│   │   │   ├── error.go
│   │   │   ├── extapi.go
│   │   │   ├── limit.go
│   │   │   ├── limit_config_test.backwards-compat.json
│   │   │   ├── limit_config_test.go
│   │   │   ├── limit_config_test.json
│   │   │   ├── limit_config_test_default.json
│   │   │   ├── limit_defaults.go
│   │   │   ├── limit_test.go
│   │   │   ├── limits_metrics_test.go
│   │   │   ├── metrics.go
│   │   │   ├── noalloc_test.go
│   │   │   ├── obs/
│   │   │   │   └── obs.go
│   │   │   ├── rcmgr.go
│   │   │   ├── rcmgr_test.go
│   │   │   ├── scope.go
│   │   │   ├── scope_test.go
│   │   │   ├── stats.go
│   │   │   ├── stats_test.go
│   │   │   ├── sys_not_unix.go
│   │   │   ├── sys_unix.go
│   │   │   ├── sys_windows.go
│   │   │   └── trace.go
│   │   └── routed/
│   │       ├── routed.go
│   │       └── routed_test.go
│   ├── http/
│   │   ├── auth/
│   │   │   ├── auth.go
│   │   │   ├── auth_test.go
│   │   │   ├── client.go
│   │   │   ├── internal/
│   │   │   │   └── handshake/
│   │   │   │       ├── alloc_test.go
│   │   │   │       ├── client.go
│   │   │   │       ├── handshake.go
│   │   │   │       ├── handshake_test.go
│   │   │   │       └── server.go
│   │   │   └── server.go
│   │   ├── example_test.go
│   │   ├── libp2phttp.go
│   │   ├── libp2phttp_test.go
│   │   ├── options.go
│   │   └── ping/
│   │       └── ping.go
│   ├── metricshelper/
│   │   ├── conn.go
│   │   ├── conn_test.go
│   │   ├── dir.go
│   │   ├── pool.go
│   │   ├── pool_test.go
│   │   ├── registerer.go
│   │   └── registerer_test.go
│   ├── muxer/
│   │   ├── testsuite/
│   │   │   └── mux.go
│   │   └── yamux/
│   │       ├── conn.go
│   │       ├── stream.go
│   │       ├── transport.go
│   │       └── transport_test.go
│   ├── net/
│   │   ├── README.md
│   │   ├── conngater/
│   │   │   ├── conngater.go
│   │   │   └── conngater_test.go
│   │   ├── connmgr/
│   │   │   ├── bench_test.go
│   │   │   ├── connmgr.go
│   │   │   ├── connmgr_test.go
│   │   │   ├── decay.go
│   │   │   ├── decay_test.go
│   │   │   └── options.go
│   │   ├── gostream/
│   │   │   ├── addr.go
│   │   │   ├── conn.go
│   │   │   ├── gostream.go
│   │   │   ├── gostream_test.go
│   │   │   └── listener.go
│   │   ├── mock/
│   │   │   ├── complement.go
│   │   │   ├── interface.go
│   │   │   ├── log2.txt
│   │   │   ├── mock.go
│   │   │   ├── mock_conn.go
│   │   │   ├── mock_link.go
│   │   │   ├── mock_net.go
│   │   │   ├── mock_notif_test.go
│   │   │   ├── mock_peernet.go
│   │   │   ├── mock_printer.go
│   │   │   ├── mock_stream.go
│   │   │   ├── mock_test.go
│   │   │   └── ratelimiter.go
│   │   ├── nat/
│   │   │   ├── internal/
│   │   │   │   └── nat/
│   │   │   │       ├── LICENSE
│   │   │   │       ├── README.md
│   │   │   │       ├── nat.go
│   │   │   │       ├── natpmp.go
│   │   │   │       └── upnp.go
│   │   │   ├── mock_nat_test.go
│   │   │   ├── nat.go
│   │   │   └── nat_test.go
│   │   ├── pnet/
│   │   │   ├── protector.go
│   │   │   ├── psk_conn.go
│   │   │   └── psk_conn_test.go
│   │   ├── reuseport/
│   │   │   ├── dial.go
│   │   │   ├── dialer.go
│   │   │   ├── listen.go
│   │   │   ├── reuseport.go
│   │   │   ├── reuseport_plan9.go
│   │   │   ├── reuseport_posix.go
│   │   │   ├── reuseport_test.go
│   │   │   ├── transport.go
│   │   │   └── transport_test.go
│   │   ├── swarm/
│   │   │   ├── black_hole_detector.go
│   │   │   ├── black_hole_detector_test.go
│   │   │   ├── clock.go
│   │   │   ├── connectedness_event_emitter.go
│   │   │   ├── dial_error.go
│   │   │   ├── dial_error_test.go
│   │   │   ├── dial_ranker.go
│   │   │   ├── dial_ranker_test.go
│   │   │   ├── dial_sync.go
│   │   │   ├── dial_sync_test.go
│   │   │   ├── dial_test.go
│   │   │   ├── dial_worker.go
│   │   │   ├── dial_worker_test.go
│   │   │   ├── limiter.go
│   │   │   ├── limiter_test.go
│   │   │   ├── peers_test.go
│   │   │   ├── resolve_test.go
│   │   │   ├── simul_test.go
│   │   │   ├── swarm.go
│   │   │   ├── swarm_addr.go
│   │   │   ├── swarm_addr_test.go
│   │   │   ├── swarm_conn.go
│   │   │   ├── swarm_dial.go
│   │   │   ├── swarm_dial_test.go
│   │   │   ├── swarm_event_test.go
│   │   │   ├── swarm_listen.go
│   │   │   ├── swarm_metrics.go
│   │   │   ├── swarm_metrics_test.go
│   │   │   ├── swarm_net_test.go
│   │   │   ├── swarm_notif_test.go
│   │   │   ├── swarm_stream.go
│   │   │   ├── swarm_test.go
│   │   │   ├── swarm_transport.go
│   │   │   ├── testing/
│   │   │   │   ├── testing.go
│   │   │   │   └── testing_test.go
│   │   │   ├── transport_test.go
│   │   │   └── util_test.go
│   │   └── upgrader/
│   │       ├── conn.go
│   │       ├── gater_test.go
│   │       ├── listener.go
│   │       ├── listener_test.go
│   │       ├── threshold.go
│   │       ├── upgrader.go
│   │       └── upgrader_test.go
│   ├── protocol/
│   │   ├── autonatv2/
│   │   │   ├── autonat.go
│   │   │   ├── autonat_test.go
│   │   │   ├── client.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── msg_reader.go
│   │   │   ├── options.go
│   │   │   ├── pb/
│   │   │   │   ├── autonatv2.pb.go
│   │   │   │   └── autonatv2.proto
│   │   │   ├── server.go
│   │   │   └── server_test.go
│   │   ├── circuitv2/
│   │   │   ├── client/
│   │   │   │   ├── client.go
│   │   │   │   ├── conn.go
│   │   │   │   ├── dial.go
│   │   │   │   ├── handlers.go
│   │   │   │   ├── listen.go
│   │   │   │   ├── reservation.go
│   │   │   │   ├── reservation_test.go
│   │   │   │   └── transport.go
│   │   │   ├── pb/
│   │   │   │   ├── circuit.pb.go
│   │   │   │   ├── circuit.proto
│   │   │   │   ├── voucher.pb.go
│   │   │   │   └── voucher.proto
│   │   │   ├── proto/
│   │   │   │   ├── protocol.go
│   │   │   │   ├── voucher.go
│   │   │   │   └── voucher_test.go
│   │   │   ├── relay/
│   │   │   │   ├── acl.go
│   │   │   │   ├── constraints.go
│   │   │   │   ├── constraints_test.go
│   │   │   │   ├── metrics.go
│   │   │   │   ├── metrics_test.go
│   │   │   │   ├── options.go
│   │   │   │   ├── relay.go
│   │   │   │   ├── relay_priv_test.go
│   │   │   │   ├── relay_test.go
│   │   │   │   └── resources.go
│   │   │   └── util/
│   │   │       ├── io.go
│   │   │       └── pbconv.go
│   │   ├── holepunch/
│   │   │   ├── filter.go
│   │   │   ├── holepunch_test.go
│   │   │   ├── holepuncher.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_noalloc_test.go
│   │   │   ├── metrics_test.go
│   │   │   ├── pb/
│   │   │   │   ├── holepunch.pb.go
│   │   │   │   └── holepunch.proto
│   │   │   ├── svc.go
│   │   │   ├── tracer.go
│   │   │   └── util.go
│   │   ├── identify/
│   │   │   ├── id.go
│   │   │   ├── id_glass_test.go
│   │   │   ├── id_test.go
│   │   │   ├── internal/
│   │   │   │   └── user-agent/
│   │   │   │       └── user_agent.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── opts.go
│   │   │   ├── pb/
│   │   │   │   ├── identify.pb.go
│   │   │   │   └── identify.proto
│   │   │   └── snapshot_test.go
│   │   └── ping/
│   │       ├── ping.go
│   │       └── ping_test.go
│   ├── security/
│   │   ├── insecure/
│   │   │   ├── insecure.go
│   │   │   ├── insecure_test.go
│   │   │   └── pb/
│   │   │       ├── plaintext.pb.go
│   │   │       └── plaintext.proto
│   │   ├── noise/
│   │   │   ├── benchmark_test.go
│   │   │   ├── crypto.go
│   │   │   ├── crypto_test.go
│   │   │   ├── handshake.go
│   │   │   ├── pb/
│   │   │   │   ├── payload.pb.go
│   │   │   │   └── payload.proto
│   │   │   ├── rw.go
│   │   │   ├── session.go
│   │   │   ├── session_test.go
│   │   │   ├── session_transport.go
│   │   │   ├── transport.go
│   │   │   └── transport_test.go
│   │   └── tls/
│   │       ├── cmd/
│   │       │   ├── README.md
│   │       │   ├── tlsdiag/
│   │       │   │   ├── client.go
│   │       │   │   ├── key.go
│   │       │   │   └── server.go
│   │       │   └── tlsdiag.go
│   │       ├── conn.go
│   │       ├── crypto.go
│   │       ├── crypto_test.go
│   │       ├── extension.go
│   │       ├── extension_test.go
│   │       ├── transport.go
│   │       └── transport_test.go
│   ├── test/
│   │   ├── backpressure/
│   │   │   ├── backpressure.go
│   │   │   └── backpressure_test.go
│   │   ├── basichost/
│   │   │   └── basic_host_test.go
│   │   ├── negotiation/
│   │   │   ├── muxer_test.go
│   │   │   └── security_test.go
│   │   ├── notifications/
│   │   │   └── notification_test.go
│   │   ├── quic/
│   │   │   └── quic_test.go
│   │   ├── reconnects/
│   │   │   ├── reconnect.go
│   │   │   └── reconnect_test.go
│   │   ├── resource-manager/
│   │   │   ├── echo.go
│   │   │   ├── echo_test.go
│   │   │   └── rcmgr_test.go
│   │   ├── security/
│   │   │   └── bench_test.go
│   │   ├── swarm/
│   │   │   └── swarm_test.go
│   │   ├── transport/
│   │   │   ├── deadline_test.go
│   │   │   ├── gating_test.go
│   │   │   ├── mock_connection_gater_test.go
│   │   │   ├── rcmgr_test.go
│   │   │   └── transport_test.go
│   │   └── webtransport/
│   │       └── webtransport_test.go
│   └── transport/
│       ├── quic/
│       │   ├── cmd/
│       │   │   ├── client/
│       │   │   │   └── main.go
│       │   │   ├── lib/
│       │   │   │   ├── lib.go
│       │   │   │   └── lib_test.go
│       │   │   └── server/
│       │   │       └── main.go
│       │   ├── conn.go
│       │   ├── conn_test.go
│       │   ├── listener.go
│       │   ├── listener_test.go
│       │   ├── mock_connection_gater_test.go
│       │   ├── stream.go
│       │   ├── transport.go
│       │   ├── transport_test.go
│       │   └── virtuallistener.go
│       ├── quicreuse/
│       │   ├── config.go
│       │   ├── connmgr.go
│       │   ├── connmgr_test.go
│       │   ├── listener.go
│       │   ├── nonquic_packetconn.go
│       │   ├── options.go
│       │   ├── quic_multiaddr.go
│       │   ├── quic_multiaddr_test.go
│       │   ├── reuse.go
│       │   └── reuse_test.go
│       ├── tcp/
│       │   ├── metrics.go
│       │   ├── metrics_darwin.go
│       │   ├── metrics_general.go
│       │   ├── metrics_linux.go
│       │   ├── metrics_none.go
│       │   ├── metrics_test.go
│       │   ├── tcp.go
│       │   └── tcp_test.go
│       ├── tcpreuse/
│       │   ├── connwithscope.go
│       │   ├── demultiplex.go
│       │   ├── demultiplex_test.go
│       │   ├── dialer.go
│       │   ├── internal/
│       │   │   └── sampledconn/
│       │   │       ├── sampledconn.go
│       │   │       └── sampledconn_test.go
│       │   ├── listener.go
│       │   ├── listener_test.go
│       │   └── reuseport.go
│       ├── testsuite/
│       │   ├── stream_suite.go
│       │   ├── transport_suite.go
│       │   └── utils_suite.go
│       ├── webrtc/
│       │   ├── connection.go
│       │   ├── fingerprint.go
│       │   ├── hex.go
│       │   ├── hex_test.go
│       │   ├── listener.go
│       │   ├── logger.go
│       │   ├── pb/
│       │   │   ├── message.pb.go
│       │   │   └── message.proto
│       │   ├── sdp.go
│       │   ├── sdp_test.go
│       │   ├── stream.go
│       │   ├── stream_read.go
│       │   ├── stream_test.go
│       │   ├── stream_write.go
│       │   ├── transport.go
│       │   ├── transport_test.go
│       │   └── udpmux/
│       │       ├── mux.go
│       │       ├── mux_test.go
│       │       └── muxed_connection.go
│       ├── websocket/
│       │   ├── LICENSE-APACHE
│       │   ├── LICENSE-MIT
│       │   ├── addrs.go
│       │   ├── addrs_test.go
│       │   ├── conn.go
│       │   ├── listener.go
│       │   ├── websocket.go
│       │   └── websocket_test.go
│       └── webtransport/
│           ├── cert_manager.go
│           ├── cert_manager_test.go
│           ├── conn.go
│           ├── crypto.go
│           ├── crypto_test.go
│           ├── listener.go
│           ├── mock_connection_gater_test.go
│           ├── multiaddr.go
│           ├── multiaddr_test.go
│           ├── noise_early_data.go
│           ├── stream.go
│           ├── transport.go
│           └── transport_test.go
├── proto_test.go
├── scripts/
│   ├── .gitignore
│   ├── download-protoc.sh
│   ├── gen-proto.sh
│   ├── mkreleaselog
│   ├── print-protoc-hashes.sh
│   └── test_analysis/
│       ├── cmd/
│       │   └── gotest2sql/
│       │       └── main.go
│       ├── go.mod
│       ├── go.sum
│       ├── main.go
│       └── main_test.go
├── test-plans/
│   ├── .gitignore
│   ├── PingDockerfile
│   ├── README.md
│   ├── cmd/
│   │   └── ping/
│   │       └── main.go
│   ├── go.mod
│   ├── go.sum
│   └── ping-version.json
├── tools.go
├── version.json
└── x/
    ├── rate/
    │   ├── limiter.go
    │   └── limiter_test.go
    └── simlibp2p/
        ├── libp2p.go
        └── synctest_test.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .codecov.yml
================================================
github_checks:
  annotations: false


================================================
FILE: .githooks/README.md
================================================
# Git Hooks

This directory contains useful Git hooks for working with go-libp2p.

Install them by running
```bash
git config core.hooksPath .githooks
```


================================================
FILE: .githooks/pre-commit
================================================
#!/bin/bash

pushd ./test-plans > /dev/null
go mod tidy
if [[ -n $(git diff --name-only -- "go.mod" "go.sum") ]]; then
  echo "go.mod / go.sum in test-plans not tidied"
  errored=true
fi
popd > /dev/null

if [ "$errored" = true ]; then
	exit 1
fi


================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.md
================================================
---
name: 'Bug Report'
about: 'Report a bug in go-libp2p.'
labels: bug
---

<!-- This is where you get to tell us what went wrong. When doing so, please make sure to include *all* relevant information.

Please try to include:
  * What you were doing when you experienced the bug.
  * Any error messages you saw, *where* you saw them, and what you believe may have caused them (if you have any ideas).
  * When possible, steps to reliably produce the bug.
-->

<details>
<summary>Version Information</summary>
<pre>
<!-- Insert the output of `go list -m all` HERE -->
</pre>
</details>


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
  - name: Technical Questions
    url: https://github.com/libp2p/go-libp2p/discussions/new?category=q-a
    about: Please ask technical questions in the go-libp2p Github Discusions forum.
  - name: Community-wide libp2p Discussion
    url: https://discuss.libp2p.io
    about: Discussions and questions about the libp2p community.


================================================
FILE: .github/ISSUE_TEMPLATE/doc.md
================================================
---
name: 'Documentation Issue'
about: 'Report missing/erroneous documentation, propose new documentation, report broken links, etc.'
labels: documentation
---

#### Location

<!-- In the case of missing/erroneous documentation, where is the error? If possible, a link/url would be great! -->

#### Description

<!-- Describe the documentation issue. -->


================================================
FILE: .github/ISSUE_TEMPLATE/enhancement.md
================================================
---
name: 'Enhancement'
about: 'Suggest an improvement to an existing go-libp2p feature.'
labels: enhancement
---

<!--
Note: If you'd like to suggest an idea related to libp2p but not specifically related to the Go implementation, please file an issue at https://github.com/libp2p/specs instead. Even better, create a new topic on the forums (https://discuss.libp2p.io).

When requesting an _enhancement_, please be sure to include your motivation and try to be as specific as possible.
-->


================================================
FILE: .github/ISSUE_TEMPLATE/feature.md
================================================
---
name: 'Feature'
about: 'Suggest a new feature in go-libp2p.'
labels: feature
---

<!--
Note: If you'd like to suggest an idea related to libp2p but not specifically related to the Go implementation, please file an issue at https://github.com/libp2p/specs instead. Even better, create a new topic on the forums (https://discuss.libp2p.io).

When requesting a _feature_, please be sure to include:
  * Your motivation. Why do you need the feature?
  * How the feature should work.

Please try to be as specific and concrete as possible.
-->


================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: 'Question/Support'
about: 'Ask a question about go-libp2p or request support.'
labels: question, invalid
---

This bug tracker is only for actionable bug reports and feature requests. Please direct any questions to https://discuss.libp2p.io or to our Matrix (#libp2p:matrix.org) or IRC (#libp2p on freenode) channels.

If you don't get an immediate response, please keep trying.


================================================
FILE: .github/ISSUE_TEMPLATE/release.md
================================================
---
name: 'Libp2p Release'
about: 'Start a new libp2p release.'
---

## 🗺 What's left for release

<List of items with remaining PRs and/or Issues to be considered for this release>

## 🔦 Highlights

< top highlights for this release notes >

## Changelog

< changelog generated by scripts/mkreleaselog >

## ✅ Release Checklist

- [ ] **Stage 0 - Finishing Touches**
    - [ ] Go through relevant libp2p repos looking for unreleased changes that should make it into the release. If you find any, cut releases.
    - [ ] Run `go get -u ./...` to see if there are any out-of-date deps that look important. If there are, bubble them. Try to avoid _directly_ updating indirect deps in go-libp2p's `go.mod` when possible.
- [ ] **Stage 1 - Release**
  - [ ] Publish the release through the GitHub UI, adding the release notes. Some users rely on this to receive notifications of new releases.
  - [ ] Announce the release on the [discuss.libp2p.io](https://discuss.libp2p.io).
- [ ] **Stage 2 - Update Upstream**
  - [ ] Update the examples to the final release
  - [ ] Update the upstream dependencies to the final release and create PRs.
    - [ ] [filecoin-project/lotus](https://github.com/filecoin-project/lotus)
    - [ ] [go-libp2p-kad-dht](https://github.com/libp2p/go-libp2p-kad-dht/)
    - [ ] [go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub) (In case of breaking changes.)
    - [ ] [ipfs/kubo](https://github.com/ipfs/kubo)
  - [ ] Add new release to interop tester in [test-plans](https://github.com/libp2p/test-plans/)
- [ ] Make required changes to the release process.


================================================
FILE: .github/actions/go-check-setup/action.yml
================================================
runs:
  using: "composite"
  steps:
    - name: Install Protoc
      uses: trail-of-forks/setup-protoc@a97892a429d98fae78d26f40334ab7eb616d08b9 # include https://github.com/arduino/setup-protoc/pull/58
      with:
        version: '21.12'
        repo-token: ${{ github.token }}
    - name: Install Protobuf compiler
      shell: bash
      run: go install google.golang.org/protobuf/cmd/protoc-gen-go


================================================
FILE: .github/actions/go-test-setup/action.yml
================================================
runs:
  using: "composite"
  steps:
    - name: increase the UDP receive buffer size # see https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size
      shell: bash
      run: sysctl -w net.core.rmem_max=2500000
      if: ${{ matrix.os == 'ubuntu' }}
    - name: Run nocover tests. These are tests that require the coverage analysis to be off # See https://github.com/protocol/.github/issues/460
      shell: bash
      # This matches only tests with "NoCover" in their test name to avoid running all tests again.
      run: go test -tags nocover -run NoCover -v ./...
    - name: Run synctests tests. These are tests that require go 1.25 and the experimental testing/synctest package
      shell: bash
      if: ${{ contains(matrix.go, '1.25') }}
      run: go test -run "_synctest$" -v ./...
    - name: Install testing tools
      shell: bash
      run: cd scripts/test_analysis && go install ./cmd/gotest2sql
    - name: Install test_analysis
      shell: bash
      run: cd scripts/test_analysis && go install .


================================================
FILE: .github/workflows/generated-pr.yml
================================================
name: Close Generated PRs

on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:

permissions:
  issues: write
  pull-requests: write

jobs:
  stale:
    uses: ipdxco/unified-github-workflows/.github/workflows/reusable-generated-pr.yml@v1


================================================
FILE: .github/workflows/go-check-config.json
================================================
{
  "gogenerate": true
}


================================================
FILE: .github/workflows/go-check.yml
================================================
name: Go Checks

on:
  pull_request:
  push:
    branches: ["master", "release-v0[0-9][0-9]"]
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
  cancel-in-progress: true

jobs:
  go-check:
    uses: ipdxco/unified-github-workflows/.github/workflows/go-check.yml@v1.0
    with:
      go-generate-ignore-protoc-version-comments: true


================================================
FILE: .github/workflows/go-test-config.json
================================================
{
    "skip32bit": true
}


================================================
FILE: .github/workflows/go-test-template.yml
================================================
name: Go Test
on:
  workflow_call:
    inputs:
      go-versions:
        required: false
        type: string
        default: '["this", "next"]'
    secrets:
      CODECOV_TOKEN:
        required: false

defaults:
  run:
    shell: bash

jobs:
  unit:
    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu", "macos", "windows"]
        go: ${{ fromJSON(inputs.go-versions) }}
    env:
      GOTESTFLAGS: -cover -coverprofile=module-coverage.txt -coverpkg=./...
      GO386FLAGS: ""
      GORACEFLAGS: ""
    runs-on: ${{ fromJSON(format('"{0}-latest"', matrix.os)) }}
    name: ${{ matrix.os }} (go ${{ matrix.go }})
    steps:
      - name: Use msys2 on windows
        if: matrix.os == 'windows'
        # The executable for msys2 is also called bash.cmd
        #   https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#shells
        # If we prepend its location to the PATH
        #   subsequent 'shell: bash' steps will use msys2 instead of gitbash
        run: echo "C:/msys64/usr/bin" >> $GITHUB_PATH
      - name: Check out the repository
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Check out the latest stable version of Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
          cache: ${{ matrix.os != 'windows' }} # Windows VMs are slow to use caching. Can add ~15m to the job
      - name: Read the Unified GitHub Workflows configuration
        id: config
        uses: ipdxco/unified-github-workflows/.github/actions/read-config@main
      - name: Read the go.mod file
        id: go-mod
        uses: ipdxco/unified-github-workflows/.github/actions/read-go-mod@main
      - name: Determine the Go version to use based on the go.mod file
        id: go
        env:
          MATRIX_GO: ${{ matrix.go }}
          GO_MOD_VERSION: ${{ fromJSON(steps.go-mod.outputs.json).Go }}
        run: |
          if [[ "$MATRIX_GO" == "this" ]]; then
            echo "version=$GO_MOD_VERSION.x" >> $GITHUB_OUTPUT
          elif [[ "$MATRIX_GO" == "next" ]]; then
            MAJOR="${GO_MOD_VERSION%.[0-9]*}"
            MINOR="${GO_MOD_VERSION#[0-9]*.}"
            echo "version=$MAJOR.$(($MINOR+1)).x" >> $GITHUB_OUTPUT
          elif [[ "$MATRIX_GO" == "prev" ]]; then
            MAJOR="${GO_MOD_VERSION%.[0-9]*}"
            MINOR="${GO_MOD_VERSION#[0-9]*.}"
            echo "version=$MAJOR.$(($MINOR-1)).x" >> $GITHUB_OUTPUT
          else
            echo "version=$MATRIX_GO" >> $GITHUB_OUTPUT
          fi
      - name: Enable shuffle flag for go test command
        if: toJSON(fromJSON(steps.config.outputs.json).shuffle) != 'false'
        run: |
          echo "GOTESTFLAGS=-shuffle=on $GOTESTFLAGS" >> $GITHUB_ENV
          echo "GO386FLAGS=-shuffle=on $GO386FLAGS" >> $GITHUB_ENV
          echo "GORACEFLAGS=-shuffle=on $GORACEFLAGS" >> $GITHUB_ENV
      - name: Enable verbose flag for go test command
        if: toJSON(fromJSON(steps.config.outputs.json).verbose) != 'false'
        run: |
          echo "GOTESTFLAGS=-v $GOTESTFLAGS" >> $GITHUB_ENV
          echo "GO386FLAGS=-v $GO386FLAGS" >> $GITHUB_ENV
          echo "GORACEFLAGS=-v $GORACEFLAGS" >> $GITHUB_ENV
      - name: Set extra flags for go test command
        if: fromJSON(steps.config.outputs.json).gotestflags != ''
        run: |
          echo "GOTESTFLAGS=${{ fromJSON(steps.config.outputs.json).gotestflags }} $GOTESTFLAGS" >> $GITHUB_ENV
      - name: Set extra flags for go test race command
        if: fromJSON(steps.config.outputs.json).goraceflags != ''
        run: |
          echo "GORACEFLAGS=${{ fromJSON(steps.config.outputs.json).goraceflags }} $GORACEFLAGS" >> $GITHUB_ENV
      - name: Set up the Go version read from the go.mod file
        uses: actions/setup-go@v5
        with:
          go-version: ${{ steps.go.outputs.version }}
          cache: ${{ matrix.os != 'windows' }} # Windows VMs are slow to use caching. Can add ~15m to the job
      - name: Display the Go version and environment
        run: |
          go version
          go env
      - name: Run repo-specific setup
        uses: ./.github/actions/go-test-setup
        if: hashFiles('./.github/actions/go-test-setup') != ''
      - name: Run tests
        id: test
        if: contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false
        uses: protocol/multiple-go-modules@v1.4
        with:
          run: test_analysis ${{ env.GOTESTFLAGS }}
      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.os }}_${{ matrix.go }}_test_results.db
          path: ./test_results.db
      - name: Add failure summary
        if: always()
        run: |
          echo "### Failure Summary" >> $GITHUB_STEP_SUMMARY
          test_analysis summarize >> $GITHUB_STEP_SUMMARY
      - name: Remove test results
        run: rm ./test_results.db
      - name: Run tests with race detector
        # speed things up. Windows and OSX VMs are slow
        if: matrix.os == 'ubuntu' &&
          fromJSON(steps.config.outputs.json).skipRace != true &&
          contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false
        uses: protocol/multiple-go-modules@v1.4
        id: race
        with:
          run: test_analysis -race ${{ env.GORACEFLAGS }} ./...
      - name: Upload test results (Race)
        if: (steps.race.conclusion == 'success' || steps.race.conclusion == 'failure')
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.os }}_${{ matrix.go }}_test_results_race.db
          path: ./test_results.db
      - name: Add failure summary
        if: (steps.race.conclusion == 'success' || steps.race.conclusion == 'failure')
        run: |
          echo "# Tests with race detector failure summary" >> $GITHUB_STEP_SUMMARY
          test_analysis summarize >> $GITHUB_STEP_SUMMARY
      - name: Adding Link to Run Analysis
        run: echo "### [Test flakiness analysis](https://observablehq.com/d/d74435ea5bbf24c7?run-id=$GITHUB_RUN_ID)" >> $GITHUB_STEP_SUMMARY
      - name: Collect coverage files
        id: coverages
        run: echo "files=$(find . -type f -name 'module-coverage.txt' | tr -s '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0
        with:
          files: ${{ steps.coverages.outputs.files }}
          env_vars: OS=${{ matrix.os }}, GO=${{ steps.go.outputs.version }}
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: false


================================================
FILE: .github/workflows/go-test.yml
================================================
name: Go Test

on:
  pull_request:
  push:
    branches: ["master", "release-v0[0-9][0-9]"]
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
  cancel-in-progress: true

jobs:
  go-test:
    uses: ./.github/workflows/go-test-template.yml
    with:
      go-versions: '["1.25.x", "1.26.x"]'
    secrets:
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}


================================================
FILE: .github/workflows/interop-test.yml
================================================
name: Interoperability Testing

on:
  workflow_dispatch:
  pull_request:
    paths:
      - "config/**"
      - "core/**"
      - "internal/**"
      - "p2p/**"
      - "test-plans/**"
      - ".github/workflows/interop-test.yml"
  push:
    branches:
      - "master"
    paths:
      - "config/**"
      - "core/**"
      - "internal/**"
      - "p2p/**"
      - "test-plans/**"

jobs:
  run-transport-interop:
    name: Run transport interoperability tests
    runs-on: ubuntu-latest
    steps:
      - name: Free Disk Space (Ubuntu)
        if: vars['INTEROP_TEST_RUNNER_UBUNTU'] == ''
        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
        with:
          tool-cache: true
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t go-libp2p-head -f test-plans/PingDockerfile .
      - uses: libp2p/test-plans/.github/actions/run-transport-interop-test@master
        with:
          test-filter: go-libp2p-head
          # Known incompatiblity between the draft versions of WebTransport
          test-ignore: "go-libp2p-head x go-v0.46 (webtransport)|go-libp2p-head x go-v0.45 (webtransport)"
          extra-versions: ${{ github.workspace }}/test-plans/ping-version.json
          s3-cache-bucket: ${{ vars.S3_LIBP2P_BUILD_CACHE_BUCKET_NAME }}
          s3-access-key-id: ${{ vars.S3_LIBP2P_BUILD_CACHE_AWS_ACCESS_KEY_ID }}
          s3-secret-access-key: ${{ secrets.S3_LIBP2P_BUILD_CACHE_AWS_SECRET_ACCESS_KEY }}


================================================
FILE: .github/workflows/link-check.yml
================================================
name: Markdown Link Checking
on:
  pull_request:
  push:
    branches:
      - "master"

jobs:
  check-links:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: tcort/github-action-markdown-link-check@v1
        with:
          use-quiet-mode: 'yes'   # show only broken links
          use-verbose-mode: 'yes'
          config-file: .github/workflows/markdown-links-config.json # for removing any false positives


================================================
FILE: .github/workflows/markdown-links-config.json
================================================
{
  "ignorePatterns": [
    {
        "pattern": "^http://localhost"
    },
    {
        "pattern": "^https://twitter.com/"
    },
    {
        "pattern": "^https://opensource.org/"
    }
  ],
  "aliveStatusCodes": [200],
  "httpHeaders": [
    {
      "urls": ["https://docs.github.com/"],
      "headers": {
        "Accept-Encoding": "*"
      }
    }
  ]
}

================================================
FILE: .github/workflows/release-check.yml
================================================
name: Release Checker

on:
  pull_request_target:
    paths: [ 'version.json' ]
    types: [ opened, synchronize, reopened, labeled, unlabeled ]
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  release-check:
    uses: ipdxco/unified-github-workflows/.github/workflows/release-check.yml@v1.0


================================================
FILE: .github/workflows/releaser.yml
================================================
name: Releaser

on:
  push:
    paths: [ 'version.json' ]
  workflow_dispatch:

permissions:
  contents: write

concurrency:
  group: ${{ github.workflow }}-${{ github.sha }}
  cancel-in-progress: true

jobs:
  releaser:
    uses: ipdxco/unified-github-workflows/.github/workflows/releaser.yml@v1.0


================================================
FILE: .github/workflows/stale.yml
================================================
name: Close Stale Issues

on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:

permissions:
  issues: write
  pull-requests: write

jobs:
  stale:
    uses: ipdxco/unified-github-workflows/.github/workflows/reusable-stale-issue.yml@v1


================================================
FILE: .github/workflows/tagpush.yml
================================================
name: Tag Push Checker

on:
  push:
    tags:
      - v*

permissions:
  contents: read
  issues: write

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  releaser:
    uses: ipdxco/unified-github-workflows/.github/workflows/tagpush.yml@v1.0


================================================
FILE: .github/workflows/upstream.yml
================================================
on:
  pull_request:
    branches:
      - master
  push:
    branches:
      - master
name: Upstream Test

jobs:
  unit:
    strategy:
      fail-fast: false
      matrix:
        os:
          - 'ubuntu'
        go:
          # - '1.15.x'
          - '1.16.x'
        upstream:
          # - 'libp2p/go-libp2p-pubsub' flaky
          # - 'ipfs/go-bitswap' flaky
          # - 'libp2p/go-libp2p-kad-dht'
          - 'libp2p/go-libp2p-daemon'
    runs-on: ${{ matrix.os }}-latest
    name: ${{ matrix.upstream }} unit tests (${{ matrix.os }}, Go ${{ matrix.go }})
    steps:
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ matrix.go }}
      - name: Go information
        run: |
          go version
          go env
      - uses: actions/checkout@v4
        with:
          path: 'libp2p'
      - uses: actions/checkout@v4
        with:
          repository: ${{ matrix.upstream }}
          path: upstream
      - name: Patch in new go-libp2p
        working-directory: upstream
        run: |
          go mod edit -replace "github.com/libp2p/go-libp2p=../libp2p"
          go mod tidy
      - name: Run tests
        working-directory: upstream
        run: go test -v ./...
      - name: Run tests (32 bit)
        working-directory: upstream
        if: ${{ matrix.os != 'macos' }} # can't run 32 bit tests on OSX.
        env:
          GOARCH: 386
        run: go test -v ./...
      - name: Run tests with race detector
        working-directory: upstream
        if: ${{ matrix.os == 'ubuntu' }} # speed things up. Windows and OSX VMs are slow
        run: go test -v -race ./...


================================================
FILE: .gitignore
================================================
*.swp
.idea
*.qlog
*.sqlog
*.qlog.zst
*.sqlog.zst
go.work
go.work.sum


================================================
FILE: .golangci.yml
================================================
version: "2"

run:
  timeout: 5m

issues:
  max-issues-per-linter: 0
  max-same-issues: 0
  exclude-rules:
    - path: _test\.go
      linters:
        - prealloc

linters:
  enable:
    - revive
    - unused
    - prealloc
  disable:
    - errcheck
    - staticcheck

  settings:
    revive:
      severity: warning
      rules:
        - name: unused-parameter
          severity: warning

severity:
  default: warning


================================================
FILE: CHANGELOG.md
================================================
# Table Of Contents <!-- omit in toc -->
- [v0.28.0](#v0280)
- [v0.27.0](#v0270)
- [v0.26.4](#v0264)
- [v0.26.3](#v0263)
- [v0.26.2](#v0262)
- [v0.26.1](#v0261)
- [v0.26.0](#v0260)
- [v0.25.1](#v0251)
- [v0.25.0](#v0250)

# [v0.28.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.28.0)

## 🔦 Highlights <!-- omit in toc -->

### Smart Dialing <!-- omit in toc -->

This release introduces smart dialing logic. Currently, libp2p dials all addresses of a remote peer in parallel, and
aborts all outstanding dials as soon as the first one succeeds.
Dialing many addresses in parallel creates a lot of churn on the client side, and unnecessary load on the network and
on the server side, and is heavily discouraged by the networking community (see [RFC 8305](https://www.rfc-editor.org/rfc/rfc8305) for example).

When connecting to a peer we first determine the order to dial its addresses. This ranking logic considers a number of corner cases
described in detail in the documentation of the swarm package (`swarm.DefaultDialRanker`).
At a high level, this is what happens:
* If a peer offers a WebTransport and a QUIC address (on the same IP:port), the QUIC address is preferred.
* If a peer has a QUIC and a TCP address, the QUIC address is dialed first. Only if the connection attempt doesn't succeed within 250ms, a TCP connection is started.

Our measurements on the IPFS network show that for >90% of established libp2p connections, the first connection attempt succeeds,
leading a dramatic decrease in the number of aborted connection attempts.

We also added new metrics to the swarm Grafana dashboard, showing:
* The number of connection attempts it took to establish a connection
* The delay introduced by the ranking logic

This feature should be safe to enable for nodes running in data centers and for most nodes in home networks.
However, there are some (mostly home and corporate networks) that block all UDP traffic. If enabled, the current implementation
of the smart dialing logic will lead to a regression, since it preferes QUIC addresses over TCP addresses. Nodes would still be
able to connect, but connection establishment of the TCP connection would be delayed by 250ms.

In a future release (see #1605 for details), we will introduce a feature called blackhole detection. By observing the outcome of
QUIC connection attempts, we can determine if UDP traffic is blocked (namely, if all QUIC connection attempts fail), and stop
dialing QUIC in this case altogether. Once this detection logic is in place, smart dialing will be enabled by default.

### More Metrics! <!-- omit in toc -->
Since the last release, we've added metrics for:
* [Holepunching](https://github.com/libp2p/go-libp2p/pull/2246)
* Smart Dialing (see above)

### WebTransport <!-- omit in toc -->
* [#2251](https://github.com/libp2p/go-libp2p/pull/2251): Infer public WebTransport address from `quic-v1` addresses if both transports are using the same port for both quic-v1 and WebTransport addresses.
* [#2271](https://github.com/libp2p/go-libp2p/pull/2271): Only add certificate hashes to WebTransport mulitaddress if listening on WebTransport

## Housekeeping updates <!-- omit in toc -->
* Identify
  * [#2303](https://github.com/libp2p/go-libp2p/pull/2303): Don't send default protocol version
  * Prevent polluting PeerStore with local addrs
    * [#2325](https://github.com/libp2p/go-libp2p/pull/2325): Don't save signed peer records
    * [#2300](https://github.com/libp2p/go-libp2p/pull/2300): Filter received addresses based on the node's remote address
* WebSocket
  * [#2280](https://github.com/libp2p/go-libp2p/pull/2280): Reverted back to the Gorilla library for WebSocket
* NAT
  * [#2248](https://github.com/libp2p/go-libp2p/pull/2248): Move NAT mapping logic out of the host

## 🐞 Bugfixes <!-- omit in toc -->
* Identify
  * [Reject signed peer records on peer ID mismatch](https://github.com/libp2p/go-libp2p/commit/8d771355b41297623e05b04a865d029a2522a074)
  * [#2299](https://github.com/libp2p/go-libp2p/pull/2299): Avoid spuriously pushing updates
* Swarm
  * [#2322](https://github.com/libp2p/go-libp2p/pull/2322): Dedup addresses to dial
  * [#2284](https://github.com/libp2p/go-libp2p/pull/2284): Change maps with multiaddress keys to use strings
* QUIC
  * [#2262](https://github.com/libp2p/go-libp2p/pull/2262): Prioritize listen connections for reuse
  * [#2276](https://github.com/libp2p/go-libp2p/pull/2276): Don't panic when quic-go's accept call errors
  * [#2263](https://github.com/libp2p/go-libp2p/pull/2263): Fix race condition when generating random holepunch packet

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.27.0...v0.28.0

# [v0.27.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.27.0)

### Breaking Changes <!-- omit in toc -->

* The `LocalPrivateKey` method was removed from the `network.Conn` interface. [#2144](https://github.com/libp2p/go-libp2p/pull/2144)

## 🔦 Highlights <!-- omit in toc -->

### Additional metrics <!-- omit in toc -->
Since the last release, we've added metrics for:
* [Relay Service](https://github.com/libp2p/go-libp2p/pull/2154): RequestStatus, RequestCounts, RejectionReasons for Reservation and Connection Requests,
ConnectionDuration, BytesTransferred, Relay Service Status.
* [Autorelay](https://github.com/libp2p/go-libp2p/pull/2185): relay finder status, reservation request outcomes, current reservations, candidate circuit v2 support, current candidates, relay addresses updated, num relay address, and scheduled work times

## 🐞 Bugfixes <!-- omit in toc -->

* autonat: don't change status on dial request refused [2225](https://github.com/libp2p/go-libp2p/pull/2225)
* relaysvc: fix flaky TestReachabilityChangeEvent [2215](https://github.com/libp2p/go-libp2p/pull/2215)
* basichost: prevent duplicate dials [2196](https://github.com/libp2p/go-libp2p/pull/2196)
* websocket: don't set a WSS multiaddr for accepted unencrypted conns [2199](https://github.com/libp2p/go-libp2p/pull/2199)
* identify: Fix IdentifyWait when Connected events happen out of order [2173](https://github.com/libp2p/go-libp2p/pull/2173)
* circuitv2: cleanup relay service properly [2164](https://github.com/libp2p/go-libp2p/pull/2164)

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.26.4...v0.27.0

# [v0.26.4](https://github.com/libp2p/go-libp2p/releases/tag/v0.26.4)

This patch release fixes a busy-looping happening inside AutoRelay on private nodes, see [2208](https://github.com/libp2p/go-libp2p/pull/2208).

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.26.0...v0.26.4

# [v0.26.3](https://github.com/libp2p/go-libp2p/releases/tag/v0.26.3)

* rcmgr: fix JSON marshalling of ResourceManagerStat peer map [2156](https://github.com/libp2p/go-libp2p/pull/2156)
* websocket: Don't limit message sizes in the websocket reader [2193](https://github.com/libp2p/go-libp2p/pull/2193)

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.26.0...v0.26.3

# [v0.26.2](https://github.com/libp2p/go-libp2p/releases/tag/v0.26.2)

This patch release fixes two bugs:
* A panic in WebTransport: https://github.com/quic-go/webtransport-go/releases/tag/v0.5.2
* Incorrect accounting of accepted connections in the swarm metrics: [#2147](https://github.com/libp2p/go-libp2p/pull/2147)

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.26.0...v0.26.2

# v0.26.1

This version was retracted due to errors when publishing the release.

# [v0.26.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.26.0)

## 🔦 Highlights <!-- omit in toc -->

### Circuit Relay Changes <!-- omit in toc -->

#### [Removed Circuit Relay v1](https://github.com/libp2p/go-libp2p/pull/2107) <!-- omit in toc -->

We've decided to remove support for Circuit Relay v1 in this release. v1 Relays have been retired a few months ago. Notably, running the Relay v1 protocol was expensive and resulted in only a small number of nodes in the network. Users had to either manually configure these nodes as static relays, or discover them from the DHT.
Furthermore, rust-libp2p [has dropped support](https://github.com/libp2p/rust-libp2p/pull/2549) and js-libp2p [is dropping support](https://github.com/libp2p/js-libp2p/pull/1533) for Relay v1.

Support for Relay v2 was first added in [late 2021 in v0.16.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.16.0). With Circuit Relay v2 it became cheap to run (limited) relays. Public nodes also started the relay service by default. There's now a massive number of Relay v2 nodes on the IPFS network, and they don't advertise their service to the DHT any more. Because there's now so many of these nodes, connecting to just a small number of nodes (e.g. by joining the DHT), a node is statistically guaranteed to connect to some relays.

#### [Unlimited Relay v2](https://github.com/libp2p/go-libp2p/pull/2125) <!-- omit in toc -->

In conjunction with removing relay v1, we also added an option to Circuit Relay v2 to disable limits.
This done by enabling `WithInfiniteLimits`. When enabled this allows for users to have a drop in replacement for Relay v1 with Relay v2.

### Additional metrics <!-- omit in toc -->

Since the last release, we've added additional metrics to different components.
Metrics were added to:
* [AutoNat](https://github.com/libp2p/go-libp2p/pull/2086): Current Reachability Status and Confidence, Client and Server DialResponses, Server DialRejections. The dashboard is [available here](https://github.com/libp2p/go-libp2p/blob/master/dashboards/autonat/autonat.json).
* Swarm:
  - [Early Muxer Selection](https://github.com/libp2p/go-libp2p/pull/2119): Added early_muxer label indicating whether a connection was established using early muxer selection.
  - [IP Version](https://github.com/libp2p/go-libp2p/pull/2114): Added ip_version label to connection metrics
* Identify:
  - Metrics for Identify, IdentifyPush, PushesTriggered (https://github.com/libp2p/go-libp2p/pull/2069)
  - Address Count, Protocol Count, Connection IDPush Support (https://github.com/libp2p/go-libp2p/pull/2126)


We also migrated the metric dashboards to a top-level [dashboards](https://github.com/libp2p/go-libp2p/tree/master/dashboards) directory.

## 🐞 Bugfixes <!-- omit in toc -->

### AutoNat <!-- omit in toc -->
* [Fixed a bug](https://github.com/libp2p/go-libp2p/issues/2091) where AutoNat would emit events when the observed address has changed even though the node reachability hadn't changed.

### Relay Manager <!-- omit in toc -->
* [Fixed a bug](https://github.com/libp2p/go-libp2p/pull/2093) where the Relay Manager started a new relay even though the previous reachability was `Public` or if a relay already existed.

### [Stop sending detailed error messages on closing QUIC connections](https://github.com/libp2p/go-libp2p/pull/2112) <!-- omit in toc -->

Users reported seeing confusing error messages and could not determine the root cause or if the error was from a local or remote peer:

```{12D... Application error 0x0: conn-27571160: system: cannot reserve inbound connection: resource limit exceeded}```

This error occurred when a connection had been made with a remote peer but the remote peer dropped the connection (due to it exceeding limits).
This was actually an `Application error` emitted by `quic-go` and it was a bug in go-libp2p that we sent the whole message.
For now, we decided to stop sending this confusing error message. In the future, we will report such errors via [error codes](https://github.com/libp2p/specs/issues/479).

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.25.1...v0.26.0

# [v0.25.1](https://github.com/libp2p/go-libp2p/releases/tag/v0.25.1)

Fix some test-utils used by https://github.com/libp2p/go-libp2p-kad-dht

* mocknet: Start host in mocknet by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2078
* chore: update go-multistream by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2081

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.25.0...v0.25.1

# [v0.25.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.25.0)

## 🔦 Highlights <!-- omit in toc -->

### Metrics <!-- omit in toc -->

We've started instrumenting the entire stack. In this release, we're adding metrics for:
* the swarm: tracking incoming and outgoing connections, transports, security protocols and stream multiplexers in use: (https://github.com/libp2p/go-libp2p/blob/master/dashboards/swarm/swarm.json)
* the event bus: tracking how different events are propagated through the stack and to external consumers (https://github.com/libp2p/go-libp2p/blob/master/dashboards/eventbus/eventbus.json)

Our metrics effort is still ongoing, see https://github.com/libp2p/go-libp2p/issues/1356 for progress. We'll add metrics and dashboards for more libp2p components in a future release.

### Switching to Google's official Protobuf compiler <!-- omit in toc -->

So far, we were using GoGo Protobuf to compile our Protobuf definitions to Go code. However, this library was deprecated in October last year: https://twitter.com/awalterschulze/status/1584553056100057088. We [benchmarked](https://github.com/libp2p/go-libp2p/issues/1976#issuecomment-1371527732) serialization and deserialization, and found that it's (only) 20% slower than GoGo. Since the vast majority of go-libp2p's CPU time is spent in code paths other than Protobuf handling, switching to the official compiler seemed like a worthwhile tradeoff.

### Removal of OpenSSL <!-- omit in toc -->

Before this release, go-libp2p had an option to use OpenSSL bindings for certain cryptographic primitives, mostly to speed up the generation of signatures and their verification. When building go-libp2p using `go build`, we'd use the standard library crypto packages. OpenSSL was only used when passing in a build tag: `go build -tags openssl`.
Maintaining our own fork of the long unmaintained [go-openssl package](https://github.com/libp2p/go-openssl) has proven to place a larger than expected maintenance burden on the libp2p stewards, and when we recently discovered a range of new bugs ([this](https://github.com/libp2p/go-openssl/issues/38) and [this](https://github.com/libp2p/go-libp2p/issues/1892) and [this](https://github.com/libp2p/go-libp2p/issues/1951)), we decided to re-evaluate if this code path is really worth it. The results surprised us, it turns out that:
* The Go standard library is faster than OpenSSL for all key types that are not RSA.
* Verifying RSA signatures is as fast as Ed25519 signatures using the Go standard library, and even faster in OpenSSL.
* Generating RSA signatures is painfully slow, both using Go standard library crypto and using OpenSSL (but even slower using Go standard library).

Now the good news is, that if your node is not using an RSA key, it will never create any RSA signatures (it might need to verify them though, when it connects to a node that uses RSA keys). If you're concerned about CPU performance, it's a good idea to avoid RSA keys (the same applies to bandwidth, RSA keys are huge!). Even for nodes using RSA keys, it turns out that generating the signatures is not a significant part of their CPU load, as verified by profiling one of Kubo's bootstrap nodes.

We therefore concluded that it's safe to drop this code path altogether, and thereby reduce our maintenance burden.

### New Resource Manager types <!-- omit in toc -->

* Introduces a new type `LimitVal` which can explicitly specify "use default", "unlimited", "block all", as well as any positive number. The zero value of `LimitVal` (the value when you create the object in Go) is "Use default".
  * The JSON marshalling of this is straightforward.
* Introduces a new `ResourceLimits` type which uses `LimitVal` instead of ints so it can encode the above for the resources.
* Changes `LimitConfig` to `PartialLimitConfig` and uses `ResourceLimits`. This along with the marshalling changes means you can now marshal the fact that some resource limit is set to block all.
  * Because the default is to use the defaults, this avoids the footgun of initializing the resource manager with 0 limits (that would block everything).

In general, you can go from a resource config with defaults to a concrete one with `.Build()`. e.g. `ResourceLimits.Build() => BaseLimit`, `PartialLimitConfig.Build() => ConcreteLimitConfig`, `LimitVal.Build() => int`. See PR #2000 for more details.

If you're using the defaults for the resource manager, there should be no changes needed.

### Other Breaking Changes <!-- omit in toc -->

We've cleaned up our API to consistently use `protocol.ID` for libp2p and application protocols. Specifically, this means that the peer store now uses `protocol.ID`s, and the host's `SetStreamHandler` as well.

## What's Changed <!-- omit in toc -->
* chore: use generic LRU cache by @muXxer in https://github.com/libp2p/go-libp2p/pull/1980
* core/crypto: drop all OpenSSL code paths by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1953
* add WebTransport to the list of default transports by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1915
* identify: remove old code targeting Go 1.17 by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1964
* core: remove introspection package by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1978
* identify: remove support for Identify Delta by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1975
* roadmap: remove optimizations of the TCP-based handshake by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1959
* circuitv2: correctly set the transport in the ConnectionState by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1972
* switch to Google's Protobuf library, make protobufs compile with go generate by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1979
* ci: run go generate as part of the go-check workflow by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1986
* ci: use GitHub token to install protoc by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1996
* feat: add some users to the readme by @p-shahi in https://github.com/libp2p/go-libp2p/pull/1981
* CI: Fast multidimensional Interop tests by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/1991
* Fix: Ignore zero values when marshalling Limits. by @ajnavarro in https://github.com/libp2p/go-libp2p/pull/1998
* feat: add ci flakiness score to readme by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2002
* peerstore: make it possible to use an empty peer ID by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2006
* feat: rcmgr: Export resource manager errors by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2008
* feat: ci test-plans: Parse test timeout parameter for interop test by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2014
* Clean addresses with peer id before adding to addrbook by @sukunrt in https://github.com/libp2p/go-libp2p/pull/2007
* Expose muxer ids by @aschmahmann in https://github.com/libp2p/go-libp2p/pull/2012
* swarm: add a basic metrics tracer by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1973
* consistently use protocol.ID instead of strings by @sukunrt in https://github.com/libp2p/go-libp2p/pull/2004
* swarm metrics: fix datasource for dashboard by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2024
* chore: remove textual roadmap in favor for Starmap by @p-shahi in https://github.com/libp2p/go-libp2p/pull/2036
* rcmgr: *: Always close connscope by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2037
* chore: remove license files from the eventbus package by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2042
* Migrate to test-plan composite action by @thomaseizinger in https://github.com/libp2p/go-libp2p/pull/2039
* use quic-go and webtransport-go from quic-go organization by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2040
* holepunch: fix flaky test by not removing holepunch protocol handler by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1948
* quic / webtransport: extend test to test dialing a draft-29 and a v1  by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1957
* p2p/test: add test for EvtLocalAddressesUpdated event by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2016
* quic, tcp: only register Prometheus counters when metrics are enabled by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1971
* p2p/test: fix flaky notification test by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2051
* quic: disable sending of Version Negotiation packets by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2015
* eventbus: add metrics by @sukunrt in https://github.com/libp2p/go-libp2p/pull/2038
* metrics: use a single slice pool for all metrics tracer by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2054
* webtransport: tidy up some test output by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2053
* set names for eventbus event subscriptions by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2057
* autorelay: Split libp2p.EnableAutoRelay into 2 functions by @sukunrt in https://github.com/libp2p/go-libp2p/pull/2022
* rcmgr: Use prometheus SDK for rcmgr metrics by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2044
* websocket: Replace gorilla websocket transport with nhooyr websocket transport by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/1982
* rcmgr: add libp2p prefix to all metrics by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2063
* chore: git-ignore various flavors of qlog files by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2064
* interop: Update interop test to match spec by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2049
* chore: update webtransport-go to v0.5.1 by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2072
* identify: refactor sending of Identify pushes by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/1984
* feat!: rcmgr: Change LimitConfig to use LimitVal type by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2000
* p2p/test/quic: use contexts with a timeout for Connect calls by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2070
* identify: add some basic metrics by @marten-seemann in https://github.com/libp2p/go-libp2p/pull/2069
* chore: Release v0.25.0 by @MarcoPolo in https://github.com/libp2p/go-libp2p/pull/2077

## New Contributors <!-- omit in toc -->
* @muXxer made their first contribution in https://github.com/libp2p/go-libp2p/pull/1980
* @ajnavarro made their first contribution in https://github.com/libp2p/go-libp2p/pull/1998
* @sukunrt made their first contribution in https://github.com/libp2p/go-libp2p/pull/2007
* @thomaseizinger made their first contribution in https://github.com/libp2p/go-libp2p/pull/2039

**Full Changelog**: https://github.com/libp2p/go-libp2p/compare/v0.24.2...v0.25.0


================================================
FILE: FUNDING.json
================================================
{
    "opRetro": {
      "projectId": "0xc71faa1bcb4ceb785816c3f22823377e9e5e7c48649badd9f0a0ce491f20d4b3"
    },
    "drips": {
      "filecoin": {
        "ownedBy": "0xEF22379b7527762a00FC5820AF55BdE363624f03"
      }
    }
  }


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2014 Juan Batiz-Benet

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: README.md
================================================

<h1 align="center">
  <a href="https://libp2p.io/"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/black-bg-2.png?raw=true" alt="libp2p hex logo" /></a>
</h1>

<h3 align="center">The Go implementation of the libp2p Networking Stack.</h3>

<p align="center">
  <a href="http://protocol.ai"><img src="https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square" /></a>
  <a href="http://libp2p.io/"><img src="https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square" /></a>
  <a href="https://pkg.go.dev/github.com/libp2p/go-libp2p"><img src="https://pkg.go.dev/badge/github.com/libp2p/go-libp2p.svg" alt="Go Reference"></a>
  <a href="https://discuss.libp2p.io"><img src="https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg"/></a>
  <a href="https://marcopolo.github.io/FlakyTests/"><img src="https://marcopolo.github.io/FlakyTests/current-score.svg"/></a>
</p>

# Table of Contents <!-- omit in toc -->
- [Background](#background)
- [Usage](#usage)
  - [Examples](#examples)
  - [Dashboards](#dashboards)
- [Contribute](#contribute)
  - [Supported Go Versions](#supported-go-versions)
- [Notable Users](#notable-users)

# Background

[libp2p](https://github.com/libp2p/specs) is a networking stack and library modularized out of [The IPFS Project](https://github.com/ipfs/ipfs), and bundled separately for other tools to use.
>
libp2p is the product of a long, and arduous quest of understanding -- a deep dive into the internet's network stack, and plentiful peer-to-peer protocols from the past. Building large-scale peer-to-peer systems has been complex and difficult in the last 15 years, and libp2p is a way to fix that. It is a "network stack" -- a protocol suite -- that cleanly separates concerns, and enables sophisticated applications to only use the protocols they absolutely need, without giving up interoperability and upgradeability. libp2p grew out of IPFS, but it is built so that lots of people can use it, for lots of different projects.

To learn more, check out the following resources:
- [**Our documentation**](https://docs.libp2p.io)
- [**Our community discussion forum**](https://discuss.libp2p.io)
- [**The libp2p Specification**](https://github.com/libp2p/specs)
- [**js-libp2p implementation**](https://github.com/libp2p/js-libp2p)
- [**rust-libp2p implementation**](https://github.com/libp2p/rust-libp2p)

# Usage

This repository (`go-libp2p`) serves as the entrypoint to the universe of packages that compose the Go implementation of the libp2p stack.

You can start using go-libp2p in your Go application simply by adding imports from our repos, e.g.:

```go
import "github.com/libp2p/go-libp2p"
```

## Examples

Examples can be found in the [examples folder](examples).

## Dashboards

We provide prebuilt Grafana dashboards so that applications can better monitor libp2p in production.
You can find the [dashboard JSON files here](https://github.com/libp2p/go-libp2p/tree/master/dashboards).

We also have live [Public Dashboards](https://github.com/libp2p/go-libp2p/tree/master/dashboards/README.md#public-dashboards) that you can check out to see real time monitoring in action.


# Contribute

go-libp2p is MIT-licensed open source software. We welcome contributions big and small! Take a look at the [community contributing notes](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md). Please make sure to check the [issues](https://github.com/libp2p/go-libp2p/issues). Search the closed ones before reporting things, and help us with the open ones.

Guidelines:

- read the [libp2p spec](https://github.com/libp2p/specs)
- for general questions, use our [discussion forum](https://github.com/libp2p/go-libp2p/discussions)
- for bug reports, open an [issue](https://github.com/libp2p/go-libp2p/issues)
- for development questions of go-libp2p itself, please join the [mailing list](mailto:go+subscribe@libp2p.io)
- chat at [#libp2p on Libera Chat](https://web.libera.chat/gamja/?channel=#libp2p)
- ensure you are able to contribute (no legal issues please -- we use the DCO)
- get in touch with @libp2p/go-libp2p-maintainers about how best to contribute
- No drive-by contributions seeking to collect airdrops.
  - Many projects aim to reward contributors to common goods. Great. However,
    this creates an unfortunate incentive for low-effort PRs, submitted solely to
    claim rewards. These PRs consume maintainers’ time and energy to triage, with
    little to no impact on end users. If we suspect this is the intent of a PR,
    we may close it without comment. If you believe this was done in error,
    contact us via email. Reference this README section and explain why your PR
    is not a “drive-by contribution.”
- have fun!

There's a few things you can do right now to help out:
 - **Perform code reviews**.
 - **Add tests**. There can never be enough tests.
 - Go through the modules below 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.

## AI Assistance Notice

> [!IMPORTANT]
>
> If you are using **any kind of AI assistance** to contribute to libp2p,
> it must be disclosed in the pull request.

If you are using any kind of AI assistance while contributing to libp2p,
**this must be disclosed in the pull request**, along with the extent to
which AI assistance was used (e.g. docs only vs. code generation).
If PR responses are being generated by an AI, disclose that as well.
As a small exception, trivial tab-completion doesn't need to be disclosed,
so long as it is limited to single keywords or short phrases.

An example disclosure:

> This PR was written primarily by Claude Code.

Or a more detailed disclosure:

> I consulted ChatGPT to understand the codebase but the solution
> was fully authored manually by myself.

Failure to disclose this is first and foremost rude to the human operators
on the other end of the pull request, but it also makes it difficult to
determine how much scrutiny to apply to the contribution.

In a perfect world, AI assistance would produce equal or higher quality
work than any human. That isn't the world we live in today, and in most cases
it's generating slop. I say this despite being a fan of and using them
successfully myself (with heavy supervision)!

Please be respectful to maintainers and disclose AI assistance.

# Supported Go Versions

We test against and support the two most recent major releases of Go. This is
informed by Go's own [security policy](https://go.dev/doc/security/policy).

# Notable Users
Some notable users of go-libp2p are:
- [Kubo](https://github.com/ipfs/kubo) - The original Go implementation of IPFS
- [Lotus](https://github.com/filecoin-project/lotus) - An implementation of the Filecoin protocol
- [Prysm](https://github.com/prysmaticlabs/prysm) - An Ethereum Beacon Chain consensus client built by [Prysmatic Labs](https://prysmaticlabs.com/)
- [Berty](https://github.com/berty/berty) - An open, secure, offline-first, peer-to-peer and zero trust messaging app.
- [Wasp](https://github.com/iotaledger/wasp) - A node that runs IOTA Smart Contracts built by the [IOTA Foundation](https://www.iota.org/)
- [Mina](https://github.com/minaprotocol/mina) - A lightweight, constant-sized blockchain that runs zero-knowledge smart contracts
- [Polygon Edge](https://github.com/0xPolygon/polygon-edge) - A modular, extensible framework for building Ethereum compatible networks
- [Celestia Node](https://github.com/celestiaorg/celestia-node) - The Go implementation of Celestia's data availability nodes
- [Status go](https://github.com/status-im/status-go) - Status bindings for go-ethereum, built by [Status.im](https://status.im/)
- [Flow](https://github.com/onflow/flow-go) - A blockchain built to support games, apps, and digital assets built by [Dapper Labs](https://www.dapperlabs.com/)
- [Swarm Bee](https://github.com/ethersphere/bee) - A client for connecting to the [Swarm network](https://www.ethswarm.org/)
- [MultiversX Node](https://github.com/multiversx/mx-chain-go) - The Go implementation of the MultiversX network protocol
- [Sonr](https://github.com/sonr-io/sonr) - A platform to integrate DID Documents, WebAuthn, and IPFS and manage digital identity and assets.
- [EdgeVPN](https://github.com/mudler/edgevpn) - A decentralized, immutable, portable VPN and reverse proxy over p2p.
- [Kairos](https://github.com/kairos-io/kairos) - A Kubernetes-focused, Cloud Native Linux meta-distribution.
- [Oasis Core](https://github.com/oasisprotocol/oasis-core) - The consensus and runtime layers of the [Oasis protocol](https://oasisprotocol.org/).
- [Spacemesh](https://github.com/spacemeshos/go-spacemesh/) - The Go implementation of the [Spacemesh protocol](https://spacemesh.io/), a novel layer one blockchain
- [Tau](https://github.com/taubyte/tau/) - Open source distributed Platform as a Service (PaaS)

Please open a pull request if you want your project (min. 250 GitHub stars) to be added here.


================================================
FILE: SECURITY.md
================================================
# Security Policy

go-libp2p is still in development. This means that there may be problems in our protocols,
or there may be mistakes in our implementations.
We take security vulnerabilities very seriously. If you discover a security issue,
please bring it to our attention right away!

## Reporting a Vulnerability

If you find a vulnerability that may affect live deployments -- for example, by exposing
a remote execution exploit -- please [**report privately**](https://github.com/libp2p/go-libp2p/security/advisories/new).
Please **DO NOT file a public issue**.

If the issue is an implementation weakness that cannot be immediately exploited or
something not yet deployed, just discuss it openly.
If you need assistance, please reach out to [security@libp2p.io](mailto:security@libp2p.io).

## Reporting a non security bug

For non-security bugs, please simply file a GitHub [issue](https://github.com/libp2p/go-libp2p/issues/new).


================================================
FILE: config/config.go
================================================
package config

import (
	"context"
	"crypto/rand"
	"errors"
	"fmt"
	"net"
	"slices"
	"time"

	"github.com/libp2p/go-libp2p/core/connmgr"
	"github.com/libp2p/go-libp2p/core/crypto"
	"github.com/libp2p/go-libp2p/core/event"
	"github.com/libp2p/go-libp2p/core/host"
	"github.com/libp2p/go-libp2p/core/metrics"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/peerstore"
	"github.com/libp2p/go-libp2p/core/pnet"
	"github.com/libp2p/go-libp2p/core/protocol"
	"github.com/libp2p/go-libp2p/core/routing"
	"github.com/libp2p/go-libp2p/core/sec"
	"github.com/libp2p/go-libp2p/core/transport"
	logging "github.com/libp2p/go-libp2p/gologshim"
	"github.com/libp2p/go-libp2p/p2p/host/autonat"
	"github.com/libp2p/go-libp2p/p2p/host/autorelay"
	bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
	blankhost "github.com/libp2p/go-libp2p/p2p/host/blank"
	"github.com/libp2p/go-libp2p/p2p/host/eventbus"
	"github.com/libp2p/go-libp2p/p2p/host/observedaddrs"
	"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
	rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
	routed "github.com/libp2p/go-libp2p/p2p/host/routed"
	"github.com/libp2p/go-libp2p/p2p/net/swarm"
	tptu "github.com/libp2p/go-libp2p/p2p/net/upgrader"
	"github.com/libp2p/go-libp2p/p2p/protocol/autonatv2"
	circuitv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
	relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay"
	"github.com/libp2p/go-libp2p/p2p/protocol/holepunch"
	"github.com/libp2p/go-libp2p/p2p/protocol/identify"
	"github.com/libp2p/go-libp2p/p2p/security/insecure"
	"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
	"github.com/libp2p/go-libp2p/p2p/transport/tcpreuse"
	libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
	"github.com/prometheus/client_golang/prometheus"

	ma "github.com/multiformats/go-multiaddr"
	manet "github.com/multiformats/go-multiaddr/net"
	"github.com/quic-go/quic-go"
	"go.uber.org/fx"
	"go.uber.org/fx/fxevent"
)

var log = logging.Logger("p2p-config")

// AddrsFactory is a function that takes a set of multiaddrs we're listening on and
// returns the set of multiaddrs we should advertise to the network.
type AddrsFactory = bhost.AddrsFactory

// NATManagerC is a NATManager constructor.
type NATManagerC func(network.Network) bhost.NATManager

type RoutingC func(host.Host) (routing.PeerRouting, error)

// AutoNATConfig defines the AutoNAT behavior for the libp2p host.
type AutoNATConfig struct {
	ForceReachability   *network.Reachability
	EnableService       bool
	ThrottleGlobalLimit int
	ThrottlePeerLimit   int
	ThrottleInterval    time.Duration
}

type Security struct {
	ID          protocol.ID
	Constructor any
}

// Config describes a set of settings for a libp2p node
//
// This is *not* a stable interface. Use the options defined in the root
// package.
type Config struct {
	// UserAgent is the identifier this node will send to other peers when
	// identifying itself, e.g. via the identify protocol.
	//
	// Set it via the UserAgent option function.
	UserAgent string

	// ProtocolVersion is the protocol version that identifies the family
	// of protocols used by the peer in the Identify protocol. It is set
	// using the [ProtocolVersion] option.
	ProtocolVersion string

	PeerKey crypto.PrivKey

	QUICReuse          []fx.Option
	Transports         []fx.Option
	Muxers             []tptu.StreamMuxer
	SecurityTransports []Security
	Insecure           bool
	PSK                pnet.PSK

	DialTimeout time.Duration

	RelayCustom bool
	Relay       bool // should the relay transport be used

	EnableRelayService bool // should we run a circuitv2 relay (if publicly reachable)
	RelayServiceOpts   []relayv2.Option

	ListenAddrs     []ma.Multiaddr
	AddrsFactory    bhost.AddrsFactory
	ConnectionGater connmgr.ConnectionGater

	ConnManager     connmgr.ConnManager
	ResourceManager network.ResourceManager

	NATManager NATManagerC
	Peerstore  peerstore.Peerstore
	Reporter   metrics.Reporter

	MultiaddrResolver network.MultiaddrDNSResolver

	DisablePing bool

	Routing RoutingC

	EnableAutoRelay bool
	AutoRelayOpts   []autorelay.Option
	AutoNATConfig

	EnableHolePunching  bool
	HolePunchingOptions []holepunch.Option

	DisableMetrics       bool
	PrometheusRegisterer prometheus.Registerer

	DialRanker network.DialRanker

	SwarmOpts []swarm.Option

	DisableIdentifyAddressDiscovery bool

	EnableAutoNATv2 bool

	UDPBlackHoleSuccessCounter        *swarm.BlackHoleSuccessCounter
	CustomUDPBlackHoleSuccessCounter  bool
	IPv6BlackHoleSuccessCounter       *swarm.BlackHoleSuccessCounter
	CustomIPv6BlackHoleSuccessCounter bool

	UserFxOptions []fx.Option

	ShareTCPListener bool
}

func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swarm, error) {
	if cfg.Peerstore == nil {
		return nil, fmt.Errorf("no peerstore specified")
	}

	// Check this early. Prevents us from even *starting* without verifying this.
	if pnet.ForcePrivateNetwork && len(cfg.PSK) == 0 {
		log.Error("tried to create a libp2p node with no Private Network Protector but usage of Private Networks is forced by the environment")
		// Note: This is *also* checked the upgrader itself, so it'll be
		// enforced even *if* you don't use the libp2p constructor.
		return nil, pnet.ErrNotInPrivateNetwork
	}

	if cfg.PeerKey == nil {
		return nil, fmt.Errorf("no peer key specified")
	}

	// Obtain Peer ID from public key
	pid, err := peer.IDFromPublicKey(cfg.PeerKey.GetPublic())
	if err != nil {
		return nil, err
	}

	if err := cfg.Peerstore.AddPrivKey(pid, cfg.PeerKey); err != nil {
		return nil, err
	}
	if err := cfg.Peerstore.AddPubKey(pid, cfg.PeerKey.GetPublic()); err != nil {
		return nil, err
	}

	opts := append(cfg.SwarmOpts,
		swarm.WithUDPBlackHoleSuccessCounter(cfg.UDPBlackHoleSuccessCounter),
		swarm.WithIPv6BlackHoleSuccessCounter(cfg.IPv6BlackHoleSuccessCounter),
	)
	if cfg.Reporter != nil {
		opts = append(opts, swarm.WithMetrics(cfg.Reporter))
	}
	if cfg.ConnectionGater != nil {
		opts = append(opts, swarm.WithConnectionGater(cfg.ConnectionGater))
	}
	if cfg.DialTimeout != 0 {
		opts = append(opts, swarm.WithDialTimeout(cfg.DialTimeout))
	}
	if cfg.ResourceManager != nil {
		opts = append(opts, swarm.WithResourceManager(cfg.ResourceManager))
	}
	if cfg.MultiaddrResolver != nil {
		opts = append(opts, swarm.WithMultiaddrResolver(cfg.MultiaddrResolver))
	}
	if cfg.DialRanker != nil {
		opts = append(opts, swarm.WithDialRanker(cfg.DialRanker))
	}

	if enableMetrics {
		opts = append(opts,
			swarm.WithMetricsTracer(swarm.NewMetricsTracer(swarm.WithRegisterer(cfg.PrometheusRegisterer))))
	}
	// TODO: Make the swarm implementation configurable.
	return swarm.NewSwarm(pid, cfg.Peerstore, eventBus, opts...)
}

func (cfg *Config) makeAutoNATV2Host() (host.Host, error) {
	autonatPrivKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
	if err != nil {
		return nil, err
	}
	ps, err := pstoremem.NewPeerstore()
	if err != nil {
		return nil, err
	}

	autoNatCfg := Config{
		Transports:                  cfg.Transports,
		Muxers:                      cfg.Muxers,
		SecurityTransports:          cfg.SecurityTransports,
		Insecure:                    cfg.Insecure,
		PSK:                         cfg.PSK,
		ConnectionGater:             cfg.ConnectionGater,
		Reporter:                    cfg.Reporter,
		PeerKey:                     autonatPrivKey,
		Peerstore:                   ps,
		DialRanker:                  swarm.NoDelayDialRanker,
		UDPBlackHoleSuccessCounter:  cfg.UDPBlackHoleSuccessCounter,
		IPv6BlackHoleSuccessCounter: cfg.IPv6BlackHoleSuccessCounter,
		ResourceManager:             cfg.ResourceManager,
		SwarmOpts: []swarm.Option{
			// Don't update black hole state for failed autonat dials
			swarm.WithReadOnlyBlackHoleDetector(),
		},
	}
	fxopts, err := autoNatCfg.addTransports()
	if err != nil {
		return nil, err
	}
	var dialerHost host.Host
	fxopts = append(fxopts,
		fx.Provide(eventbus.NewBus),
		fx.Provide(func(lifecycle fx.Lifecycle, b event.Bus) (*swarm.Swarm, error) {
			lifecycle.Append(fx.Hook{
				OnStop: func(context.Context) error {
					return ps.Close()
				}})
			sw, err := autoNatCfg.makeSwarm(b, false)
			return sw, err
		}),
		fx.Provide(func(sw *swarm.Swarm) *blankhost.BlankHost {
			return blankhost.NewBlankHost(sw)
		}),
		fx.Provide(func(bh *blankhost.BlankHost) host.Host {
			return bh
		}),
		fx.Provide(func() crypto.PrivKey { return autonatPrivKey }),
		fx.Provide(func(bh host.Host) peer.ID { return bh.ID() }),
		fx.Invoke(func(bh *blankhost.BlankHost) {
			dialerHost = bh
		}),
	)
	app := fx.New(fxopts...)
	if err := app.Err(); err != nil {
		return nil, err
	}
	err = app.Start(context.Background())
	if err != nil {
		return nil, err
	}
	go func() {
		<-dialerHost.Network().(*swarm.Swarm).Done()
		app.Stop(context.Background())
	}()
	return dialerHost, nil
}

func (cfg *Config) addTransports() ([]fx.Option, error) {
	fxopts := []fx.Option{
		fx.WithLogger(func() fxevent.Logger {
			return &fxevent.SlogLogger{
				Logger: log.With("system", "fx"),
			}
		}),
		fx.Provide(fx.Annotate(tptu.New, fx.ParamTags(`name:"security"`))),
		fx.Supply(cfg.Muxers),
		fx.Provide(func() connmgr.ConnectionGater { return cfg.ConnectionGater }),
		fx.Provide(func() pnet.PSK { return cfg.PSK }),
		fx.Provide(func() network.ResourceManager { return cfg.ResourceManager }),
		fx.Provide(func(upgrader transport.Upgrader) *tcpreuse.ConnMgr {
			if !cfg.ShareTCPListener {
				return nil
			}
			return tcpreuse.NewConnMgr(tcpreuse.EnvReuseportVal, upgrader)
		}),
		fx.Provide(func(cm *quicreuse.ConnManager, sw *swarm.Swarm) libp2pwebrtc.ListenUDPFn {
			hasQuicAddrPortFor := func(network string, laddr *net.UDPAddr) bool {
				quicAddrPorts := map[string]struct{}{}
				for _, addr := range sw.ListenAddresses() {
					if _, err := addr.ValueForProtocol(ma.P_QUIC_V1); err == nil {
						netw, addr, err := manet.DialArgs(addr)
						if err != nil {
							return false
						}
						quicAddrPorts[netw+"_"+addr] = struct{}{}
					}
				}
				_, ok := quicAddrPorts[network+"_"+laddr.String()]
				return ok
			}

			return func(network string, laddr *net.UDPAddr) (net.PacketConn, error) {
				if hasQuicAddrPortFor(network, laddr) {
					return cm.SharedNonQUICPacketConn(network, laddr)
				}
				return net.ListenUDP(network, laddr)
			}
		}),
	}
	fxopts = append(fxopts, cfg.Transports...)
	if cfg.Insecure {
		fxopts = append(fxopts,
			fx.Provide(
				fx.Annotate(
					func(id peer.ID, priv crypto.PrivKey) []sec.SecureTransport {
						return []sec.SecureTransport{insecure.NewWithIdentity(insecure.ID, id, priv)}
					},
					fx.ResultTags(`name:"security"`),
				),
			),
		)
	} else {
		// fx groups are unordered, but we need to preserve the order of the security transports
		// First of all, we construct the security transports that are needed,
		// and save them to a group call security_unordered.
		for _, s := range cfg.SecurityTransports {
			fxName := fmt.Sprintf(`name:"security_%s"`, s.ID)
			fxopts = append(fxopts, fx.Supply(fx.Annotate(s.ID, fx.ResultTags(fxName))))
			fxopts = append(fxopts,
				fx.Provide(fx.Annotate(
					s.Constructor,
					fx.ParamTags(fxName),
					fx.As(new(sec.SecureTransport)),
					fx.ResultTags(`group:"security_unordered"`),
				)),
			)
		}
		// Then we consume the group security_unordered, and order them by the user's preference.
		fxopts = append(fxopts, fx.Provide(
			fx.Annotate(
				func(secs []sec.SecureTransport) ([]sec.SecureTransport, error) {
					if len(secs) != len(cfg.SecurityTransports) {
						return nil, errors.New("inconsistent length for security transports")
					}
					t := make([]sec.SecureTransport, 0, len(secs))
					for _, s := range cfg.SecurityTransports {
						for _, st := range secs {
							if s.ID != st.ID() {
								continue
							}
							t = append(t, st)
						}
					}
					return t, nil
				},
				fx.ParamTags(`group:"security_unordered"`),
				fx.ResultTags(`name:"security"`),
			)))
	}

	fxopts = append(fxopts, fx.Provide(PrivKeyToStatelessResetKey))
	fxopts = append(fxopts, fx.Provide(PrivKeyToTokenGeneratorKey))
	if cfg.QUICReuse != nil {
		fxopts = append(fxopts, cfg.QUICReuse...)
	} else {
		fxopts = append(fxopts,
			fx.Provide(func(key quic.StatelessResetKey, tokenGenerator quic.TokenGeneratorKey, rcmgr network.ResourceManager, lifecycle fx.Lifecycle) (*quicreuse.ConnManager, error) {
				opts := []quicreuse.Option{
					quicreuse.ConnContext(func(ctx context.Context, clientInfo *quic.ClientInfo) (context.Context, error) {
						// even if creating the quic maddr fails, let the rcmgr decide what to do with the connection
						addr, err := quicreuse.ToQuicMultiaddr(clientInfo.RemoteAddr, quic.Version1)
						if err != nil {
							addr = nil
						}
						scope, err := rcmgr.OpenConnection(network.DirInbound, false, addr)
						if err != nil {
							return ctx, err
						}
						ctx = network.WithConnManagementScope(ctx, scope)
						context.AfterFunc(ctx, func() {
							scope.Done()
						})
						return ctx, nil
					}),
					quicreuse.VerifySourceAddress(func(addr net.Addr) bool {
						return rcmgr.VerifySourceAddress(addr)
					}),
				}
				if !cfg.DisableMetrics {
					opts = append(opts, quicreuse.EnableMetrics(cfg.PrometheusRegisterer))
				}
				cm, err := quicreuse.NewConnManager(key, tokenGenerator, opts...)
				if err != nil {
					return nil, err
				}
				lifecycle.Append(fx.StopHook(cm.Close))
				return cm, nil
			}),
		)
	}

	fxopts = append(fxopts, fx.Invoke(
		fx.Annotate(
			func(swrm *swarm.Swarm, tpts []transport.Transport) error {
				for _, t := range tpts {
					if err := swrm.AddTransport(t); err != nil {
						return err
					}
				}
				return nil
			},
			fx.ParamTags("", `group:"transport"`),
		)),
	)
	if cfg.Relay {
		fxopts = append(fxopts, fx.Invoke(circuitv2.AddTransport))
	}
	return fxopts, nil
}

func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus, an *autonatv2.AutoNAT, o bhost.ObservedAddrsManager) (*bhost.BasicHost, error) {
	h, err := bhost.NewHost(swrm, &bhost.HostOpts{
		EventBus:             eventBus,
		ConnManager:          cfg.ConnManager,
		AddrsFactory:         cfg.AddrsFactory,
		NATManager:           cfg.NATManager,
		EnablePing:           !cfg.DisablePing,
		UserAgent:            cfg.UserAgent,
		ProtocolVersion:      cfg.ProtocolVersion,
		EnableHolePunching:   cfg.EnableHolePunching,
		HolePunchingOptions:  cfg.HolePunchingOptions,
		EnableRelayService:   cfg.EnableRelayService,
		RelayServiceOpts:     cfg.RelayServiceOpts,
		EnableMetrics:        !cfg.DisableMetrics,
		PrometheusRegisterer: cfg.PrometheusRegisterer,
		AutoNATv2:            an,
		ObservedAddrsManager: o,
	})
	if err != nil {
		return nil, err
	}
	return h, nil
}

func (cfg *Config) validate() error {
	if cfg.EnableAutoRelay && !cfg.Relay {
		return fmt.Errorf("cannot enable autorelay; relay is not enabled")
	}
	// If possible check that the resource manager conn limit is higher than the
	// limit set in the conn manager.
	if l, ok := cfg.ResourceManager.(connmgr.GetConnLimiter); ok {
		err := cfg.ConnManager.CheckLimit(l)
		if err != nil {
			log.Warn("rcmgr limit conflicts with connmgr limit", "err", err)
		}
	}

	if len(cfg.PSK) > 0 && cfg.ShareTCPListener {
		return errors.New("cannot use shared TCP listener with PSK")
	}

	return nil
}

// NewNode constructs a new libp2p Host from the Config.
//
// This function consumes the config. Do not reuse it (really!).
func (cfg *Config) NewNode() (host.Host, error) {

	validateErr := cfg.validate()
	if validateErr != nil {
		if cfg.ResourceManager != nil {
			cfg.ResourceManager.Close()
		}
		if cfg.ConnManager != nil {
			cfg.ConnManager.Close()
		}
		if cfg.Peerstore != nil {
			cfg.Peerstore.Close()
		}

		return nil, validateErr
	}

	if !cfg.DisableMetrics {
		rcmgr.MustRegisterWith(cfg.PrometheusRegisterer)
	}

	fxopts := []fx.Option{
		fx.Provide(func() event.Bus {
			return eventbus.NewBus(eventbus.WithMetricsTracer(eventbus.NewMetricsTracer(eventbus.WithRegisterer(cfg.PrometheusRegisterer))))
		}),
		fx.Provide(func() crypto.PrivKey {
			return cfg.PeerKey
		}),
		// Make sure the swarm constructor depends on the quicreuse.ConnManager.
		// That way, the ConnManager will be started before the swarm, and more importantly,
		// the swarm will be stopped before the ConnManager.
		fx.Provide(func(eventBus event.Bus, _ *quicreuse.ConnManager, lifecycle fx.Lifecycle) (*swarm.Swarm, error) {
			sw, err := cfg.makeSwarm(eventBus, !cfg.DisableMetrics)
			if err != nil {
				return nil, err
			}
			lifecycle.Append(fx.Hook{
				OnStart: func(context.Context) error {
					// TODO: This method succeeds if listening on one address succeeds. We
					// should probably fail if listening on *any* addr fails.
					return sw.Listen(cfg.ListenAddrs...)
				},
				OnStop: func(context.Context) error {
					return sw.Close()
				},
			})
			return sw, nil
		}),
		fx.Provide(func(eventBus event.Bus, s *swarm.Swarm, lifecycle fx.Lifecycle) (bhost.ObservedAddrsManager, error) {
			if cfg.DisableIdentifyAddressDiscovery {
				return nil, nil
			}
			o, err := observedaddrs.NewManager(eventBus, s)
			if err != nil {
				return nil, err
			}
			lifecycle.Append(fx.Hook{
				OnStart: func(context.Context) error {
					o.Start(s)
					return nil
				},
				OnStop: func(context.Context) error {
					return o.Close()
				},
			})
			return o, nil
		}),
		fx.Provide(func() (*autonatv2.AutoNAT, error) {
			if !cfg.EnableAutoNATv2 {
				return nil, nil
			}
			ah, err := cfg.makeAutoNATV2Host()
			if err != nil {
				return nil, err
			}
			var mt autonatv2.MetricsTracer
			if !cfg.DisableMetrics {
				mt = autonatv2.NewMetricsTracer(cfg.PrometheusRegisterer)
			}
			autoNATv2, err := autonatv2.New(ah, autonatv2.WithMetricsTracer(mt))
			if err != nil {
				return nil, fmt.Errorf("failed to create autonatv2: %w", err)
			}
			return autoNATv2, nil
		}),
		fx.Provide(cfg.newBasicHost),
		fx.Provide(func(bh *bhost.BasicHost) identify.IDService {
			return bh.IDService()
		}),
		fx.Provide(func(bh *bhost.BasicHost) host.Host {
			return bh
		}),
		fx.Provide(func(h *swarm.Swarm) peer.ID { return h.LocalPeer() }),
	}
	transportOpts, err := cfg.addTransports()
	if err != nil {
		return nil, err
	}
	fxopts = append(fxopts, transportOpts...)

	// Configure routing
	if cfg.Routing != nil {
		fxopts = append(fxopts,
			fx.Provide(cfg.Routing),
			fx.Provide(func(h host.Host, router routing.PeerRouting) *routed.RoutedHost {
				return routed.Wrap(h, router)
			}),
		)
	}

	// enable autorelay
	fxopts = append(fxopts,
		fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) error {
			if cfg.EnableAutoRelay {
				if !cfg.DisableMetrics {
					mt := autorelay.WithMetricsTracer(
						autorelay.NewMetricsTracer(autorelay.WithRegisterer(cfg.PrometheusRegisterer)))
					mtOpts := []autorelay.Option{mt}
					cfg.AutoRelayOpts = append(mtOpts, cfg.AutoRelayOpts...)
				}

				ar, err := autorelay.NewAutoRelay(h, cfg.AutoRelayOpts...)
				if err != nil {
					return err
				}
				lifecycle.Append(fx.StartStopHook(ar.Start, ar.Close))
				return nil
			}
			return nil
		}),
	)

	var bh *bhost.BasicHost
	fxopts = append(fxopts, fx.Invoke(func(bho *bhost.BasicHost) { bh = bho }))
	fxopts = append(fxopts, fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) {
		lifecycle.Append(fx.StartHook(h.Start))
	}))

	var rh *routed.RoutedHost
	if cfg.Routing != nil {
		fxopts = append(fxopts, fx.Invoke(func(bho *routed.RoutedHost) { rh = bho }))
	}

	fxopts = append(fxopts, cfg.UserFxOptions...)

	app := fx.New(fxopts...)
	if err := app.Start(context.Background()); err != nil {
		return nil, err
	}

	if err := cfg.addAutoNAT(bh); err != nil {
		app.Stop(context.Background())
		if cfg.Routing != nil {
			rh.Close()
		} else {
			bh.Close()
		}
		return nil, err
	}

	if cfg.Routing != nil {
		return &closableRoutedHost{
			closableBasicHost: closableBasicHost{
				App:       app,
				BasicHost: bh,
			},
			RoutedHost: rh,
		}, nil
	}
	return &closableBasicHost{App: app, BasicHost: bh}, nil
}

func (cfg *Config) addAutoNAT(h *bhost.BasicHost) error {
	// Only use public addresses for autonat
	addrFunc := func() []ma.Multiaddr {
		return slices.DeleteFunc(h.AllAddrs(), func(a ma.Multiaddr) bool { return !manet.IsPublicAddr(a) })
	}
	if cfg.AddrsFactory != nil {
		addrFunc = func() []ma.Multiaddr {
			return slices.DeleteFunc(
				slices.Clone(cfg.AddrsFactory(h.AllAddrs())),
				func(a ma.Multiaddr) bool { return !manet.IsPublicAddr(a) })
		}
	}
	autonatOpts := []autonat.Option{
		autonat.UsingAddresses(addrFunc),
	}
	if !cfg.DisableMetrics {
		autonatOpts = append(autonatOpts, autonat.WithMetricsTracer(
			autonat.NewMetricsTracer(autonat.WithRegisterer(cfg.PrometheusRegisterer)),
		))
	}
	if cfg.AutoNATConfig.ThrottleInterval != 0 {
		autonatOpts = append(autonatOpts,
			autonat.WithThrottling(cfg.AutoNATConfig.ThrottleGlobalLimit, cfg.AutoNATConfig.ThrottleInterval),
			autonat.WithPeerThrottling(cfg.AutoNATConfig.ThrottlePeerLimit))
	}
	if cfg.AutoNATConfig.EnableService {
		autonatPrivKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
		if err != nil {
			return err
		}
		ps, err := pstoremem.NewPeerstore()
		if err != nil {
			return err
		}

		// Pull out the pieces of the config that we _actually_ care about.
		// Specifically, don't set up things like listeners, identify, etc.
		autoNatCfg := Config{
			Transports:         cfg.Transports,
			Muxers:             cfg.Muxers,
			SecurityTransports: cfg.SecurityTransports,
			Insecure:           cfg.Insecure,
			PSK:                cfg.PSK,
			ConnectionGater:    cfg.ConnectionGater,
			Reporter:           cfg.Reporter,
			PeerKey:            autonatPrivKey,
			Peerstore:          ps,
			DialRanker:         swarm.NoDelayDialRanker,
			ResourceManager:    cfg.ResourceManager,
			SwarmOpts: []swarm.Option{
				swarm.WithUDPBlackHoleSuccessCounter(nil),
				swarm.WithIPv6BlackHoleSuccessCounter(nil),
			},
		}

		fxopts, err := autoNatCfg.addTransports()
		if err != nil {
			return err
		}
		var dialer *swarm.Swarm

		fxopts = append(fxopts,
			fx.Provide(eventbus.NewBus),
			fx.Provide(func(lifecycle fx.Lifecycle, b event.Bus) (*swarm.Swarm, error) {
				lifecycle.Append(fx.Hook{
					OnStop: func(context.Context) error {
						return ps.Close()
					}})
				var err error
				dialer, err = autoNatCfg.makeSwarm(b, false)
				return dialer, err

			}),
			fx.Provide(func(s *swarm.Swarm) peer.ID { return s.LocalPeer() }),
			fx.Provide(func() crypto.PrivKey { return autonatPrivKey }),
		)
		app := fx.New(fxopts...)
		if err := app.Err(); err != nil {
			return err
		}
		err = app.Start(context.Background())
		if err != nil {
			return err
		}
		go func() {
			<-dialer.Done() // The swarm used for autonat has closed, we can cleanup now
			app.Stop(context.Background())
		}()
		autonatOpts = append(autonatOpts, autonat.EnableService(dialer))
	}
	if cfg.AutoNATConfig.ForceReachability != nil {
		autonatOpts = append(autonatOpts, autonat.WithReachability(*cfg.AutoNATConfig.ForceReachability))
	}

	autonat, err := autonat.New(h, autonatOpts...)
	if err != nil {
		return fmt.Errorf("autonat init failed: %w", err)
	}
	h.SetAutoNat(autonat)
	return nil
}

// Option is a libp2p config option that can be given to the libp2p constructor
// (`libp2p.New`).
type Option func(cfg *Config) error

// Apply applies the given options to the config, returning the first error
// encountered (if any).
func (cfg *Config) Apply(opts ...Option) error {
	for _, opt := range opts {
		if opt == nil {
			continue
		}
		if err := opt(cfg); err != nil {
			return err
		}
	}
	return nil
}


================================================
FILE: config/config_test.go
================================================
package config

import (
	"testing"
)

func TestNilOption(t *testing.T) {
	var cfg Config
	optsRun := 0
	opt := func(_ *Config) error {
		optsRun++
		return nil
	}
	if err := cfg.Apply(nil); err != nil {
		t.Fatal(err)
	}
	if err := cfg.Apply(opt, nil, nil, opt, opt, nil); err != nil {
		t.Fatal(err)
	}
	if optsRun != 3 {
		t.Fatalf("expected to have handled 3 options, handled %d", optsRun)
	}
}


================================================
FILE: config/host.go
================================================
package config

import (
	"context"

	basichost "github.com/libp2p/go-libp2p/p2p/host/basic"
	routed "github.com/libp2p/go-libp2p/p2p/host/routed"

	"go.uber.org/fx"
)

type closableBasicHost struct {
	*fx.App
	*basichost.BasicHost
}

func (h *closableBasicHost) Close() error {
	_ = h.App.Stop(context.Background())
	return h.BasicHost.Close()
}

type closableRoutedHost struct {
	// closableBasicHost is embedded here so that interface assertions on
	// BasicHost exported methods work correctly.
	closableBasicHost
	*routed.RoutedHost
}

func (h *closableRoutedHost) Close() error {
	_ = h.App.Stop(context.Background())
	// The routed host will close the basic host
	return h.RoutedHost.Close()
}


================================================
FILE: config/quic.go
================================================
package config

import (
	"crypto/sha256"
	"io"

	"golang.org/x/crypto/hkdf"

	"github.com/libp2p/go-libp2p/core/crypto"

	"github.com/quic-go/quic-go"
)

const (
	statelessResetKeyInfo = "libp2p quic stateless reset key"
	tokenGeneratorKeyInfo = "libp2p quic token generator key"
)

func PrivKeyToStatelessResetKey(key crypto.PrivKey) (quic.StatelessResetKey, error) {
	var statelessResetKey quic.StatelessResetKey
	keyBytes, err := key.Raw()
	if err != nil {
		return statelessResetKey, err
	}
	keyReader := hkdf.New(sha256.New, keyBytes, nil, []byte(statelessResetKeyInfo))
	if _, err := io.ReadFull(keyReader, statelessResetKey[:]); err != nil {
		return statelessResetKey, err
	}
	return statelessResetKey, nil
}

func PrivKeyToTokenGeneratorKey(key crypto.PrivKey) (quic.TokenGeneratorKey, error) {
	var tokenKey quic.TokenGeneratorKey
	keyBytes, err := key.Raw()
	if err != nil {
		return tokenKey, err
	}
	keyReader := hkdf.New(sha256.New, keyBytes, nil, []byte(tokenGeneratorKeyInfo))
	if _, err := io.ReadFull(keyReader, tokenKey[:]); err != nil {
		return tokenKey, err
	}
	return tokenKey, nil
}


================================================
FILE: core/alias.go
================================================
// Package core provides convenient access to foundational, central go-libp2p primitives via type aliases.
package core

import (
	"github.com/libp2p/go-libp2p/core/host"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/protocol"

	"github.com/multiformats/go-multiaddr"
)

// Multiaddr aliases the Multiaddr type from github.com/multiformats/go-multiaddr.
//
// Refer to the docs on that type for more info.
type Multiaddr = multiaddr.Multiaddr

// PeerID aliases peer.ID.
//
// Refer to the docs on that type for more info.
type PeerID = peer.ID

// ProtocolID aliases protocol.ID.
//
// Refer to the docs on that type for more info.
type ProtocolID = protocol.ID

// PeerAddrInfo aliases peer.AddrInfo.
//
// Refer to the docs on that type for more info.
type PeerAddrInfo = peer.AddrInfo

// Host aliases host.Host.
//
// Refer to the docs on that type for more info.
type Host = host.Host

// Network aliases network.Network.
//
// Refer to the docs on that type for more info.
type Network = network.Network

// Conn aliases network.Conn.
//
// Refer to the docs on that type for more info.
type Conn = network.Conn

// Stream aliases network.Stream.
//
// Refer to the docs on that type for more info.
type Stream = network.Stream


================================================
FILE: core/connmgr/decay.go
================================================
package connmgr

import (
	"io"
	"time"

	"github.com/libp2p/go-libp2p/core/peer"
)

// Decayer is implemented by connection managers supporting decaying tags. A
// decaying tag is one whose value automatically decays over time.
//
// The actual application of the decay behaviour is encapsulated in a
// user-provided decaying function (DecayFn). The function is called on every
// tick (determined by the interval parameter), and returns either the new value
// of the tag, or whether it should be erased altogether.
//
// We do not set values on a decaying tag. Rather, we "bump" decaying tags by a
// delta. This calls the BumpFn with the old value and the delta, to determine
// the new value.
//
// Such a pluggable design affords a great deal of flexibility and versatility.
// Behaviours that are straightforward to implement include:
//
//   - Decay a tag by -1, or by half its current value, on every tick.
//   - Every time a value is bumped, sum it to its current value.
//   - Exponentially boost a score with every bump.
//   - Sum the incoming score, but keep it within min, max bounds.
//
// Commonly used DecayFns and BumpFns are provided in this package.
type Decayer interface {
	io.Closer

	// RegisterDecayingTag creates and registers a new decaying tag, if and only
	// if a tag with the supplied name doesn't exist yet. Otherwise, an error is
	// returned.
	//
	// The caller provides the interval at which the tag is refreshed, as well
	// as the decay function and the bump function. Refer to godocs on DecayFn
	// and BumpFn for more info.
	RegisterDecayingTag(name string, interval time.Duration, decayFn DecayFn, bumpFn BumpFn) (DecayingTag, error)
}

// DecayFn applies a decay to the peer's score. The implementation must call
// DecayFn at the interval supplied when registering the tag.
//
// It receives a copy of the decaying value, and returns the score after
// applying the decay, as well as a flag to signal if the tag should be erased.
type DecayFn func(value DecayingValue) (after int, rm bool)

// BumpFn applies a delta onto an existing score, and returns the new score.
//
// Non-trivial bump functions include exponential boosting, moving averages,
// ceilings, etc.
type BumpFn func(value DecayingValue, delta int) (after int)

// DecayingTag represents a decaying tag. The tag is a long-lived general
// object, used to operate on tag values for peers.
type DecayingTag interface {
	// Name returns the name of the tag.
	Name() string

	// Interval is the effective interval at which this tag will tick. Upon
	// registration, the desired interval may be overwritten depending on the
	// decayer's resolution, and this method allows you to obtain the effective
	// interval.
	Interval() time.Duration

	// Bump applies a delta to a tag value, calling its bump function. The bump
	// will be applied asynchronously, and a non-nil error indicates a fault
	// when queuing.
	Bump(peer peer.ID, delta int) error

	// Remove removes a decaying tag from a peer. The removal will be applied
	// asynchronously, and a non-nil error indicates a fault when queuing.
	Remove(peer peer.ID) error

	// Close closes a decaying tag. The Decayer will stop tracking this tag,
	// and the state of all peers in the Connection Manager holding this tag
	// will be updated.
	//
	// The deletion is performed asynchronously.
	//
	// Once deleted, a tag should not be used, and further calls to Bump/Remove
	// will error.
	//
	// Duplicate calls to Remove will not return errors, but a failure to queue
	// the first actual removal, will (e.g. when the system is backlogged).
	Close() error
}

// DecayingValue represents a value for a decaying tag.
type DecayingValue struct {
	// Tag points to the tag this value belongs to.
	Tag DecayingTag

	// Peer is the peer ID to whom this value is associated.
	Peer peer.ID

	// Added is the timestamp when this value was added for the first time for
	// a tag and a peer.
	Added time.Time

	// LastVisit is the timestamp of the last visit.
	LastVisit time.Time

	// Value is the current value of the tag.
	Value int
}


================================================
FILE: core/connmgr/gater.go
================================================
package connmgr

import (
	ma "github.com/multiformats/go-multiaddr"

	"github.com/libp2p/go-libp2p/core/control"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
)

// ConnectionGater can be implemented by a type that supports active
// inbound or outbound connection gating.
//
// ConnectionGaters are active, whereas ConnManagers tend to be passive.
//
// A ConnectionGater will be consulted during different states in the lifecycle
// of a connection being established/upgraded. Specific functions will be called
// throughout the process, to allow you to intercept the connection at that stage.
//
//	InterceptPeerDial is called on an imminent outbound peer dial request, prior
//	to the addresses of that peer being available/resolved. Blocking connections
//	at this stage is typical for blacklisting scenarios.
//
//	InterceptAddrDial is called on an imminent outbound dial to a peer on a
//	particular address. Blocking connections at this stage is typical for
//	address filtering.
//
//	InterceptAccept is called as soon as a transport listener receives an
//	inbound connection request, before any upgrade takes place. Transports who
//	accept already secure and/or multiplexed connections (e.g. possibly QUIC)
//	MUST call this method regardless, for correctness/consistency.
//
//	InterceptSecured is called for both inbound and outbound connections,
//	after a security handshake has taken place and we've authenticated the peer.
//
//	InterceptUpgraded is called for inbound and outbound connections, after
//	libp2p has finished upgrading the connection entirely to a secure,
//	multiplexed channel.
//
// This interface can be used to implement *strict/active* connection management
// policies, such as hard limiting of connections once a maximum count has been
// reached, maintaining a peer blacklist, or limiting connections by transport
// quotas.
//
// EXPERIMENTAL: a DISCONNECT protocol/message will be supported in the future.
// This allows gaters and other components to communicate the intention behind
// a connection closure, to curtail potential reconnection attempts.
//
// For now, InterceptUpgraded can return a non-zero DisconnectReason when
// blocking a connection, but this interface is likely to change in the future
// as we solidify this feature. The reason why only this method can handle
// DisconnectReasons is that we require stream multiplexing capability to open a
// control protocol stream to transmit the message.
type ConnectionGater interface {
	// InterceptPeerDial tests whether we're permitted to Dial the specified peer.
	//
	// This is called by the network.Network implementation when dialling a peer.
	InterceptPeerDial(p peer.ID) (allow bool)

	// InterceptAddrDial tests whether we're permitted to dial the specified
	// multiaddr for the given peer.
	//
	// This is called by the network.Network implementation after it has
	// resolved the peer's addrs, and prior to dialling each.
	InterceptAddrDial(peer.ID, ma.Multiaddr) (allow bool)

	// InterceptAccept tests whether an incipient inbound connection is allowed.
	//
	// This is called by the upgrader, or by the transport directly (e.g. QUIC,
	// Bluetooth), straight after it has accepted a connection from its socket.
	InterceptAccept(network.ConnMultiaddrs) (allow bool)

	// InterceptSecured tests whether a given connection, now authenticated,
	// is allowed.
	//
	// This is called by the upgrader, after it has performed the security
	// handshake, and before it negotiates the muxer, or by the directly by the
	// transport, at the exact same checkpoint.
	InterceptSecured(network.Direction, peer.ID, network.ConnMultiaddrs) (allow bool)

	// InterceptUpgraded tests whether a fully capable connection is allowed.
	//
	// At this point, the connection a multiplexer has been selected.
	// When rejecting a connection, the gater can return a DisconnectReason.
	// Refer to the godoc on the ConnectionGater type for more information.
	//
	// NOTE: the go-libp2p implementation currently IGNORES the disconnect reason.
	InterceptUpgraded(network.Conn) (allow bool, reason control.DisconnectReason)
}


================================================
FILE: core/connmgr/manager.go
================================================
// Package connmgr provides connection tracking and management interfaces for libp2p.
//
// The ConnManager interface exported from this package allows libp2p to enforce an
// upper bound on the total number of open connections. To avoid service disruptions,
// connections can be tagged with metadata and optionally "protected" to ensure that
// essential connections are not arbitrarily cut.
package connmgr

import (
	"context"
	"time"

	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
)

// SupportsDecay evaluates if the provided ConnManager supports decay, and if
// so, it returns the Decayer object. Refer to godocs on Decayer for more info.
func SupportsDecay(mgr ConnManager) (Decayer, bool) {
	d, ok := mgr.(Decayer)
	return d, ok
}

// ConnManager tracks connections to peers, and allows consumers to associate
// metadata with each peer.
//
// It enables connections to be trimmed based on implementation-defined
// heuristics. The ConnManager allows libp2p to enforce an upper bound on the
// total number of open connections.
//
// ConnManagers supporting decaying tags implement Decayer. Use the
// SupportsDecay function to safely cast an instance to Decayer, if supported.
type ConnManager interface {
	// TagPeer tags a peer with a string, associating a weight with the tag.
	TagPeer(peer.ID, string, int)

	// UntagPeer removes the tagged value from the peer.
	UntagPeer(p peer.ID, tag string)

	// UpsertTag updates an existing tag or inserts a new one.
	//
	// The connection manager calls the upsert function supplying the current
	// value of the tag (or zero if inexistent). The return value is used as
	// the new value of the tag.
	UpsertTag(p peer.ID, tag string, upsert func(int) int)

	// GetTagInfo returns the metadata associated with the peer,
	// or nil if no metadata has been recorded for the peer.
	GetTagInfo(p peer.ID) *TagInfo

	// TrimOpenConns terminates open connections based on an implementation-defined
	// heuristic.
	TrimOpenConns(ctx context.Context)

	// Notifee returns an implementation that can be called back to inform of
	// opened and closed connections.
	Notifee() network.Notifiee

	// Protect protects a peer from having its connection(s) pruned.
	//
	// Tagging allows different parts of the system to manage protections without interfering with one another.
	//
	// Calls to Protect() with the same tag are idempotent. They are not refcounted, so after multiple calls
	// to Protect() with the same tag, a single Unprotect() call bearing the same tag will revoke the protection.
	Protect(id peer.ID, tag string)

	// Unprotect removes a protection that may have been placed on a peer, under the specified tag.
	//
	// The return value indicates whether the peer continues to be protected after this call, by way of a different tag.
	// See notes on Protect() for more info.
	Unprotect(id peer.ID, tag string) (protected bool)

	// IsProtected returns true if the peer is protected for some tag; if the tag is the empty string
	// then it will return true if the peer is protected for any tag
	IsProtected(id peer.ID, tag string) (protected bool)

	// CheckLimit will return an error if the connection manager's internal
	// connection limit exceeds the provided system limit.
	CheckLimit(l GetConnLimiter) error

	// Close closes the connection manager and stops background processes.
	Close() error
}

// TagInfo stores metadata associated with a peer.
type TagInfo struct {
	FirstSeen time.Time
	Value     int

	// Tags maps tag ids to the numerical values.
	Tags map[string]int

	// Conns maps connection ids (such as remote multiaddr) to their creation time.
	Conns map[string]time.Time
}

// GetConnLimiter provides access to a component's total connection limit.
type GetConnLimiter interface {
	// GetConnLimit returns the total connection limit of the implementing component.
	GetConnLimit() int
}


================================================
FILE: core/connmgr/null.go
================================================
package connmgr

import (
	"context"

	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
)

// NullConnMgr is a ConnMgr that provides no functionality.
type NullConnMgr struct{}

var _ ConnManager = (*NullConnMgr)(nil)

func (NullConnMgr) TagPeer(peer.ID, string, int)             {}
func (NullConnMgr) UntagPeer(peer.ID, string)                {}
func (NullConnMgr) UpsertTag(peer.ID, string, func(int) int) {}
func (NullConnMgr) GetTagInfo(peer.ID) *TagInfo              { return &TagInfo{} }
func (NullConnMgr) TrimOpenConns(_ context.Context)          {}
func (NullConnMgr) Notifee() network.Notifiee                { return network.GlobalNoopNotifiee }
func (NullConnMgr) Protect(peer.ID, string)                  {}
func (NullConnMgr) Unprotect(peer.ID, string) bool           { return false }
func (NullConnMgr) IsProtected(peer.ID, string) bool         { return false }
func (NullConnMgr) CheckLimit(_ GetConnLimiter) error        { return nil }
func (NullConnMgr) Close() error                             { return nil }


================================================
FILE: core/connmgr/presets.go
================================================
package connmgr

import (
	"math"
	"time"
)

// DecayNone applies no decay.
func DecayNone() DecayFn {
	return func(value DecayingValue) (_ int, rm bool) {
		return value.Value, false
	}
}

// DecayFixed subtracts from by the provided minuend, and deletes the tag when
// first reaching 0 or negative.
func DecayFixed(minuend int) DecayFn {
	return func(value DecayingValue) (_ int, rm bool) {
		v := value.Value - minuend
		return v, v <= 0
	}
}

// DecayLinear applies a fractional coefficient to the value of the current tag,
// rounding down via math.Floor. It erases the tag when the result is zero.
func DecayLinear(coef float64) DecayFn {
	return func(value DecayingValue) (after int, rm bool) {
		v := math.Floor(float64(value.Value) * coef)
		return int(v), v <= 0
	}
}

// DecayExpireWhenInactive expires a tag after a certain period of no bumps.
func DecayExpireWhenInactive(after time.Duration) DecayFn {
	return func(value DecayingValue) (_ int, rm bool) {
		rm = time.Until(value.LastVisit) >= after
		return 0, rm
	}
}

// BumpSumUnbounded adds the incoming value to the peer's score.
func BumpSumUnbounded() BumpFn {
	return func(value DecayingValue, delta int) (after int) {
		return value.Value + delta
	}
}

// BumpSumBounded keeps summing the incoming score, keeping it within a
// [min, max] range.
func BumpSumBounded(min, max int) BumpFn {
	return func(value DecayingValue, delta int) (after int) {
		v := value.Value + delta
		if v >= max {
			return max
		} else if v <= min {
			return min
		}
		return v
	}
}

// BumpOverwrite replaces the current value of the tag with the incoming one.
func BumpOverwrite() BumpFn {
	return func(_ DecayingValue, delta int) (after int) {
		return delta
	}
}


================================================
FILE: core/control/disconnect.go
================================================
package control

// DisconnectReason communicates the reason why a connection is being closed.
//
// A zero value stands for "no reason" / NA.
//
// This is an EXPERIMENTAL type. It will change in the future. Refer to the
// connmgr.ConnectionGater godoc for more info.
type DisconnectReason int


================================================
FILE: core/crypto/bench_test.go
================================================
package crypto

import "testing"

func BenchmarkSignRSA1B(b *testing.B)      { RunBenchmarkSignRSA(b, 1) }
func BenchmarkSignRSA10B(b *testing.B)     { RunBenchmarkSignRSA(b, 10) }
func BenchmarkSignRSA100B(b *testing.B)    { RunBenchmarkSignRSA(b, 100) }
func BenchmarkSignRSA1000B(b *testing.B)   { RunBenchmarkSignRSA(b, 1000) }
func BenchmarkSignRSA10000B(b *testing.B)  { RunBenchmarkSignRSA(b, 10000) }
func BenchmarkSignRSA100000B(b *testing.B) { RunBenchmarkSignRSA(b, 100000) }

func BenchmarkVerifyRSA1B(b *testing.B)      { RunBenchmarkVerifyRSA(b, 1) }
func BenchmarkVerifyRSA10B(b *testing.B)     { RunBenchmarkVerifyRSA(b, 10) }
func BenchmarkVerifyRSA100B(b *testing.B)    { RunBenchmarkVerifyRSA(b, 100) }
func BenchmarkVerifyRSA1000B(b *testing.B)   { RunBenchmarkVerifyRSA(b, 1000) }
func BenchmarkVerifyRSA10000B(b *testing.B)  { RunBenchmarkVerifyRSA(b, 10000) }
func BenchmarkVerifyRSA100000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 100000) }

func BenchmarkSignEd255191B(b *testing.B)      { RunBenchmarkSignEd25519(b, 1) }
func BenchmarkSignEd2551910B(b *testing.B)     { RunBenchmarkSignEd25519(b, 10) }
func BenchmarkSignEd25519100B(b *testing.B)    { RunBenchmarkSignEd25519(b, 100) }
func BenchmarkSignEd255191000B(b *testing.B)   { RunBenchmarkSignEd25519(b, 1000) }
func BenchmarkSignEd2551910000B(b *testing.B)  { RunBenchmarkSignEd25519(b, 10000) }
func BenchmarkSignEd25519100000B(b *testing.B) { RunBenchmarkSignEd25519(b, 100000) }

func BenchmarkVerifyEd255191B(b *testing.B)      { RunBenchmarkVerifyEd25519(b, 1) }
func BenchmarkVerifyEd2551910B(b *testing.B)     { RunBenchmarkVerifyEd25519(b, 10) }
func BenchmarkVerifyEd25519100B(b *testing.B)    { RunBenchmarkVerifyEd25519(b, 100) }
func BenchmarkVerifyEd255191000B(b *testing.B)   { RunBenchmarkVerifyEd25519(b, 1000) }
func BenchmarkVerifyEd2551910000B(b *testing.B)  { RunBenchmarkVerifyEd25519(b, 10000) }
func BenchmarkVerifyEd25519100000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 100000) }

func RunBenchmarkSignRSA(b *testing.B, numBytes int) {
	runBenchmarkSign(b, numBytes, RSA)
}

func RunBenchmarkSignEd25519(b *testing.B, numBytes int) {
	runBenchmarkSign(b, numBytes, Ed25519)
}

func runBenchmarkSign(b *testing.B, numBytes int, t int) {
	secret, _, err := GenerateKeyPair(t, 2048)
	if err != nil {
		b.Fatal(err)
	}
	someData := make([]byte, numBytes)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, err := secret.Sign(someData)
		if err != nil {
			b.Fatal(err)
		}
	}
}

func RunBenchmarkVerifyRSA(b *testing.B, numBytes int) {
	runBenchmarkVerify(b, numBytes, RSA)
}

func RunBenchmarkVerifyEd25519(b *testing.B, numBytes int) {
	runBenchmarkVerify(b, numBytes, Ed25519)
}

func runBenchmarkVerify(b *testing.B, numBytes int, t int) {
	secret, public, err := GenerateKeyPair(t, 2048)
	if err != nil {
		b.Fatal(err)
	}
	someData := make([]byte, numBytes)
	signature, err := secret.Sign(someData)
	if err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		valid, err := public.Verify(someData, signature)
		if err != nil {
			b.Fatal(err)
		}
		if !valid {
			b.Fatal("signature should be valid")
		}
	}
}


================================================
FILE: core/crypto/ecdsa.go
================================================
package crypto

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"crypto/x509"
	"encoding/asn1"
	"errors"
	"io"
	"math/big"

	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
	"github.com/libp2p/go-libp2p/core/internal/catch"
)

// ECDSAPrivateKey is an implementation of an ECDSA private key
type ECDSAPrivateKey struct {
	priv *ecdsa.PrivateKey
}

// ECDSAPublicKey is an implementation of an ECDSA public key
type ECDSAPublicKey struct {
	pub *ecdsa.PublicKey
}

// ECDSASig holds the r and s values of an ECDSA signature
type ECDSASig struct {
	R, S *big.Int
}

var (
	// ErrNotECDSAPubKey is returned when the public key passed is not an ecdsa public key
	ErrNotECDSAPubKey = errors.New("not an ecdsa public key")
	// ErrNilSig is returned when the signature is nil
	ErrNilSig = errors.New("sig is nil")
	// ErrNilPrivateKey is returned when a nil private key is provided
	ErrNilPrivateKey = errors.New("private key is nil")
	// ErrNilPublicKey is returned when a nil public key is provided
	ErrNilPublicKey = errors.New("public key is nil")
	// ECDSACurve is the default ecdsa curve used
	ECDSACurve = elliptic.P256()
)

// GenerateECDSAKeyPair generates a new ecdsa private and public key
func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) {
	return GenerateECDSAKeyPairWithCurve(ECDSACurve, src)
}

// GenerateECDSAKeyPairWithCurve generates a new ecdsa private and public key with a specified curve
func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) {
	priv, err := ecdsa.GenerateKey(curve, src)
	if err != nil {
		return nil, nil, err
	}

	return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil
}

// ECDSAKeyPairFromKey generates a new ecdsa private and public key from an input private key
func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) {
	if priv == nil {
		return nil, nil, ErrNilPrivateKey
	}

	return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil
}

// ECDSAPublicKeyFromPubKey generates a new ecdsa public key from an input public key
func ECDSAPublicKeyFromPubKey(pub ecdsa.PublicKey) (PubKey, error) {
	return &ECDSAPublicKey{pub: &pub}, nil
}

// MarshalECDSAPrivateKey returns x509 bytes from a private key
func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) (res []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key marshal") }()
	return x509.MarshalECPrivateKey(ePriv.priv)
}

// MarshalECDSAPublicKey returns x509 bytes from a public key
func MarshalECDSAPublicKey(ePub ECDSAPublicKey) (res []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "ECDSA public-key marshal") }()
	return x509.MarshalPKIXPublicKey(ePub.pub)
}

// UnmarshalECDSAPrivateKey returns a private key from x509 bytes
func UnmarshalECDSAPrivateKey(data []byte) (res PrivKey, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key unmarshal") }()

	priv, err := x509.ParseECPrivateKey(data)
	if err != nil {
		return nil, err
	}

	return &ECDSAPrivateKey{priv}, nil
}

// UnmarshalECDSAPublicKey returns the public key from x509 bytes
func UnmarshalECDSAPublicKey(data []byte) (key PubKey, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "ECDSA public-key unmarshal") }()

	pubIfc, err := x509.ParsePKIXPublicKey(data)
	if err != nil {
		return nil, err
	}

	pub, ok := pubIfc.(*ecdsa.PublicKey)
	if !ok {
		return nil, ErrNotECDSAPubKey
	}

	return &ECDSAPublicKey{pub}, nil
}

// Type returns the key type
func (ePriv *ECDSAPrivateKey) Type() pb.KeyType {
	return pb.KeyType_ECDSA
}

// Raw returns x509 bytes from a private key
func (ePriv *ECDSAPrivateKey) Raw() (res []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key marshal") }()
	return x509.MarshalECPrivateKey(ePriv.priv)
}

// Equals compares two private keys
func (ePriv *ECDSAPrivateKey) Equals(o Key) bool {
	return basicEquals(ePriv, o)
}

// Sign returns the signature of the input data
func (ePriv *ECDSAPrivateKey) Sign(data []byte) (sig []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "ECDSA signing") }()
	hash := sha256.Sum256(data)
	r, s, err := ecdsa.Sign(rand.Reader, ePriv.priv, hash[:])
	if err != nil {
		return nil, err
	}

	return asn1.Marshal(ECDSASig{
		R: r,
		S: s,
	})
}

// GetPublic returns a public key
func (ePriv *ECDSAPrivateKey) GetPublic() PubKey {
	return &ECDSAPublicKey{&ePriv.priv.PublicKey}
}

// Type returns the key type
func (ePub *ECDSAPublicKey) Type() pb.KeyType {
	return pb.KeyType_ECDSA
}

// Raw returns x509 bytes from a public key
func (ePub *ECDSAPublicKey) Raw() ([]byte, error) {
	return x509.MarshalPKIXPublicKey(ePub.pub)
}

// Equals compares to public keys
func (ePub *ECDSAPublicKey) Equals(o Key) bool {
	return basicEquals(ePub, o)
}

// Verify compares data to a signature
func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (success bool, err error) {
	defer func() {
		catch.HandlePanic(recover(), &err, "ECDSA signature verification")

		// Just to be extra paranoid.
		if err != nil {
			success = false
		}
	}()

	sig := new(ECDSASig)
	if _, err := asn1.Unmarshal(sigBytes, sig); err != nil {
		return false, err
	}

	hash := sha256.Sum256(data)

	return ecdsa.Verify(ePub.pub, hash[:], sig.R, sig.S), nil
}


================================================
FILE: core/crypto/ecdsa_test.go
================================================
package crypto

import (
	"crypto/ecdsa"
	"crypto/rand"
	"testing"
)

func TestECDSABasicSignAndVerify(t *testing.T) {
	priv, pub, err := GenerateECDSAKeyPair(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := []byte("hello! and welcome to some awesome crypto primitives")

	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}

	if !ok {
		t.Fatal("signature didn't match")
	}

	// change data
	data[0] = ^data[0]
	ok, err = pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}

	if ok {
		t.Fatal("signature matched and shouldn't")
	}
}

func TestECDSASignZero(t *testing.T) {
	priv, pub, err := GenerateECDSAKeyPair(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := make([]byte, 0)
	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}
	if !ok {
		t.Fatal("signature didn't match")
	}
}

func TestECDSAMarshalLoop(t *testing.T) {
	priv, pub, err := GenerateECDSAKeyPair(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	privB, err := MarshalPrivateKey(priv)
	if err != nil {
		t.Fatal(err)
	}

	privNew, err := UnmarshalPrivateKey(privB)
	if err != nil {
		t.Fatal(err)
	}

	if !priv.Equals(privNew) || !privNew.Equals(priv) {
		t.Fatal("keys are not equal")
	}

	pubB, err := MarshalPublicKey(pub)
	if err != nil {
		t.Fatal(err)
	}
	pubNew, err := UnmarshalPublicKey(pubB)
	if err != nil {
		t.Fatal(err)
	}

	if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
		t.Fatal("keys are not equal")
	}

}

func TestECDSAPublicKeyFromPubKey(t *testing.T) {
	ecdsaPrivK, err := ecdsa.GenerateKey(ECDSACurve, rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	privK, _, err := ECDSAKeyPairFromKey(ecdsaPrivK)
	if err != nil {
		t.Fatal(err)
	}

	data := []byte("Hello world!")
	signature, err := privK.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	pubKey, err := ECDSAPublicKeyFromPubKey(ecdsaPrivK.PublicKey)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pubKey.Verify(data, signature)
	if err != nil {
		t.Fatal(err)
	}

	if !ok {
		t.Fatal("signature didn't match")
	}

	pubB, err := MarshalPublicKey(pubKey)
	if err != nil {
		t.Fatal(err)
	}
	pubNew, err := UnmarshalPublicKey(pubB)
	if err != nil {
		t.Fatal(err)
	}

	if !pubKey.Equals(pubNew) || !pubNew.Equals(pubKey) {
		t.Fatal("keys are not equal")
	}
}


================================================
FILE: core/crypto/ed25519.go
================================================
package crypto

import (
	"bytes"
	"crypto/ed25519"
	"crypto/subtle"
	"errors"
	"fmt"
	"io"

	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
	"github.com/libp2p/go-libp2p/core/internal/catch"
)

// Ed25519PrivateKey is an ed25519 private key.
type Ed25519PrivateKey struct {
	k ed25519.PrivateKey
}

// Ed25519PublicKey is an ed25519 public key.
type Ed25519PublicKey struct {
	k ed25519.PublicKey
}

// GenerateEd25519Key generates a new ed25519 private and public key pair.
func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) {
	pub, priv, err := ed25519.GenerateKey(src)
	if err != nil {
		return nil, nil, err
	}

	return &Ed25519PrivateKey{
			k: priv,
		},
		&Ed25519PublicKey{
			k: pub,
		},
		nil
}

// Type of the private key (Ed25519).
func (k *Ed25519PrivateKey) Type() pb.KeyType {
	return pb.KeyType_Ed25519
}

// Raw private key bytes.
func (k *Ed25519PrivateKey) Raw() ([]byte, error) {
	// The Ed25519 private key contains two 32-bytes curve points, the private
	// key and the public key.
	// It makes it more efficient to get the public key without re-computing an
	// elliptic curve multiplication.
	buf := make([]byte, len(k.k))
	copy(buf, k.k)

	return buf, nil
}

func (k *Ed25519PrivateKey) pubKeyBytes() []byte {
	return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:]
}

// Equals compares two ed25519 private keys.
func (k *Ed25519PrivateKey) Equals(o Key) bool {
	edk, ok := o.(*Ed25519PrivateKey)
	if !ok {
		return basicEquals(k, o)
	}

	return subtle.ConstantTimeCompare(k.k, edk.k) == 1
}

// GetPublic returns an ed25519 public key from a private key.
func (k *Ed25519PrivateKey) GetPublic() PubKey {
	return &Ed25519PublicKey{k: k.pubKeyBytes()}
}

// Sign returns a signature from an input message.
func (k *Ed25519PrivateKey) Sign(msg []byte) (res []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "ed15519 signing") }()

	return ed25519.Sign(k.k, msg), nil
}

// Type of the public key (Ed25519).
func (k *Ed25519PublicKey) Type() pb.KeyType {
	return pb.KeyType_Ed25519
}

// Raw public key bytes.
func (k *Ed25519PublicKey) Raw() ([]byte, error) {
	return k.k, nil
}

// Equals compares two ed25519 public keys.
func (k *Ed25519PublicKey) Equals(o Key) bool {
	edk, ok := o.(*Ed25519PublicKey)
	if !ok {
		return basicEquals(k, o)
	}

	return bytes.Equal(k.k, edk.k)
}

// Verify checks a signature against the input data.
func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (success bool, err error) {
	defer func() {
		catch.HandlePanic(recover(), &err, "ed15519 signature verification")

		// To be safe.
		if err != nil {
			success = false
		}
	}()
	return ed25519.Verify(k.k, data, sig), nil
}

// UnmarshalEd25519PublicKey returns a public key from input bytes.
func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) {
	if len(data) != 32 {
		return nil, errors.New("expect ed25519 public key data size to be 32")
	}

	return &Ed25519PublicKey{
		k: ed25519.PublicKey(data),
	}, nil
}

// UnmarshalEd25519PrivateKey returns a private key from input bytes.
func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {
	switch len(data) {
	case ed25519.PrivateKeySize + ed25519.PublicKeySize:
		// Remove the redundant public key. See issue #36.
		redundantPk := data[ed25519.PrivateKeySize:]
		pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize]
		if subtle.ConstantTimeCompare(pk, redundantPk) == 0 {
			return nil, errors.New("expected redundant ed25519 public key to be redundant")
		}

		// No point in storing the extra data.
		newKey := make([]byte, ed25519.PrivateKeySize)
		copy(newKey, data[:ed25519.PrivateKeySize])
		data = newKey
	case ed25519.PrivateKeySize:
	default:
		return nil, fmt.Errorf(
			"expected ed25519 data size to be %d or %d, got %d",
			ed25519.PrivateKeySize,
			ed25519.PrivateKeySize+ed25519.PublicKeySize,
			len(data),
		)
	}

	return &Ed25519PrivateKey{
		k: ed25519.PrivateKey(data),
	}, nil
}


================================================
FILE: core/crypto/ed25519_test.go
================================================
package crypto

import (
	"crypto/ed25519"
	"crypto/rand"
	"testing"

	"github.com/libp2p/go-libp2p/core/crypto/pb"

	"google.golang.org/protobuf/proto"
)

func TestBasicSignAndVerify(t *testing.T) {
	priv, pub, err := GenerateEd25519Key(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := []byte("hello! and welcome to some awesome crypto primitives")

	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}

	if !ok {
		t.Fatal("signature didn't match")
	}

	// change data
	data[0] = ^data[0]
	ok, err = pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}

	if ok {
		t.Fatal("signature matched and shouldn't")
	}
}

func TestSignZero(t *testing.T) {
	priv, pub, err := GenerateEd25519Key(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := make([]byte, 0)
	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}
	if !ok {
		t.Fatal("signature didn't match")
	}
}

func TestMarshalLoop(t *testing.T) {
	priv, pub, err := GenerateEd25519Key(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	t.Run("PrivateKey", func(t *testing.T) {
		for name, f := range map[string]func() ([]byte, error){
			"Marshal": func() ([]byte, error) {
				return MarshalPrivateKey(priv)
			},
			"Redundant": func() ([]byte, error) {
				// See issue #36.
				// Ed25519 private keys used to contain the public key twice.
				// For backwards-compatibility, we need to continue supporting
				// that scenario.
				data, err := priv.Raw()
				if err != nil {
					t.Fatal(err)
				}
				data = append(data, data[len(data)-ed25519.PublicKeySize:]...)
				return proto.Marshal(&pb.PrivateKey{
					Type: priv.Type().Enum(),
					Data: data,
				})
			},
		} {
			t.Run(name, func(t *testing.T) {
				bts, err := f()
				if err != nil {
					t.Fatal(err)
				}

				privNew, err := UnmarshalPrivateKey(bts)
				if err != nil {
					t.Fatal(err)
				}

				if !priv.Equals(privNew) || !privNew.Equals(priv) {
					t.Fatal("keys are not equal")
				}

				msg := []byte("My child, my sister,\nThink of the rapture\nOf living together there!")
				signed, err := privNew.Sign(msg)
				if err != nil {
					t.Fatal(err)
				}

				ok, err := privNew.GetPublic().Verify(msg, signed)
				if err != nil {
					t.Fatal(err)
				}

				if !ok {
					t.Fatal("signature didn't match")
				}
			})
		}
	})

	t.Run("PublicKey", func(t *testing.T) {
		for name, f := range map[string]func() ([]byte, error){
			"Marshal": func() ([]byte, error) {
				return MarshalPublicKey(pub)
			},
		} {
			t.Run(name, func(t *testing.T) {
				bts, err := f()
				if err != nil {
					t.Fatal(err)
				}
				pubNew, err := UnmarshalPublicKey(bts)
				if err != nil {
					t.Fatal(err)
				}

				if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
					t.Fatal("keys are not equal")
				}
			})
		}
	})
}

func TestUnmarshalErrors(t *testing.T) {
	t.Run("PublicKey", func(t *testing.T) {
		t.Run("Invalid data length", func(t *testing.T) {
			data, err := proto.Marshal(&pb.PublicKey{
				Type: pb.KeyType_Ed25519.Enum(),
				Data: []byte{42},
			})
			if err != nil {
				t.Fatal(err)
			}
			if _, err := UnmarshalPublicKey(data); err == nil {
				t.Fatal("expected an error")
			}
		})
	})

	t.Run("PrivateKey", func(t *testing.T) {
		t.Run("Redundant public key mismatch", func(t *testing.T) {
			priv, _, err := GenerateEd25519Key(rand.Reader)
			if err != nil {
				t.Fatal(err)
			}

			data, err := priv.Raw()
			if err != nil {
				t.Fatal(err)
			}
			// Append the private key instead of the public key.
			data = append(data, data[:ed25519.PublicKeySize]...)

			b, err := proto.Marshal(&pb.PrivateKey{
				Type: priv.Type().Enum(),
				Data: data,
			})
			if err != nil {
				t.Fatal(err)
			}

			_, err = UnmarshalPrivateKey(b)
			if err == nil {
				t.Fatal("expected an error")
			}
			if err.Error() != "expected redundant ed25519 public key to be redundant" {
				t.Fatalf("invalid error received: %s", err.Error())
			}
		})

		t.Run("Invalid data length", func(t *testing.T) {
			data, err := proto.Marshal(&pb.PrivateKey{
				Type: pb.KeyType_Ed25519.Enum(),
				Data: []byte{42},
			})
			if err != nil {
				t.Fatal(err)
			}

			_, err = UnmarshalPrivateKey(data)
			if err == nil {
				t.Fatal("expected an error")
			}
		})
	})
}


================================================
FILE: core/crypto/fixture_test.go
================================================
package crypto_test

import (
	"bytes"
	"crypto/rand"
	"fmt"
	"io"
	"os"
	"testing"

	"github.com/libp2p/go-libp2p/core/crypto"
	crypto_pb "github.com/libp2p/go-libp2p/core/crypto/pb"
)

var message = []byte("Libp2p is the _best_!")

type testCase struct {
	keyType          crypto_pb.KeyType
	gen              func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error)
	sigDeterministic bool
}

var keyTypes = []testCase{
	{
		keyType: crypto_pb.KeyType_ECDSA,
		gen:     crypto.GenerateECDSAKeyPair,
	},
	{
		keyType:          crypto_pb.KeyType_Secp256k1,
		sigDeterministic: true,
		gen:              crypto.GenerateSecp256k1Key,
	},
	{
		keyType:          crypto_pb.KeyType_RSA,
		sigDeterministic: true,
		gen: func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error) {
			return crypto.GenerateRSAKeyPair(2048, i)
		},
	},
}

func fname(kt crypto_pb.KeyType, ext string) string {
	return fmt.Sprintf("test_data/%d.%s", kt, ext)
}

func TestFixtures(t *testing.T) {
	for _, tc := range keyTypes {
		t.Run(tc.keyType.String(), func(t *testing.T) {
			pubBytes, err := os.ReadFile(fname(tc.keyType, "pub"))
			if err != nil {
				t.Fatal(err)
			}
			privBytes, err := os.ReadFile(fname(tc.keyType, "priv"))
			if err != nil {
				t.Fatal(err)
			}
			sigBytes, err := os.ReadFile(fname(tc.keyType, "sig"))
			if err != nil {
				t.Fatal(err)
			}
			pub, err := crypto.UnmarshalPublicKey(pubBytes)
			if err != nil {
				t.Fatal(err)
			}
			pubBytes2, err := crypto.MarshalPublicKey(pub)
			if err != nil {
				t.Fatal(err)
			}
			if !bytes.Equal(pubBytes2, pubBytes) {
				t.Fatal("encoding round-trip failed")
			}
			priv, err := crypto.UnmarshalPrivateKey(privBytes)
			if err != nil {
				t.Fatal(err)
			}
			privBytes2, err := crypto.MarshalPrivateKey(priv)
			if err != nil {
				t.Fatal(err)
			}
			if !bytes.Equal(privBytes2, privBytes) {
				t.Fatal("encoding round-trip failed")
			}
			ok, err := pub.Verify(message, sigBytes)
			if !ok || err != nil {
				t.Fatal("failed to validate signature with public key")
			}

			if tc.sigDeterministic {
				sigBytes2, err := priv.Sign(message)
				if err != nil {
					t.Fatal(err)
				}
				if !bytes.Equal(sigBytes2, sigBytes) {
					t.Fatal("signature not deterministic")
				}
			}
		})
	}
}

func init() {
	// set to true to re-generate test data
	if false {
		generate()
		panic("generated")
	}
}

// generate re-generates test data
func generate() {
	for _, tc := range keyTypes {
		priv, pub, err := tc.gen(rand.Reader)
		if err != nil {
			panic(err)
		}
		pubb, err := crypto.MarshalPublicKey(pub)
		if err != nil {
			panic(err)
		}
		privb, err := crypto.MarshalPrivateKey(priv)
		if err != nil {
			panic(err)
		}
		sig, err := priv.Sign(message)
		if err != nil {
			panic(err)
		}
		os.WriteFile(fname(tc.keyType, "pub"), pubb, 0666)
		os.WriteFile(fname(tc.keyType, "priv"), privb, 0666)
		os.WriteFile(fname(tc.keyType, "sig"), sig, 0666)
	}
}


================================================
FILE: core/crypto/key.go
================================================
// Package crypto implements various cryptographic utilities used by libp2p.
// This includes a Public and Private key interface and key implementations
// for supported key algorithms.
package crypto

import (
	"crypto/rand"
	"crypto/subtle"
	"encoding/base64"
	"errors"
	"io"

	"github.com/libp2p/go-libp2p/core/crypto/pb"

	"google.golang.org/protobuf/proto"
)

const (
	// RSA is an enum for the supported RSA key type
	RSA = iota
	// Ed25519 is an enum for the supported Ed25519 key type
	Ed25519
	// Secp256k1 is an enum for the supported Secp256k1 key type
	Secp256k1
	// ECDSA is an enum for the supported ECDSA key type
	ECDSA
)

var (
	// ErrBadKeyType is returned when a key is not supported
	ErrBadKeyType = errors.New("invalid or unsupported key type")
	// KeyTypes is a list of supported keys
	KeyTypes = []int{
		RSA,
		Ed25519,
		Secp256k1,
		ECDSA,
	}
)

// PubKeyUnmarshaller is a func that creates a PubKey from a given slice of bytes
type PubKeyUnmarshaller func(data []byte) (PubKey, error)

// PrivKeyUnmarshaller is a func that creates a PrivKey from a given slice of bytes
type PrivKeyUnmarshaller func(data []byte) (PrivKey, error)

// PubKeyUnmarshallers is a map of unmarshallers by key type
var PubKeyUnmarshallers = map[pb.KeyType]PubKeyUnmarshaller{
	pb.KeyType_RSA:       UnmarshalRsaPublicKey,
	pb.KeyType_Ed25519:   UnmarshalEd25519PublicKey,
	pb.KeyType_Secp256k1: UnmarshalSecp256k1PublicKey,
	pb.KeyType_ECDSA:     UnmarshalECDSAPublicKey,
}

// PrivKeyUnmarshallers is a map of unmarshallers by key type
var PrivKeyUnmarshallers = map[pb.KeyType]PrivKeyUnmarshaller{
	pb.KeyType_RSA:       UnmarshalRsaPrivateKey,
	pb.KeyType_Ed25519:   UnmarshalEd25519PrivateKey,
	pb.KeyType_Secp256k1: UnmarshalSecp256k1PrivateKey,
	pb.KeyType_ECDSA:     UnmarshalECDSAPrivateKey,
}

// Key represents a crypto key that can be compared to another key
type Key interface {
	// Equals checks whether two PubKeys are the same
	Equals(Key) bool

	// Raw returns the raw bytes of the key (not wrapped in the
	// libp2p-crypto protobuf).
	//
	// This function is the inverse of {Priv,Pub}KeyUnmarshaler.
	Raw() ([]byte, error)

	// Type returns the protobuf key type.
	Type() pb.KeyType
}

// PrivKey represents a private key that can be used to generate a public key and sign data
type PrivKey interface {
	Key

	// Cryptographically sign the given bytes
	Sign([]byte) ([]byte, error)

	// Return a public key paired with this private key
	GetPublic() PubKey
}

// PubKey is a public key that can be used to verify data signed with the corresponding private key
type PubKey interface {
	Key

	// Verify that 'sig' is the signed hash of 'data'
	Verify(data []byte, sig []byte) (bool, error)
}

// GenSharedKey generates the shared key from a given private key
type GenSharedKey func([]byte) ([]byte, error)

// GenerateKeyPair generates a private and public key
func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
	return GenerateKeyPairWithReader(typ, bits, rand.Reader)
}

// GenerateKeyPairWithReader returns a keypair of the given type and bit-size
func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, error) {
	switch typ {
	case RSA:
		return GenerateRSAKeyPair(bits, src)
	case Ed25519:
		return GenerateEd25519Key(src)
	case Secp256k1:
		return GenerateSecp256k1Key(src)
	case ECDSA:
		return GenerateECDSAKeyPair(src)
	default:
		return nil, nil, ErrBadKeyType
	}
}

// UnmarshalPublicKey converts a protobuf serialized public key into its
// representative object
func UnmarshalPublicKey(data []byte) (PubKey, error) {
	pmes := new(pb.PublicKey)
	err := proto.Unmarshal(data, pmes)
	if err != nil {
		return nil, err
	}

	return PublicKeyFromProto(pmes)
}

// PublicKeyFromProto converts an unserialized protobuf PublicKey message
// into its representative object.
func PublicKeyFromProto(pmes *pb.PublicKey) (PubKey, error) {
	um, ok := PubKeyUnmarshallers[pmes.GetType()]
	if !ok {
		return nil, ErrBadKeyType
	}

	data := pmes.GetData()

	pk, err := um(data)
	if err != nil {
		return nil, err
	}

	switch tpk := pk.(type) {
	case *RsaPublicKey:
		tpk.cached, _ = proto.Marshal(pmes)
	}

	return pk, nil
}

// MarshalPublicKey converts a public key object into a protobuf serialized
// public key
func MarshalPublicKey(k PubKey) ([]byte, error) {
	pbmes, err := PublicKeyToProto(k)
	if err != nil {
		return nil, err
	}

	return proto.Marshal(pbmes)
}

// PublicKeyToProto converts a public key object into an unserialized
// protobuf PublicKey message.
func PublicKeyToProto(k PubKey) (*pb.PublicKey, error) {
	data, err := k.Raw()
	if err != nil {
		return nil, err
	}
	return &pb.PublicKey{
		Type: k.Type().Enum(),
		Data: data,
	}, nil
}

// UnmarshalPrivateKey converts a protobuf serialized private key into its
// representative object
func UnmarshalPrivateKey(data []byte) (PrivKey, error) {
	pmes := new(pb.PrivateKey)
	err := proto.Unmarshal(data, pmes)
	if err != nil {
		return nil, err
	}

	um, ok := PrivKeyUnmarshallers[pmes.GetType()]
	if !ok {
		return nil, ErrBadKeyType
	}

	return um(pmes.GetData())
}

// MarshalPrivateKey converts a key object into its protobuf serialized form.
func MarshalPrivateKey(k PrivKey) ([]byte, error) {
	data, err := k.Raw()
	if err != nil {
		return nil, err
	}
	return proto.Marshal(&pb.PrivateKey{
		Type: k.Type().Enum(),
		Data: data,
	})
}

// ConfigDecodeKey decodes from b64 (for config file) to a byte array that can be unmarshalled.
func ConfigDecodeKey(b string) ([]byte, error) {
	return base64.StdEncoding.DecodeString(b)
}

// ConfigEncodeKey encodes a marshalled key to b64 (for config file).
func ConfigEncodeKey(b []byte) string {
	return base64.StdEncoding.EncodeToString(b)
}

// KeyEqual checks whether two Keys are equivalent (have identical byte representations).
func KeyEqual(k1, k2 Key) bool {
	if k1 == k2 {
		return true
	}

	return k1.Equals(k2)
}

func basicEquals(k1, k2 Key) bool {
	if k1.Type() != k2.Type() {
		return false
	}

	a, err := k1.Raw()
	if err != nil {
		return false
	}
	b, err := k2.Raw()
	if err != nil {
		return false
	}
	return subtle.ConstantTimeCompare(a, b) == 1
}


================================================
FILE: core/crypto/key_test.go
================================================
package crypto_test

import (
	"bytes"
	"crypto"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"fmt"
	"reflect"
	"testing"

	. "github.com/libp2p/go-libp2p/core/crypto"
	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
	"github.com/libp2p/go-libp2p/core/test"

	"github.com/decred/dcrd/dcrec/secp256k1/v4"
	secp256k1ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
)

func TestKeys(t *testing.T) {
	for _, typ := range KeyTypes {
		testKeyType(typ, t)
	}
}

func TestKeyPairFromKey(t *testing.T) {
	var (
		data   = []byte(`hello world`)
		hashed = sha256.Sum256(data)
	)

	privk, err := secp256k1.GeneratePrivateKey()
	if err != nil {
		t.Fatalf("err generating btcec priv key:\n%v", err)
	}
	sigK := secp256k1ecdsa.Sign(privk, hashed[:])

	eKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatalf("err generating ecdsa priv key:\n%v", err)
	}
	sigE, err := eKey.Sign(rand.Reader, hashed[:], crypto.SHA256)
	if err != nil {
		t.Fatalf("err generating ecdsa sig:\n%v", err)
	}

	rKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		t.Fatalf("err generating rsa priv key:\n%v", err)
	}
	sigR, err := rKey.Sign(rand.Reader, hashed[:], crypto.SHA256)
	if err != nil {
		t.Fatalf("err generating rsa sig:\n%v", err)
	}

	_, edKey, err := ed25519.GenerateKey(rand.Reader)
	sigEd := ed25519.Sign(edKey, data[:])
	if err != nil {
		t.Fatalf("err generating ed25519 sig:\n%v", err)
	}

	for i, tt := range []struct {
		in  crypto.PrivateKey
		typ pb.KeyType
		sig []byte
	}{
		{
			eKey,
			ECDSA,
			sigE,
		},
		{
			privk,
			Secp256k1,
			sigK.Serialize(),
		},
		{
			rKey,
			RSA,
			sigR,
		},
		{
			&edKey,
			Ed25519,
			sigEd,
		},
	} {
		t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
			priv, pub, err := KeyPairFromStdKey(tt.in)
			if err != nil {
				t.Fatal(err)
			}

			if priv == nil || pub == nil {
				t.Errorf("received nil private key or public key: %v, %v", priv, pub)
			}

			if priv == nil || priv.Type() != tt.typ {
				t.Errorf("want %v; got %v", tt.typ, priv.Type())
			}

			v, err := pub.Verify(data[:], tt.sig)
			if err != nil {
				t.Error(err)
			}

			if !v {
				t.Error("signature was not verified")
			}

			stdPub, err := PubKeyToStdKey(pub)
			if stdPub == nil {
				t.Errorf("err getting std public key from key: %v", err)
			}

			var stdPubBytes []byte

			switch p := stdPub.(type) {
			case *Secp256k1PublicKey:
				stdPubBytes, err = p.Raw()
			case ed25519.PublicKey:
				stdPubBytes = []byte(p)
			default:
				stdPubBytes, err = x509.MarshalPKIXPublicKey(stdPub)
			}

			if err != nil {
				t.Errorf("Error while marshaling %v key: %v", reflect.TypeOf(stdPub), err)
			}

			pubBytes, err := pub.Raw()
			if err != nil {
				t.Errorf("err getting raw bytes for %v key: %v", reflect.TypeOf(pub), err)
			}
			if !bytes.Equal(stdPubBytes, pubBytes) {
				t.Errorf("err roundtripping %v key", reflect.TypeOf(pub))
			}

			stdPriv, err := PrivKeyToStdKey(priv)
			if stdPub == nil {
				t.Errorf("err getting std private key from key: %v", err)
			}

			var stdPrivBytes []byte

			switch p := stdPriv.(type) {
			case *Secp256k1PrivateKey:
				stdPrivBytes, err = p.Raw()
			case *ecdsa.PrivateKey:
				stdPrivBytes, err = x509.MarshalECPrivateKey(p)
			case *ed25519.PrivateKey:
				stdPrivBytes = *p
			case *rsa.PrivateKey:
				stdPrivBytes = x509.MarshalPKCS1PrivateKey(p)
			}

			if err != nil {
				t.Errorf("err marshaling %v key: %v", reflect.TypeOf(stdPriv), err)
			}

			privBytes, err := priv.Raw()
			if err != nil {
				t.Errorf("err getting raw bytes for %v key: %v", reflect.TypeOf(priv), err)
			}

			if !bytes.Equal(stdPrivBytes, privBytes) {
				t.Errorf("err roundtripping %v key", reflect.TypeOf(priv))
			}
		})
	}
}

func testKeyType(typ int, t *testing.T) {
	bits := 512
	if typ == RSA {
		bits = 2048
	}
	sk, pk, err := test.RandTestKeyPair(typ, bits)
	if err != nil {
		t.Fatal(err)
	}

	testKeySignature(t, sk)
	testKeyEncoding(t, sk)
	testKeyEquals(t, sk)
	testKeyEquals(t, pk)
}

func testKeySignature(t *testing.T, sk PrivKey) {
	pk := sk.GetPublic()

	text := make([]byte, 16)
	if _, err := rand.Read(text); err != nil {
		t.Fatal(err)
	}

	sig, err := sk.Sign(text)
	if err != nil {
		t.Fatal(err)
	}

	valid, err := pk.Verify(text, sig)
	if err != nil {
		t.Fatal(err)
	}

	if !valid {
		t.Fatal("Invalid signature.")
	}
}

func testKeyEncoding(t *testing.T, sk PrivKey) {
	skbm, err := MarshalPrivateKey(sk)
	if err != nil {
		t.Fatal(err)
	}

	sk2, err := UnmarshalPrivateKey(skbm)
	if err != nil {
		t.Fatal(err)
	}

	if !sk.Equals(sk2) {
		t.Error("Unmarshaled private key didn't match original.\n")
	}

	skbm2, err := MarshalPrivateKey(sk2)
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(skbm, skbm2) {
		t.Error("skb -> marshal -> unmarshal -> skb failed.\n", skbm, "\n", skbm2)
	}

	pk := sk.GetPublic()
	pkbm, err := MarshalPublicKey(pk)
	if err != nil {
		t.Fatal(err)
	}

	pk2, err := UnmarshalPublicKey(pkbm)
	if err != nil {
		t.Fatal(err)
	}

	if !pk.Equals(pk2) {
		t.Error("Unmarshaled public key didn't match original.\n")
	}

	pkbm2, err := MarshalPublicKey(pk)
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(pkbm, pkbm2) {
		t.Error("skb -> marshal -> unmarshal -> skb failed.\n", pkbm, "\n", pkbm2)
	}
}

func testKeyEquals(t *testing.T, k Key) {
	// kb, err := k.Raw()
	// if err != nil {
	// 	t.Fatal(err)
	// }

	if !KeyEqual(k, k) {
		t.Fatal("Key not equal to itself.")
	}

	// bad test, relies on deep internals..
	// if !KeyEqual(k, testkey(kb)) {
	// 	t.Fatal("Key not equal to key with same bytes.")
	// }

	sk, pk, err := test.RandTestKeyPair(RSA, 2048)
	if err != nil {
		t.Fatal(err)
	}

	if KeyEqual(k, sk) {
		t.Fatal("Keys should not equal.")
	}

	if KeyEqual(k, pk) {
		t.Fatal("Keys should not equal.")
	}
}


================================================
FILE: core/crypto/key_to_stdlib.go
================================================
package crypto

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/rsa"

	"github.com/decred/dcrd/dcrec/secp256k1/v4"
)

// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p/core/crypto keys
func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) {
	if priv == nil {
		return nil, nil, ErrNilPrivateKey
	}

	switch p := priv.(type) {
	case *rsa.PrivateKey:
		return &RsaPrivateKey{*p}, &RsaPublicKey{k: p.PublicKey}, nil

	case *ecdsa.PrivateKey:
		return &ECDSAPrivateKey{p}, &ECDSAPublicKey{&p.PublicKey}, nil

	case *ed25519.PrivateKey:
		pubIfc := p.Public()
		pub, _ := pubIfc.(ed25519.PublicKey)
		return &Ed25519PrivateKey{*p}, &Ed25519PublicKey{pub}, nil

	case *secp256k1.PrivateKey:
		sPriv := Secp256k1PrivateKey(*p)
		sPub := Secp256k1PublicKey(*p.PubKey())
		return &sPriv, &sPub, nil

	default:
		return nil, nil, ErrBadKeyType
	}
}

// PrivKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) private keys
func PrivKeyToStdKey(priv PrivKey) (crypto.PrivateKey, error) {
	if priv == nil {
		return nil, ErrNilPrivateKey
	}

	switch p := priv.(type) {
	case *RsaPrivateKey:
		return &p.sk, nil
	case *ECDSAPrivateKey:
		return p.priv, nil
	case *Ed25519PrivateKey:
		return &p.k, nil
	case *Secp256k1PrivateKey:
		return p, nil
	default:
		return nil, ErrBadKeyType
	}
}

// PubKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) public keys
func PubKeyToStdKey(pub PubKey) (crypto.PublicKey, error) {
	if pub == nil {
		return nil, ErrNilPublicKey
	}

	switch p := pub.(type) {
	case *RsaPublicKey:
		return &p.k, nil
	case *ECDSAPublicKey:
		return p.pub, nil
	case *Ed25519PublicKey:
		return p.k, nil
	case *Secp256k1PublicKey:
		return p, nil
	default:
		return nil, ErrBadKeyType
	}
}


================================================
FILE: core/crypto/pb/crypto.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.36.6
// 	protoc        v5.29.2
// source: core/crypto/pb/crypto.proto

package pb

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
	unsafe "unsafe"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type KeyType int32

const (
	KeyType_RSA       KeyType = 0
	KeyType_Ed25519   KeyType = 1
	KeyType_Secp256k1 KeyType = 2
	KeyType_ECDSA     KeyType = 3
)

// Enum value maps for KeyType.
var (
	KeyType_name = map[int32]string{
		0: "RSA",
		1: "Ed25519",
		2: "Secp256k1",
		3: "ECDSA",
	}
	KeyType_value = map[string]int32{
		"RSA":       0,
		"Ed25519":   1,
		"Secp256k1": 2,
		"ECDSA":     3,
	}
)

func (x KeyType) Enum() *KeyType {
	p := new(KeyType)
	*p = x
	return p
}

func (x KeyType) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (KeyType) Descriptor() protoreflect.EnumDescriptor {
	return file_core_crypto_pb_crypto_proto_enumTypes[0].Descriptor()
}

func (KeyType) Type() protoreflect.EnumType {
	return &file_core_crypto_pb_crypto_proto_enumTypes[0]
}

func (x KeyType) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Do not use.
func (x *KeyType) UnmarshalJSON(b []byte) error {
	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
	if err != nil {
		return err
	}
	*x = KeyType(num)
	return nil
}

// Deprecated: Use KeyType.Descriptor instead.
func (KeyType) EnumDescriptor() ([]byte, []int) {
	return file_core_crypto_pb_crypto_proto_rawDescGZIP(), []int{0}
}

type PublicKey struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Type          *KeyType               `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type,omitempty"`
	Data          []byte                 `protobuf:"bytes,2,req,name=Data" json:"Data,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *PublicKey) Reset() {
	*x = PublicKey{}
	mi := &file_core_crypto_pb_crypto_proto_msgTypes[0]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *PublicKey) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*PublicKey) ProtoMessage() {}

func (x *PublicKey) ProtoReflect() protoreflect.Message {
	mi := &file_core_crypto_pb_crypto_proto_msgTypes[0]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead.
func (*PublicKey) Descriptor() ([]byte, []int) {
	return file_core_crypto_pb_crypto_proto_rawDescGZIP(), []int{0}
}

func (x *PublicKey) GetType() KeyType {
	if x != nil && x.Type != nil {
		return *x.Type
	}
	return KeyType_RSA
}

func (x *PublicKey) GetData() []byte {
	if x != nil {
		return x.Data
	}
	return nil
}

type PrivateKey struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Type          *KeyType               `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type,omitempty"`
	Data          []byte                 `protobuf:"bytes,2,req,name=Data" json:"Data,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *PrivateKey) Reset() {
	*x = PrivateKey{}
	mi := &file_core_crypto_pb_crypto_proto_msgTypes[1]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *PrivateKey) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*PrivateKey) ProtoMessage() {}

func (x *PrivateKey) ProtoReflect() protoreflect.Message {
	mi := &file_core_crypto_pb_crypto_proto_msgTypes[1]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use PrivateKey.ProtoReflect.Descriptor instead.
func (*PrivateKey) Descriptor() ([]byte, []int) {
	return file_core_crypto_pb_crypto_proto_rawDescGZIP(), []int{1}
}

func (x *PrivateKey) GetType() KeyType {
	if x != nil && x.Type != nil {
		return *x.Type
	}
	return KeyType_RSA
}

func (x *PrivateKey) GetData() []byte {
	if x != nil {
		return x.Data
	}
	return nil
}

var File_core_crypto_pb_crypto_proto protoreflect.FileDescriptor

const file_core_crypto_pb_crypto_proto_rawDesc = "" +
	"\n" +
	"\x1bcore/crypto/pb/crypto.proto\x12\tcrypto.pb\"G\n" +
	"\tPublicKey\x12&\n" +
	"\x04Type\x18\x01 \x02(\x0e2\x12.crypto.pb.KeyTypeR\x04Type\x12\x12\n" +
	"\x04Data\x18\x02 \x02(\fR\x04Data\"H\n" +
	"\n" +
	"PrivateKey\x12&\n" +
	"\x04Type\x18\x01 \x02(\x0e2\x12.crypto.pb.KeyTypeR\x04Type\x12\x12\n" +
	"\x04Data\x18\x02 \x02(\fR\x04Data*9\n" +
	"\aKeyType\x12\a\n" +
	"\x03RSA\x10\x00\x12\v\n" +
	"\aEd25519\x10\x01\x12\r\n" +
	"\tSecp256k1\x10\x02\x12\t\n" +
	"\x05ECDSA\x10\x03B,Z*github.com/libp2p/go-libp2p/core/crypto/pb"

var (
	file_core_crypto_pb_crypto_proto_rawDescOnce sync.Once
	file_core_crypto_pb_crypto_proto_rawDescData []byte
)

func file_core_crypto_pb_crypto_proto_rawDescGZIP() []byte {
	file_core_crypto_pb_crypto_proto_rawDescOnce.Do(func() {
		file_core_crypto_pb_crypto_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_core_crypto_pb_crypto_proto_rawDesc), len(file_core_crypto_pb_crypto_proto_rawDesc)))
	})
	return file_core_crypto_pb_crypto_proto_rawDescData
}

var file_core_crypto_pb_crypto_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_core_crypto_pb_crypto_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_core_crypto_pb_crypto_proto_goTypes = []any{
	(KeyType)(0),       // 0: crypto.pb.KeyType
	(*PublicKey)(nil),  // 1: crypto.pb.PublicKey
	(*PrivateKey)(nil), // 2: crypto.pb.PrivateKey
}
var file_core_crypto_pb_crypto_proto_depIdxs = []int32{
	0, // 0: crypto.pb.PublicKey.Type:type_name -> crypto.pb.KeyType
	0, // 1: crypto.pb.PrivateKey.Type:type_name -> crypto.pb.KeyType
	2, // [2:2] is the sub-list for method output_type
	2, // [2:2] is the sub-list for method input_type
	2, // [2:2] is the sub-list for extension type_name
	2, // [2:2] is the sub-list for extension extendee
	0, // [0:2] is the sub-list for field type_name
}

func init() { file_core_crypto_pb_crypto_proto_init() }
func file_core_crypto_pb_crypto_proto_init() {
	if File_core_crypto_pb_crypto_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_core_crypto_pb_crypto_proto_rawDesc), len(file_core_crypto_pb_crypto_proto_rawDesc)),
			NumEnums:      1,
			NumMessages:   2,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_core_crypto_pb_crypto_proto_goTypes,
		DependencyIndexes: file_core_crypto_pb_crypto_proto_depIdxs,
		EnumInfos:         file_core_crypto_pb_crypto_proto_enumTypes,
		MessageInfos:      file_core_crypto_pb_crypto_proto_msgTypes,
	}.Build()
	File_core_crypto_pb_crypto_proto = out.File
	file_core_crypto_pb_crypto_proto_goTypes = nil
	file_core_crypto_pb_crypto_proto_depIdxs = nil
}


================================================
FILE: core/crypto/pb/crypto.proto
================================================
syntax = "proto2";

package crypto.pb;

option go_package = "github.com/libp2p/go-libp2p/core/crypto/pb";

enum KeyType {
	RSA = 0;
	Ed25519 = 1;
	Secp256k1 = 2;
	ECDSA = 3;
}

message PublicKey {
	required KeyType Type = 1;
	required bytes Data = 2;
}

message PrivateKey {
	required KeyType Type = 1;
	required bytes Data = 2;
}


================================================
FILE: core/crypto/rsa_common.go
================================================
package crypto

import (
	"fmt"
	"os"
)

// WeakRsaKeyEnv is an environment variable which, when set, lowers the
// minimum required bits of RSA keys to 512. This should be used exclusively in
// test situations.
const WeakRsaKeyEnv = "LIBP2P_ALLOW_WEAK_RSA_KEYS"

var MinRsaKeyBits = 2048

var maxRsaKeyBits = 8192

// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key
// that's smaller than MinRsaKeyBits bits. In test
var ErrRsaKeyTooSmall error
var ErrRsaKeyTooBig error = fmt.Errorf("rsa keys must be <= %d bits", maxRsaKeyBits)

func init() {
	if _, ok := os.LookupEnv(WeakRsaKeyEnv); ok {
		MinRsaKeyBits = 512
	}

	ErrRsaKeyTooSmall = fmt.Errorf("rsa keys must be >= %d bits to be useful", MinRsaKeyBits)
}


================================================
FILE: core/crypto/rsa_go.go
================================================
package crypto

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"errors"
	"io"

	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
	"github.com/libp2p/go-libp2p/core/internal/catch"
)

// RsaPrivateKey is a rsa private key
type RsaPrivateKey struct {
	sk rsa.PrivateKey
}

// RsaPublicKey is a rsa public key
type RsaPublicKey struct {
	k rsa.PublicKey

	cached []byte
}

// GenerateRSAKeyPair generates a new rsa private and public key
func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
	if bits < MinRsaKeyBits {
		return nil, nil, ErrRsaKeyTooSmall
	}
	if bits > maxRsaKeyBits {
		return nil, nil, ErrRsaKeyTooBig
	}
	priv, err := rsa.GenerateKey(src, bits)
	if err != nil {
		return nil, nil, err
	}
	pk := priv.PublicKey
	return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{k: pk}, nil
}

// Verify compares a signature against input data
func (pk *RsaPublicKey) Verify(data, sig []byte) (success bool, err error) {
	defer func() {
		catch.HandlePanic(recover(), &err, "RSA signature verification")

		// To be safe
		if err != nil {
			success = false
		}
	}()
	hashed := sha256.Sum256(data)
	err = rsa.VerifyPKCS1v15(&pk.k, crypto.SHA256, hashed[:], sig)
	if err != nil {
		return false, err
	}
	return true, nil
}

func (pk *RsaPublicKey) Type() pb.KeyType {
	return pb.KeyType_RSA
}

func (pk *RsaPublicKey) Raw() (res []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "RSA public-key marshaling") }()
	return x509.MarshalPKIXPublicKey(&pk.k)
}

// Equals checks whether this key is equal to another
func (pk *RsaPublicKey) Equals(k Key) bool {
	// make sure this is a rsa public key
	other, ok := (k).(*RsaPublicKey)
	if !ok {
		return basicEquals(pk, k)
	}

	return pk.k.N.Cmp(other.k.N) == 0 && pk.k.E == other.k.E
}

// Sign returns a signature of the input data
func (sk *RsaPrivateKey) Sign(message []byte) (sig []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "RSA signing") }()
	hashed := sha256.Sum256(message)
	return rsa.SignPKCS1v15(rand.Reader, &sk.sk, crypto.SHA256, hashed[:])
}

// GetPublic returns a public key
func (sk *RsaPrivateKey) GetPublic() PubKey {
	return &RsaPublicKey{k: sk.sk.PublicKey}
}

func (sk *RsaPrivateKey) Type() pb.KeyType {
	return pb.KeyType_RSA
}

func (sk *RsaPrivateKey) Raw() (res []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "RSA private-key marshaling") }()
	b := x509.MarshalPKCS1PrivateKey(&sk.sk)
	return b, nil
}

// Equals checks whether this key is equal to another
func (sk *RsaPrivateKey) Equals(k Key) bool {
	// make sure this is a rsa public key
	other, ok := (k).(*RsaPrivateKey)
	if !ok {
		return basicEquals(sk, k)
	}

	a := sk.sk
	b := other.sk

	// Don't care about constant time. We're only comparing the public half.
	return a.PublicKey.N.Cmp(b.PublicKey.N) == 0 && a.PublicKey.E == b.PublicKey.E
}

// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes
func UnmarshalRsaPrivateKey(b []byte) (key PrivKey, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "RSA private-key unmarshaling") }()
	sk, err := x509.ParsePKCS1PrivateKey(b)
	if err != nil {
		return nil, err
	}
	if sk.N.BitLen() < MinRsaKeyBits {
		return nil, ErrRsaKeyTooSmall
	}
	if sk.N.BitLen() > maxRsaKeyBits {
		return nil, ErrRsaKeyTooBig
	}
	return &RsaPrivateKey{sk: *sk}, nil
}

// UnmarshalRsaPublicKey returns a public key from the input x509 bytes
func UnmarshalRsaPublicKey(b []byte) (key PubKey, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "RSA public-key unmarshaling") }()
	pub, err := x509.ParsePKIXPublicKey(b)
	if err != nil {
		return nil, err
	}
	pk, ok := pub.(*rsa.PublicKey)
	if !ok {
		return nil, errors.New("not actually an rsa public key")
	}
	if pk.N.BitLen() < MinRsaKeyBits {
		return nil, ErrRsaKeyTooSmall
	}
	if pk.N.BitLen() > maxRsaKeyBits {
		return nil, ErrRsaKeyTooBig
	}

	return &RsaPublicKey{k: *pk}, nil
}


================================================
FILE: core/crypto/rsa_test.go
================================================
package crypto

import (
	"crypto/rand"
	"testing"
)

func TestRSABasicSignAndVerify(t *testing.T) {
	priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := []byte("hello! and welcome to some awesome crypto primitives")

	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}

	if !ok {
		t.Fatal("signature didn't match")
	}

	// change data
	data[0] = ^data[0]
	ok, err = pub.Verify(data, sig)
	if err == nil {
		t.Fatal("should have produced a verification error")
	}

	if ok {
		t.Fatal("signature matched and shouldn't")
	}
}

func TestRSASmallKey(t *testing.T) {
	_, _, err := GenerateRSAKeyPair(MinRsaKeyBits/2, rand.Reader)
	if err != ErrRsaKeyTooSmall {
		t.Fatal("should have refused to create small RSA key")
	}
	MinRsaKeyBits /= 2
	badPriv, badPub, err := GenerateRSAKeyPair(MinRsaKeyBits, rand.Reader)
	if err != nil {
		t.Fatalf("should have succeeded, got: %s", err)
	}
	pubBytes, err := MarshalPublicKey(badPub)
	if err != nil {
		t.Fatal(err)
	}
	privBytes, err := MarshalPrivateKey(badPriv)
	if err != nil {
		t.Fatal(err)
	}
	MinRsaKeyBits *= 2
	_, err = UnmarshalPublicKey(pubBytes)
	if err != ErrRsaKeyTooSmall {
		t.Fatal("should have refused to unmarshal a weak key")
	}
	_, err = UnmarshalPrivateKey(privBytes)
	if err != ErrRsaKeyTooSmall {
		t.Fatal("should have refused to unmarshal a weak key")
	}
}

func TestRSABigKeyFailsToGenerate(t *testing.T) {
	_, _, err := GenerateRSAKeyPair(maxRsaKeyBits*2, rand.Reader)
	if err != ErrRsaKeyTooBig {
		t.Fatal("should have refused to create too big RSA key")
	}
}

func TestRSABigKey(t *testing.T) {
	// Make the global limit smaller for this test to run faster.
	// Note we also change the limit below, but this is different
	origSize := maxRsaKeyBits
	maxRsaKeyBits = 2048
	defer func() { maxRsaKeyBits = origSize }() //

	maxRsaKeyBits *= 2
	badPriv, badPub, err := GenerateRSAKeyPair(maxRsaKeyBits, rand.Reader)
	if err != nil {
		t.Fatalf("should have succeeded, got: %s", err)
	}
	pubBytes, err := MarshalPublicKey(badPub)
	if err != nil {
		t.Fatal(err)
	}
	privBytes, err := MarshalPrivateKey(badPriv)
	if err != nil {
		t.Fatal(err)
	}
	maxRsaKeyBits /= 2
	_, err = UnmarshalPublicKey(pubBytes)
	if err != ErrRsaKeyTooBig {
		t.Fatal("should have refused to unmarshal a too big key")
	}
	_, err = UnmarshalPrivateKey(privBytes)
	if err != ErrRsaKeyTooBig {
		t.Fatal("should have refused to unmarshal a too big key")
	}
}

func TestRSASignZero(t *testing.T) {
	priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := make([]byte, 0)
	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}
	if !ok {
		t.Fatal("signature didn't match")
	}
}

func TestRSAMarshalLoop(t *testing.T) {
	priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	privB, err := MarshalPrivateKey(priv)
	if err != nil {
		t.Fatal(err)
	}

	privNew, err := UnmarshalPrivateKey(privB)
	if err != nil {
		t.Fatal(err)
	}

	if !priv.Equals(privNew) || !privNew.Equals(priv) {
		t.Fatal("keys are not equal")
	}

	pubB, err := MarshalPublicKey(pub)
	if err != nil {
		t.Fatal(err)
	}
	pubNew, err := UnmarshalPublicKey(pubB)
	if err != nil {
		t.Fatal(err)
	}

	if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
		t.Fatal("keys are not equal")
	}
}


================================================
FILE: core/crypto/secp256k1.go
================================================
package crypto

import (
	"crypto/sha256"
	"fmt"
	"io"

	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
	"github.com/libp2p/go-libp2p/core/internal/catch"

	"github.com/decred/dcrd/dcrec/secp256k1/v4"
	"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
)

// Secp256k1PrivateKey is a Secp256k1 private key
type Secp256k1PrivateKey secp256k1.PrivateKey

// Secp256k1PublicKey is a Secp256k1 public key
type Secp256k1PublicKey secp256k1.PublicKey

// GenerateSecp256k1Key generates a new Secp256k1 private and public key pair
func GenerateSecp256k1Key(_ io.Reader) (PrivKey, PubKey, error) {
	privk, err := secp256k1.GeneratePrivateKey()
	if err != nil {
		return nil, nil, err
	}

	k := (*Secp256k1PrivateKey)(privk)
	return k, k.GetPublic(), nil
}

// UnmarshalSecp256k1PrivateKey returns a private key from bytes
func UnmarshalSecp256k1PrivateKey(data []byte) (k PrivKey, err error) {
	if len(data) != secp256k1.PrivKeyBytesLen {
		return nil, fmt.Errorf("expected secp256k1 data size to be %d", secp256k1.PrivKeyBytesLen)
	}
	defer func() { catch.HandlePanic(recover(), &err, "secp256k1 private-key unmarshal") }()

	privk := secp256k1.PrivKeyFromBytes(data)
	return (*Secp256k1PrivateKey)(privk), nil
}

// UnmarshalSecp256k1PublicKey returns a public key from bytes
func UnmarshalSecp256k1PublicKey(data []byte) (_k PubKey, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public-key unmarshal") }()
	k, err := secp256k1.ParsePubKey(data)
	if err != nil {
		return nil, err
	}

	return (*Secp256k1PublicKey)(k), nil
}

// Type returns the private key type
func (k *Secp256k1PrivateKey) Type() pb.KeyType {
	return pb.KeyType_Secp256k1
}

// Raw returns the bytes of the key
func (k *Secp256k1PrivateKey) Raw() ([]byte, error) {
	return (*secp256k1.PrivateKey)(k).Serialize(), nil
}

// Equals compares two private keys
func (k *Secp256k1PrivateKey) Equals(o Key) bool {
	sk, ok := o.(*Secp256k1PrivateKey)
	if !ok {
		return basicEquals(k, o)
	}

	return k.GetPublic().Equals(sk.GetPublic())
}

// Sign returns a signature from input data
func (k *Secp256k1PrivateKey) Sign(data []byte) (_sig []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "secp256k1 signing") }()
	key := (*secp256k1.PrivateKey)(k)
	hash := sha256.Sum256(data)
	sig := ecdsa.Sign(key, hash[:])

	return sig.Serialize(), nil
}

// GetPublic returns a public key
func (k *Secp256k1PrivateKey) GetPublic() PubKey {
	return (*Secp256k1PublicKey)((*secp256k1.PrivateKey)(k).PubKey())
}

// Type returns the public key type
func (k *Secp256k1PublicKey) Type() pb.KeyType {
	return pb.KeyType_Secp256k1
}

// Raw returns the bytes of the key
func (k *Secp256k1PublicKey) Raw() (res []byte, err error) {
	defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public key marshaling") }()
	return (*secp256k1.PublicKey)(k).SerializeCompressed(), nil
}

// Equals compares two public keys
func (k *Secp256k1PublicKey) Equals(o Key) bool {
	sk, ok := o.(*Secp256k1PublicKey)
	if !ok {
		return basicEquals(k, o)
	}

	return (*secp256k1.PublicKey)(k).IsEqual((*secp256k1.PublicKey)(sk))
}

// Verify compares a signature against the input data
func (k *Secp256k1PublicKey) Verify(data []byte, sigStr []byte) (success bool, err error) {
	defer func() {
		catch.HandlePanic(recover(), &err, "secp256k1 signature verification")

		// To be extra safe.
		if err != nil {
			success = false
		}
	}()
	sig, err := ecdsa.ParseDERSignature(sigStr)
	if err != nil {
		return false, err
	}

	hash := sha256.Sum256(data)
	return sig.Verify(hash[:], (*secp256k1.PublicKey)(k)), nil
}


================================================
FILE: core/crypto/secp256k1_test.go
================================================
package crypto

import (
	"crypto/rand"
	"testing"
)

func TestSecp256k1BasicSignAndVerify(t *testing.T) {
	priv, pub, err := GenerateSecp256k1Key(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := []byte("hello! and welcome to some awesome crypto primitives")

	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}

	if !ok {
		t.Fatal("signature didn't match")
	}

	// change data
	data[0] = ^data[0]
	ok, err = pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}

	if ok {
		t.Fatal("signature matched and shouldn't")
	}
}

func TestSecp256k1SignZero(t *testing.T) {
	priv, pub, err := GenerateSecp256k1Key(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := make([]byte, 0)
	sig, err := priv.Sign(data)
	if err != nil {
		t.Fatal(err)
	}

	ok, err := pub.Verify(data, sig)
	if err != nil {
		t.Fatal(err)
	}
	if !ok {
		t.Fatal("signature didn't match")
	}
}

func TestSecp256k1MarshalLoop(t *testing.T) {
	priv, pub, err := GenerateSecp256k1Key(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	privB, err := MarshalPrivateKey(priv)
	if err != nil {
		t.Fatal(err)
	}

	privNew, err := UnmarshalPrivateKey(privB)
	if err != nil {
		t.Fatal(err)
	}

	if !priv.Equals(privNew) || !privNew.Equals(priv) {
		t.Fatal("keys are not equal")
	}

	pubB, err := MarshalPublicKey(pub)
	if err != nil {
		t.Fatal(err)
	}
	pubNew, err := UnmarshalPublicKey(pubB)
	if err != nil {
		t.Fatal(err)
	}

	if !pub.Equals(pubNew) || !pubNew.Equals(pub) {
		t.Fatal("keys are not equal")
	}

}


================================================
FILE: core/crypto/test_data/2.priv
================================================
 1A`jPLD4N[-XFX

================================================
FILE: core/crypto/test_data/2.pub
================================================
!5@*5QMU&PkS֢

================================================
FILE: core/crypto/test_data/2.sig
================================================
0D 13ZCuܛ@L I!EGuCꏲpCG5I<@;Y

================================================
FILE: core/discovery/discovery.go
================================================
// Package discovery provides service advertisement and peer discovery interfaces for libp2p.
package discovery

import (
	"context"
	"time"

	"github.com/libp2p/go-libp2p/core/peer"
)

// Advertiser is an interface for advertising services
type Advertiser interface {
	// Advertise advertises a service
	Advertise(ctx context.Context, ns string, opts ...Option) (time.Duration, error)
}

// Discoverer is an interface for peer discovery
type Discoverer interface {
	// FindPeers discovers peers providing a service
	FindPeers(ctx context.Context, ns string, opts ...Option) (<-chan peer.AddrInfo, error)
}

// Discovery is an interface that combines service advertisement and peer discovery
type Discovery interface {
	Advertiser
	Discoverer
}


================================================
FILE: core/discovery/options.go
================================================
package discovery

import "time"

// DiscoveryOpt is a single discovery option.
type Option func(opts *Options) error

// DiscoveryOpts is a set of discovery options.
type Options struct {
	Ttl   time.Duration
	Limit int

	// Other (implementation-specific) options
	Other map[any]any
}

// Apply applies the given options to this DiscoveryOpts
func (opts *Options) Apply(options ...Option) error {
	for _, o := range options {
		if err := o(opts); err != nil {
			return err
		}
	}
	return nil
}

// TTL is an option that provides a hint for the duration of an advertisement
func TTL(ttl time.Duration) Option {
	return func(opts *Options) error {
		opts.Ttl = ttl
		return nil
	}
}

// Limit is an option that provides an upper bound on the peer count for discovery
func Limit(limit int) Option {
	return func(opts *Options) error {
		opts.Limit = limit
		return nil
	}
}


================================================
FILE: core/event/addrs.go
================================================
package event

import (
	"github.com/libp2p/go-libp2p/core/record"

	ma "github.com/multiformats/go-multiaddr"
)

// AddrAction represents an action taken on one of a Host's listen addresses.
// It is used to add context to address change events in EvtLocalAddressesUpdated.
type AddrAction int

const (
	// Unknown means that the event producer was unable to determine why the address
	// is in the current state.
	Unknown AddrAction = iota

	// Added means that the address is new and was not present prior to the event.
	Added

	// Maintained means that the address was not altered between the current and
	// previous states.
	Maintained

	// Removed means that the address was removed from the Host.
	Removed
)

// UpdatedAddress is used in the EvtLocalAddressesUpdated event to convey
// address change information.
type UpdatedAddress struct {
	// Address contains the address that was updated.
	Address ma.Multiaddr

	// Action indicates what action was taken on the address during the
	// event. May be Unknown if the event producer cannot produce diffs.
	Action AddrAction
}

// EvtLocalAddressesUpdated should be emitted when the set of listen addresses for
// the local host changes. This may happen for a number of reasons. For example,
// we may have opened a new relay connection, established a new NAT mapping via
// UPnP, or been informed of our observed address by another peer.
//
// EvtLocalAddressesUpdated contains a snapshot of the current listen addresses,
// and may also contain a diff between the current state and the previous state.
// If the event producer is capable of creating a diff, the Diffs field will be
// true, and event consumers can inspect the Action field of each UpdatedAddress
// to see how each address was modified.
//
// For example, the Action will tell you whether an address in
// the Current list was Added by the event producer, or was Maintained without
// changes. Addresses that were removed from the Host will have the AddrAction
// of Removed, and will be in the Removed list.
//
// If the event producer is not capable or producing diffs, the Diffs field will
// be false, the Removed list will always be empty, and the Action for each
// UpdatedAddress in the Current list will be Unknown.
//
// In addition to the above, EvtLocalAddressesUpdated also contains the updated peer.PeerRecord
// for the Current set of listen addresses, wrapped in a record.Envelope and signed by the Host's private key.
// This record can be shared with other peers to inform them of what we believe are our diallable addresses
// a secure and authenticated way.
type EvtLocalAddressesUpdated struct {

	// Diffs indicates whether this event contains a diff of the Host's previous
	// address set.
	Diffs bool

	// Current contains all current listen addresses for the Host.
	// If Diffs == true, the Action field of each UpdatedAddress will tell
	// you whether an address was Added, or was Maintained from the previous
	// state.
	Current []UpdatedAddress

	// Removed contains addresses that were removed from the Host.
	// This field is only set when Diffs == true.
	Removed []UpdatedAddress

	// SignedPeerRecord contains our own updated peer.PeerRecord, listing the addresses enumerated in Current.
	// wrapped in a record.Envelope and signed by the Host's private key.
	SignedPeerRecord *record.Envelope
}

// EvtAutoRelayAddrsUpdated is sent by the autorelay when the node's relay addresses are updated
type EvtAutoRelayAddrsUpdated struct {
	RelayAddrs []ma.Multiaddr
}


================================================
FILE: core/event/bus.go
================================================
package event

import (
	"io"
	"reflect"
)

// SubscriptionOpt represents a subscriber option. Use the options exposed by the implementation of choice.
type SubscriptionOpt = func(any) error

// EmitterOpt represents an emitter option. Use the options exposed by the implementation of choice.
type EmitterOpt = func(any) error

// CancelFunc closes a subscriber.
type CancelFunc = func()

// wildcardSubscriptionType is a virtual type to represent wildcard
// subscriptions.
type wildcardSubscriptionType any

// WildcardSubscription is the type to subscribe to receive all events
// emitted in the eventbus.
var WildcardSubscription = new(wildcardSubscriptionType)

// Emitter represents an actor that emits events onto the eventbus.
type Emitter interface {
	io.Closer

	// Emit emits an event onto the eventbus. If any channel subscribed to the topic is blocked,
	// calls to Emit will block.
	//
	// Calling this function with wrong event type will cause a panic.
	Emit(evt any) error
}

// Subscription represents a subscription to one or multiple event types.
type Subscription interface {
	io.Closer

	// Out returns the channel from which to consume events.
	Out() <-chan any

	// Name returns the name for the subscription
	Name() string
}

// Bus is an interface for a type-based event delivery system.
type Bus interface {
	// Subscribe creates a new Subscription.
	//
	// eventType can be either a pointer to a single event type, or a slice of pointers to
	// subscribe to multiple event types at once, under a single subscription (and channel).
	//
	// Failing to drain the channel may cause publishers to block.
	//
	// If you want to subscribe to ALL events emitted in the bus, use
	// `WildcardSubscription` as the `eventType`:
	//
	//  eventbus.Subscribe(WildcardSubscription)
	//
	// Simple example
	//
	//  sub, err := eventbus.Subscribe(new(EventType))
	//  defer sub.Close()
	//  for e := range sub.Out() {
	//    event := e.(EventType) // guaranteed safe
	//    [...]
	//  }
	//
	// Multi-type example
	//
	//  sub, err := eventbus.Subscribe([]interface{}{new(EventA), new(EventB)})
	//  defer sub.Close()
	//  for e := range sub.Out() {
	//    select e.(type):
	//      case EventA:
	//        [...]
	//      case EventB:
	//        [...]
	//    }
	//  }
	Subscribe(eventType any, opts ...SubscriptionOpt) (Subscription, error)

	// Emitter creates a new event emitter.
	//
	// eventType accepts typed nil pointers, and uses the type information for wiring purposes.
	//
	// Example:
	//  em, err := eventbus.Emitter(new(EventT))
	//  defer em.Close() // MUST call this after being done with the emitter
	//  em.Emit(EventT{})
	Emitter(eventType any, opts ...EmitterOpt) (Emitter, error)

	// GetAllEventTypes returns all the event types that this bus knows about
	// (having emitters and subscribers). It omits the WildcardSubscription.
	//
	// The caller is guaranteed that this function will only return value types;
	// no pointer types will be returned.
	GetAllEventTypes() []reflect.Type
}


================================================
FILE: core/event/dht.go
================================================
package event

// RawJSON is a type that contains a raw JSON string.
type RawJSON string

// GenericDHTEvent is a type that encapsulates an actual DHT event by carrying
// its raw JSON.
//
// Context: the DHT event system is rather bespoke and a bit messy at the time,
// so until we unify/clean that up, this event bridges the gap. It should only
// be consumed for informational purposes.
//
// EXPERIMENTAL: this will likely be removed if/when the DHT event types are
// hoisted to core, and the DHT event system is reconciled with the eventbus.
type GenericDHTEvent struct {
	// Type is the type of the DHT event that occurred.
	Type string

	// Raw is the raw JSON representation of the event payload.
	Raw RawJSON
}


================================================
FILE: core/event/doc.go
================================================
// Package event contains the abstractions for a local event bus, along with the standard events
// that libp2p subsystems may emit.
//
// Source code is arranged as follows:
//   - doc.go: this file.
//   - bus.go: abstractions for the event bus.
//   - rest: event structs, sensibly categorised in files by entity, and following this naming convention:
//     Evt[Entity (noun)][Event (verb past tense / gerund)]
//     The past tense is used to convey that something happened, whereas the gerund form of the verb (-ing)
//     expresses that a process is in progress. Examples: EvtConnEstablishing, EvtConnEstablished.
package event


================================================
FILE: core/event/identify.go
================================================
package event

import (
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/protocol"
	"github.com/libp2p/go-libp2p/core/record"
	"github.com/multiformats/go-multiaddr"
)

// EvtPeerIdentificationCompleted is emitted when the initial identification round for a peer is completed.
type EvtPeerIdentificationCompleted struct {
	// Peer is the ID of the peer whose identification succeeded.
	Peer peer.ID

	// Conn is the connection we identified.
	Conn network.Conn

	// ListenAddrs is the list of addresses the peer is listening on.
	ListenAddrs []multiaddr.Multiaddr

	// Protocols is the list of protocols the peer advertised on this connection.
	Protocols []protocol.ID

	// SignedPeerRecord is the provided signed peer record of the peer. May be nil.
	SignedPeerRecord *record.Envelope

	// AgentVersion is like a UserAgent string in browsers, or client version in
	// bittorrent includes the client name and client.
	AgentVersion string

	// ProtocolVersion is the protocolVersion field in the identify message
	ProtocolVersion string

	// ObservedAddr is the our side's connection address as observed by the
	// peer. This is not verified, the peer could return anything here.
	ObservedAddr multiaddr.Multiaddr
}

// EvtPeerIdentificationFailed is emitted when the initial identification round for a peer failed.
type EvtPeerIdentificationFailed struct {
	// Peer is the ID of the peer whose identification failed.
	Peer peer.ID
	// Reason is the reason why identification failed.
	Reason error
}


================================================
FILE: core/event/nattype.go
================================================
package event

import "github.com/libp2p/go-libp2p/core/network"

// EvtNATDeviceTypeChanged is an event struct to be emitted when the type of the NAT device changes for a Transport Protocol.
//
// Note: This event is meaningful ONLY if the AutoNAT Reachability is Private.
// Consumers of this event should ALSO consume the `EvtLocalReachabilityChanged` event and interpret
// this event ONLY if the Reachability on the `EvtLocalReachabilityChanged` is Private.
type EvtNATDeviceTypeChanged struct {
	// TransportProtocol is the Transport Protocol for which the NAT Device Type has been determined.
	TransportProtocol network.NATTransportProtocol
	// NatDeviceType indicates the type of the NAT Device for the Transport Protocol.
	// Currently, it can be either a `EndpointIndependent NAT` or a `EndpointDependent NAT`. Please see the detailed documentation
	// on `network.NATDeviceType` enumerations for a better understanding of what these types mean and
	// how they impact Connectivity and Hole Punching.
	NatDeviceType network.NATDeviceType
}


================================================
FILE: core/event/network.go
================================================
package event

import (
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
)

// EvtPeerConnectednessChanged should be emitted every time the "connectedness" to a
// given peer changes. Specifically, this event is emitted in the following
// cases:
//
//   - Connectedness = Connected: Every time we transition from having no
//     connections to a peer to having at least one connection to the peer.
//   - Connectedness = NotConnected: Every time we transition from having at least
//     one connection to a peer to having no connections to the peer.
//
// Additional connectedness states may be added in the future. This list should
// not be considered exhaustive.
//
// Take note:
//
//   - It's possible to have _multiple_ connections to a given peer.
//   - Both libp2p and networks are asynchronous.
//
// This means that all the following situations are possible:
//
// A connection is cut and is re-established:
//
//   - Peer A observes a transition from Connected -> NotConnected -> Connected
//   - Peer B observes a transition from Connected -> NotConnected -> Connected
//
// Explanation: Both peers observe the connection die. This is the "nice" case.
//
// A connection is cut and is re-established.
//
//   - Peer A observes a transition from Connected -> NotConnected -> Connected.
//   - Peer B observes no transition.
//
// Explanation: Peer A re-establishes the dead connection. Peer B observes the
// new connection form before it observes the old connection die.
//
// A connection is cut:
//
//   - Peer A observes no transition.
//   - Peer B observes no transition.
//
// Explanation: There were two connections and one was cut. This connection
// might have been in active use but neither peer will observe a change in
// "connectedness". Peers should always make sure to retry network requests.
type EvtPeerConnectednessChanged struct {
	// Peer is the remote peer whose connectedness has changed.
	Peer peer.ID
	// Connectedness is the new connectedness state.
	Connectedness network.Connectedness
}


================================================
FILE: core/event/protocol.go
================================================
package event

import (
	peer "github.com/libp2p/go-libp2p/core/peer"
	protocol "github.com/libp2p/go-libp2p/core/protocol"
)

// EvtPeerProtocolsUpdated should be emitted when a peer we're connected to adds or removes protocols from their stack.
type EvtPeerProtocolsUpdated struct {
	// Peer is the peer whose protocols were updated.
	Peer peer.ID
	// Added enumerates the protocols that were added by this peer.
	Added []protocol.ID
	// Removed enumerates the protocols that were removed by this peer.
	Removed []protocol.ID
}

// EvtLocalProtocolsUpdated should be emitted when stream handlers are attached or detached from the local host.
// For handlers attached with a matcher predicate (host.SetStreamHandlerMatch()), only the protocol ID will be
// included in this event.
type EvtLocalProtocolsUpdated struct {
	// Added enumerates the protocols that were added locally.
	Added []protocol.ID
	// Removed enumerates the protocols that were removed locally.
	Removed []protocol.ID
}


================================================
FILE: core/event/reachability.go
================================================
package event

import (
	"github.com/libp2p/go-libp2p/core/network"
	ma "github.com/multiformats/go-multiaddr"
)

// EvtLocalReachabilityChanged is an event struct to be emitted when the local's
// node reachability changes state.
//
// This event is usually emitted by the AutoNAT subsystem.
type EvtLocalReachabilityChanged struct {
	Reachability network.Reachability
}

// EvtHostReachableAddrsChanged is sent when host's reachable or unreachable addresses change
// Reachable, Unreachable, and Unknown only contain Public IP or DNS addresses
//
// Experimental: This API is unstable. Any changes to this event will be done without a deprecation notice.
type EvtHostReachableAddrsChanged struct {
	Reachable   []ma.Multiaddr
	Unreachable []ma.Multiaddr
	Unknown     []ma.Multiaddr
}


================================================
FILE: core/host/helpers.go
================================================
package host

import "github.com/libp2p/go-libp2p/core/peer"

// InfoFromHost returns a peer.AddrInfo struct with the Host's ID and all of its Addrs.
func InfoFromHost(h Host) *peer.AddrInfo {
	return &peer.AddrInfo{
		ID:    h.ID(),
		Addrs: h.Addrs(),
	}
}


================================================
FILE: core/host/host.go
================================================
// Package host provides the core Host interface for libp2p.
//
// Host represents a single libp2p node in a peer-to-peer network.
package host

import (
	"context"

	"github.com/libp2p/go-libp2p/core/connmgr"
	"github.com/libp2p/go-libp2p/core/event"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/peerstore"
	"github.com/libp2p/go-libp2p/core/protocol"

	ma "github.com/multiformats/go-multiaddr"
)

// Host is an object participating in a p2p network, which
// implements protocols or provides services. It handles
// requests like a Server, and issues requests like a Client.
// It is called Host because it is both Server and Client (and Peer
// may be confusing).
type Host interface {
	// ID returns the (local) peer.ID associated with this Host
	ID() peer.ID

	// Peerstore returns the Host's repository of Peer Addresses and Keys.
	Peerstore() peerstore.Peerstore

	// Addrs returns the listen addresses of the Host
	Addrs() []ma.Multiaddr

	// Network returns the Network interface of the Host
	Network() network.Network

	// Mux returns the Mux multiplexing incoming streams to protocol handlers
	Mux() protocol.Switch

	// Connect ensures there is a connection between this host and the peer with
	// given peer.ID. Connect will absorb the addresses in pi into its internal
	// peerstore. If there is not an active connection, Connect will issue a
	// h.Network.Dial, and block until a connection is open, or an error is
	// returned.
	Connect(ctx context.Context, pi peer.AddrInfo) error

	// SetStreamHandler sets the protocol handler on the Host's Mux.
	// This is equivalent to:
	//   host.Mux().SetHandler(proto, handler)
	// (Thread-safe)
	SetStreamHandler(pid protocol.ID, handler network.StreamHandler)

	// SetStreamHandlerMatch sets the protocol handler on the Host's Mux
	// using a matching function for protocol selection.
	SetStreamHandlerMatch(protocol.ID, func(protocol.ID) bool, network.StreamHandler)

	// RemoveStreamHandler removes a handler on the mux that was set by
	// SetStreamHandler
	RemoveStreamHandler(pid protocol.ID)

	// NewStream opens a new stream to given peer p, and writes a p2p/protocol
	// header with given ProtocolID. If there is no connection to p, attempts
	// to create one. If ProtocolID is "", writes no header.
	// (Thread-safe)
	NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (network.Stream, error)

	// Close shuts down the host, its Network, and services.
	Close() error

	// ConnManager returns this hosts connection manager
	ConnManager() connmgr.ConnManager

	// EventBus returns the hosts eventbus
	EventBus() event.Bus
}


================================================
FILE: core/internal/catch/catch.go
================================================
package catch

import (
	"fmt"
	"io"
	"os"
	"runtime/debug"
)

var panicWriter io.Writer = os.Stderr

// HandlePanic handles and logs panics.
func HandlePanic(rerr any, err *error, where string) {
	if rerr != nil {
		fmt.Fprintf(panicWriter, "caught panic: %s\n%s\n", rerr, debug.Stack())
		*err = fmt.Errorf("panic in %s: %s", where, rerr)
	}
}


================================================
FILE: core/internal/catch/catch_test.go
================================================
package catch

import (
	"bytes"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestCatch(t *testing.T) {
	buf := new(bytes.Buffer)

	oldPanicWriter := panicWriter
	t.Cleanup(func() { panicWriter = oldPanicWriter })
	panicWriter = buf

	panicAndCatch := func() (err error) {
		defer func() { HandlePanic(recover(), &err, "somewhere") }()

		panic("here")
	}

	err := panicAndCatch()
	require.Error(t, err)
	require.Contains(t, err.Error(), "panic in somewhere: here")

	require.Contains(t, buf.String(), "caught panic: here")
}


================================================
FILE: core/metrics/bandwidth.go
================================================
// Package metrics provides metrics collection and reporting interfaces for libp2p.
package metrics

import (
	"time"

	"github.com/libp2p/go-flow-metrics"

	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/protocol"
)

// BandwidthCounter tracks incoming and outgoing data transferred by the local peer.
// Metrics are available for total bandwidth across all peers / protocols, as well
// as segmented by remote peer ID and protocol ID.
type BandwidthCounter struct {
	totalIn  flow.Meter
	totalOut flow.Meter

	protocolIn  flow.MeterRegistry
	protocolOut flow.MeterRegistry

	peerIn  flow.MeterRegistry
	peerOut flow.MeterRegistry
}

// NewBandwidthCounter creates a new BandwidthCounter.
func NewBandwidthCounter() *BandwidthCounter {
	return new(BandwidthCounter)
}

// LogSentMessage records the size of an outgoing message
// without associating the bandwidth to a specific peer or protocol.
func (bwc *BandwidthCounter) LogSentMessage(size int64) {
	bwc.totalOut.Mark(uint64(size))
}

// LogRecvMessage records the size of an incoming message
// without associating the bandwidth to a specific peer or protocol.
func (bwc *BandwidthCounter) LogRecvMessage(size int64) {
	bwc.totalIn.Mark(uint64(size))
}

// LogSentMessageStream records the size of an outgoing message over a single logical stream.
// Bandwidth is associated with the given protocol.ID and peer.ID.
func (bwc *BandwidthCounter) LogSentMessageStream(size int64, proto protocol.ID, p peer.ID) {
	bwc.protocolOut.Get(string(proto)).Mark(uint64(size))
	bwc.peerOut.Get(string(p)).Mark(uint64(size))
}

// LogRecvMessageStream records the size of an incoming message over a single logical stream.
// Bandwidth is associated with the given protocol.ID and peer.ID.
func (bwc *BandwidthCounter) LogRecvMessageStream(size int64, proto protocol.ID, p peer.ID) {
	bwc.protocolIn.Get(string(proto)).Mark(uint64(size))
	bwc.peerIn.Get(string(p)).Mark(uint64(size))
}

// GetBandwidthForPeer returns a Stats struct with bandwidth metrics associated with the given peer.ID.
// The metrics returned include all traffic sent / received for the peer, regardless of protocol.
func (bwc *BandwidthCounter) GetBandwidthForPeer(p peer.ID) (out Stats) {
	inSnap := bwc.peerIn.Get(string(p)).Snapshot()
	outSnap := bwc.peerOut.Get(string(p)).Snapshot()

	return Stats{
		TotalIn:  int64(inSnap.Total),
		TotalOut: int64(outSnap.Total),
		RateIn:   inSnap.Rate,
		RateOut:  outSnap.Rate,
	}
}

// GetBandwidthForProtocol returns a Stats struct with bandwidth metrics associated with the given protocol.ID.
// The metrics returned include all traffic sent / received for the protocol, regardless of which peers were
// involved.
func (bwc *BandwidthCounter) GetBandwidthForProtocol(proto protocol.ID) (out Stats) {
	inSnap := bwc.protocolIn.Get(string(proto)).Snapshot()
	outSnap := bwc.protocolOut.Get(string(proto)).Snapshot()

	return Stats{
		TotalIn:  int64(inSnap.Total),
		TotalOut: int64(outSnap.Total),
		RateIn:   inSnap.Rate,
		RateOut:  outSnap.Rate,
	}
}

// GetBandwidthTotals returns a Stats struct with bandwidth metrics for all data sent / received by the
// local peer, regardless of protocol or remote peer IDs.
func (bwc *BandwidthCounter) GetBandwidthTotals() (out Stats) {
	inSnap := bwc.totalIn.Snapshot()
	outSnap := bwc.totalOut.Snapshot()

	return Stats{
		TotalIn:  int64(inSnap.Total),
		TotalOut: int64(outSnap.Total),
		RateIn:   inSnap.Rate,
		RateOut:  outSnap.Rate,
	}
}

// GetBandwidthByPeer returns a map of all remembered peers and the bandwidth
// metrics with respect to each. This method may be very expensive.
func (bwc *BandwidthCounter) GetBandwidthByPeer() map[peer.ID]Stats {
	peers := make(map[peer.ID]Stats)

	bwc.peerIn.ForEach(func(p string, meter *flow.Meter) {
		id := peer.ID(p)
		snap := meter.Snapshot()

		stat := peers[id]
		stat.TotalIn = int64(snap.Total)
		stat.RateIn = snap.Rate
		peers[id] = stat
	})

	bwc.peerOut.ForEach(func(p string, meter *flow.Meter) {
		id := peer.ID(p)
		snap := meter.Snapshot()

		stat := peers[id]
		stat.TotalOut = int64(snap.Total)
		stat.RateOut = snap.Rate
		peers[id] = stat
	})

	return peers
}

// GetBandwidthByProtocol returns a map of all remembered protocols and
// the bandwidth metrics with respect to each. This method may be moderately
// expensive.
func (bwc *BandwidthCounter) GetBandwidthByProtocol() map[protocol.ID]Stats {
	protocols := make(map[protocol.ID]Stats)

	bwc.protocolIn.ForEach(func(p string, meter *flow.Meter) {
		id := protocol.ID(p)
		snap := meter.Snapshot()

		stat := protocols[id]
		stat.TotalIn = int64(snap.Total)
		stat.RateIn = snap.Rate
		protocols[id] = stat
	})

	bwc.protocolOut.ForEach(func(p string, meter *flow.Meter) {
		id := protocol.ID(p)
		snap := meter.Snapshot()

		stat := protocols[id]
		stat.TotalOut = int64(snap.Total)
		stat.RateOut = snap.Rate
		protocols[id] = stat
	})

	return protocols
}

// Reset clears all stats.
func (bwc *BandwidthCounter) Reset() {
	bwc.totalIn.Reset()
	bwc.totalOut.Reset()

	bwc.protocolIn.Clear()
	bwc.protocolOut.Clear()

	bwc.peerIn.Clear()
	bwc.peerOut.Clear()
}

// TrimIdle trims all timers idle since the given time.
func (bwc *BandwidthCounter) TrimIdle(since time.Time) {
	bwc.peerIn.TrimIdle(since)
	bwc.peerOut.TrimIdle(since)
	bwc.protocolIn.TrimIdle(since)
	bwc.protocolOut.TrimIdle(since)
}


================================================
FILE: core/metrics/bandwidth_test.go
================================================
package metrics

import (
	"fmt"
	"sync"
	"testing"
	"time"

	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/protocol"

	"github.com/libp2p/go-flow-metrics"

	"github.com/benbjohnson/clock"
	"github.com/stretchr/testify/require"
)

var cl = clock.NewMock()

func init() {
	flow.SetClock(cl)
}

func BenchmarkBandwidthCounter(b *testing.B) {
	b.StopTimer()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		bwc := NewBandwidthCounter()
		round(bwc, b)
	}
}

func round(bwc *BandwidthCounter, b *testing.B) {
	start := make(chan struct{})
	var wg sync.WaitGroup
	wg.Add(10000)
	for i := range 1000 {
		p := peer.ID(fmt.Sprintf("peer-%d", i))
		for j := range 10 {
			proto := protocol.ID(fmt.Sprintf("bitswap-%d", j))
			go func() {
				defer wg.Done()
				<-start

				for range 1000 {
					bwc.LogSentMessage(100)
					bwc.LogSentMessageStream(100, proto, p)
					time.Sleep(1 * time.Millisecond)
				}
			}()
		}
	}

	b.StartTimer()
	close(start)
	wg.Wait()
	b.StopTimer()
}

func TestBandwidthCounter(t *testing.T) {
	bwc := NewBandwidthCounter()
	for range 40 {
		for i := range 100 {
			p := peer.ID(fmt.Sprintf("peer-%d", i))
			for j := range 2 {
				proto := protocol.ID(fmt.Sprintf("proto-%d", j))

				// make sure the bandwidth counters are active
				bwc.LogSentMessage(100)
				bwc.LogRecvMessage(50)
				bwc.LogSentMessageStream(100, proto, p)
				bwc.LogRecvMessageStream(50, proto, p)

				// <-start
			}
		}
		cl.Add(100 * time.Millisecond)
	}

	assertProtocols := func(check func(Stats)) {
		byProtocol := bwc.GetBandwidthByProtocol()
		require.Len(t, byProtocol, 2, "expected 2 protocols")
		for i := range 2 {
			p := protocol.ID(fmt.Sprintf("proto-%d", i))
			for _, stats := range [...]Stats{bwc.GetBandwidthForProtocol(p), byProtocol[p]} {
				check(stats)
			}
		}
	}

	assertPeers := func(check func(Stats)) {
		byPeer := bwc.GetBandwidthByPeer()
		require.Len(t, byPeer, 100, "expected 100 peers")
		for i := range 100 {
			p := peer.ID(fmt.Sprintf("peer-%d", i))
			for _, stats := range [...]Stats{bwc.GetBandwidthForPeer(p), byPeer[p]} {
				check(stats)
			}
		}
	}

	assertPeers(func(stats Stats) {
		require.Equal(t, int64(8000), stats.TotalOut)
		require.Equal(t, int64(4000), stats.TotalIn)
	})

	assertProtocols(func(stats Stats) {
		require.Equal(t, int64(400000), stats.TotalOut)
		require.Equal(t, int64(200000), stats.TotalIn)
	})

	stats := bwc.GetBandwidthTotals()
	require.Equal(t, int64(800000), stats.TotalOut)
	require.Equal(t, int64(400000), stats.TotalIn)
}

func TestResetBandwidthCounter(t *testing.T) {
	bwc := NewBandwidthCounter()

	p := peer.ID("peer-0")
	proto := protocol.ID("proto-0")

	// We don't calculate bandwidth till we've been active for a second.
	bwc.LogSentMessage(42)
	bwc.LogRecvMessage(24)
	bwc.LogSentMessageStream(100, proto, p)
	bwc.LogRecvMessageStream(50, proto, p)

	time.Sleep(200 * time.Millisecond) // make sure the meters are registered with the sweeper
	cl.Add(time.Second)

	bwc.LogSentMessage(42)
	bwc.LogRecvMessage(24)
	bwc.LogSentMessageStream(100, proto, p)
	bwc.LogRecvMessageStream(50, proto, p)

	cl.Add(time.Second)

	{
		stats := bwc.GetBandwidthTotals()
		require.Equal(t, int64(84), stats.TotalOut)
		require.Equal(t, int64(48), stats.TotalIn)
	}

	{
		stats := bwc.GetBandwidthByProtocol()
		require.Len(t, stats, 1)
		stat := stats[proto]
		require.Equal(t, float64(100), stat.RateOut)
		require.Equal(t, float64(50), stat.RateIn)
	}

	{
		stats := bwc.GetBandwidthByPeer()
		require.Len(t, stats, 1)
		stat := stats[p]
		require.Equal(t, float64(100), stat.RateOut)
		require.Equal(t, float64(50), stat.RateIn)
	}

	bwc.Reset()
	{
		stats := bwc.GetBandwidthTotals()
		require.Zero(t, stats.TotalOut)
		require.Zero(t, stats.TotalIn)
		require.Empty(t, bwc.GetBandwidthByProtocol(), "expected 0 protocols")
		require.Empty(t, bwc.GetBandwidthByPeer(), "expected 0 peers")
	}
}


================================================
FILE: core/metrics/reporter.go
================================================
// Package metrics provides metrics collection and reporting interfaces for libp2p.
package metrics

import (
	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/protocol"
	"time"
)

// Stats represents a point-in-time snapshot of bandwidth metrics.
//
// The TotalIn and TotalOut fields record cumulative bytes sent / received.
// The RateIn and RateOut fields record bytes sent / received per second.
type Stats struct {
	TotalIn  int64
	TotalOut int64
	RateIn   float64
	RateOut  float64
}

// Reporter provides methods for logging and retrieving metrics.
type Reporter interface {
	LogSentMessage(int64)
	LogRecvMessage(int64)
	LogSentMessageStream(int64, protocol.ID, peer.ID)
	LogRecvMessageStream(int64, protocol.ID, peer.ID)
	GetBandwidthForPeer(peer.ID) Stats
	GetBandwidthForProtocol(protocol.ID) Stats
	GetBandwidthTotals() Stats
	GetBandwidthByPeer() map[peer.ID]Stats
	GetBandwidthByProtocol() map[protocol.ID]Stats
	Reset()
	TrimIdle(since time.Time)
}


================================================
FILE: core/network/conn.go
================================================
package network

import (
	"context"
	"fmt"
	"io"

	ic "github.com/libp2p/go-libp2p/core/crypto"

	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/core/protocol"

	ma "github.com/multiformats/go-multiaddr"
)

type ConnErrorCode uint32

type ConnError struct {
	Remote         bool
	ErrorCode      ConnErrorCode
	TransportError error
}

func (c *ConnError) Error() string {
	side := "local"
	if c.Remote {
		side = "remote"
	}
	if c.TransportError != nil {
		return fmt.Sprintf("connection closed (%s): code: 0x%x: transport error: %s", side, c.ErrorCode, c.TransportError)
	}
	return fmt.Sprintf("connection closed (%s): code: 0x%x", side, c.ErrorCode)
}

func (c *ConnError) Is(target error) bool {
	if tce, ok := target.(*ConnError); ok {
		return tce.ErrorCode == c.ErrorCode && tce.Remote == c.Remote
	}
	return false
}

func (c *ConnError) Unwrap() []error {
	return []error{ErrReset, c.TransportError}
}

const (
	ConnNoError                   ConnErrorCode = 0
	ConnProtocolNegotiationFailed ConnErrorCode = 0x1000
	ConnResourceLimitExceeded     ConnErrorCode = 0x1001
	ConnRateLimited               ConnErrorCode = 0x1002
	ConnProtocolViolation         ConnErrorCode = 0x1003
	ConnSupplanted                ConnErrorCode = 0x1004
	ConnGarbageCollected          ConnErrorCode = 0x1005
	ConnShutdown                  ConnErrorCode = 0x1006
	ConnGated                     ConnErrorCode = 0x1007
	ConnCodeOutOfRange            ConnErrorCode = 0x1008
)

// Conn is a connection to a remote peer. It multiplexes streams.
// Usually there is no need to use a Conn directly, but it may
// be useful to get information about the peer on the other side:
//
//	stream.Conn().RemotePeer()
type Conn interface {
	io.Closer

	ConnSecurity
	ConnMultiaddrs
	ConnStat
	ConnScoper

	// CloseWithError closes the connection with errCode. The errCode is sent to the
	// peer on a best effort basis. For transports that do not support sending error
	// codes on connection close, the behavior is identical to calling Close.
	CloseWithError(errCode ConnErrorCode) error

	// ID returns an identifier that uniquely identifies this Conn within this
	// host, during this run. Connection IDs may repeat across restarts.
	ID() string

	// NewStream constructs a new Stream over this conn.
	NewStream(context.Context) (Stream, error)

	// GetStreams returns all open streams over this conn.
	GetStreams() []Stream

	// IsClosed returns whether a connection is fully closed, so it can
	// be garbage collected.
	IsClosed() bool

	// As finds the first conn in Conn's wrapped types that matches target, and
	// if one is found, sets target to that conn value and returns true.
	// Otherwise, it returns false. Similar to errors.As.
	//
	// target must be a pointer to the type you are matching against.
	//
	// This is an EXPERIMENTAL API. Getting access to the underlying type can
	// lead to hard to debug issues. For example, if you mutate connection state
	// on the underlying type, hooks that relied on only mutating that state
	// from the wrapped connection would never be called.
	//
	// You very likely do not need to use this method.
	As(target any) bool
}

// ConnectionState holds information about the connection.
type ConnectionState struct {
	// The stream multiplexer used on this connection (if any). For example: /yamux/1.0.0
	StreamMultiplexer protocol.ID
	// The security protocol used on this connection (if any). For example: /tls/1.0.0
	Security protocol.ID
	// the transport used on this connection. For example: tcp
	Transport string
	// indicates whether StreamMultiplexer was selected using inlined muxer negotiation
	UsedEarlyMuxerNegotiation bool
}

// ConnSecurity is the interface that one can mix into a connection interface to
// give it the security methods.
type ConnSecurity interface {
	// LocalPeer returns our peer ID
	LocalPeer() peer.ID

	// RemotePeer returns the peer ID of the remote peer.
	RemotePeer() peer.ID

	// RemotePublicKey returns the public key of the remote peer.
	RemotePublicKey() ic.PubKey

	// ConnState returns information about the connection state.
	ConnState() ConnectionState
}

// ConnMultiaddrs is an interface mixin for connection types that provide multiaddr
// addresses for the endpoints.
type ConnMultiaddrs interface {
	// LocalMultiaddr returns the local Multiaddr associated
	// with this connection
	LocalMultiaddr() ma.Multiaddr

	// RemoteMultiaddr returns the remote Multiaddr associated
	// with this connection
	RemoteMultiaddr() ma.Multiaddr
}

// ConnStat is an interface mixin for connection types that provide connection statistics.
type ConnStat interface {
	// Stat stores metadata pertaining to this conn.
	Stat() ConnStats
}

// ConnScoper is the interface that one can mix into a connection interface to give it a resource
// management scope
type ConnScoper interface {
	// Scope returns the user view of this connection's resource scope
	Scope() ConnScope
}


================================================
FILE: core/network/context.go
================================================
package network

import (
	"context"
	"time"
)
Download .txt
gitextract_smkgriw_/

├── .codecov.yml
├── .githooks/
│   ├── README.md
│   └── pre-commit
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.md
│   │   ├── config.yml
│   │   ├── doc.md
│   │   ├── enhancement.md
│   │   ├── feature.md
│   │   ├── question.md
│   │   └── release.md
│   ├── actions/
│   │   ├── go-check-setup/
│   │   │   └── action.yml
│   │   └── go-test-setup/
│   │       └── action.yml
│   └── workflows/
│       ├── generated-pr.yml
│       ├── go-check-config.json
│       ├── go-check.yml
│       ├── go-test-config.json
│       ├── go-test-template.yml
│       ├── go-test.yml
│       ├── interop-test.yml
│       ├── link-check.yml
│       ├── markdown-links-config.json
│       ├── release-check.yml
│       ├── releaser.yml
│       ├── stale.yml
│       ├── tagpush.yml
│       └── upstream.yml
├── .gitignore
├── .golangci.yml
├── CHANGELOG.md
├── FUNDING.json
├── LICENSE
├── README.md
├── SECURITY.md
├── config/
│   ├── config.go
│   ├── config_test.go
│   ├── host.go
│   └── quic.go
├── core/
│   ├── alias.go
│   ├── connmgr/
│   │   ├── decay.go
│   │   ├── gater.go
│   │   ├── manager.go
│   │   ├── null.go
│   │   └── presets.go
│   ├── control/
│   │   └── disconnect.go
│   ├── crypto/
│   │   ├── bench_test.go
│   │   ├── ecdsa.go
│   │   ├── ecdsa_test.go
│   │   ├── ed25519.go
│   │   ├── ed25519_test.go
│   │   ├── fixture_test.go
│   │   ├── key.go
│   │   ├── key_test.go
│   │   ├── key_to_stdlib.go
│   │   ├── pb/
│   │   │   ├── crypto.pb.go
│   │   │   └── crypto.proto
│   │   ├── rsa_common.go
│   │   ├── rsa_go.go
│   │   ├── rsa_test.go
│   │   ├── secp256k1.go
│   │   ├── secp256k1_test.go
│   │   └── test_data/
│   │       ├── 0.priv
│   │       ├── 0.pub
│   │       ├── 0.sig
│   │       ├── 2.priv
│   │       ├── 2.pub
│   │       ├── 2.sig
│   │       ├── 3.priv
│   │       ├── 3.pub
│   │       └── 3.sig
│   ├── discovery/
│   │   ├── discovery.go
│   │   └── options.go
│   ├── event/
│   │   ├── addrs.go
│   │   ├── bus.go
│   │   ├── dht.go
│   │   ├── doc.go
│   │   ├── identify.go
│   │   ├── nattype.go
│   │   ├── network.go
│   │   ├── protocol.go
│   │   └── reachability.go
│   ├── host/
│   │   ├── helpers.go
│   │   └── host.go
│   ├── internal/
│   │   └── catch/
│   │       ├── catch.go
│   │       └── catch_test.go
│   ├── metrics/
│   │   ├── bandwidth.go
│   │   ├── bandwidth_test.go
│   │   └── reporter.go
│   ├── network/
│   │   ├── conn.go
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── errors.go
│   │   ├── mocks/
│   │   │   ├── mock_conn_management_scope.go
│   │   │   ├── mock_peer_scope.go
│   │   │   ├── mock_protocol_scope.go
│   │   │   ├── mock_resource_manager.go
│   │   │   ├── mock_resource_scope_span.go
│   │   │   ├── mock_stream_management_scope.go
│   │   │   └── network.go
│   │   ├── mux.go
│   │   ├── nattype.go
│   │   ├── network.go
│   │   ├── notifee.go
│   │   ├── notifee_test.go
│   │   ├── rcmgr.go
│   │   └── stream.go
│   ├── peer/
│   │   ├── addrinfo.go
│   │   ├── addrinfo_serde.go
│   │   ├── addrinfo_test.go
│   │   ├── pb/
│   │   │   ├── peer_record.pb.go
│   │   │   └── peer_record.proto
│   │   ├── peer.go
│   │   ├── peer_serde.go
│   │   ├── peer_serde_test.go
│   │   ├── peer_test.go
│   │   ├── record.go
│   │   └── record_test.go
│   ├── peerstore/
│   │   ├── helpers.go
│   │   └── peerstore.go
│   ├── pnet/
│   │   ├── codec.go
│   │   ├── codec_test.go
│   │   ├── env.go
│   │   ├── error.go
│   │   ├── error_test.go
│   │   └── protector.go
│   ├── protocol/
│   │   ├── id.go
│   │   └── switch.go
│   ├── record/
│   │   ├── envelope.go
│   │   ├── envelope_test.go
│   │   ├── pb/
│   │   │   ├── envelope.pb.go
│   │   │   └── envelope.proto
│   │   ├── record.go
│   │   └── record_test.go
│   ├── routing/
│   │   ├── options.go
│   │   ├── query.go
│   │   ├── query_serde.go
│   │   ├── query_test.go
│   │   └── routing.go
│   ├── sec/
│   │   └── security.go
│   ├── test/
│   │   ├── addrs.go
│   │   ├── crypto.go
│   │   ├── errors.go
│   │   ├── mockclock.go
│   │   ├── mockclock_test.go
│   │   └── peer.go
│   └── transport/
│       └── transport.go
├── dashboards/
│   ├── README.md
│   ├── autonat/
│   │   └── autonat.json
│   ├── autonatv2/
│   │   └── autonatv2.json
│   ├── autorelay/
│   │   └── autorelay.json
│   ├── dashboard.yml
│   ├── datasources.yml
│   ├── docker-compose-linux.yml
│   ├── docker-compose.base.yml
│   ├── eventbus/
│   │   └── eventbus.json
│   ├── holepunch/
│   │   └── holepunch.json
│   ├── host-addrs/
│   │   └── host-addrs.json
│   ├── identify/
│   │   └── identify.json
│   ├── prometheus.yml
│   ├── relaysvc/
│   │   └── relaysvc.json
│   ├── resource-manager/
│   │   ├── README.md
│   │   └── resource-manager.json
│   └── swarm/
│       └── swarm.json
├── defaults.go
├── docs/
│   └── flaky-tests.md
├── examples/
│   ├── README.md
│   ├── go.mod
│   ├── go.sum
│   ├── ipfs-camp-2019/
│   │   ├── README.md
│   │   ├── go.mod
│   │   └── go.sum
│   ├── metrics-and-dashboards/
│   │   ├── README.md
│   │   ├── compose.yml
│   │   ├── go-libp2p-node.Dockerfile
│   │   ├── main.go
│   │   └── prometheus.yml
│   ├── pubsub/
│   │   ├── README.md
│   │   └── basic-chat-with-rendezvous/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── go.mod
│   │       ├── go.sum
│   │       └── main.go
│   └── testutils/
│       ├── logharness.go
│       └── net.go
├── fx_options_test.go
├── go.mod
├── go.sum
├── gologshim/
│   ├── gologshim.go
│   └── gologshim_test.go
├── leaky_tests/
│   ├── README.md
│   └── leaky_test.go
├── libp2p.go
├── libp2p_test.go
├── limits.go
├── options.go
├── options_filter.go
├── p2p/
│   ├── canonicallog/
│   │   ├── canonicallog.go
│   │   └── canonicallog_test.go
│   ├── discovery/
│   │   ├── backoff/
│   │   │   ├── backoff.go
│   │   │   ├── backoff_test.go
│   │   │   ├── backoffcache.go
│   │   │   ├── backoffcache_test.go
│   │   │   ├── backoffconnector.go
│   │   │   └── backoffconnector_test.go
│   │   ├── mdns/
│   │   │   ├── mdns.go
│   │   │   └── mdns_test.go
│   │   ├── mocks/
│   │   │   └── mocks.go
│   │   ├── routing/
│   │   │   ├── routing.go
│   │   │   └── routing_test.go
│   │   └── util/
│   │       └── util.go
│   ├── host/
│   │   ├── autonat/
│   │   │   ├── autonat.go
│   │   │   ├── autonat_test.go
│   │   │   ├── client.go
│   │   │   ├── dialpolicy.go
│   │   │   ├── dialpolicy_test.go
│   │   │   ├── interface.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── notify.go
│   │   │   ├── options.go
│   │   │   ├── pb/
│   │   │   │   ├── autonat.pb.go
│   │   │   │   └── autonat.proto
│   │   │   ├── proto.go
│   │   │   ├── svc.go
│   │   │   ├── svc_test.go
│   │   │   └── test/
│   │   │       ├── autonat_test.go
│   │   │       └── dummy.go
│   │   ├── autorelay/
│   │   │   ├── addrsplosion.go
│   │   │   ├── addrsplosion_test.go
│   │   │   ├── autorelay.go
│   │   │   ├── autorelay_test.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_noalloc_test.go
│   │   │   ├── options.go
│   │   │   └── relay_finder.go
│   │   ├── basic/
│   │   │   ├── addrs_manager.go
│   │   │   ├── addrs_manager_test.go
│   │   │   ├── addrs_metrics.go
│   │   │   ├── addrs_metrics_test.go
│   │   │   ├── addrs_reachability_tracker.go
│   │   │   ├── addrs_reachability_tracker_test.go
│   │   │   ├── basic_host.go
│   │   │   ├── basic_host_synctest_test.go
│   │   │   ├── basic_host_test.go
│   │   │   ├── mock_nat_test.go
│   │   │   ├── mocks.go
│   │   │   ├── natmgr.go
│   │   │   └── natmgr_test.go
│   │   ├── blank/
│   │   │   └── blank.go
│   │   ├── eventbus/
│   │   │   ├── basic.go
│   │   │   ├── basic_metrics.go
│   │   │   ├── basic_metrics_test.go
│   │   │   ├── basic_test.go
│   │   │   └── opts.go
│   │   ├── observedaddrs/
│   │   │   ├── manager.go
│   │   │   ├── manager_glass_test.go
│   │   │   └── manager_test.go
│   │   ├── peerstore/
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── peerstore.go
│   │   │   ├── pstoreds/
│   │   │   │   ├── addr_book.go
│   │   │   │   ├── addr_book_gc.go
│   │   │   │   ├── addr_book_gc_test.go
│   │   │   │   ├── cache.go
│   │   │   │   ├── cyclic_batch.go
│   │   │   │   ├── deprecate.go
│   │   │   │   ├── ds_test.go
│   │   │   │   ├── keybook.go
│   │   │   │   ├── metadata.go
│   │   │   │   ├── pb/
│   │   │   │   │   ├── pstore.pb.go
│   │   │   │   │   └── pstore.proto
│   │   │   │   ├── peerstore.go
│   │   │   │   └── protobook.go
│   │   │   ├── pstoremem/
│   │   │   │   ├── addr_book.go
│   │   │   │   ├── addr_book_test.go
│   │   │   │   ├── inmem_test.go
│   │   │   │   ├── keybook.go
│   │   │   │   ├── metadata.go
│   │   │   │   ├── peerstore.go
│   │   │   │   ├── peerstore_test.go
│   │   │   │   ├── protobook.go
│   │   │   │   ├── sorting.go
│   │   │   │   └── sorting_test.go
│   │   │   └── test/
│   │   │       ├── addr_book_suite.go
│   │   │       ├── benchmarks_suite.go
│   │   │       ├── keybook_suite.go
│   │   │       ├── peerstore_suite.go
│   │   │       └── utils.go
│   │   ├── pstoremanager/
│   │   │   ├── mock_peerstore_test.go
│   │   │   ├── pstoremanager.go
│   │   │   └── pstoremanager_test.go
│   │   ├── relaysvc/
│   │   │   ├── relay.go
│   │   │   └── relay_test.go
│   │   ├── resource-manager/
│   │   │   ├── README.md
│   │   │   ├── allowlist.go
│   │   │   ├── allowlist_test.go
│   │   │   ├── conn_limiter.go
│   │   │   ├── conn_limiter_test.go
│   │   │   ├── conn_rate_limiter.go
│   │   │   ├── docs/
│   │   │   │   └── allowlist.md
│   │   │   ├── error.go
│   │   │   ├── extapi.go
│   │   │   ├── limit.go
│   │   │   ├── limit_config_test.backwards-compat.json
│   │   │   ├── limit_config_test.go
│   │   │   ├── limit_config_test.json
│   │   │   ├── limit_config_test_default.json
│   │   │   ├── limit_defaults.go
│   │   │   ├── limit_test.go
│   │   │   ├── limits_metrics_test.go
│   │   │   ├── metrics.go
│   │   │   ├── noalloc_test.go
│   │   │   ├── obs/
│   │   │   │   └── obs.go
│   │   │   ├── rcmgr.go
│   │   │   ├── rcmgr_test.go
│   │   │   ├── scope.go
│   │   │   ├── scope_test.go
│   │   │   ├── stats.go
│   │   │   ├── stats_test.go
│   │   │   ├── sys_not_unix.go
│   │   │   ├── sys_unix.go
│   │   │   ├── sys_windows.go
│   │   │   └── trace.go
│   │   └── routed/
│   │       ├── routed.go
│   │       └── routed_test.go
│   ├── http/
│   │   ├── auth/
│   │   │   ├── auth.go
│   │   │   ├── auth_test.go
│   │   │   ├── client.go
│   │   │   ├── internal/
│   │   │   │   └── handshake/
│   │   │   │       ├── alloc_test.go
│   │   │   │       ├── client.go
│   │   │   │       ├── handshake.go
│   │   │   │       ├── handshake_test.go
│   │   │   │       └── server.go
│   │   │   └── server.go
│   │   ├── example_test.go
│   │   ├── libp2phttp.go
│   │   ├── libp2phttp_test.go
│   │   ├── options.go
│   │   └── ping/
│   │       └── ping.go
│   ├── metricshelper/
│   │   ├── conn.go
│   │   ├── conn_test.go
│   │   ├── dir.go
│   │   ├── pool.go
│   │   ├── pool_test.go
│   │   ├── registerer.go
│   │   └── registerer_test.go
│   ├── muxer/
│   │   ├── testsuite/
│   │   │   └── mux.go
│   │   └── yamux/
│   │       ├── conn.go
│   │       ├── stream.go
│   │       ├── transport.go
│   │       └── transport_test.go
│   ├── net/
│   │   ├── README.md
│   │   ├── conngater/
│   │   │   ├── conngater.go
│   │   │   └── conngater_test.go
│   │   ├── connmgr/
│   │   │   ├── bench_test.go
│   │   │   ├── connmgr.go
│   │   │   ├── connmgr_test.go
│   │   │   ├── decay.go
│   │   │   ├── decay_test.go
│   │   │   └── options.go
│   │   ├── gostream/
│   │   │   ├── addr.go
│   │   │   ├── conn.go
│   │   │   ├── gostream.go
│   │   │   ├── gostream_test.go
│   │   │   └── listener.go
│   │   ├── mock/
│   │   │   ├── complement.go
│   │   │   ├── interface.go
│   │   │   ├── log2.txt
│   │   │   ├── mock.go
│   │   │   ├── mock_conn.go
│   │   │   ├── mock_link.go
│   │   │   ├── mock_net.go
│   │   │   ├── mock_notif_test.go
│   │   │   ├── mock_peernet.go
│   │   │   ├── mock_printer.go
│   │   │   ├── mock_stream.go
│   │   │   ├── mock_test.go
│   │   │   └── ratelimiter.go
│   │   ├── nat/
│   │   │   ├── internal/
│   │   │   │   └── nat/
│   │   │   │       ├── LICENSE
│   │   │   │       ├── README.md
│   │   │   │       ├── nat.go
│   │   │   │       ├── natpmp.go
│   │   │   │       └── upnp.go
│   │   │   ├── mock_nat_test.go
│   │   │   ├── nat.go
│   │   │   └── nat_test.go
│   │   ├── pnet/
│   │   │   ├── protector.go
│   │   │   ├── psk_conn.go
│   │   │   └── psk_conn_test.go
│   │   ├── reuseport/
│   │   │   ├── dial.go
│   │   │   ├── dialer.go
│   │   │   ├── listen.go
│   │   │   ├── reuseport.go
│   │   │   ├── reuseport_plan9.go
│   │   │   ├── reuseport_posix.go
│   │   │   ├── reuseport_test.go
│   │   │   ├── transport.go
│   │   │   └── transport_test.go
│   │   ├── swarm/
│   │   │   ├── black_hole_detector.go
│   │   │   ├── black_hole_detector_test.go
│   │   │   ├── clock.go
│   │   │   ├── connectedness_event_emitter.go
│   │   │   ├── dial_error.go
│   │   │   ├── dial_error_test.go
│   │   │   ├── dial_ranker.go
│   │   │   ├── dial_ranker_test.go
│   │   │   ├── dial_sync.go
│   │   │   ├── dial_sync_test.go
│   │   │   ├── dial_test.go
│   │   │   ├── dial_worker.go
│   │   │   ├── dial_worker_test.go
│   │   │   ├── limiter.go
│   │   │   ├── limiter_test.go
│   │   │   ├── peers_test.go
│   │   │   ├── resolve_test.go
│   │   │   ├── simul_test.go
│   │   │   ├── swarm.go
│   │   │   ├── swarm_addr.go
│   │   │   ├── swarm_addr_test.go
│   │   │   ├── swarm_conn.go
│   │   │   ├── swarm_dial.go
│   │   │   ├── swarm_dial_test.go
│   │   │   ├── swarm_event_test.go
│   │   │   ├── swarm_listen.go
│   │   │   ├── swarm_metrics.go
│   │   │   ├── swarm_metrics_test.go
│   │   │   ├── swarm_net_test.go
│   │   │   ├── swarm_notif_test.go
│   │   │   ├── swarm_stream.go
│   │   │   ├── swarm_test.go
│   │   │   ├── swarm_transport.go
│   │   │   ├── testing/
│   │   │   │   ├── testing.go
│   │   │   │   └── testing_test.go
│   │   │   ├── transport_test.go
│   │   │   └── util_test.go
│   │   └── upgrader/
│   │       ├── conn.go
│   │       ├── gater_test.go
│   │       ├── listener.go
│   │       ├── listener_test.go
│   │       ├── threshold.go
│   │       ├── upgrader.go
│   │       └── upgrader_test.go
│   ├── protocol/
│   │   ├── autonatv2/
│   │   │   ├── autonat.go
│   │   │   ├── autonat_test.go
│   │   │   ├── client.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── msg_reader.go
│   │   │   ├── options.go
│   │   │   ├── pb/
│   │   │   │   ├── autonatv2.pb.go
│   │   │   │   └── autonatv2.proto
│   │   │   ├── server.go
│   │   │   └── server_test.go
│   │   ├── circuitv2/
│   │   │   ├── client/
│   │   │   │   ├── client.go
│   │   │   │   ├── conn.go
│   │   │   │   ├── dial.go
│   │   │   │   ├── handlers.go
│   │   │   │   ├── listen.go
│   │   │   │   ├── reservation.go
│   │   │   │   ├── reservation_test.go
│   │   │   │   └── transport.go
│   │   │   ├── pb/
│   │   │   │   ├── circuit.pb.go
│   │   │   │   ├── circuit.proto
│   │   │   │   ├── voucher.pb.go
│   │   │   │   └── voucher.proto
│   │   │   ├── proto/
│   │   │   │   ├── protocol.go
│   │   │   │   ├── voucher.go
│   │   │   │   └── voucher_test.go
│   │   │   ├── relay/
│   │   │   │   ├── acl.go
│   │   │   │   ├── constraints.go
│   │   │   │   ├── constraints_test.go
│   │   │   │   ├── metrics.go
│   │   │   │   ├── metrics_test.go
│   │   │   │   ├── options.go
│   │   │   │   ├── relay.go
│   │   │   │   ├── relay_priv_test.go
│   │   │   │   ├── relay_test.go
│   │   │   │   └── resources.go
│   │   │   └── util/
│   │   │       ├── io.go
│   │   │       └── pbconv.go
│   │   ├── holepunch/
│   │   │   ├── filter.go
│   │   │   ├── holepunch_test.go
│   │   │   ├── holepuncher.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_noalloc_test.go
│   │   │   ├── metrics_test.go
│   │   │   ├── pb/
│   │   │   │   ├── holepunch.pb.go
│   │   │   │   └── holepunch.proto
│   │   │   ├── svc.go
│   │   │   ├── tracer.go
│   │   │   └── util.go
│   │   ├── identify/
│   │   │   ├── id.go
│   │   │   ├── id_glass_test.go
│   │   │   ├── id_test.go
│   │   │   ├── internal/
│   │   │   │   └── user-agent/
│   │   │   │       └── user_agent.go
│   │   │   ├── metrics.go
│   │   │   ├── metrics_test.go
│   │   │   ├── opts.go
│   │   │   ├── pb/
│   │   │   │   ├── identify.pb.go
│   │   │   │   └── identify.proto
│   │   │   └── snapshot_test.go
│   │   └── ping/
│   │       ├── ping.go
│   │       └── ping_test.go
│   ├── security/
│   │   ├── insecure/
│   │   │   ├── insecure.go
│   │   │   ├── insecure_test.go
│   │   │   └── pb/
│   │   │       ├── plaintext.pb.go
│   │   │       └── plaintext.proto
│   │   ├── noise/
│   │   │   ├── benchmark_test.go
│   │   │   ├── crypto.go
│   │   │   ├── crypto_test.go
│   │   │   ├── handshake.go
│   │   │   ├── pb/
│   │   │   │   ├── payload.pb.go
│   │   │   │   └── payload.proto
│   │   │   ├── rw.go
│   │   │   ├── session.go
│   │   │   ├── session_test.go
│   │   │   ├── session_transport.go
│   │   │   ├── transport.go
│   │   │   └── transport_test.go
│   │   └── tls/
│   │       ├── cmd/
│   │       │   ├── README.md
│   │       │   ├── tlsdiag/
│   │       │   │   ├── client.go
│   │       │   │   ├── key.go
│   │       │   │   └── server.go
│   │       │   └── tlsdiag.go
│   │       ├── conn.go
│   │       ├── crypto.go
│   │       ├── crypto_test.go
│   │       ├── extension.go
│   │       ├── extension_test.go
│   │       ├── transport.go
│   │       └── transport_test.go
│   ├── test/
│   │   ├── backpressure/
│   │   │   ├── backpressure.go
│   │   │   └── backpressure_test.go
│   │   ├── basichost/
│   │   │   └── basic_host_test.go
│   │   ├── negotiation/
│   │   │   ├── muxer_test.go
│   │   │   └── security_test.go
│   │   ├── notifications/
│   │   │   └── notification_test.go
│   │   ├── quic/
│   │   │   └── quic_test.go
│   │   ├── reconnects/
│   │   │   ├── reconnect.go
│   │   │   └── reconnect_test.go
│   │   ├── resource-manager/
│   │   │   ├── echo.go
│   │   │   ├── echo_test.go
│   │   │   └── rcmgr_test.go
│   │   ├── security/
│   │   │   └── bench_test.go
│   │   ├── swarm/
│   │   │   └── swarm_test.go
│   │   ├── transport/
│   │   │   ├── deadline_test.go
│   │   │   ├── gating_test.go
│   │   │   ├── mock_connection_gater_test.go
│   │   │   ├── rcmgr_test.go
│   │   │   └── transport_test.go
│   │   └── webtransport/
│   │       └── webtransport_test.go
│   └── transport/
│       ├── quic/
│       │   ├── cmd/
│       │   │   ├── client/
│       │   │   │   └── main.go
│       │   │   ├── lib/
│       │   │   │   ├── lib.go
│       │   │   │   └── lib_test.go
│       │   │   └── server/
│       │   │       └── main.go
│       │   ├── conn.go
│       │   ├── conn_test.go
│       │   ├── listener.go
│       │   ├── listener_test.go
│       │   ├── mock_connection_gater_test.go
│       │   ├── stream.go
│       │   ├── transport.go
│       │   ├── transport_test.go
│       │   └── virtuallistener.go
│       ├── quicreuse/
│       │   ├── config.go
│       │   ├── connmgr.go
│       │   ├── connmgr_test.go
│       │   ├── listener.go
│       │   ├── nonquic_packetconn.go
│       │   ├── options.go
│       │   ├── quic_multiaddr.go
│       │   ├── quic_multiaddr_test.go
│       │   ├── reuse.go
│       │   └── reuse_test.go
│       ├── tcp/
│       │   ├── metrics.go
│       │   ├── metrics_darwin.go
│       │   ├── metrics_general.go
│       │   ├── metrics_linux.go
│       │   ├── metrics_none.go
│       │   ├── metrics_test.go
│       │   ├── tcp.go
│       │   └── tcp_test.go
│       ├── tcpreuse/
│       │   ├── connwithscope.go
│       │   ├── demultiplex.go
│       │   ├── demultiplex_test.go
│       │   ├── dialer.go
│       │   ├── internal/
│       │   │   └── sampledconn/
│       │   │       ├── sampledconn.go
│       │   │       └── sampledconn_test.go
│       │   ├── listener.go
│       │   ├── listener_test.go
│       │   └── reuseport.go
│       ├── testsuite/
│       │   ├── stream_suite.go
│       │   ├── transport_suite.go
│       │   └── utils_suite.go
│       ├── webrtc/
│       │   ├── connection.go
│       │   ├── fingerprint.go
│       │   ├── hex.go
│       │   ├── hex_test.go
│       │   ├── listener.go
│       │   ├── logger.go
│       │   ├── pb/
│       │   │   ├── message.pb.go
│       │   │   └── message.proto
│       │   ├── sdp.go
│       │   ├── sdp_test.go
│       │   ├── stream.go
│       │   ├── stream_read.go
│       │   ├── stream_test.go
│       │   ├── stream_write.go
│       │   ├── transport.go
│       │   ├── transport_test.go
│       │   └── udpmux/
│       │       ├── mux.go
│       │       ├── mux_test.go
│       │       └── muxed_connection.go
│       ├── websocket/
│       │   ├── LICENSE-APACHE
│       │   ├── LICENSE-MIT
│       │   ├── addrs.go
│       │   ├── addrs_test.go
│       │   ├── conn.go
│       │   ├── listener.go
│       │   ├── websocket.go
│       │   └── websocket_test.go
│       └── webtransport/
│           ├── cert_manager.go
│           ├── cert_manager_test.go
│           ├── conn.go
│           ├── crypto.go
│           ├── crypto_test.go
│           ├── listener.go
│           ├── mock_connection_gater_test.go
│           ├── multiaddr.go
│           ├── multiaddr_test.go
│           ├── noise_early_data.go
│           ├── stream.go
│           ├── transport.go
│           └── transport_test.go
├── proto_test.go
├── scripts/
│   ├── .gitignore
│   ├── download-protoc.sh
│   ├── gen-proto.sh
│   ├── mkreleaselog
│   ├── print-protoc-hashes.sh
│   └── test_analysis/
│       ├── cmd/
│       │   └── gotest2sql/
│       │       └── main.go
│       ├── go.mod
│       ├── go.sum
│       ├── main.go
│       └── main_test.go
├── test-plans/
│   ├── .gitignore
│   ├── PingDockerfile
│   ├── README.md
│   ├── cmd/
│   │   └── ping/
│   │       └── main.go
│   ├── go.mod
│   ├── go.sum
│   └── ping-version.json
├── tools.go
├── version.json
└── x/
    ├── rate/
    │   ├── limiter.go
    │   └── limiter_test.go
    └── simlibp2p/
        ├── libp2p.go
        └── synctest_test.go
Download .txt
Showing preview only (535K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5856 symbols across 528 files)

FILE: config/config.go
  type NATManagerC (line 62) | type NATManagerC
  type RoutingC (line 64) | type RoutingC
  type AutoNATConfig (line 67) | type AutoNATConfig struct
  type Security (line 75) | type Security struct
  type Config (line 84) | type Config struct
    method makeSwarm (line 158) | func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (...
    method makeAutoNATV2Host (line 219) | func (cfg *Config) makeAutoNATV2Host() (host.Host, error) {
    method addTransports (line 290) | func (cfg *Config) addTransports() ([]fx.Option, error) {
    method newBasicHost (line 443) | func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus,...
    method validate (line 467) | func (cfg *Config) validate() error {
    method NewNode (line 490) | func (cfg *Config) NewNode() (host.Host, error) {
    method addAutoNAT (line 662) | func (cfg *Config) addAutoNAT(h *bhost.BasicHost) error {
    method Apply (line 770) | func (cfg *Config) Apply(opts ...Option) error {
  type Option (line 766) | type Option

FILE: config/config_test.go
  function TestNilOption (line 7) | func TestNilOption(t *testing.T) {

FILE: config/host.go
  type closableBasicHost (line 12) | type closableBasicHost struct
    method Close (line 17) | func (h *closableBasicHost) Close() error {
  type closableRoutedHost (line 22) | type closableRoutedHost struct
    method Close (line 29) | func (h *closableRoutedHost) Close() error {

FILE: config/quic.go
  constant statelessResetKeyInfo (line 15) | statelessResetKeyInfo = "libp2p quic stateless reset key"
  constant tokenGeneratorKeyInfo (line 16) | tokenGeneratorKeyInfo = "libp2p quic token generator key"
  function PrivKeyToStatelessResetKey (line 19) | func PrivKeyToStatelessResetKey(key crypto.PrivKey) (quic.StatelessReset...
  function PrivKeyToTokenGeneratorKey (line 32) | func PrivKeyToTokenGeneratorKey(key crypto.PrivKey) (quic.TokenGenerator...

FILE: core/connmgr/decay.go
  type Decayer (line 31) | type Decayer interface
  type DecayFn (line 49) | type DecayFn
  type BumpFn (line 55) | type BumpFn
  type DecayingTag (line 59) | type DecayingTag interface
  type DecayingValue (line 93) | type DecayingValue struct

FILE: core/connmgr/gater.go
  type ConnectionGater (line 54) | type ConnectionGater interface

FILE: core/connmgr/manager.go
  function SupportsDecay (line 19) | func SupportsDecay(mgr ConnManager) (Decayer, bool) {
  type ConnManager (line 33) | type ConnManager interface
  type TagInfo (line 86) | type TagInfo struct
  type GetConnLimiter (line 98) | type GetConnLimiter interface

FILE: core/connmgr/null.go
  type NullConnMgr (line 11) | type NullConnMgr struct
    method TagPeer (line 15) | func (NullConnMgr) TagPeer(peer.ID, string, int)             {}
    method UntagPeer (line 16) | func (NullConnMgr) UntagPeer(peer.ID, string)                {}
    method UpsertTag (line 17) | func (NullConnMgr) UpsertTag(peer.ID, string, func(int) int) {}
    method GetTagInfo (line 18) | func (NullConnMgr) GetTagInfo(peer.ID) *TagInfo              { return ...
    method TrimOpenConns (line 19) | func (NullConnMgr) TrimOpenConns(_ context.Context)          {}
    method Notifee (line 20) | func (NullConnMgr) Notifee() network.Notifiee                { return ...
    method Protect (line 21) | func (NullConnMgr) Protect(peer.ID, string)                  {}
    method Unprotect (line 22) | func (NullConnMgr) Unprotect(peer.ID, string) bool           { return ...
    method IsProtected (line 23) | func (NullConnMgr) IsProtected(peer.ID, string) bool         { return ...
    method CheckLimit (line 24) | func (NullConnMgr) CheckLimit(_ GetConnLimiter) error        { return ...
    method Close (line 25) | func (NullConnMgr) Close() error                             { return ...

FILE: core/connmgr/presets.go
  function DecayNone (line 9) | func DecayNone() DecayFn {
  function DecayFixed (line 17) | func DecayFixed(minuend int) DecayFn {
  function DecayLinear (line 26) | func DecayLinear(coef float64) DecayFn {
  function DecayExpireWhenInactive (line 34) | func DecayExpireWhenInactive(after time.Duration) DecayFn {
  function BumpSumUnbounded (line 42) | func BumpSumUnbounded() BumpFn {
  function BumpSumBounded (line 50) | func BumpSumBounded(min, max int) BumpFn {
  function BumpOverwrite (line 63) | func BumpOverwrite() BumpFn {

FILE: core/control/disconnect.go
  type DisconnectReason (line 9) | type DisconnectReason

FILE: core/crypto/bench_test.go
  function BenchmarkSignRSA1B (line 5) | func BenchmarkSignRSA1B(b *testing.B)      { RunBenchmarkSignRSA(b, 1) }
  function BenchmarkSignRSA10B (line 6) | func BenchmarkSignRSA10B(b *testing.B)     { RunBenchmarkSignRSA(b, 10) }
  function BenchmarkSignRSA100B (line 7) | func BenchmarkSignRSA100B(b *testing.B)    { RunBenchmarkSignRSA(b, 100) }
  function BenchmarkSignRSA1000B (line 8) | func BenchmarkSignRSA1000B(b *testing.B)   { RunBenchmarkSignRSA(b, 1000) }
  function BenchmarkSignRSA10000B (line 9) | func BenchmarkSignRSA10000B(b *testing.B)  { RunBenchmarkSignRSA(b, 1000...
  function BenchmarkSignRSA100000B (line 10) | func BenchmarkSignRSA100000B(b *testing.B) { RunBenchmarkSignRSA(b, 1000...
  function BenchmarkVerifyRSA1B (line 12) | func BenchmarkVerifyRSA1B(b *testing.B)      { RunBenchmarkVerifyRSA(b, ...
  function BenchmarkVerifyRSA10B (line 13) | func BenchmarkVerifyRSA10B(b *testing.B)     { RunBenchmarkVerifyRSA(b, ...
  function BenchmarkVerifyRSA100B (line 14) | func BenchmarkVerifyRSA100B(b *testing.B)    { RunBenchmarkVerifyRSA(b, ...
  function BenchmarkVerifyRSA1000B (line 15) | func BenchmarkVerifyRSA1000B(b *testing.B)   { RunBenchmarkVerifyRSA(b, ...
  function BenchmarkVerifyRSA10000B (line 16) | func BenchmarkVerifyRSA10000B(b *testing.B)  { RunBenchmarkVerifyRSA(b, ...
  function BenchmarkVerifyRSA100000B (line 17) | func BenchmarkVerifyRSA100000B(b *testing.B) { RunBenchmarkVerifyRSA(b, ...
  function BenchmarkSignEd255191B (line 19) | func BenchmarkSignEd255191B(b *testing.B)      { RunBenchmarkSignEd25519...
  function BenchmarkSignEd2551910B (line 20) | func BenchmarkSignEd2551910B(b *testing.B)     { RunBenchmarkSignEd25519...
  function BenchmarkSignEd25519100B (line 21) | func BenchmarkSignEd25519100B(b *testing.B)    { RunBenchmarkSignEd25519...
  function BenchmarkSignEd255191000B (line 22) | func BenchmarkSignEd255191000B(b *testing.B)   { RunBenchmarkSignEd25519...
  function BenchmarkSignEd2551910000B (line 23) | func BenchmarkSignEd2551910000B(b *testing.B)  { RunBenchmarkSignEd25519...
  function BenchmarkSignEd25519100000B (line 24) | func BenchmarkSignEd25519100000B(b *testing.B) { RunBenchmarkSignEd25519...
  function BenchmarkVerifyEd255191B (line 26) | func BenchmarkVerifyEd255191B(b *testing.B)      { RunBenchmarkVerifyEd2...
  function BenchmarkVerifyEd2551910B (line 27) | func BenchmarkVerifyEd2551910B(b *testing.B)     { RunBenchmarkVerifyEd2...
  function BenchmarkVerifyEd25519100B (line 28) | func BenchmarkVerifyEd25519100B(b *testing.B)    { RunBenchmarkVerifyEd2...
  function BenchmarkVerifyEd255191000B (line 29) | func BenchmarkVerifyEd255191000B(b *testing.B)   { RunBenchmarkVerifyEd2...
  function BenchmarkVerifyEd2551910000B (line 30) | func BenchmarkVerifyEd2551910000B(b *testing.B)  { RunBenchmarkVerifyEd2...
  function BenchmarkVerifyEd25519100000B (line 31) | func BenchmarkVerifyEd25519100000B(b *testing.B) { RunBenchmarkVerifyEd2...
  function RunBenchmarkSignRSA (line 33) | func RunBenchmarkSignRSA(b *testing.B, numBytes int) {
  function RunBenchmarkSignEd25519 (line 37) | func RunBenchmarkSignEd25519(b *testing.B, numBytes int) {
  function runBenchmarkSign (line 41) | func runBenchmarkSign(b *testing.B, numBytes int, t int) {
  function RunBenchmarkVerifyRSA (line 56) | func RunBenchmarkVerifyRSA(b *testing.B, numBytes int) {
  function RunBenchmarkVerifyEd25519 (line 60) | func RunBenchmarkVerifyEd25519(b *testing.B, numBytes int) {
  function runBenchmarkVerify (line 64) | func runBenchmarkVerify(b *testing.B, numBytes int, t int) {

FILE: core/crypto/ecdsa.go
  type ECDSAPrivateKey (line 19) | type ECDSAPrivateKey struct
    method Type (line 117) | func (ePriv *ECDSAPrivateKey) Type() pb.KeyType {
    method Raw (line 122) | func (ePriv *ECDSAPrivateKey) Raw() (res []byte, err error) {
    method Equals (line 128) | func (ePriv *ECDSAPrivateKey) Equals(o Key) bool {
    method Sign (line 133) | func (ePriv *ECDSAPrivateKey) Sign(data []byte) (sig []byte, err error) {
    method GetPublic (line 148) | func (ePriv *ECDSAPrivateKey) GetPublic() PubKey {
  type ECDSAPublicKey (line 24) | type ECDSAPublicKey struct
    method Type (line 153) | func (ePub *ECDSAPublicKey) Type() pb.KeyType {
    method Raw (line 158) | func (ePub *ECDSAPublicKey) Raw() ([]byte, error) {
    method Equals (line 163) | func (ePub *ECDSAPublicKey) Equals(o Key) bool {
    method Verify (line 168) | func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (success boo...
  type ECDSASig (line 29) | type ECDSASig struct
  function GenerateECDSAKeyPair (line 47) | func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) {
  function GenerateECDSAKeyPairWithCurve (line 52) | func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) ...
  function ECDSAKeyPairFromKey (line 62) | func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) {
  function ECDSAPublicKeyFromPubKey (line 71) | func ECDSAPublicKeyFromPubKey(pub ecdsa.PublicKey) (PubKey, error) {
  function MarshalECDSAPrivateKey (line 76) | func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) (res []byte, err erro...
  function MarshalECDSAPublicKey (line 82) | func MarshalECDSAPublicKey(ePub ECDSAPublicKey) (res []byte, err error) {
  function UnmarshalECDSAPrivateKey (line 88) | func UnmarshalECDSAPrivateKey(data []byte) (res PrivKey, err error) {
  function UnmarshalECDSAPublicKey (line 100) | func UnmarshalECDSAPublicKey(data []byte) (key PubKey, err error) {

FILE: core/crypto/ecdsa_test.go
  function TestECDSABasicSignAndVerify (line 9) | func TestECDSABasicSignAndVerify(t *testing.T) {
  function TestECDSASignZero (line 43) | func TestECDSASignZero(t *testing.T) {
  function TestECDSAMarshalLoop (line 64) | func TestECDSAMarshalLoop(t *testing.T) {
  function TestECDSAPublicKeyFromPubKey (line 99) | func TestECDSAPublicKeyFromPubKey(t *testing.T) {

FILE: core/crypto/ed25519.go
  type Ed25519PrivateKey (line 16) | type Ed25519PrivateKey struct
    method Type (line 42) | func (k *Ed25519PrivateKey) Type() pb.KeyType {
    method Raw (line 47) | func (k *Ed25519PrivateKey) Raw() ([]byte, error) {
    method pubKeyBytes (line 58) | func (k *Ed25519PrivateKey) pubKeyBytes() []byte {
    method Equals (line 63) | func (k *Ed25519PrivateKey) Equals(o Key) bool {
    method GetPublic (line 73) | func (k *Ed25519PrivateKey) GetPublic() PubKey {
    method Sign (line 78) | func (k *Ed25519PrivateKey) Sign(msg []byte) (res []byte, err error) {
  type Ed25519PublicKey (line 21) | type Ed25519PublicKey struct
    method Type (line 85) | func (k *Ed25519PublicKey) Type() pb.KeyType {
    method Raw (line 90) | func (k *Ed25519PublicKey) Raw() ([]byte, error) {
    method Equals (line 95) | func (k *Ed25519PublicKey) Equals(o Key) bool {
    method Verify (line 105) | func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (success bo...
  function GenerateEd25519Key (line 26) | func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) {
  function UnmarshalEd25519PublicKey (line 118) | func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) {
  function UnmarshalEd25519PrivateKey (line 129) | func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {

FILE: core/crypto/ed25519_test.go
  function TestBasicSignAndVerify (line 13) | func TestBasicSignAndVerify(t *testing.T) {
  function TestSignZero (line 47) | func TestSignZero(t *testing.T) {
  function TestMarshalLoop (line 68) | func TestMarshalLoop(t *testing.T) {
  function TestUnmarshalErrors (line 152) | func TestUnmarshalErrors(t *testing.T) {

FILE: core/crypto/fixture_test.go
  type testCase (line 17) | type testCase struct
  function fname (line 42) | func fname(kt crypto_pb.KeyType, ext string) string {
  function TestFixtures (line 46) | func TestFixtures(t *testing.T) {
  function init (line 101) | func init() {
  function generate (line 110) | func generate() {

FILE: core/crypto/key.go
  constant RSA (line 20) | RSA = iota
  constant Ed25519 (line 22) | Ed25519
  constant Secp256k1 (line 24) | Secp256k1
  constant ECDSA (line 26) | ECDSA
  type PubKeyUnmarshaller (line 42) | type PubKeyUnmarshaller
  type PrivKeyUnmarshaller (line 45) | type PrivKeyUnmarshaller
  type Key (line 64) | type Key interface
  type PrivKey (line 79) | type PrivKey interface
  type PubKey (line 90) | type PubKey interface
  type GenSharedKey (line 98) | type GenSharedKey
  function GenerateKeyPair (line 101) | func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
  function GenerateKeyPairWithReader (line 106) | func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, P...
  function UnmarshalPublicKey (line 123) | func UnmarshalPublicKey(data []byte) (PubKey, error) {
  function PublicKeyFromProto (line 135) | func PublicKeyFromProto(pmes *pb.PublicKey) (PubKey, error) {
  function MarshalPublicKey (line 158) | func MarshalPublicKey(k PubKey) ([]byte, error) {
  function PublicKeyToProto (line 169) | func PublicKeyToProto(k PubKey) (*pb.PublicKey, error) {
  function UnmarshalPrivateKey (line 182) | func UnmarshalPrivateKey(data []byte) (PrivKey, error) {
  function MarshalPrivateKey (line 198) | func MarshalPrivateKey(k PrivKey) ([]byte, error) {
  function ConfigDecodeKey (line 210) | func ConfigDecodeKey(b string) ([]byte, error) {
  function ConfigEncodeKey (line 215) | func ConfigEncodeKey(b []byte) string {
  function KeyEqual (line 220) | func KeyEqual(k1, k2 Key) bool {
  function basicEquals (line 228) | func basicEquals(k1, k2 Key) bool {

FILE: core/crypto/key_test.go
  function TestKeys (line 25) | func TestKeys(t *testing.T) {
  function TestKeyPairFromKey (line 31) | func TestKeyPairFromKey(t *testing.T) {
  function testKeyType (line 178) | func testKeyType(typ int, t *testing.T) {
  function testKeySignature (line 194) | func testKeySignature(t *testing.T, sk PrivKey) {
  function testKeyEncoding (line 217) | func testKeyEncoding(t *testing.T, sk PrivKey) {
  function testKeyEquals (line 266) | func testKeyEquals(t *testing.T, k Key) {

FILE: core/crypto/key_to_stdlib.go
  function KeyPairFromStdKey (line 13) | func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) {
  function PrivKeyToStdKey (line 41) | func PrivKeyToStdKey(priv PrivKey) (crypto.PrivateKey, error) {
  function PubKeyToStdKey (line 61) | func PubKeyToStdKey(pub PubKey) (crypto.PublicKey, error) {

FILE: core/crypto/pb/crypto.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type KeyType (line 24) | type KeyType
    method Enum (line 49) | func (x KeyType) Enum() *KeyType {
    method String (line 55) | func (x KeyType) String() string {
    method Descriptor (line 59) | func (KeyType) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 63) | func (KeyType) Type() protoreflect.EnumType {
    method Number (line 67) | func (x KeyType) Number() protoreflect.EnumNumber {
    method UnmarshalJSON (line 72) | func (x *KeyType) UnmarshalJSON(b []byte) error {
    method EnumDescriptor (line 82) | func (KeyType) EnumDescriptor() ([]byte, []int) {
  constant KeyType_RSA (line 27) | KeyType_RSA       KeyType = 0
  constant KeyType_Ed25519 (line 28) | KeyType_Ed25519   KeyType = 1
  constant KeyType_Secp256k1 (line 29) | KeyType_Secp256k1 KeyType = 2
  constant KeyType_ECDSA (line 30) | KeyType_ECDSA     KeyType = 3
  type PublicKey (line 86) | type PublicKey struct
    method Reset (line 94) | func (x *PublicKey) Reset() {
    method String (line 101) | func (x *PublicKey) String() string {
    method ProtoMessage (line 105) | func (*PublicKey) ProtoMessage() {}
    method ProtoReflect (line 107) | func (x *PublicKey) ProtoReflect() protoreflect.Message {
    method Descriptor (line 120) | func (*PublicKey) Descriptor() ([]byte, []int) {
    method GetType (line 124) | func (x *PublicKey) GetType() KeyType {
    method GetData (line 131) | func (x *PublicKey) GetData() []byte {
  type PrivateKey (line 138) | type PrivateKey struct
    method Reset (line 146) | func (x *PrivateKey) Reset() {
    method String (line 153) | func (x *PrivateKey) String() string {
    method ProtoMessage (line 157) | func (*PrivateKey) ProtoMessage() {}
    method ProtoReflect (line 159) | func (x *PrivateKey) ProtoReflect() protoreflect.Message {
    method Descriptor (line 172) | func (*PrivateKey) Descriptor() ([]byte, []int) {
    method GetType (line 176) | func (x *PrivateKey) GetType() KeyType {
    method GetData (line 183) | func (x *PrivateKey) GetData() []byte {
  constant file_core_crypto_pb_crypto_proto_rawDesc (line 192) | file_core_crypto_pb_crypto_proto_rawDesc = "" +
  function file_core_crypto_pb_crypto_proto_rawDescGZIP (line 213) | func file_core_crypto_pb_crypto_proto_rawDescGZIP() []byte {
  function init (line 237) | func init() { file_core_crypto_pb_crypto_proto_init() }
  function file_core_crypto_pb_crypto_proto_init (line 238) | func file_core_crypto_pb_crypto_proto_init() {

FILE: core/crypto/rsa_common.go
  constant WeakRsaKeyEnv (line 11) | WeakRsaKeyEnv = "LIBP2P_ALLOW_WEAK_RSA_KEYS"
  function init (line 22) | func init() {

FILE: core/crypto/rsa_go.go
  type RsaPrivateKey (line 17) | type RsaPrivateKey struct
    method Sign (line 83) | func (sk *RsaPrivateKey) Sign(message []byte) (sig []byte, err error) {
    method GetPublic (line 90) | func (sk *RsaPrivateKey) GetPublic() PubKey {
    method Type (line 94) | func (sk *RsaPrivateKey) Type() pb.KeyType {
    method Raw (line 98) | func (sk *RsaPrivateKey) Raw() (res []byte, err error) {
    method Equals (line 105) | func (sk *RsaPrivateKey) Equals(k Key) bool {
  type RsaPublicKey (line 22) | type RsaPublicKey struct
    method Verify (line 45) | func (pk *RsaPublicKey) Verify(data, sig []byte) (success bool, err er...
    method Type (line 62) | func (pk *RsaPublicKey) Type() pb.KeyType {
    method Raw (line 66) | func (pk *RsaPublicKey) Raw() (res []byte, err error) {
    method Equals (line 72) | func (pk *RsaPublicKey) Equals(k Key) bool {
  function GenerateRSAKeyPair (line 29) | func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
  function UnmarshalRsaPrivateKey (line 120) | func UnmarshalRsaPrivateKey(b []byte) (key PrivKey, err error) {
  function UnmarshalRsaPublicKey (line 136) | func UnmarshalRsaPublicKey(b []byte) (key PubKey, err error) {

FILE: core/crypto/rsa_test.go
  function TestRSABasicSignAndVerify (line 8) | func TestRSABasicSignAndVerify(t *testing.T) {
  function TestRSASmallKey (line 42) | func TestRSASmallKey(t *testing.T) {
  function TestRSABigKeyFailsToGenerate (line 71) | func TestRSABigKeyFailsToGenerate(t *testing.T) {
  function TestRSABigKey (line 78) | func TestRSABigKey(t *testing.T) {
  function TestRSASignZero (line 109) | func TestRSASignZero(t *testing.T) {
  function TestRSAMarshalLoop (line 130) | func TestRSAMarshalLoop(t *testing.T) {

FILE: core/crypto/secp256k1.go
  type Secp256k1PrivateKey (line 16) | type Secp256k1PrivateKey
    method Type (line 55) | func (k *Secp256k1PrivateKey) Type() pb.KeyType {
    method Raw (line 60) | func (k *Secp256k1PrivateKey) Raw() ([]byte, error) {
    method Equals (line 65) | func (k *Secp256k1PrivateKey) Equals(o Key) bool {
    method Sign (line 75) | func (k *Secp256k1PrivateKey) Sign(data []byte) (_sig []byte, err erro...
    method GetPublic (line 85) | func (k *Secp256k1PrivateKey) GetPublic() PubKey {
  type Secp256k1PublicKey (line 19) | type Secp256k1PublicKey
    method Type (line 90) | func (k *Secp256k1PublicKey) Type() pb.KeyType {
    method Raw (line 95) | func (k *Secp256k1PublicKey) Raw() (res []byte, err error) {
    method Equals (line 101) | func (k *Secp256k1PublicKey) Equals(o Key) bool {
    method Verify (line 111) | func (k *Secp256k1PublicKey) Verify(data []byte, sigStr []byte) (succe...
  function GenerateSecp256k1Key (line 22) | func GenerateSecp256k1Key(_ io.Reader) (PrivKey, PubKey, error) {
  function UnmarshalSecp256k1PrivateKey (line 33) | func UnmarshalSecp256k1PrivateKey(data []byte) (k PrivKey, err error) {
  function UnmarshalSecp256k1PublicKey (line 44) | func UnmarshalSecp256k1PublicKey(data []byte) (_k PubKey, err error) {

FILE: core/crypto/secp256k1_test.go
  function TestSecp256k1BasicSignAndVerify (line 8) | func TestSecp256k1BasicSignAndVerify(t *testing.T) {
  function TestSecp256k1SignZero (line 42) | func TestSecp256k1SignZero(t *testing.T) {
  function TestSecp256k1MarshalLoop (line 63) | func TestSecp256k1MarshalLoop(t *testing.T) {

FILE: core/discovery/discovery.go
  type Advertiser (line 12) | type Advertiser interface
  type Discoverer (line 18) | type Discoverer interface
  type Discovery (line 24) | type Discovery interface

FILE: core/discovery/options.go
  type Option (line 6) | type Option
  type Options (line 9) | type Options struct
    method Apply (line 18) | func (opts *Options) Apply(options ...Option) error {
  function TTL (line 28) | func TTL(ttl time.Duration) Option {
  function Limit (line 36) | func Limit(limit int) Option {

FILE: core/event/addrs.go
  type AddrAction (line 11) | type AddrAction
  constant Unknown (line 16) | Unknown AddrAction = iota
  constant Added (line 19) | Added
  constant Maintained (line 23) | Maintained
  constant Removed (line 26) | Removed
  type UpdatedAddress (line 31) | type UpdatedAddress struct
  type EvtLocalAddressesUpdated (line 64) | type EvtLocalAddressesUpdated struct
  type EvtAutoRelayAddrsUpdated (line 86) | type EvtAutoRelayAddrsUpdated struct

FILE: core/event/bus.go
  type wildcardSubscriptionType (line 19) | type wildcardSubscriptionType
  type Emitter (line 26) | type Emitter interface
  type Subscription (line 37) | type Subscription interface
  type Bus (line 48) | type Bus interface

FILE: core/event/dht.go
  type RawJSON (line 4) | type RawJSON
  type GenericDHTEvent (line 15) | type GenericDHTEvent struct

FILE: core/event/identify.go
  type EvtPeerIdentificationCompleted (line 12) | type EvtPeerIdentificationCompleted struct
  type EvtPeerIdentificationFailed (line 41) | type EvtPeerIdentificationFailed struct

FILE: core/event/nattype.go
  type EvtNATDeviceTypeChanged (line 10) | type EvtNATDeviceTypeChanged struct

FILE: core/event/network.go
  type EvtPeerConnectednessChanged (line 50) | type EvtPeerConnectednessChanged struct

FILE: core/event/protocol.go
  type EvtPeerProtocolsUpdated (line 9) | type EvtPeerProtocolsUpdated struct
  type EvtLocalProtocolsUpdated (line 21) | type EvtLocalProtocolsUpdated struct

FILE: core/event/reachability.go
  type EvtLocalReachabilityChanged (line 12) | type EvtLocalReachabilityChanged struct
  type EvtHostReachableAddrsChanged (line 20) | type EvtHostReachableAddrsChanged struct

FILE: core/host/helpers.go
  function InfoFromHost (line 6) | func InfoFromHost(h Host) *peer.AddrInfo {

FILE: core/host/host.go
  type Host (line 24) | type Host interface

FILE: core/internal/catch/catch.go
  function HandlePanic (line 13) | func HandlePanic(rerr any, err *error, where string) {

FILE: core/internal/catch/catch_test.go
  function TestCatch (line 10) | func TestCatch(t *testing.T) {

FILE: core/metrics/bandwidth.go
  type BandwidthCounter (line 16) | type BandwidthCounter struct
    method LogSentMessage (line 34) | func (bwc *BandwidthCounter) LogSentMessage(size int64) {
    method LogRecvMessage (line 40) | func (bwc *BandwidthCounter) LogRecvMessage(size int64) {
    method LogSentMessageStream (line 46) | func (bwc *BandwidthCounter) LogSentMessageStream(size int64, proto pr...
    method LogRecvMessageStream (line 53) | func (bwc *BandwidthCounter) LogRecvMessageStream(size int64, proto pr...
    method GetBandwidthForPeer (line 60) | func (bwc *BandwidthCounter) GetBandwidthForPeer(p peer.ID) (out Stats) {
    method GetBandwidthForProtocol (line 75) | func (bwc *BandwidthCounter) GetBandwidthForProtocol(proto protocol.ID...
    method GetBandwidthTotals (line 89) | func (bwc *BandwidthCounter) GetBandwidthTotals() (out Stats) {
    method GetBandwidthByPeer (line 103) | func (bwc *BandwidthCounter) GetBandwidthByPeer() map[peer.ID]Stats {
    method GetBandwidthByProtocol (line 132) | func (bwc *BandwidthCounter) GetBandwidthByProtocol() map[protocol.ID]...
    method Reset (line 159) | func (bwc *BandwidthCounter) Reset() {
    method TrimIdle (line 171) | func (bwc *BandwidthCounter) TrimIdle(since time.Time) {
  function NewBandwidthCounter (line 28) | func NewBandwidthCounter() *BandwidthCounter {

FILE: core/metrics/bandwidth_test.go
  function init (line 20) | func init() {
  function BenchmarkBandwidthCounter (line 24) | func BenchmarkBandwidthCounter(b *testing.B) {
  function round (line 34) | func round(bwc *BandwidthCounter, b *testing.B) {
  function TestBandwidthCounter (line 61) | func TestBandwidthCounter(t *testing.T) {
  function TestResetBandwidthCounter (line 118) | func TestResetBandwidthCounter(t *testing.T) {

FILE: core/metrics/reporter.go
  type Stats (line 14) | type Stats struct
  type Reporter (line 22) | type Reporter interface

FILE: core/network/conn.go
  type ConnErrorCode (line 16) | type ConnErrorCode
  type ConnError (line 18) | type ConnError struct
    method Error (line 24) | func (c *ConnError) Error() string {
    method Is (line 35) | func (c *ConnError) Is(target error) bool {
    method Unwrap (line 42) | func (c *ConnError) Unwrap() []error {
  constant ConnNoError (line 47) | ConnNoError                   ConnErrorCode = 0
  constant ConnProtocolNegotiationFailed (line 48) | ConnProtocolNegotiationFailed ConnErrorCode = 0x1000
  constant ConnResourceLimitExceeded (line 49) | ConnResourceLimitExceeded     ConnErrorCode = 0x1001
  constant ConnRateLimited (line 50) | ConnRateLimited               ConnErrorCode = 0x1002
  constant ConnProtocolViolation (line 51) | ConnProtocolViolation         ConnErrorCode = 0x1003
  constant ConnSupplanted (line 52) | ConnSupplanted                ConnErrorCode = 0x1004
  constant ConnGarbageCollected (line 53) | ConnGarbageCollected          ConnErrorCode = 0x1005
  constant ConnShutdown (line 54) | ConnShutdown                  ConnErrorCode = 0x1006
  constant ConnGated (line 55) | ConnGated                     ConnErrorCode = 0x1007
  constant ConnCodeOutOfRange (line 56) | ConnCodeOutOfRange            ConnErrorCode = 0x1008
  type Conn (line 64) | type Conn interface
  type ConnectionState (line 107) | type ConnectionState struct
  type ConnSecurity (line 120) | type ConnSecurity interface
  type ConnMultiaddrs (line 136) | type ConnMultiaddrs interface
  type ConnStat (line 147) | type ConnStat interface
  type ConnScoper (line 154) | type ConnScoper interface

FILE: core/network/context.go
  type noDialCtxKey (line 13) | type noDialCtxKey struct
  type dialPeerTimeoutCtxKey (line 14) | type dialPeerTimeoutCtxKey struct
  type forceDirectDialCtxKey (line 15) | type forceDirectDialCtxKey struct
  type allowLimitedConnCtxKey (line 16) | type allowLimitedConnCtxKey struct
  type simConnectCtxKey (line 17) | type simConnectCtxKey struct
  function WithForceDirectDial (line 28) | func WithForceDirectDial(ctx context.Context, reason string) context.Con...
  function GetForceDirectDial (line 34) | func GetForceDirectDial(ctx context.Context) (forceDirect bool, reason s...
  function WithSimultaneousConnect (line 46) | func WithSimultaneousConnect(ctx context.Context, isClient bool, reason ...
  function GetSimultaneousConnect (line 55) | func GetSimultaneousConnect(ctx context.Context) (simconnect bool, isCli...
  function WithNoDial (line 67) | func WithNoDial(ctx context.Context, reason string) context.Context {
  function GetNoDial (line 72) | func GetNoDial(ctx context.Context) (nodial bool, reason string) {
  function GetDialPeerTimeout (line 82) | func GetDialPeerTimeout(ctx context.Context) time.Duration {
  function WithDialPeerTimeout (line 93) | func WithDialPeerTimeout(ctx context.Context, timeout time.Duration) con...
  function WithAllowLimitedConn (line 100) | func WithAllowLimitedConn(ctx context.Context, reason string) context.Co...
  function WithUseTransient (line 108) | func WithUseTransient(ctx context.Context, reason string) context.Context {
  function GetAllowLimitedConn (line 113) | func GetAllowLimitedConn(ctx context.Context) (usetransient bool, reason...
  function GetUseTransient (line 124) | func GetUseTransient(ctx context.Context) (usetransient bool, reason str...

FILE: core/network/context_test.go
  function TestDefaultTimeout (line 11) | func TestDefaultTimeout(t *testing.T) {
  function TestNonDefaultTimeout (line 19) | func TestNonDefaultTimeout(t *testing.T) {
  function TestSettingTimeout (line 32) | func TestSettingTimeout(t *testing.T) {
  function TestSimultaneousConnect (line 44) | func TestSimultaneousConnect(t *testing.T) {

FILE: core/network/errors.go
  type temporaryError (line 8) | type temporaryError
    method Error (line 10) | func (e temporaryError) Error() string   { return string(e) }
    method Temporary (line 11) | func (e temporaryError) Temporary() bool { return true }
    method Timeout (line 12) | func (e temporaryError) Timeout() bool   { return false }

FILE: core/network/mocks/mock_conn_management_scope.go
  type MockConnManagementScope (line 21) | type MockConnManagementScope struct
    method EXPECT (line 40) | func (m *MockConnManagementScope) EXPECT() *MockConnManagementScopeMoc...
    method BeginSpan (line 45) | func (m *MockConnManagementScope) BeginSpan() (network.ResourceScopeSp...
    method Done (line 60) | func (m *MockConnManagementScope) Done() {
    method PeerScope (line 72) | func (m *MockConnManagementScope) PeerScope() network.PeerScope {
    method ReleaseMemory (line 86) | func (m *MockConnManagementScope) ReleaseMemory(size int) {
    method ReserveMemory (line 98) | func (m *MockConnManagementScope) ReserveMemory(size int, prio uint8) ...
    method SetPeer (line 112) | func (m *MockConnManagementScope) SetPeer(arg0 peer.ID) error {
    method Stat (line 126) | func (m *MockConnManagementScope) Stat() network.ScopeStat {
  type MockConnManagementScopeMockRecorder (line 28) | type MockConnManagementScopeMockRecorder struct
    method BeginSpan (line 54) | func (mr *MockConnManagementScopeMockRecorder) BeginSpan() *gomock.Call {
    method Done (line 66) | func (mr *MockConnManagementScopeMockRecorder) Done() *gomock.Call {
    method PeerScope (line 80) | func (mr *MockConnManagementScopeMockRecorder) PeerScope() *gomock.Call {
    method ReleaseMemory (line 92) | func (mr *MockConnManagementScopeMockRecorder) ReleaseMemory(size any)...
    method ReserveMemory (line 106) | func (mr *MockConnManagementScopeMockRecorder) ReserveMemory(size, pri...
    method SetPeer (line 120) | func (mr *MockConnManagementScopeMockRecorder) SetPeer(arg0 any) *gomo...
    method Stat (line 134) | func (mr *MockConnManagementScopeMockRecorder) Stat() *gomock.Call {
  function NewMockConnManagementScope (line 33) | func NewMockConnManagementScope(ctrl *gomock.Controller) *MockConnManage...

FILE: core/network/mocks/mock_peer_scope.go
  type MockPeerScope (line 21) | type MockPeerScope struct
    method EXPECT (line 40) | func (m *MockPeerScope) EXPECT() *MockPeerScopeMockRecorder {
    method BeginSpan (line 45) | func (m *MockPeerScope) BeginSpan() (network.ResourceScopeSpan, error) {
    method Peer (line 60) | func (m *MockPeerScope) Peer() peer.ID {
    method ReleaseMemory (line 74) | func (m *MockPeerScope) ReleaseMemory(size int) {
    method ReserveMemory (line 86) | func (m *MockPeerScope) ReserveMemory(size int, prio uint8) error {
    method Stat (line 100) | func (m *MockPeerScope) Stat() network.ScopeStat {
  type MockPeerScopeMockRecorder (line 28) | type MockPeerScopeMockRecorder struct
    method BeginSpan (line 54) | func (mr *MockPeerScopeMockRecorder) BeginSpan() *gomock.Call {
    method Peer (line 68) | func (mr *MockPeerScopeMockRecorder) Peer() *gomock.Call {
    method ReleaseMemory (line 80) | func (mr *MockPeerScopeMockRecorder) ReleaseMemory(size any) *gomock.C...
    method ReserveMemory (line 94) | func (mr *MockPeerScopeMockRecorder) ReserveMemory(size, prio any) *go...
    method Stat (line 108) | func (mr *MockPeerScopeMockRecorder) Stat() *gomock.Call {
  function NewMockPeerScope (line 33) | func NewMockPeerScope(ctrl *gomock.Controller) *MockPeerScope {

FILE: core/network/mocks/mock_protocol_scope.go
  type MockProtocolScope (line 21) | type MockProtocolScope struct
    method EXPECT (line 40) | func (m *MockProtocolScope) EXPECT() *MockProtocolScopeMockRecorder {
    method BeginSpan (line 45) | func (m *MockProtocolScope) BeginSpan() (network.ResourceScopeSpan, er...
    method Protocol (line 60) | func (m *MockProtocolScope) Protocol() protocol.ID {
    method ReleaseMemory (line 74) | func (m *MockProtocolScope) ReleaseMemory(size int) {
    method ReserveMemory (line 86) | func (m *MockProtocolScope) ReserveMemory(size int, prio uint8) error {
    method Stat (line 100) | func (m *MockProtocolScope) Stat() network.ScopeStat {
  type MockProtocolScopeMockRecorder (line 28) | type MockProtocolScopeMockRecorder struct
    method BeginSpan (line 54) | func (mr *MockProtocolScopeMockRecorder) BeginSpan() *gomock.Call {
    method Protocol (line 68) | func (mr *MockProtocolScopeMockRecorder) Protocol() *gomock.Call {
    method ReleaseMemory (line 80) | func (mr *MockProtocolScopeMockRecorder) ReleaseMemory(size any) *gomo...
    method ReserveMemory (line 94) | func (mr *MockProtocolScopeMockRecorder) ReserveMemory(size, prio any)...
    method Stat (line 108) | func (mr *MockProtocolScopeMockRecorder) Stat() *gomock.Call {
  function NewMockProtocolScope (line 33) | func NewMockProtocolScope(ctrl *gomock.Controller) *MockProtocolScope {

FILE: core/network/mocks/mock_resource_manager.go
  type MockResourceManager (line 24) | type MockResourceManager struct
    method EXPECT (line 43) | func (m *MockResourceManager) EXPECT() *MockResourceManagerMockRecorder {
    method Close (line 48) | func (m *MockResourceManager) Close() error {
    method OpenConnection (line 62) | func (m *MockResourceManager) OpenConnection(dir network.Direction, us...
    method OpenStream (line 77) | func (m *MockResourceManager) OpenStream(p peer.ID, dir network.Direct...
    method VerifySourceAddress (line 92) | func (m *MockResourceManager) VerifySourceAddress(addr net.Addr) bool {
    method ViewPeer (line 106) | func (m *MockResourceManager) ViewPeer(arg0 peer.ID, arg1 func(network...
    method ViewProtocol (line 120) | func (m *MockResourceManager) ViewProtocol(arg0 protocol.ID, arg1 func...
    method ViewService (line 134) | func (m *MockResourceManager) ViewService(arg0 string, arg1 func(netwo...
    method ViewSystem (line 148) | func (m *MockResourceManager) ViewSystem(arg0 func(network.ResourceSco...
    method ViewTransient (line 162) | func (m *MockResourceManager) ViewTransient(arg0 func(network.Resource...
  type MockResourceManagerMockRecorder (line 31) | type MockResourceManagerMockRecorder struct
    method Close (line 56) | func (mr *MockResourceManagerMockRecorder) Close() *gomock.Call {
    method OpenConnection (line 71) | func (mr *MockResourceManagerMockRecorder) OpenConnection(dir, usefd, ...
    method OpenStream (line 86) | func (mr *MockResourceManagerMockRecorder) OpenStream(p, dir any) *gom...
    method VerifySourceAddress (line 100) | func (mr *MockResourceManagerMockRecorder) VerifySourceAddress(addr an...
    method ViewPeer (line 114) | func (mr *MockResourceManagerMockRecorder) ViewPeer(arg0, arg1 any) *g...
    method ViewProtocol (line 128) | func (mr *MockResourceManagerMockRecorder) ViewProtocol(arg0, arg1 any...
    method ViewService (line 142) | func (mr *MockResourceManagerMockRecorder) ViewService(arg0, arg1 any)...
    method ViewSystem (line 156) | func (mr *MockResourceManagerMockRecorder) ViewSystem(arg0 any) *gomoc...
    method ViewTransient (line 170) | func (mr *MockResourceManagerMockRecorder) ViewTransient(arg0 any) *go...
  function NewMockResourceManager (line 36) | func NewMockResourceManager(ctrl *gomock.Controller) *MockResourceManager {

FILE: core/network/mocks/mock_resource_scope_span.go
  type MockResourceScopeSpan (line 20) | type MockResourceScopeSpan struct
    method EXPECT (line 39) | func (m *MockResourceScopeSpan) EXPECT() *MockResourceScopeSpanMockRec...
    method BeginSpan (line 44) | func (m *MockResourceScopeSpan) BeginSpan() (network.ResourceScopeSpan...
    method Done (line 59) | func (m *MockResourceScopeSpan) Done() {
    method ReleaseMemory (line 71) | func (m *MockResourceScopeSpan) ReleaseMemory(size int) {
    method ReserveMemory (line 83) | func (m *MockResourceScopeSpan) ReserveMemory(size int, prio uint8) er...
    method Stat (line 97) | func (m *MockResourceScopeSpan) Stat() network.ScopeStat {
  type MockResourceScopeSpanMockRecorder (line 27) | type MockResourceScopeSpanMockRecorder struct
    method BeginSpan (line 53) | func (mr *MockResourceScopeSpanMockRecorder) BeginSpan() *gomock.Call {
    method Done (line 65) | func (mr *MockResourceScopeSpanMockRecorder) Done() *gomock.Call {
    method ReleaseMemory (line 77) | func (mr *MockResourceScopeSpanMockRecorder) ReleaseMemory(size any) *...
    method ReserveMemory (line 91) | func (mr *MockResourceScopeSpanMockRecorder) ReserveMemory(size, prio ...
    method Stat (line 105) | func (mr *MockResourceScopeSpanMockRecorder) Stat() *gomock.Call {
  function NewMockResourceScopeSpan (line 32) | func NewMockResourceScopeSpan(ctrl *gomock.Controller) *MockResourceScop...

FILE: core/network/mocks/mock_stream_management_scope.go
  type MockStreamManagementScope (line 21) | type MockStreamManagementScope struct
    method EXPECT (line 40) | func (m *MockStreamManagementScope) EXPECT() *MockStreamManagementScop...
    method BeginSpan (line 45) | func (m *MockStreamManagementScope) BeginSpan() (network.ResourceScope...
    method Done (line 60) | func (m *MockStreamManagementScope) Done() {
    method PeerScope (line 72) | func (m *MockStreamManagementScope) PeerScope() network.PeerScope {
    method ProtocolScope (line 86) | func (m *MockStreamManagementScope) ProtocolScope() network.ProtocolSc...
    method ReleaseMemory (line 100) | func (m *MockStreamManagementScope) ReleaseMemory(size int) {
    method ReserveMemory (line 112) | func (m *MockStreamManagementScope) ReserveMemory(size int, prio uint8...
    method ServiceScope (line 126) | func (m *MockStreamManagementScope) ServiceScope() network.ServiceScope {
    method SetProtocol (line 140) | func (m *MockStreamManagementScope) SetProtocol(proto protocol.ID) err...
    method SetService (line 154) | func (m *MockStreamManagementScope) SetService(srv string) error {
    method Stat (line 168) | func (m *MockStreamManagementScope) Stat() network.ScopeStat {
  type MockStreamManagementScopeMockRecorder (line 28) | type MockStreamManagementScopeMockRecorder struct
    method BeginSpan (line 54) | func (mr *MockStreamManagementScopeMockRecorder) BeginSpan() *gomock.C...
    method Done (line 66) | func (mr *MockStreamManagementScopeMockRecorder) Done() *gomock.Call {
    method PeerScope (line 80) | func (mr *MockStreamManagementScopeMockRecorder) PeerScope() *gomock.C...
    method ProtocolScope (line 94) | func (mr *MockStreamManagementScopeMockRecorder) ProtocolScope() *gomo...
    method ReleaseMemory (line 106) | func (mr *MockStreamManagementScopeMockRecorder) ReleaseMemory(size an...
    method ReserveMemory (line 120) | func (mr *MockStreamManagementScopeMockRecorder) ReserveMemory(size, p...
    method ServiceScope (line 134) | func (mr *MockStreamManagementScopeMockRecorder) ServiceScope() *gomoc...
    method SetProtocol (line 148) | func (mr *MockStreamManagementScopeMockRecorder) SetProtocol(proto any...
    method SetService (line 162) | func (mr *MockStreamManagementScopeMockRecorder) SetService(srv any) *...
    method Stat (line 176) | func (mr *MockStreamManagementScopeMockRecorder) Stat() *gomock.Call {
  function NewMockStreamManagementScope (line 33) | func NewMockStreamManagementScope(ctrl *gomock.Controller) *MockStreamMa...

FILE: core/network/mux.go
  type StreamErrorCode (line 15) | type StreamErrorCode
  type StreamError (line 17) | type StreamError struct
    method Error (line 23) | func (s *StreamError) Error() string {
    method Is (line 34) | func (s *StreamError) Is(target error) bool {
    method Unwrap (line 41) | func (s *StreamError) Unwrap() []error {
  constant StreamNoError (line 46) | StreamNoError                   StreamErrorCode = 0
  constant StreamProtocolNegotiationFailed (line 47) | StreamProtocolNegotiationFailed StreamErrorCode = 0x1001
  constant StreamResourceLimitExceeded (line 48) | StreamResourceLimitExceeded     StreamErrorCode = 0x1002
  constant StreamRateLimited (line 49) | StreamRateLimited               StreamErrorCode = 0x1003
  constant StreamProtocolViolation (line 50) | StreamProtocolViolation         StreamErrorCode = 0x1004
  constant StreamSupplanted (line 51) | StreamSupplanted                StreamErrorCode = 0x1005
  constant StreamGarbageCollected (line 52) | StreamGarbageCollected          StreamErrorCode = 0x1006
  constant StreamShutdown (line 53) | StreamShutdown                  StreamErrorCode = 0x1007
  constant StreamGated (line 54) | StreamGated                     StreamErrorCode = 0x1008
  constant StreamCodeOutOfRange (line 55) | StreamCodeOutOfRange            StreamErrorCode = 0x1009
  type MuxedStream (line 59) | type MuxedStream interface
  type MuxedConn (line 123) | type MuxedConn interface
  type Multiplexer (line 159) | type Multiplexer interface

FILE: core/network/nattype.go
  type NATDeviceType (line 4) | type NATDeviceType
    method String (line 45) | func (r NATDeviceType) String() string {
  constant NATDeviceTypeUnknown (line 8) | NATDeviceTypeUnknown NATDeviceType = iota
  constant NATDeviceTypeEndpointIndependent (line 20) | NATDeviceTypeEndpointIndependent
  constant NATDeviceTypeEndpointDependent (line 31) | NATDeviceTypeEndpointDependent
  constant NATDeviceTypeCone (line 38) | NATDeviceTypeCone = NATDeviceTypeEndpointIndependent
  constant NATDeviceTypeSymmetric (line 42) | NATDeviceTypeSymmetric = NATDeviceTypeEndpointDependent
  type NATTransportProtocol (line 59) | type NATTransportProtocol
    method String (line 68) | func (n NATTransportProtocol) String() string {
  constant NATTransportUDP (line 63) | NATTransportUDP NATTransportProtocol = iota
  constant NATTransportTCP (line 65) | NATTransportTCP

FILE: core/network/network.go
  constant MessageSizeMax (line 23) | MessageSizeMax = 1 << 22
  type Direction (line 26) | type Direction
    method String (line 39) | func (d Direction) String() string {
  constant DirUnknown (line 30) | DirUnknown Direction = iota
  constant DirInbound (line 32) | DirInbound
  constant DirOutbound (line 34) | DirOutbound
  constant unrecognized (line 37) | unrecognized = "(unrecognized)"
  type Connectedness (line 49) | type Connectedness
    method String (line 73) | func (c Connectedness) String() string {
  constant NotConnected (line 53) | NotConnected Connectedness = iota
  constant Connected (line 56) | Connected
  constant CanConnect (line 61) | CanConnect
  constant CannotConnect (line 67) | CannotConnect
  constant Limited (line 70) | Limited
  type Reachability (line 82) | type Reachability
    method String (line 100) | func (r Reachability) String() string {
  constant ReachabilityUnknown (line 87) | ReachabilityUnknown Reachability = iota
  constant ReachabilityPublic (line 91) | ReachabilityPublic
  constant ReachabilityPrivate (line 97) | ReachabilityPrivate
  type ConnStats (line 109) | type ConnStats struct
  type Stats (line 116) | type Stats struct
  type StreamHandler (line 131) | type StreamHandler
  type Network (line 137) | type Network interface
  type MultiaddrDNSResolver (line 164) | type MultiaddrDNSResolver interface
  type Dialer (line 175) | type Dialer interface
  type AddrDelay (line 212) | type AddrDelay struct
  type DialRanker (line 218) | type DialRanker

FILE: core/network/notifee.go
  type Notifiee (line 9) | type Notifiee interface
  type NotifyBundle (line 19) | type NotifyBundle struct
    method Listen (line 30) | func (nb *NotifyBundle) Listen(n Network, a ma.Multiaddr) {
    method ListenClose (line 37) | func (nb *NotifyBundle) ListenClose(n Network, a ma.Multiaddr) {
    method Connected (line 44) | func (nb *NotifyBundle) Connected(n Network, c Conn) {
    method Disconnected (line 51) | func (nb *NotifyBundle) Disconnected(n Network, c Conn) {
  type NoopNotifiee (line 60) | type NoopNotifiee struct
    method Connected (line 64) | func (nn *NoopNotifiee) Connected(_ Network, _ Conn)           {}
    method Disconnected (line 65) | func (nn *NoopNotifiee) Disconnected(_ Network, _ Conn)        {}
    method Listen (line 66) | func (nn *NoopNotifiee) Listen(_ Network, _ ma.Multiaddr)      {}
    method ListenClose (line 67) | func (nn *NoopNotifiee) ListenClose(_ Network, _ ma.Multiaddr) {}

FILE: core/network/notifee_test.go
  function TestListen (line 9) | func TestListen(T *testing.T) {
  function TestListenClose (line 31) | func TestListenClose(T *testing.T) {
  function TestConnected (line 53) | func TestConnected(T *testing.T) {
  function TestDisconnected (line 71) | func TestDisconnected(T *testing.T) {

FILE: core/network/rcmgr.go
  type ResourceManager (line 85) | type ResourceManager interface
  type ResourceScopeViewer (line 111) | type ResourceScopeViewer interface
  constant ReservationPriorityLow (line 140) | ReservationPriorityLow uint8 = 101
  constant ReservationPriorityMedium (line 143) | ReservationPriorityMedium uint8 = 152
  constant ReservationPriorityHigh (line 146) | ReservationPriorityHigh uint8 = 203
  constant ReservationPriorityAlways (line 149) | ReservationPriorityAlways uint8 = 255
  type ResourceScope (line 153) | type ResourceScope interface
  type ResourceScopeSpan (line 191) | type ResourceScopeSpan interface
  type ServiceScope (line 198) | type ServiceScope interface
  type ProtocolScope (line 206) | type ProtocolScope interface
  type PeerScope (line 214) | type PeerScope interface
  type ConnManagementScope (line 224) | type ConnManagementScope interface
  type ConnScope (line 236) | type ConnScope interface
  type StreamManagementScope (line 243) | type StreamManagementScope interface
  type StreamScope (line 262) | type StreamScope interface
  type ScopeStat (line 270) | type ScopeStat struct
  type connManagementScopeKey (line 281) | type connManagementScopeKey struct
  function WithConnManagementScope (line 283) | func WithConnManagementScope(ctx context.Context, scope ConnManagementSc...
  function UnwrapConnManagementScope (line 287) | func UnwrapConnManagementScope(ctx context.Context) (ConnManagementScope...
  type NullResourceManager (line 300) | type NullResourceManager struct
    method ViewSystem (line 317) | func (n *NullResourceManager) ViewSystem(f func(ResourceScope) error) ...
    method ViewTransient (line 320) | func (n *NullResourceManager) ViewTransient(f func(ResourceScope) erro...
    method ViewService (line 323) | func (n *NullResourceManager) ViewService(_ string, f func(ServiceScop...
    method ViewProtocol (line 326) | func (n *NullResourceManager) ViewProtocol(_ protocol.ID, f func(Proto...
    method ViewPeer (line 329) | func (n *NullResourceManager) ViewPeer(_ peer.ID, f func(PeerScope) er...
    method OpenConnection (line 332) | func (n *NullResourceManager) OpenConnection(_ Direction, _ bool, _ mu...
    method OpenStream (line 335) | func (n *NullResourceManager) OpenStream(_ peer.ID, _ Direction) (Stre...
    method VerifySourceAddress (line 338) | func (*NullResourceManager) VerifySourceAddress(_ net.Addr) bool {
    method Close (line 342) | func (n *NullResourceManager) Close() error {
  type NullScope (line 315) | type NullScope struct
    method ReserveMemory (line 346) | func (n *NullScope) ReserveMemory(_ int, _ uint8) error    { return nil }
    method ReleaseMemory (line 347) | func (n *NullScope) ReleaseMemory(_ int)                   {}
    method Stat (line 348) | func (n *NullScope) Stat() ScopeStat                       { return Sc...
    method BeginSpan (line 349) | func (n *NullScope) BeginSpan() (ResourceScopeSpan, error) { return &N...
    method Done (line 350) | func (n *NullScope) Done()                                 {}
    method Name (line 351) | func (n *NullScope) Name() string                          { return "" }
    method Protocol (line 352) | func (n *NullScope) Protocol() protocol.ID                 { return "" }
    method Peer (line 353) | func (n *NullScope) Peer() peer.ID                         { return "" }
    method PeerScope (line 354) | func (n *NullScope) PeerScope() PeerScope                  { return &N...
    method SetPeer (line 355) | func (n *NullScope) SetPeer(peer.ID) error                 { return nil }
    method ProtocolScope (line 356) | func (n *NullScope) ProtocolScope() ProtocolScope          { return &N...
    method SetProtocol (line 357) | func (n *NullScope) SetProtocol(_ protocol.ID) error       { return nil }
    method ServiceScope (line 358) | func (n *NullScope) ServiceScope() ServiceScope            { return &N...
    method SetService (line 359) | func (n *NullScope) SetService(_ string) error             { return nil }
    method VerifySourceAddress (line 360) | func (n *NullScope) VerifySourceAddress(_ net.Addr) bool   { return fa...

FILE: core/network/stream.go
  type Stream (line 12) | type Stream interface

FILE: core/peer/addrinfo.go
  type AddrInfo (line 11) | type AddrInfo struct
    method String (line 18) | func (pi AddrInfo) String() string {
    method Loggable (line 121) | func (pi *AddrInfo) Loggable() map[string]any {
  function AddrInfosFromP2pAddrs (line 25) | func AddrInfosFromP2pAddrs(maddrs ...ma.Multiaddr) ([]AddrInfo, error) {
  function SplitAddr (line 51) | func SplitAddr(m ma.Multiaddr) (transport ma.Multiaddr, id ID) {
  function IDFromP2PAddr (line 65) | func IDFromP2PAddr(m ma.Multiaddr) (ID, error) {
  function AddrInfoFromString (line 83) | func AddrInfoFromString(s string) (*AddrInfo, error) {
  function AddrInfoFromP2pAddr (line 93) | func AddrInfoFromP2pAddr(m ma.Multiaddr) (*AddrInfo, error) {
  function AddrInfoToP2pAddrs (line 106) | func AddrInfoToP2pAddrs(pi *AddrInfo) ([]ma.Multiaddr, error) {
  function AddrInfosToIDs (line 129) | func AddrInfosToIDs(pis []AddrInfo) []ID {

FILE: core/peer/addrinfo_serde.go
  type addrInfoJson (line 12) | type addrInfoJson struct
  method MarshalJSON (line 17) | func (pi AddrInfo) MarshalJSON() (res []byte, err error) {
  method UnmarshalJSON (line 30) | func (pi *AddrInfo) UnmarshalJSON(b []byte) (err error) {

FILE: core/peer/addrinfo_test.go
  function init (line 17) | func init() {
  function TestSplitAddr (line 28) | func TestSplitAddr(t *testing.T) {
  function TestIDFromP2PAddr (line 54) | func TestIDFromP2PAddr(t *testing.T) {
  function TestAddrInfoFromP2pAddr (line 67) | func TestAddrInfoFromP2pAddr(t *testing.T) {
  function TestAddrInfosFromP2pAddrs (line 96) | func TestAddrInfosFromP2pAddrs(t *testing.T) {
  function TestAddrInfoJSON (line 150) | func TestAddrInfoJSON(t *testing.T) {

FILE: core/peer/pb/peer_record.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type PeerRecord (line 32) | type PeerRecord struct
    method Reset (line 44) | func (x *PeerRecord) Reset() {
    method String (line 51) | func (x *PeerRecord) String() string {
    method ProtoMessage (line 55) | func (*PeerRecord) ProtoMessage() {}
    method ProtoReflect (line 57) | func (x *PeerRecord) ProtoReflect() protoreflect.Message {
    method Descriptor (line 70) | func (*PeerRecord) Descriptor() ([]byte, []int) {
    method GetPeerId (line 74) | func (x *PeerRecord) GetPeerId() []byte {
    method GetSeq (line 81) | func (x *PeerRecord) GetSeq() uint64 {
    method GetAddresses (line 88) | func (x *PeerRecord) GetAddresses() []*PeerRecord_AddressInfo {
  type PeerRecord_AddressInfo (line 97) | type PeerRecord_AddressInfo struct
    method Reset (line 104) | func (x *PeerRecord_AddressInfo) Reset() {
    method String (line 111) | func (x *PeerRecord_AddressInfo) String() string {
    method ProtoMessage (line 115) | func (*PeerRecord_AddressInfo) ProtoMessage() {}
    method ProtoReflect (line 117) | func (x *PeerRecord_AddressInfo) ProtoReflect() protoreflect.Message {
    method Descriptor (line 130) | func (*PeerRecord_AddressInfo) Descriptor() ([]byte, []int) {
    method GetMultiaddr (line 134) | func (x *PeerRecord_AddressInfo) GetMultiaddr() []byte {
  constant file_core_peer_pb_peer_record_proto_rawDesc (line 143) | file_core_peer_pb_peer_record_proto_rawDesc = "" +
  function file_core_peer_pb_peer_record_proto_rawDescGZIP (line 159) | func file_core_peer_pb_peer_record_proto_rawDescGZIP() []byte {
  function init (line 180) | func init() { file_core_peer_pb_peer_record_proto_init() }
  function file_core_peer_pb_peer_record_proto_init (line 181) | func file_core_peer_pb_peer_record_proto_init() {

FILE: core/peer/peer.go
  constant maxInlineKeyLength (line 36) | maxInlineKeyLength = 42
  type ID (line 42) | type ID
    method Loggable (line 45) | func (id ID) Loggable() map[string]any {
    method String (line 51) | func (id ID) String() string {
    method ShortString (line 61) | func (id ID) ShortString() string {
    method MatchesPrivateKey (line 70) | func (id ID) MatchesPrivateKey(sk ic.PrivKey) bool {
    method MatchesPublicKey (line 75) | func (id ID) MatchesPublicKey(pk ic.PubKey) bool {
    method ExtractPublicKey (line 87) | func (id ID) ExtractPublicKey() (ic.PubKey, error) {
    method Validate (line 103) | func (id ID) Validate() error {
  function IDFromBytes (line 113) | func IDFromBytes(b []byte) (ID, error) {
  function Decode (line 125) | func Decode(s string) (ID, error) {
  function FromCid (line 143) | func FromCid(c cid.Cid) (ID, error) {
  function ToCid (line 154) | func ToCid(id ID) cid.Cid {
  function IDFromPublicKey (line 163) | func IDFromPublicKey(pk ic.PubKey) (ID, error) {
  function IDFromPrivateKey (line 180) | func IDFromPrivateKey(sk ic.PrivKey) (ID, error) {
  type IDSlice (line 185) | type IDSlice
    method Len (line 187) | func (es IDSlice) Len() int           { return len(es) }
    method Swap (line 188) | func (es IDSlice) Swap(i, j int)      { es[i], es[j] = es[j], es[i] }
    method Less (line 189) | func (es IDSlice) Less(i, j int) bool { return string(es[i]) < string(...
    method String (line 191) | func (es IDSlice) String() string {

FILE: core/peer/peer_serde.go
  method Marshal (line 20) | func (id ID) Marshal() ([]byte, error) {
  method MarshalBinary (line 25) | func (id ID) MarshalBinary() ([]byte, error) {
  method MarshalTo (line 29) | func (id ID) MarshalTo(data []byte) (n int, err error) {
  method Unmarshal (line 33) | func (id *ID) Unmarshal(data []byte) (err error) {
  method UnmarshalBinary (line 39) | func (id *ID) UnmarshalBinary(data []byte) error {
  method Size (line 43) | func (id ID) Size() int {
  method MarshalJSON (line 47) | func (id ID) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 51) | func (id *ID) UnmarshalJSON(data []byte) (err error) {
  method MarshalText (line 61) | func (id ID) MarshalText() ([]byte, error) {
  method UnmarshalText (line 66) | func (id *ID) UnmarshalText(data []byte) error {

FILE: core/peer/peer_serde_test.go
  function TestPeerSerdePB (line 10) | func TestPeerSerdePB(t *testing.T) {
  function TestPeerSerdeJSON (line 29) | func TestPeerSerdeJSON(t *testing.T) {
  function TestBinaryMarshaler (line 47) | func TestBinaryMarshaler(t *testing.T) {
  function TestTextMarshaler (line 66) | func TestTextMarshaler(t *testing.T) {

FILE: core/peer/peer_test.go
  function hash (line 22) | func hash(b []byte) []byte {
  function init (line 27) | func init() {
  type keyset (line 41) | type keyset struct
    method generate (line 48) | func (ks *keyset) generate() error {
    method load (line 65) | func (ks *keyset) load(hpkp, skBytesStr string) error {
  function TestIDMatchesPublicKey (line 90) | func TestIDMatchesPublicKey(t *testing.T) {
  function TestIDMatchesPrivateKey (line 124) | func TestIDMatchesPrivateKey(t *testing.T) {
  function TestIDEncoding (line 155) | func TestIDEncoding(t *testing.T) {
  function TestPublicKeyExtraction (line 200) | func TestPublicKeyExtraction(t *testing.T) {
  function TestValidate (line 252) | func TestValidate(t *testing.T) {

FILE: core/peer/record.go
  function init (line 19) | func init() {
  constant PeerRecordEnvelopeDomain (line 24) | PeerRecordEnvelopeDomain = "libp2p-peer-record"
  type PeerRecord (line 83) | type PeerRecord struct
    method Domain (line 150) | func (r *PeerRecord) Domain() string {
    method Codec (line 155) | func (r *PeerRecord) Codec() []byte {
    method UnmarshalRecord (line 163) | func (r *PeerRecord) UnmarshalRecord(bytes []byte) (err error) {
    method MarshalRecord (line 188) | func (r *PeerRecord) MarshalRecord() (res []byte, err error) {
    method Equal (line 199) | func (r *PeerRecord) Equal(other *PeerRecord) bool {
    method ToProtobuf (line 221) | func (r *PeerRecord) ToProtobuf() (*pb.PeerRecord, error) {
  function NewPeerRecord (line 99) | func NewPeerRecord() *PeerRecord {
  function PeerRecordFromAddrInfo (line 105) | func PeerRecordFromAddrInfo(info AddrInfo) *PeerRecord {
  function PeerRecordFromProtobuf (line 114) | func PeerRecordFromProtobuf(msg *pb.PeerRecord) (*PeerRecord, error) {
  function TimestampSeq (line 135) | func TimestampSeq() uint64 {
  function addrsFromProtobuf (line 233) | func addrsFromProtobuf(addrs []*pb.PeerRecord_AddressInfo) []ma.Multiaddr {
  function addrsToProtobuf (line 245) | func addrsToProtobuf(addrs []ma.Multiaddr) []*pb.PeerRecord_AddressInfo {

FILE: core/peer/record_test.go
  function TestPeerRecordConstants (line 13) | func TestPeerRecordConstants(t *testing.T) {
  function TestSignedPeerRecordFromEnvelope (line 25) | func TestSignedPeerRecordFromEnvelope(t *testing.T) {
  function TestTimestampSeq (line 58) | func TestTimestampSeq(t *testing.T) {

FILE: core/peerstore/helpers.go
  function AddrInfos (line 8) | func AddrInfos(ps Peerstore, peers []peer.ID) []peer.AddrInfo {

FILE: core/peerstore/peerstore.go
  constant PermanentAddrTTL (line 43) | PermanentAddrTTL = math.MaxInt64 - iota
  constant ConnectedAddrTTL (line 48) | ConnectedAddrTTL
  type Peerstore (line 53) | type Peerstore interface
  type PeerMetadata (line 82) | type PeerMetadata interface
  type AddrBook (line 94) | type AddrBook interface
  type CertifiedAddrBook (line 140) | type CertifiedAddrBook interface
  function GetCertifiedAddrBook (line 175) | func GetCertifiedAddrBook(ab AddrBook) (cab CertifiedAddrBook, ok bool) {
  type KeyBook (line 181) | type KeyBook interface
  type Metrics (line 204) | type Metrics interface
  type ProtoBook (line 217) | type ProtoBook interface

FILE: core/pnet/codec.go
  function readHeader (line 19) | func readHeader(r *bufio.Reader) ([]byte, error) {
  function expectHeader (line 28) | func expectHeader(r *bufio.Reader, expected []byte) error {
  function DecodeV1PSK (line 40) | func DecodeV1PSK(in io.Reader) (PSK, error) {

FILE: core/pnet/codec_test.go
  function bufWithBase (line 9) | func bufWithBase(base string, windows bool) *bytes.Buffer {
  function TestDecodeHex (line 24) | func TestDecodeHex(t *testing.T) {
  function TestDecodeBad (line 29) | func TestDecodeBad(t *testing.T) {
  function testDecodeBad (line 34) | func testDecodeBad(t *testing.T, windows bool) {
  function testDecodeHex (line 44) | func testDecodeHex(t *testing.T, windows bool) {
  function TestDecodeB64 (line 62) | func TestDecodeB64(t *testing.T) {
  function testDecodeB64 (line 67) | func testDecodeB64(t *testing.T, windows bool) {
  function TestDecodeBin (line 97) | func TestDecodeBin(t *testing.T) {
  function testDecodeBin (line 102) | func testDecodeBin(t *testing.T, windows bool) {

FILE: core/pnet/env.go
  constant EnvKey (line 8) | EnvKey = "LIBP2P_FORCE_PNET"
  function init (line 17) | func init() {

FILE: core/pnet/error.go
  type Error (line 9) | type Error interface
  function NewError (line 14) | func NewError(err string) error {
  function IsPNetError (line 19) | func IsPNetError(err error) bool {
  type pnetErr (line 24) | type pnetErr
    method Error (line 28) | func (p pnetErr) Error() string {
    method IsPNetError (line 32) | func (pnetErr) IsPNetError() bool {

FILE: core/pnet/error_test.go
  function TestIsPnetErr (line 8) | func TestIsPnetErr(t *testing.T) {

FILE: core/pnet/protector.go
  type PSK (line 7) | type PSK

FILE: core/protocol/id.go
  type ID (line 4) | type ID
  constant TestingID (line 8) | TestingID ID = "/p2p/_testing"
  function ConvertFromStrings (line 13) | func ConvertFromStrings(ids []string) (res []ID) {
  function ConvertToStrings (line 23) | func ConvertToStrings(ids []ID) (res []string) {

FILE: core/protocol/switch.go
  type Router (line 26) | type Router interface
  type Negotiator (line 55) | type Negotiator interface
  type Switch (line 70) | type Switch interface

FILE: core/record/envelope.go
  type Envelope (line 25) | type Envelope struct
    method Marshal (line 191) | func (e *Envelope) Marshal() (res []byte, err error) {
    method Equal (line 210) | func (e *Envelope) Equal(other *Envelope) bool {
    method Record (line 225) | func (e *Envelope) Record() (Record, error) {
    method TypedRecord (line 242) | func (e *Envelope) TypedRecord(dest Record) error {
    method validate (line 248) | func (e *Envelope) validate(domain string) error {
  function Seal (line 51) | func Seal(rec Record, privateKey crypto.PrivKey) (*Envelope, error) {
  function ConsumeEnvelope (line 110) | func ConsumeEnvelope(data []byte, domain string) (envelope *Envelope, re...
  function ConsumeTypedEnvelope (line 149) | func ConsumeTypedEnvelope(data []byte, destRecord Record) (envelope *Env...
  function UnmarshalEnvelope (line 170) | func UnmarshalEnvelope(data []byte) (*Envelope, error) {
  function makeUnsigned (line 268) | func makeUnsigned(domain string, payloadType []byte, payload []byte) ([]...

FILE: core/record/envelope_test.go
  type simpleRecord (line 16) | type simpleRecord struct
    method Domain (line 22) | func (r *simpleRecord) Domain() string {
    method Codec (line 29) | func (r *simpleRecord) Codec() []byte {
    method MarshalRecord (line 36) | func (r *simpleRecord) MarshalRecord() ([]byte, error) {
    method UnmarshalRecord (line 40) | func (r *simpleRecord) UnmarshalRecord(buf []byte) error {
  function TestEnvelopeHappyPath (line 46) | func TestEnvelopeHappyPath(t *testing.T) {
  function TestConsumeTypedEnvelope (line 92) | func TestConsumeTypedEnvelope(t *testing.T) {
  function TestMakeEnvelopeFailsWithEmptyDomain (line 113) | func TestMakeEnvelopeFailsWithEmptyDomain(t *testing.T) {
  function TestMakeEnvelopeFailsWithEmptyPayloadType (line 131) | func TestMakeEnvelopeFailsWithEmptyPayloadType(t *testing.T) {
  type failingRecord (line 148) | type failingRecord struct
    method Domain (line 153) | func (r failingRecord) Domain() string {
    method Codec (line 157) | func (r failingRecord) Codec() []byte {
    method MarshalRecord (line 161) | func (r failingRecord) MarshalRecord() ([]byte, error) {
    method UnmarshalRecord (line 167) | func (r failingRecord) UnmarshalRecord(_ []byte) error {
  function TestSealFailsIfRecordMarshalFails (line 174) | func TestSealFailsIfRecordMarshalFails(t *testing.T) {
  function TestConsumeEnvelopeFailsIfEnvelopeUnmarshalFails (line 187) | func TestConsumeEnvelopeFailsIfEnvelopeUnmarshalFails(t *testing.T) {
  function TestConsumeEnvelopeFailsIfRecordUnmarshalFails (line 192) | func TestConsumeEnvelopeFailsIfRecordUnmarshalFails(t *testing.T) {
  function TestConsumeTypedEnvelopeFailsIfRecordUnmarshalFails (line 212) | func TestConsumeTypedEnvelopeFailsIfRecordUnmarshalFails(t *testing.T) {
  function TestEnvelopeValidateFailsForDifferentDomain (line 233) | func TestEnvelopeValidateFailsForDifferentDomain(t *testing.T) {
  function TestEnvelopeValidateFailsIfPayloadTypeIsAltered (line 252) | func TestEnvelopeValidateFailsIfPayloadTypeIsAltered(t *testing.T) {
  function TestEnvelopeValidateFailsIfContentsAreAltered (line 273) | func TestEnvelopeValidateFailsIfContentsAreAltered(t *testing.T) {
  function alterMessageAndMarshal (line 299) | func alterMessageAndMarshal(t *testing.T, envelope *Envelope, alterMsg f...

FILE: core/record/pb/envelope.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type Envelope (line 32) | type Envelope struct
    method Reset (line 50) | func (x *Envelope) Reset() {
    method String (line 57) | func (x *Envelope) String() string {
    method ProtoMessage (line 61) | func (*Envelope) ProtoMessage() {}
    method ProtoReflect (line 63) | func (x *Envelope) ProtoReflect() protoreflect.Message {
    method Descriptor (line 76) | func (*Envelope) Descriptor() ([]byte, []int) {
    method GetPublicKey (line 80) | func (x *Envelope) GetPublicKey() *pb.PublicKey {
    method GetPayloadType (line 87) | func (x *Envelope) GetPayloadType() []byte {
    method GetPayload (line 94) | func (x *Envelope) GetPayload() []byte {
    method GetSignature (line 101) | func (x *Envelope) GetSignature() []byte {
  constant file_core_record_pb_envelope_proto_rawDesc (line 110) | file_core_record_pb_envelope_proto_rawDesc = "" +
  function file_core_record_pb_envelope_proto_rawDescGZIP (line 125) | func file_core_record_pb_envelope_proto_rawDescGZIP() []byte {
  function init (line 146) | func init() { file_core_record_pb_envelope_proto_init() }
  function file_core_record_pb_envelope_proto_init (line 147) | func file_core_record_pb_envelope_proto_init() {

FILE: core/record/record.go
  type Record (line 31) | type Record interface
  function RegisterType (line 70) | func RegisterType(prototype Record) {
  function unmarshalRecordPayload (line 74) | func unmarshalRecordPayload(payloadType []byte, payloadBytes []byte) (_r...
  function blankRecordForPayloadType (line 88) | func blankRecordForPayloadType(payloadType []byte) (Record, error) {
  function getValueType (line 99) | func getValueType(i any) reflect.Type {

FILE: core/record/record_test.go
  type testPayload (line 7) | type testPayload struct
    method Domain (line 11) | func (p *testPayload) Domain() string {
    method Codec (line 15) | func (p *testPayload) Codec() []byte {
    method MarshalRecord (line 19) | func (p *testPayload) MarshalRecord() ([]byte, error) {
    method UnmarshalRecord (line 23) | func (p *testPayload) UnmarshalRecord(_ []byte) error {
  function TestUnmarshalPayload (line 28) | func TestUnmarshalPayload(t *testing.T) {

FILE: core/routing/options.go
  type Option (line 6) | type Option
  type Options (line 9) | type Options struct
    method Apply (line 18) | func (opts *Options) Apply(options ...Option) error {
    method ToOption (line 28) | func (opts *Options) ToOption() Option {

FILE: core/routing/query.go
  type QueryEventType (line 11) | type QueryEventType
  constant SendingQuery (line 18) | SendingQuery QueryEventType = iota
  constant PeerResponse (line 20) | PeerResponse
  constant FinalPeer (line 22) | FinalPeer
  constant QueryError (line 24) | QueryError
  constant Provider (line 26) | Provider
  constant Value (line 28) | Value
  constant AddingPeer (line 30) | AddingPeer
  constant DialingPeer (line 32) | DialingPeer
  type QueryEvent (line 36) | type QueryEvent struct
  type routingQueryKey (line 43) | type routingQueryKey struct
  type eventChannel (line 44) | type eventChannel struct
    method waitThenClose (line 52) | func (e *eventChannel) waitThenClose() {
    method send (line 64) | func (e *eventChannel) send(ctx context.Context, ev *QueryEvent) {
  function RegisterForQueryEvents (line 86) | func RegisterForQueryEvents(ctx context.Context) (context.Context, <-cha...
  function PublishQueryEvent (line 95) | func PublishQueryEvent(ctx context.Context, ev *QueryEvent) {
  function SubscribesToQueryEvents (line 109) | func SubscribesToQueryEvents(ctx context.Context) bool {

FILE: core/routing/query_serde.go
  method MarshalJSON (line 9) | func (qe *QueryEvent) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 18) | func (qe *QueryEvent) UnmarshalJSON(b []byte) error {

FILE: core/routing/query_test.go
  function TestEventsCancel (line 10) | func TestEventsCancel(t *testing.T) {

FILE: core/routing/routing.go
  type ContentProviding (line 23) | type ContentProviding interface
  type ContentDiscovery (line 32) | type ContentDiscovery interface
  type ContentRouting (line 45) | type ContentRouting interface
  type PeerRouting (line 53) | type PeerRouting interface
  type ValueStore (line 60) | type ValueStore interface
  type Routing (line 84) | type Routing interface
  type PubKeyFetcher (line 100) | type PubKeyFetcher interface
  function KeyForPublicKey (line 107) | func KeyForPublicKey(id peer.ID) string {
  function GetPublicKey (line 116) | func GetPublicKey(r ValueStore, ctx context.Context, p peer.ID) (ci.PubK...

FILE: core/sec/security.go
  type SecureConn (line 15) | type SecureConn interface
  type SecureTransport (line 22) | type SecureTransport interface
  type ErrPeerIDMismatch (line 34) | type ErrPeerIDMismatch struct
    method Error (line 39) | func (e ErrPeerIDMismatch) Error() string {

FILE: core/test/addrs.go
  function GenerateTestAddrs (line 11) | func GenerateTestAddrs(n int) []ma.Multiaddr {
  function AssertAddressesEqual (line 23) | func AssertAddressesEqual(t *testing.T, exp, act []ma.Multiaddr) {

FILE: core/test/crypto.go
  function RandTestKeyPair (line 12) | func RandTestKeyPair(typ, bits int) (ci.PrivKey, ci.PubKey, error) {
  function SeededTestKeyPair (line 18) | func SeededTestKeyPair(typ, bits int, seed int64) (ci.PrivKey, ci.PubKey...

FILE: core/test/errors.go
  function AssertNilError (line 7) | func AssertNilError(t *testing.T, err error) {
  function ExpectError (line 14) | func ExpectError(t *testing.T, err error, msg string) {

FILE: core/test/mockclock.go
  type MockClock (line 9) | type MockClock struct
    method InstantTimer (line 61) | func (c *MockClock) InstantTimer(when time.Time) *mockInstantTimer {
    method Since (line 75) | func (c *MockClock) Since(t time.Time) time.Duration {
    method Now (line 81) | func (c *MockClock) Now() time.Time {
    method AdvanceBy (line 87) | func (c *MockClock) AdvanceBy(dur time.Duration) {
  type mockInstantTimer (line 16) | type mockInstantTimer struct
    method Ch (line 24) | func (t *mockInstantTimer) Ch() <-chan time.Time {
    method Reset (line 28) | func (t *mockInstantTimer) Reset(d time.Time) bool {
    method Stop (line 41) | func (t *mockInstantTimer) Stop() bool {
  function NewMockClock (line 49) | func NewMockClock() *MockClock {

FILE: core/test/mockclock_test.go
  function TestMockClock (line 8) | func TestMockClock(t *testing.T) {

FILE: core/test/peer.go
  function RandPeerID (line 12) | func RandPeerID() (peer.ID, error) {
  function RandPeerIDFatal (line 19) | func RandPeerIDFatal(t testing.TB) peer.ID {

FILE: core/transport/transport.go
  type CapableConn (line 29) | type CapableConn interface
  type Transport (line 58) | type Transport interface
  type Resolver (line 88) | type Resolver interface
  type SkipResolver (line 96) | type SkipResolver interface
  type Listener (line 104) | type Listener interface
  type TransportNetwork (line 115) | type TransportNetwork interface
  type GatedMaListener (line 137) | type GatedMaListener interface
  type Upgrader (line 154) | type Upgrader interface
  type DialUpdater (line 172) | type DialUpdater interface
  type DialUpdateKind (line 178) | type DialUpdateKind
    method String (line 190) | func (k DialUpdateKind) String() string {
  constant UpdateKindDialFailed (line 182) | UpdateKindDialFailed DialUpdateKind = iota
  constant UpdateKindDialSuccessful (line 184) | UpdateKindDialSuccessful
  constant UpdateKindHandshakeProgressed (line 187) | UpdateKindHandshakeProgressed
  type DialUpdate (line 204) | type DialUpdate struct

FILE: examples/metrics-and-dashboards/main.go
  constant ClientCount (line 21) | ClientCount = 32
  function main (line 23) | func main() {
  function newClient (line 62) | func newClient(serverInfo peer.AddrInfo, pings int) {

FILE: examples/pubsub/basic-chat-with-rendezvous/main.go
  function main (line 24) | func main() {
  function initDHT (line 51) | func initDHT(ctx context.Context, h host.Host) *dht.IpfsDHT {
  function discoverPeers (line 79) | func discoverPeers(ctx context.Context, h host.Host) {
  function streamConsoleTo (line 108) | func streamConsoleTo(ctx context.Context, topic *pubsub.Topic) {
  function printMessagesFrom (line 121) | func printMessagesFrom(ctx context.Context, sub *pubsub.Subscription) {

FILE: examples/testutils/logharness.go
  type LogHarness (line 17) | type LogHarness struct
    method Run (line 29) | func (h *LogHarness) Run(t *testing.T, f func()) {
    method Expect (line 44) | func (h *LogHarness) Expect(s string) {
    method ExpectPrefix (line 52) | func (h *LogHarness) ExpectPrefix(s string) {
    method NewSequence (line 60) | func (h *LogHarness) NewSequence(name string) *Sequence {
  type Expectation (line 22) | type Expectation interface
  type prefix (line 66) | type prefix
    method IsMatch (line 68) | func (p prefix) IsMatch(line string) bool {
    method String (line 72) | func (p prefix) String() string {
  type text (line 76) | type text
    method IsMatch (line 78) | func (t text) IsMatch(line string) bool {
    method String (line 82) | func (t text) String() string {
  type Sequence (line 86) | type Sequence struct
    method Assert (line 91) | func (seq *Sequence) Assert(t *testing.T, s *bufio.Scanner) {
    method Expect (line 113) | func (seq *Sequence) Expect(s string) {
    method ExpectPrefix (line 118) | func (seq *Sequence) ExpectPrefix(s string) {

FILE: examples/testutils/net.go
  function FindFreePort (line 10) | func FindFreePort(t *testing.T, host string, maxAttempts int) (int, erro...

FILE: fx_options_test.go
  function TestGetPeerID (line 14) | func TestGetPeerID(t *testing.T) {
  function TestGetEventBus (line 26) | func TestGetEventBus(t *testing.T) {
  function TestGetHost (line 38) | func TestGetHost(t *testing.T) {
  function TestGetIDService (line 50) | func TestGetIDService(t *testing.T) {

FILE: gologshim/gologshim.go
  function SetDefaultHandler (line 68) | func SetDefaultHandler(handler slog.Handler) {
  type dynamicHandler (line 73) | type dynamicHandler struct
    method ensureHandler (line 80) | func (h *dynamicHandler) ensureHandler() slog.Handler {
    method createFallbackHandler (line 98) | func (h *dynamicHandler) createFallbackHandler() slog.Handler {
    method Enabled (line 125) | func (h *dynamicHandler) Enabled(ctx context.Context, lvl slog.Level) ...
    method Handle (line 129) | func (h *dynamicHandler) Handle(ctx context.Context, r slog.Record) er...
    method WithAttrs (line 133) | func (h *dynamicHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
    method WithGroup (line 137) | func (h *dynamicHandler) WithGroup(name string) slog.Handler {
  function Logger (line 146) | func Logger(system string) *slog.Logger {
  constant logFormatText (line 157) | logFormatText logFormat = iota
  constant logFormatJSON (line 158) | logFormatJSON
  type Config (line 161) | type Config struct
    method LevelForSystem (line 169) | func (c *Config) LevelForSystem(system string) slog.Level {
  function parseIPFSGoLogEnv (line 219) | func parseIPFSGoLogEnv(loggingLevelEnvStr string) (slog.Level, map[strin...

FILE: gologshim/gologshim_test.go
  type mockBridge (line 14) | type mockBridge struct
    method Handle (line 20) | func (m *mockBridge) Handle(_ context.Context, r slog.Record) error {
    method WithAttrs (line 28) | func (m *mockBridge) WithAttrs(_ []slog.Attr) slog.Handler {
  function TestGoLogBridgeDetection (line 36) | func TestGoLogBridgeDetection(t *testing.T) {
  function TestLazyBridgeInitialization (line 79) | func TestLazyBridgeInitialization(t *testing.T) {
  function TestConfigFromEnv (line 114) | func TestConfigFromEnv(t *testing.T) {
  function TestParseIPFSGoLogEnv (line 178) | func TestParseIPFSGoLogEnv(t *testing.T) {

FILE: leaky_tests/leaky_test.go
  function TestBadTransportConstructor (line 10) | func TestBadTransportConstructor(t *testing.T) {

FILE: libp2p.go
  function ChainOptions (line 16) | func ChainOptions(opts ...Option) Option {
  function New (line 52) | func New(opts ...Option) (host.Host, error) {
  function NewWithoutDefaults (line 62) | func NewWithoutDefaults(opts ...Option) (host.Host, error) {

FILE: libp2p_test.go
  function TestNewHost (line 53) | func TestNewHost(t *testing.T) {
  function TestTransportConstructor (line 61) | func TestTransportConstructor(t *testing.T) {
  function TestNoListenAddrs (line 76) | func TestNoListenAddrs(t *testing.T) {
  function TestNoTransports (line 85) | func TestNoTransports(t *testing.T) {
  function TestInsecure (line 104) | func TestInsecure(t *testing.T) {
  function TestDefaultListenAddrs (line 110) | func TestDefaultListenAddrs(t *testing.T) {
  function makeRandomHost (line 143) | func makeRandomHost(t *testing.T, port int) (host.Host, error) {
  function TestChainOptions (line 157) | func TestChainOptions(t *testing.T) {
  function TestTransportConstructorTCP (line 187) | func TestTransportConstructorTCP(t *testing.T) {
  function TestTransportConstructorQUIC (line 200) | func TestTransportConstructorQUIC(t *testing.T) {
  type mockTransport (line 213) | type mockTransport struct
    method Dial (line 215) | func (m mockTransport) Dial(context.Context, ma.Multiaddr, peer.ID) (t...
    method CanDial (line 219) | func (m mockTransport) CanDial(ma.Multiaddr) bool                     ...
    method Listen (line 220) | func (m mockTransport) Listen(ma.Multiaddr) (transport.Listener, error...
    method Protocols (line 221) | func (m mockTransport) Protocols() []int                              ...
    method Proxy (line 222) | func (m mockTransport) Proxy() bool                                   ...
  function TestTransportConstructorWithoutOpts (line 226) | func TestTransportConstructorWithoutOpts(t *testing.T) {
  function TestTransportConstructorWithWrongOpts (line 259) | func TestTransportConstructorWithWrongOpts(t *testing.T) {
  function TestSecurityConstructor (line 267) | func TestSecurityConstructor(t *testing.T) {
  function TestTransportConstructorWebTransport (line 306) | func TestTransportConstructorWebTransport(t *testing.T) {
  function TestTransportCustomAddressWebTransport (line 319) | func TestTransportCustomAddressWebTransport(t *testing.T) {
  function TestTransportCustomAddressWebTransportDoesNotStall (line 348) | func TestTransportCustomAddressWebTransportDoesNotStall(t *testing.T) {
  type mockPeerRouting (line 372) | type mockPeerRouting struct
    method FindPeer (line 376) | func (r *mockPeerRouting) FindPeer(_ context.Context, id peer.ID) (pee...
  function TestRoutedHost (line 381) | func TestRoutedHost(t *testing.T) {
  function TestAutoNATService (line 399) | func TestAutoNATService(t *testing.T) {
  function TestInsecureConstructor (line 405) | func TestInsecureConstructor(t *testing.T) {
  function TestAutoNATv2Service (line 420) | func TestAutoNATv2Service(t *testing.T) {
  function TestDisableIdentifyAddressDiscovery (line 426) | func TestDisableIdentifyAddressDiscovery(t *testing.T) {
  function TestMain (line 432) | func TestMain(m *testing.M) {
  function TestDialCircuitAddrWithWrappedResourceManager (line 445) | func TestDialCircuitAddrWithWrappedResourceManager(t *testing.T) {
  function TestHostAddrsFactoryAddsCerthashes (line 482) | func TestHostAddrsFactoryAddsCerthashes(t *testing.T) {
  function newRandomPort (line 505) | func newRandomPort(t *testing.T) string {
  function TestWebRTCReuseAddrWithQUIC (line 517) | func TestWebRTCReuseAddrWithQUIC(t *testing.T) {
  function TestUseCorrectTransportForDialOut (line 601) | func TestUseCorrectTransportForDialOut(t *testing.T) {
  function TestCircuitBehindWSS (line 668) | func TestCircuitBehindWSS(t *testing.T) {
  function getTLSConf (line 729) | func getTLSConf(t *testing.T, ip net.IP, start, end time.Time) *tls.Conf...
  function TestSharedTCPAddr (line 757) | func TestSharedTCPAddr(t *testing.T) {
  function TestCustomTCPDialer (line 789) | func TestCustomTCPDialer(t *testing.T) {
  function TestBasicHostInterfaceAssertion (line 817) | func TestBasicHostInterfaceAssertion(t *testing.T) {
  function BenchmarkAllAddrs (line 834) | func BenchmarkAllAddrs(b *testing.B) {
  function TestConnAs (line 848) | func TestConnAs(t *testing.T) {

FILE: limits.go
  function SetDefaultServiceLimits (line 15) | func SetDefaultServiceLimits(config *rcmgr.ScalingLimitConfig) {
  function addServiceAndProtocolLimit (line 105) | func addServiceAndProtocolLimit(config *rcmgr.ScalingLimitConfig, servic...
  function addServicePeerAndProtocolPeerLimit (line 110) | func addServicePeerAndProtocolPeerLimit(config *rcmgr.ScalingLimitConfig...

FILE: options.go
  function ListenAddrStrings (line 39) | func ListenAddrStrings(s ...string) Option {
  function ListenAddrs (line 53) | func ListenAddrs(addrs ...ma.Multiaddr) Option {
  function Security (line 73) | func Security(name string, constructor any) Option {
  function Muxer (line 95) | func Muxer(name string, muxer network.Multiplexer) Option {
  function QUICReuse (line 102) | func QUICReuse(constructor any, opts ...quicreuse.Option) Option {
  function Transport (line 144) | func Transport(constructor any, opts ...any) Option {
  function Peerstore (line 198) | func Peerstore(ps peerstore.Peerstore) Option {
  function PrivateNetwork (line 210) | func PrivateNetwork(psk pnet.PSK) Option {
  function BandwidthReporter (line 222) | func BandwidthReporter(rep metrics.Reporter) Option {
  function Identity (line 234) | func Identity(sk crypto.PrivKey) Option {
  function ConnectionManager (line 249) | func ConnectionManager(connman connmgr.ConnManager) Option {
  function AddrsFactory (line 260) | func AddrsFactory(factory config.AddrsFactory) Option {
  function EnableRelay (line 275) | func EnableRelay() Option {
  function DisableRelay (line 284) | func DisableRelay() Option {
  function EnableRelayService (line 294) | func EnableRelayService(opts ...relayv2.Option) Option {
  function EnableAutoRelay (line 314) | func EnableAutoRelay(opts ...autorelay.Option) Option {
  function EnableAutoRelayWithStaticRelays (line 326) | func EnableAutoRelayWithStaticRelays(static []peer.AddrInfo, opts ...aut...
  function EnableAutoRelayWithPeerSource (line 339) | func EnableAutoRelayWithPeerSource(peerSource autorelay.PeerSource, opts...
  function ForceReachabilityPublic (line 349) | func ForceReachabilityPublic() Option {
  function ForceReachabilityPrivate (line 359) | func ForceReachabilityPrivate() Option {
  function EnableNATService (line 370) | func EnableNATService() Option {
  function AutoNATServiceRateLimit (line 381) | func AutoNATServiceRateLimit(global, perPeer int, interval time.Duration...
  function ConnectionGater (line 395) | func ConnectionGater(cg connmgr.ConnectionGater) Option {
  function ResourceManager (line 408) | func ResourceManager(rcmgr network.ResourceManager) Option {
  function NATPortMap (line 420) | func NATPortMap() Option {
  function NATManager (line 426) | func NATManager(nm config.NATManagerC) Option {
  function Ping (line 437) | func Ping(enable bool) Option {
  function Routing (line 445) | func Routing(rt config.RoutingC) Option {
  function ProtocolVersion (line 481) | func ProtocolVersion(s string) Option {
  function UserAgent (line 489) | func UserAgent(userAgent string) Option {
  function MultiaddrResolver (line 497) | func MultiaddrResolver(rslv network.MultiaddrDNSResolver) Option {
  function EnableHolePunching (line 535) | func EnableHolePunching(opts ...holepunch.Option) Option {
  function WithDialTimeout (line 543) | func WithDialTimeout(t time.Duration) Option {
  function DisableMetrics (line 554) | func DisableMetrics() Option {
  function PrometheusRegisterer (line 562) | func PrometheusRegisterer(reg prometheus.Registerer) Option {
  function DialRanker (line 583) | func DialRanker(d network.DialRanker) Option {
  function SwarmOpts (line 594) | func SwarmOpts(opts ...swarm.Option) Option {
  function DisableIdentifyAddressDiscovery (line 605) | func DisableIdentifyAddressDiscovery() Option {
  function EnableAutoNATv2 (line 613) | func EnableAutoNATv2() Option {
  function UDPBlackHoleSuccessCounter (line 621) | func UDPBlackHoleSuccessCounter(f *swarm.BlackHoleSuccessCounter) Option {
  function IPv6BlackHoleSuccessCounter (line 630) | func IPv6BlackHoleSuccessCounter(f *swarm.BlackHoleSuccessCounter) Option {
  function WithFxOption (line 640) | func WithFxOption(opts ...fx.Option) Option {
  function ShareTCPListener (line 652) | func ShareTCPListener() Option {

FILE: options_filter.go
  type filtersConnectionGater (line 14) | type filtersConnectionGater
    method InterceptAddrDial (line 18) | func (f *filtersConnectionGater) InterceptAddrDial(_ peer.ID, addr ma....
    method InterceptPeerDial (line 22) | func (f *filtersConnectionGater) InterceptPeerDial(_ peer.ID) (allow b...
    method InterceptAccept (line 26) | func (f *filtersConnectionGater) InterceptAccept(connAddr network.Conn...
    method InterceptSecured (line 30) | func (f *filtersConnectionGater) InterceptSecured(_ network.Direction,...
    method InterceptUpgraded (line 34) | func (f *filtersConnectionGater) InterceptUpgraded(_ network.Conn) (al...

FILE: p2p/canonicallog/canonicallog.go
  function logWithSkip (line 28) | func logWithSkip(ctx context.Context, l *slog.Logger, level slog.Level, ...
  function LogMisbehavingPeer (line 45) | func LogMisbehavingPeer(p peer.ID, peerAddr multiaddr.Multiaddr, compone...
  function LogMisbehavingPeerNetAddr (line 57) | func LogMisbehavingPeerNetAddr(p peer.ID, peerAddr net.Addr, component s...
  function LogPeerStatus (line 79) | func LogPeerStatus(sampleRate int, p peer.ID, peerAddr multiaddr.Multiad...

FILE: p2p/canonicallog/canonicallog_test.go
  function TestLogs (line 15) | func TestLogs(t *testing.T) {

FILE: p2p/discovery/backoff/backoff.go
  type BackoffFactory (line 14) | type BackoffFactory
  type BackoffStrategy (line 17) | type BackoffStrategy interface
  type Jitter (line 27) | type Jitter
  function FullJitter (line 31) | func FullJitter(duration, min, max time.Duration, rng *rand.Rand) time.D...
  function NoJitter (line 42) | func NoJitter(duration, min, max time.Duration, _ *rand.Rand) time.Durat...
  type randomizedBackoff (line 46) | type randomizedBackoff struct
    method BoundedDelay (line 52) | func (b *randomizedBackoff) BoundedDelay(duration time.Duration) time....
  function boundedDuration (line 56) | func boundedDuration(d, min, max time.Duration) time.Duration {
  type attemptBackoff (line 66) | type attemptBackoff struct
    method Reset (line 72) | func (b *attemptBackoff) Reset() {
  function NewFixedBackoff (line 77) | func NewFixedBackoff(delay time.Duration) BackoffFactory {
  type fixedBackoff (line 83) | type fixedBackoff struct
    method Delay (line 87) | func (b *fixedBackoff) Delay() time.Duration {
    method Reset (line 91) | func (b *fixedBackoff) Reset() {}
  function NewPolynomialBackoff (line 97) | func NewPolynomialBackoff(min, max time.Duration, jitter Jitter,
  type polynomialBackoff (line 116) | type polynomialBackoff struct
    method Delay (line 122) | func (b *polynomialBackoff) Delay() time.Duration {
  function NewExponentialBackoff (line 146) | func NewExponentialBackoff(min, max time.Duration, jitter Jitter,
  type exponentialBackoff (line 166) | type exponentialBackoff struct
    method Delay (line 173) | func (b *exponentialBackoff) Delay() time.Duration {
  function NewExponentialDecorrelatedJitter (line 183) | func NewExponentialDecorrelatedJitter(min, max time.Duration, base float...
  type exponentialDecorrelatedJitter (line 197) | type exponentialDecorrelatedJitter struct
    method Delay (line 203) | func (b *exponentialDecorrelatedJitter) Delay() time.Duration {
    method Reset (line 214) | func (b *exponentialDecorrelatedJitter) Reset() { b.lastDelay = 0 }
  type lockedSource (line 216) | type lockedSource struct
    method Int63 (line 221) | func (r *lockedSource) Int63() (n int64) {
    method Seed (line 228) | func (r *lockedSource) Seed(seed int64) {

FILE: p2p/discovery/backoff/backoff_test.go
  function checkDelay (line 12) | func checkDelay(bkf BackoffStrategy, expected time.Duration, t *testing....
  function TestFixedBackoff (line 19) | func TestFixedBackoff(t *testing.T) {
  function TestPolynomialBackoff (line 40) | func TestPolynomialBackoff(t *testing.T) {
  function TestExponentialBackoff (line 59) | func TestExponentialBackoff(t *testing.T) {
  function minMaxJitterTest (line 80) | func minMaxJitterTest(jitter Jitter, t *testing.T) {
  function TestNoJitter (line 90) | func TestNoJitter(t *testing.T) {
  function TestFullJitter (line 100) | func TestFullJitter(t *testing.T) {
  function TestManyBackoffFactory (line 126) | func TestManyBackoffFactory(t *testing.T) {
  function testManyBackoffFactoryHelper (line 147) | func testManyBackoffFactoryHelper(concurrent int, bkf BackoffFactory) {

FILE: p2p/discovery/backoff/backoffcache.go
  type BackoffDiscovery (line 16) | type BackoffDiscovery struct
    method Advertise (line 99) | func (d *BackoffDiscovery) Advertise(ctx context.Context, ns string, o...
    method FindPeers (line 103) | func (d *BackoffDiscovery) FindPeers(ctx context.Context, ns string, o...
  type BackoffDiscoveryOption (line 28) | type BackoffDiscoveryOption
  function NewBackoffDiscovery (line 30) | func NewBackoffDiscovery(disc discovery.Discovery, stratFactory BackoffF...
  function WithBackoffDiscoverySimultaneousQueryBufferSize (line 53) | func WithBackoffDiscoverySimultaneousQueryBufferSize(size int) BackoffDi...
  function WithBackoffDiscoveryReturnedChannelSize (line 65) | func WithBackoffDiscoveryReturnedChannelSize(size int) BackoffDiscoveryO...
  type clock (line 75) | type clock interface
  type realClock (line 79) | type realClock struct
    method Now (line 81) | func (c realClock) Now() time.Time {
  type backoffCache (line 85) | type backoffCache struct
  function findPeerDispatcher (line 196) | func findPeerDispatcher(ctx context.Context, c *backoffCache, pch <-chan...
  function findPeerReceiver (line 254) | func findPeerReceiver(ctx context.Context, pch, evtCh chan peer.AddrInfo...
  function mergeAddrInfos (line 293) | func mergeAddrInfos(prevAi, newAi peer.AddrInfo) *peer.AddrInfo {
  function checkUpdates (line 315) | func checkUpdates(orig, update map[peer.ID]peer.AddrInfo) bool {

FILE: p2p/discovery/backoff/backoffcache_test.go
  type delayedDiscovery (line 19) | type delayedDiscovery struct
    method Advertise (line 25) | func (d *delayedDiscovery) Advertise(ctx context.Context, ns string, o...
    method FindPeers (line 29) | func (d *delayedDiscovery) FindPeers(ctx context.Context, ns string, o...
  function assertNumPeers (line 61) | func assertNumPeers(t *testing.T, ctx context.Context, d discovery.Disco...
  function assertNumPeersWithLimit (line 66) | func assertNumPeersWithLimit(t *testing.T, ctx context.Context, d discov...
  function withClock (line 84) | func withClock(c clock) BackoffDiscoveryOption {
  function TestBackoffDiscoverySingleBackoff (line 91) | func TestBackoffDiscoverySingleBackoff(t *testing.T) {
  function TestBackoffDiscoveryMultipleBackoff (line 137) | func TestBackoffDiscoveryMultipleBackoff(t *testing.T) {
  function TestBackoffDiscoverySimultaneousQuery (line 195) | func TestBackoffDiscoverySimultaneousQuery(t *testing.T) {
  function TestBackoffDiscoveryCacheCapacity (line 256) | func TestBackoffDiscoveryCacheCapacity(t *testing.T) {

FILE: p2p/discovery/backoff/backoffconnector.go
  type BackoffConnector (line 15) | type BackoffConnector struct
    method Connect (line 49) | func (c *BackoffConnector) Connect(ctx context.Context, peerCh <-chan ...
  function NewBackoffConnector (line 27) | func NewBackoffConnector(h host.Host, cacheSize int, connectionTryDurati...
  type connCacheData (line 41) | type connCacheData struct

FILE: p2p/discovery/backoff/backoffconnector_test.go
  type maxDialHost (line 18) | type maxDialHost struct
    method Connect (line 26) | func (h *maxDialHost) Connect(ctx context.Context, ai peer.AddrInfo) e...
  function getNetHosts (line 42) | func getNetHosts(t *testing.T, n int) []host.Host {
  function loadCh (line 55) | func loadCh(peers []host.Host) <-chan peer.AddrInfo {
  function TestBackoffConnector (line 64) | func TestBackoffConnector(t *testing.T) {

FILE: p2p/discovery/mdns/mdns.go
  constant ServiceName (line 21) | ServiceName   = "_p2p._udp"
  constant mdnsDomain (line 22) | mdnsDomain    = "local"
  constant dnsaddrPrefix (line 23) | dnsaddrPrefix = "dnsaddr="
  type Service (line 28) | type Service interface
  type Notifee (line 33) | type Notifee interface
  type mdnsService (line 37) | type mdnsService struct
    method Start (line 66) | func (s *mdnsService) Start() error {
    method Close (line 74) | func (s *mdnsService) Close() error {
    method getIPs (line 85) | func (s *mdnsService) getIPs(addrs []ma.Multiaddr) ([]string, error) {
    method startServer (line 173) | func (s *mdnsService) startServer() error {
    method startResolver (line 215) | func (s *mdnsService) startResolver(ctx context.Context) {
  function NewMdnsService (line 52) | func NewMdnsService(host host.Host, serviceName string, notifee Notifee)...
  function containsUnsuitableProtocol (line 115) | func containsUnsuitableProtocol(addr ma.Multiaddr) bool {
  function isSuitableForMDNS (line 146) | func isSuitableForMDNS(addr ma.Multiaddr) bool {
  function randomString (line 257) | func randomString(l int) string {

FILE: p2p/discovery/mdns/mdns_test.go
  function setupMDNS (line 19) | func setupMDNS(t *testing.T, notifee Notifee) peer.ID {
  type notif (line 32) | type notif struct
    method HandlePeerFound (line 39) | func (n *notif) HandlePeerFound(info peer.AddrInfo) {
    method GetPeers (line 45) | func (n *notif) GetPeers() []peer.AddrInfo {
  function TestOtherDiscovery (line 53) | func TestOtherDiscovery(t *testing.T) {
  function TestIsSuitableForMDNS (line 105) | func TestIsSuitableForMDNS(t *testing.T) {

FILE: p2p/discovery/mocks/mocks.go
  type clock (line 13) | type clock interface
  type MockDiscoveryServer (line 17) | type MockDiscoveryServer struct
    method Advertise (line 35) | func (s *MockDiscoveryServer) Advertise(ns string, info peer.AddrInfo,...
    method FindPeers (line 48) | func (s *MockDiscoveryServer) FindPeers(ns string, limit int) (<-chan ...
  type discoveryRegistration (line 23) | type discoveryRegistration struct
  function NewDiscoveryServer (line 28) | func NewDiscoveryServer(clock clock) *MockDiscoveryServer {
  type MockDiscoveryClient (line 84) | type MockDiscoveryClient struct
    method Advertise (line 96) | func (d *MockDiscoveryClient) Advertise(_ context.Context, ns string, ...
    method FindPeers (line 106) | func (d *MockDiscoveryClient) FindPeers(_ context.Context, ns string, ...
  function NewDiscoveryClient (line 89) | func NewDiscoveryClient(h host.Host, server *MockDiscoveryServer) *MockD...

FILE: p2p/discovery/routing/routing.go
  type RoutingDiscovery (line 17) | type RoutingDiscovery struct
    method Advertise (line 25) | func (d *RoutingDiscovery) Advertise(ctx context.Context, ns string, o...
    method FindPeers (line 58) | func (d *RoutingDiscovery) FindPeers(ctx context.Context, ns string, o...
  function NewRoutingDiscovery (line 21) | func NewRoutingDiscovery(router routing.ContentRouting) *RoutingDiscovery {
  function nsToCid (line 75) | func nsToCid(ns string) (cid.Cid, error) {
  function NewDiscoveryRouting (line 84) | func NewDiscoveryRouting(disc discovery.Discovery, opts ...discovery.Opt...
  type DiscoveryRouting (line 88) | type DiscoveryRouting struct
    method Provide (line 93) | func (r *DiscoveryRouting) Provide(ctx context.Context, c cid.Cid, bca...
    method FindProvidersAsync (line 102) | func (r *DiscoveryRouting) FindProvidersAsync(ctx context.Context, c c...
  function cidToNs (line 107) | func cidToNs(c cid.Cid) string {

FILE: p2p/discovery/routing/routing_test.go
  type mockRoutingTable (line 21) | type mockRoutingTable struct
  type mockRouting (line 26) | type mockRouting struct
    method Provide (line 39) | func (m *mockRouting) Provide(_ context.Context, cid cid.Cid, _ bool) ...
    method FindProvidersAsync (line 54) | func (m *mockRouting) FindProvidersAsync(ctx context.Context, cid cid....
  function NewMockRoutingTable (line 31) | func NewMockRoutingTable() *mockRoutingTable {
  function NewMockRouting (line 35) | func NewMockRouting(h host.Host, tab *mockRoutingTable) *mockRouting {
  function TestRoutingDiscovery (line 78) | func TestRoutingDiscovery(t *testing.T) {
  function TestDiscoveryRouting (line 111) | func TestDiscoveryRouting(t *testing.T) {

FILE: p2p/discovery/util/util.go
  function FindPeers (line 16) | func FindPeers(ctx context.Context, d discovery.Discoverer, ns string, o...
  function Advertise (line 32) | func Advertise(ctx context.Context, a discovery.Advertiser, ns string, o...

FILE: p2p/host/autonat/autonat.go
  constant maxConfidence (line 24) | maxConfidence = 3
  type AmbientAutoNAT (line 27) | type AmbientAutoNAT struct
    method Status (line 145) | func (as *AmbientAutoNAT) Status() network.Reachability {
    method emitStatus (line 150) | func (as *AmbientAutoNAT) emitStatus() {
    method background (line 168) | func (as *AmbientAutoNAT) background() {
    method checkAddrs (line 247) | func (as *AmbientAutoNAT) checkAddrs() (hasNewAddr bool) {
    method scheduleProbe (line 264) | func (as *AmbientAutoNAT) scheduleProbe(forceProbe bool) time.Duration {
    method handleDialResponse (line 300) | func (as *AmbientAutoNAT) handleDialResponse(dialErr error) {
    method recordObservation (line 315) | func (as *AmbientAutoNAT) recordObservation(observation network.Reacha...
    method tryProbe (line 375) | func (as *AmbientAutoNAT) tryProbe(p peer.ID) {
    method probe (line 385) | func (as *AmbientAutoNAT) probe(pi *peer.AddrInfo) {
    method getPeerToProbe (line 400) | func (as *AmbientAutoNAT) getPeerToProbe() peer.ID {
    method Close (line 436) | func (as *AmbientAutoNAT) Close() error {
  type StaticAutoNAT (line 61) | type StaticAutoNAT struct
    method Status (line 446) | func (s *StaticAutoNAT) Status() network.Reachability {
    method Close (line 450) | func (s *StaticAutoNAT) Close() error {
  function New (line 68) | func New(h host.Host, options ...Option) (AutoNAT, error) {
  function ipInList (line 158) | func ipInList(candidate ma.Multiaddr, list []ma.Multiaddr) bool {

FILE: p2p/host/autonat/autonat_test.go
  function makeAutoNATServicePrivate (line 23) | func makeAutoNATServicePrivate(t *testing.T) host.Host {
  function sayPrivateStreamHandler (line 29) | func sayPrivateStreamHandler(t *testing.T) network.StreamHandler {
  function makeAutoNATRefuseDialRequest (line 46) | func makeAutoNATRefuseDialRequest(t *testing.T, done chan struct{}) host...
  function sayRefusedStreamHandler (line 52) | func sayRefusedStreamHandler(t *testing.T, done chan struct{}) network.S...
  function makeAutoNATServicePublic (line 77) | func makeAutoNATServicePublic(t *testing.T) host.Host {
  function makeAutoNAT (line 96) | func makeAutoNAT(t *testing.T, ash host.Host) (host.Host, AutoNAT) {
  function identifyAsServer (line 106) | func identifyAsServer(server, recip host.Host) {
  function connect (line 112) | func connect(t *testing.T, a, b host.Host) {
  function expectEvent (line 120) | func expectEvent(t *testing.T, s event.Subscription, expected network.Re...
  function TestAutoNATPrivate (line 135) | func TestAutoNATPrivate(t *testing.T) {
  function TestAutoNATPublic (line 157) | func TestAutoNATPublic(t *testing.T) {
  function TestAutoNATPublictoPrivate (line 179) | func TestAutoNATPublictoPrivate(t *testing.T) {
  function TestAutoNATIncomingEvents (line 207) | func TestAutoNATIncomingEvents(t *testing.T) {
  function TestAutoNATDialRefused (line 230) | func TestAutoNATDialRefused(t *testing.T) {
  function recordObservation (line 262) | func recordObservation(an *AmbientAutoNAT, status network.Reachability) {
  function TestAutoNATObservationRecording (line 266) | func TestAutoNATObservationRecording(t *testing.T) {
  function TestStaticNat (line 314) | func TestStaticNat(t *testing.T) {

FILE: p2p/host/autonat/client.go
  function NewAutoNATClient (line 18) | func NewAutoNATClient(h host.Host, addrFunc AddrFunc, mt MetricsTracer) ...
  type client (line 25) | type client struct
    method DialBack (line 37) | func (c *client) DialBack(ctx context.Context, p peer.ID) error {
  type Error (line 100) | type Error struct
    method Error (line 105) | func (e Error) Error() string {
    method IsDialError (line 110) | func (e Error) IsDialError() bool {
    method IsDialRefused (line 115) | func (e Error) IsDialRefused() bool {
  function IsDialError (line 120) | func IsDialError(e error) bool {
  function IsDialRefused (line 126) | func IsDialRefused(e error) bool {

FILE: p2p/host/autonat/dialpolicy.go
  type dialPolicy (line 12) | type dialPolicy struct
    method skipDial (line 21) | func (d *dialPolicy) skipDial(addr ma.Multiaddr) bool {
    method skipPeer (line 59) | func (d *dialPolicy) skipPeer(addrs []ma.Multiaddr) bool {

FILE: p2p/host/autonat/dialpolicy_test.go
  function makeMA (line 17) | func makeMA(a string) multiaddr.Multiaddr {
  type mockT (line 25) | type mockT struct
    method Dial (line 31) | func (m *mockT) Dial(_ context.Context, _ multiaddr.Multiaddr, _ peer....
    method CanDial (line 34) | func (m *mockT) CanDial(_ multiaddr.Multiaddr) bool { return true }
    method Listen (line 35) | func (m *mockT) Listen(_ multiaddr.Multiaddr) (transport.Listener, err...
    method Protocols (line 38) | func (m *mockT) Protocols() []int { return []int{multiaddr.P_IP4} }
    method Proxy (line 39) | func (m *mockT) Proxy() bool      { return false }
    method String (line 40) | func (m *mockT) String() string   { return "mock-tcp-ipv4" }
  type mockL (line 42) | type mockL struct
    method Accept (line 48) | func (l *mockL) Accept() (transport.CapableConn, error) {
    method Close (line 52) | func (l *mockL) Close() error                   { l.cancel(); return n...
    method Addr (line 53) | func (l *mockL) Addr() net.Addr                 { return nil }
    method Multiaddr (line 54) | func (l *mockL) Multiaddr() multiaddr.Multiaddr { return l.addr }
  function TestSkipDial (line 56) | func TestSkipDial(t *testing.T) {
  function TestSkipPeer (line 85) | func TestSkipPeer(t *testing.T) {
  function TestSkipLocalPeer (line 120) | func TestSkipLocalPeer(t *testing.T) {

FILE: p2p/host/autonat/interface.go
  type AutoNAT (line 14) | type AutoNAT interface
  type Client (line 21) | type Client interface
  type AddrFunc (line 28) | type AddrFunc
  type Option (line 31) | type Option

FILE: p2p/host/autonat/metrics.go
  constant metricNamespace (line 12) | metricNamespace = "libp2p_autonat"
  type MetricsTracer (line 70) | type MetricsTracer interface
  function getResponseStatus (line 79) | func getResponseStatus(status pb.Message_ResponseStatus) string {
  constant rate_limited (line 99) | rate_limited     = "rate limited"
  constant dial_blocked (line 100) | dial_blocked     = "dial blocked"
  constant no_valid_address (line 101) | no_valid_address = "no valid address"
  type metricsTracer (line 104) | type metricsTracer struct
    method ReachabilityStatus (line 131) | func (mt *metricsTracer) ReachabilityStatus(status network.Reachabilit...
    method ReachabilityStatusConfidence (line 135) | func (mt *metricsTracer) ReachabilityStatusConfidence(confidence int) {
    method ReceivedDialResponse (line 139) | func (mt *metricsTracer) ReceivedDialResponse(status pb.Message_Respon...
    method OutgoingDialResponse (line 146) | func (mt *metricsTracer) OutgoingDialResponse(status pb.Message_Respon...
    method OutgoingDialRefused (line 153) | func (mt *metricsTracer) OutgoingDialRefused(reason string) {
    method NextProbeTime (line 160) | func (mt *metricsTracer) NextProbeTime(t time.Time) {
  type metricsTracerSetting (line 108) | type metricsTracerSetting struct
  type MetricsTracerOption (line 112) | type MetricsTracerOption
  function WithRegisterer (line 114) | func WithRegisterer(reg prometheus.Registerer) MetricsTracerOption {
  function NewMetricsTracer (line 122) | func NewMetricsTracer(opts ...MetricsTracerOption) MetricsTracer {

FILE: p2p/host/autonat/metrics_test.go
  function BenchmarkReachabilityStatus (line 14) | func BenchmarkReachabilityStatus(b *testing.B) {
  function BenchmarkClientDialResponse (line 22) | func BenchmarkClientDialResponse(b *testing.B) {
  function BenchmarkServerDialResponse (line 32) | func BenchmarkServerDialResponse(b *testing.B) {
  function BenchmarkServerDialRefused (line 42) | func BenchmarkServerDialRefused(b *testing.B) {
  function TestMetricsNoAllocNoCover (line 50) | func TestMetricsNoAllocNoCover(t *testing.T) {

FILE: p2p/host/autonat/notify.go
  method Listen (line 13) | func (as *AmbientAutoNAT) Listen(_ network.Network, _ ma.Multiaddr) {}
  method ListenClose (line 16) | func (as *AmbientAutoNAT) ListenClose(_ network.Network, _ ma.Multiaddr) {}
  method Connected (line 19) | func (as *AmbientAutoNAT) Connected(_ network.Network, c network.Conn) {
  method Disconnected (line 30) | func (as *AmbientAutoNAT) Disconnected(_ network.Network, _ network.Conn...

FILE: p2p/host/autonat/options.go
  type config (line 12) | type config struct
  constant maxRefreshInterval (line 54) | maxRefreshInterval = 24 * time.Hour
  function EnableService (line 62) | func EnableService(dialer network.Network) Option {
  function WithReachability (line 74) | func WithReachability(reachability network.Reachability) Option {
  function UsingAddresses (line 86) | func UsingAddresses(addrFunc AddrFunc) Option {
  function WithSchedule (line 101) | func WithSchedule(retryInterval, refreshInterval time.Duration) Option {
  function WithoutStartupDelay (line 112) | func WithoutStartupDelay() Option {
  function WithoutThrottling (line 122) | func WithoutThrottling() Option {
  function WithThrottling (line 131) | func WithThrottling(amount int, interval time.Duration) Option {
  function WithPeerThrottling (line 142) | func WithPeerThrottling(amount int) Option {
  function WithMetricsTracer (line 150) | func WithMetricsTracer(mt MetricsTracer) Option {

FILE: p2p/host/autonat/pb/autonat.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type Message_MessageType (line 24) | type Message_MessageType
    method Enum (line 43) | func (x Message_MessageType) Enum() *Message_MessageType {
    method String (line 49) | func (x Message_MessageType) String() string {
    method Descriptor (line 53) | func (Message_MessageType) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 57) | func (Message_MessageType) Type() protoreflect.EnumType {
    method Number (line 61) | func (x Message_MessageType) Number() protoreflect.EnumNumber {
    method UnmarshalJSON (line 66) | func (x *Message_MessageType) UnmarshalJSON(b []byte) error {
    method EnumDescriptor (line 76) | func (Message_MessageType) EnumDescriptor() ([]byte, []int) {
  constant Message_DIAL (line 27) | Message_DIAL          Message_MessageType = 0
  constant Message_DIAL_RESPONSE (line 28) | Message_DIAL_RESPONSE Message_MessageType = 1
  type Message_ResponseStatus (line 80) | type Message_ResponseStatus
    method Enum (line 108) | func (x Message_ResponseStatus) Enum() *Message_ResponseStatus {
    method String (line 114) | func (x Message_ResponseStatus) String() string {
    method Descriptor (line 118) | func (Message_ResponseStatus) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 122) | func (Message_ResponseStatus) Type() protoreflect.EnumType {
    method Number (line 126) | func (x Message_ResponseStatus) Number() protoreflect.EnumNumber {
    method UnmarshalJSON (line 131) | func (x *Message_ResponseStatus) UnmarshalJSON(b []byte) error {
    method EnumDescriptor (line 141) | func (Message_ResponseStatus) EnumDescriptor() ([]byte, []int) {
  constant Message_OK (line 83) | Message_OK               Message_ResponseStatus = 0
  constant Message_E_DIAL_ERROR (line 84) | Message_E_DIAL_ERROR     Message_ResponseStatus = 100
  constant Message_E_DIAL_REFUSED (line 85) | Message_E_DIAL_REFUSED   Message_ResponseStatus = 101
  constant Message_E_BAD_REQUEST (line 86) | Message_E_BAD_REQUEST    Message_ResponseStatus = 200
  constant Message_E_INTERNAL_ERROR (line 87) | Message_E_INTERNAL_ERROR Message_ResponseStatus = 300
  type Message (line 145) | type Message struct
    method Reset (line 154) | func (x *Message) Reset() {
    method String (line 161) | func (x *Message) String() string {
    method ProtoMessage (line 165) | func (*Message) ProtoMessage() {}
    method ProtoReflect (line 167) | func (x *Message) ProtoReflect() protoreflect.Message {
    method Descriptor (line 180) | func (*Message) Descriptor() ([]byte, []int) {
    method GetType (line 184) | func (x *Message) GetType() Message_MessageType {
    method GetDial (line 191) | func (x *Message) GetDial() *Message_Dial {
    method GetDialResponse (line 198) | func (x *Message) GetDialResponse() *Message_DialResponse {
  type Message_PeerInfo (line 205) | type Message_PeerInfo struct
    method Reset (line 213) | func (x *Message_PeerInfo) Reset() {
    method String (line 220) | func (x *Message_PeerInfo) String() string {
    method ProtoMessage (line 224) | func (*Message_PeerInfo) ProtoMessage() {}
    method ProtoReflect (line 226) | func (x *Message_PeerInfo) ProtoReflect() protoreflect.Message {
    method Descriptor (line 239) | func (*Message_PeerInfo) Descriptor() ([]byte, []int) {
    method GetId (line 243) | func (x *Message_PeerInfo) GetId() []byte {
    method GetAddrs (line 250) | func (x *Message_PeerInfo) GetAddrs() [][]byte {
  type Message_Dial (line 257) | type Message_Dial struct
    method Reset (line 264) | func (x *Message_Dial) Reset() {
    method String (line 271) | func (x *Message_Dial) String() string {
    method ProtoMessage (line 275) | func (*Message_Dial) ProtoMessage() {}
    method ProtoReflect (line 277) | func (x *Message_Dial) ProtoReflect() protoreflect.Message {
    method Descriptor (line 290) | func (*Message_Dial) Descriptor() ([]byte, []int) {
    method GetPeer (line 294) | func (x *Message_Dial) GetPeer() *Message_PeerInfo {
  type Message_DialResponse (line 301) | type Message_DialResponse struct
    method Reset (line 310) | func (x *Message_DialResponse) Reset() {
    method String (line 317) | func (x *Message_DialResponse) String() string {
    method ProtoMessage (line 321) | func (*Message_DialResponse) ProtoMessage() {}
    method ProtoReflect (line 323) | func (x *Message_DialResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 336) | func (*Message_DialResponse) Descriptor() ([]byte, []int) {
    method GetStatus (line 340) | func (x *Message_DialResponse) GetStatus() Message_ResponseStatus {
    method GetStatusText (line 347) | func (x *Message_DialResponse) GetStatusText() string {
    method GetAddr (line 354) | func (x *Message_DialResponse) GetAddr() []byte {
  constant file_p2p_host_autonat_pb_autonat_proto_rawDesc (line 363) | file_p2p_host_autonat_pb_autonat_proto_rawDesc = "" +
  function file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP (line 397) | func file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP() []byte {
  function init (line 427) | func init() { file_p2p_host_autonat_pb_autonat_proto_init() }
  function file_p2p_host_autonat_pb_autonat_proto_init (line 428) | func file_p2p_host_autonat_pb_autonat_proto_init() {

FILE: p2p/host/autonat/proto.go
  constant AutoNATProto (line 11) | AutoNATProto = "/libp2p/autonat/1.0.0"
  function newDialMessage (line 13) | func newDialMessage(pi peer.AddrInfo) *pb.Message {
  function newDialResponseOK (line 27) | func newDialResponseOK(addr ma.Multiaddr) *pb.Message_DialResponse {
  function newDialResponseError (line 34) | func newDialResponseError(status pb.Message_ResponseStatus, text string)...

FILE: p2p/host/autonat/svc.go
  constant ServiceName (line 23) | ServiceName = "libp2p.autonat"
  constant maxMsgSize (line 25) | maxMsgSize = 4096
  type autoNATService (line 29) | type autoNATService struct
    method handleStream (line 53) | func (as *autoNATService) handleStream(s network.Stream) {
    method handleDial (line 108) | func (as *autoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, ...
    method doDial (line 207) | func (as *autoNATService) doDial(pi peer.AddrInfo) *pb.Message_DialRes...
    method Enable (line 250) | func (as *autoNATService) Enable() {
    method Disable (line 265) | func (as *autoNATService) Disable() {
    method Close (line 276) | func (as *autoNATService) Close() error {
    method background (line 281) | func (as *autoNATService) background(ctx context.Context) {
  function newAutoNATService (line 43) | func newAutoNATService(c *config) (*autoNATService, error) {

FILE: p2p/host/autonat/svc_test.go
  function makeAutoNATConfig (line 18) | func makeAutoNATConfig(t *testing.T) *config {
  function makeAutoNATService (line 28) | func makeAutoNATService(t *testing.T, c *config) *autoNATService {
  function makeAutoNATClient (line 38) | func makeAutoNATClient(t *testing.T) (host.Host, Client) {
  function TestAutoNATServiceDialRefused (line 45) | func TestAutoNATServiceDialRefused(t *testing.T) {
  function TestAutoNATServiceDialSuccess (line 69) | func TestAutoNATServiceDialSuccess(t *testing.T) {
  function TestAutoNATServiceDialRateLimiter (line 88) | func TestAutoNATServiceDialRateLimiter(t *testing.T) {
  function TestAutoNATServiceGlobalLimiter (line 127) | func TestAutoNATServiceGlobalLimiter(t *testing.T) {
  function TestAutoNATServiceRateLimitJitter (line 166) | func TestAutoNATServiceRateLimitJitter(t *testing.T) {
  function TestAutoNATServiceStartup (line 191) | func TestAutoNATServiceStartup(t *testing.T) {

FILE: p2p/host/autonat/test/autonat_test.go
  function TestAutonatRoundtrip (line 18) | func TestAutonatRoundtrip(t *testing.T) {

FILE: p2p/host/autorelay/addrsplosion.go
  function cleanupAddressSet (line 15) | func cleanupAddressSet(addrs []ma.Multiaddr) []ma.Multiaddr {
  function isRelayAddr (line 41) | func isRelayAddr(a ma.Multiaddr) bool {
  function hasAddrsplosion (line 59) | func hasAddrsplosion(addrs []ma.Multiaddr) bool {
  function addrKeyAndPort (line 74) | func addrKeyAndPort(a ma.Multiaddr) (string, int) {
  function sanitizeAddrsplodedSet (line 106) | func sanitizeAddrsplodedSet(public, private []ma.Multiaddr) []ma.Multiad...

FILE: p2p/host/autorelay/addrsplosion_test.go
  function TestCleanupAddrs (line 10) | func TestCleanupAddrs(t *testing.T) {
  function makeAddrList (line 86) | func makeAddrList(strs ...string) []ma.Multiaddr {

FILE: p2p/host/autorelay/autorelay.go
  type AutoRelay (line 19) | type AutoRelay struct
    method Start (line 56) | func (r *AutoRelay) Start() {
    method background (line 64) | func (r *AutoRelay) background() {
    method Close (line 102) | func (r *AutoRelay) Close() error {
  function NewAutoRelay (line 34) | func NewAutoRelay(host host.Host, opts ...Option) (*AutoRelay, error) {

FILE: p2p/host/autorelay/autorelay_test.go
  constant protoIDv2 (line 26) | protoIDv2 = circuitv2_proto.ProtoIDv2Hop
  type mockClock (line 28) | type mockClock struct
    method InstantTimer (line 32) | func (c mockClock) InstantTimer(when time.Time) autorelay.InstantTimer {
  function newMockClock (line 36) | func newMockClock() mockClock {
  function numRelays (line 42) | func numRelays(h host.Host) int {
  function usedRelays (line 46) | func usedRelays(h host.Host) []peer.ID {
  function newPrivateNode (line 70) | func newPrivateNode(t *testing.T, peerSource func(context.Context, int) ...
  function newPrivateNodeWithStaticRelays (line 81) | func newPrivateNodeWithStaticRelays(t *testing.T, static []peer.AddrInfo...
  function newRelay (line 91) | func newRelay(t *testing.T) host.Host {
  function TestSingleCandidate (line 118) | func TestSingleCandidate(t *testing.T) {
  function TestSingleRelay (line 144) | func TestSingleRelay(t *testing.T) {
  function TestWaitForCandidates (line 174) | func TestWaitForCandidates(t *testing.T) {
  function TestBackoff (line 199) | func TestBackoff(t *testing.T) {
  function TestStaticRelays (line 270) | func TestStaticRelays(t *testing.T) {
  function TestConnectOnDisconnect (line 288) | func TestConnectOnDisconnect(t *testing.T) {
  function TestMaxAge (line 325) | func TestMaxAge(t *testing.T) {
  function TestReconnectToStaticRelays (line 422) | func TestReconnectToStaticRelays(t *testing.T) {
  function TestMinInterval (line 463) | func TestMinInterval(t *testing.T) {
  function TestNoBusyLoop0MinInterval (line 489) | func TestNoBusyLoop0MinInterval(t *testing.T) {
  function TestAutoRelayAddrsEvent (line 519) | func TestAutoRelayAddrsEvent(t *testing.T) {

FILE: p2p/host/autorelay/metrics.go
  constant metricNamespace (line 12) | metricNamespace = "libp2p_autorelay"
  type candidateLoopState (line 114) | type candidateLoopState
  constant peerSourceRateLimited (line 117) | peerSourceRateLimited candidateLoopState = iota
  constant waitingOnPeerChan (line 118) | waitingOnPeerChan
  constant waitingForTrigger (line 119) | waitingForTrigger
  constant stopped (line 120) | stopped
  type MetricsTracer (line 124) | type MetricsTracer interface
  type metricsTracer (line 144) | type metricsTracer struct
    method RelayFinderStatus (line 178) | func (mt *metricsTracer) RelayFinderStatus(isActive bool) {
    method ReservationEnded (line 186) | func (mt *metricsTracer) ReservationEnded(cnt int) {
    method ReservationOpened (line 190) | func (mt *metricsTracer) ReservationOpened(cnt int) {
    method ReservationRequestFinished (line 194) | func (mt *metricsTracer) ReservationRequestFinished(isRefresh bool, er...
    method RelayAddressUpdated (line 211) | func (mt *metricsTracer) RelayAddressUpdated() {
    method RelayAddressCount (line 215) | func (mt *metricsTracer) RelayAddressCount(cnt int) {
    method CandidateChecked (line 219) | func (mt *metricsTracer) CandidateChecked(supportsCircuitV2 bool) {
    method CandidateAdded (line 230) | func (mt *metricsTracer) CandidateAdded(cnt int) {
    method CandidateRemoved (line 237) | func (mt *metricsTracer) CandidateRemoved(cnt int) {
    method CandidateLoopState (line 244) | func (mt *metricsTracer) CandidateLoopState(state candidateLoopState) {
    method ScheduledWorkUpdated (line 248) | func (mt *metricsTracer) ScheduledWorkUpdated(scheduledWork *scheduled...
    method DesiredReservations (line 268) | func (mt *metricsTracer) DesiredReservations(cnt int) {
  type metricsTracerSetting (line 148) | type metricsTracerSetting struct
  type MetricsTracerOption (line 152) | type MetricsTracerOption
  function WithRegisterer (line 154) | func WithRegisterer(reg prometheus.Registerer) MetricsTracerOption {
  function NewMetricsTracer (line 162) | func NewMetricsTracer(opts ...MetricsTracerOption) MetricsTracer {
  function getReservationRequestStatus (line 272) | func getReservationRequestStatus(err error) string {
  type wrappedMetricsTracer (line 297) | type wrappedMetricsTracer struct
    method RelayFinderStatus (line 303) | func (mt *wrappedMetricsTracer) RelayFinderStatus(isActive bool) {
    method ReservationEnded (line 309) | func (mt *wrappedMetricsTracer) ReservationEnded(cnt int) {
    method ReservationOpened (line 315) | func (mt *wrappedMetricsTracer) ReservationOpened(cnt int) {
    method ReservationRequestFinished (line 321) | func (mt *wrappedMetricsTracer) ReservationRequestFinished(isRefresh b...
    method RelayAddressUpdated (line 327) | func (mt *wrappedMetricsTracer) RelayAddressUpdated() {
    method RelayAddressCount (line 333) | func (mt *wrappedMetricsTracer) RelayAddressCount(cnt int) {
    method CandidateChecked (line 339) | func (mt *wrappedMetricsTracer) CandidateChecked(supportsCircuitV2 boo...
    method CandidateAdded (line 345) | func (mt *wrappedMetricsTracer) CandidateAdded(cnt int) {
    method CandidateRemoved (line 351) | func (mt *wrappedMetricsTracer) CandidateRemoved(cnt int) {
    method ScheduledWorkUpdated (line 357) | func (mt *wrappedMetricsTracer) ScheduledWorkUpdated(scheduledWork *sc...
    method DesiredReservations (line 363) | func (mt *wrappedMetricsTracer) DesiredReservations(cnt int) {
    method CandidateLoopState (line 369) | func (mt *wrappedMetricsTracer) CandidateLoopState(state candidateLoop...

FILE: p2p/host/autorelay/metrics_noalloc_test.go
  function getRandScheduledWork (line 14) | func getRandScheduledWork() scheduledWorkTimes {
  function TestMetricsNoAllocNoCover (line 27) | func TestMetricsNoAllocNoCover(t *testing.T) {

FILE: p2p/host/autorelay/options.go
  type PeerSource (line 22) | type PeerSource
  type config (line 24) | type config struct
  type Option (line 62) | type Option
  function WithStaticRelays (line 64) | func WithStaticRelays(static []peer.AddrInfo) Option {
  function WithPeerSource (line 91) | func WithPeerSource(f PeerSource) Option {
  function WithNumRelays (line 102) | func WithNumRelays(n int) Option {
  function WithMaxCandidates (line 110) | func WithMaxCandidates(n int) Option {
  function WithMinCandidates (line 123) | func WithMinCandidates(n int) Option {
  function WithBootDelay (line 138) | func WithBootDelay(d time.Duration) Option {
  function WithBackoff (line 146) | func WithBackoff(d time.Duration) Option {
  function WithMaxCandidateAge (line 158) | func WithMaxCandidateAge(d time.Duration) Option {
  type InstantTimer (line 166) | type InstantTimer interface
  type ClockWithInstantTimer (line 174) | type ClockWithInstantTimer interface
  type RealTimer (line 180) | type RealTimer struct
    method Ch (line 184) | func (t RealTimer) Ch() <-chan time.Time {
    method Reset (line 188) | func (t RealTimer) Reset(d time.Time) bool {
    method Stop (line 192) | func (t RealTimer) Stop() bool {
  type RealClock (line 196) | type RealClock struct
    method Now (line 200) | func (RealClock) Now() time.Time {
    method Since (line 203) | func (RealClock) Since(t time.Time) time.Duration {
    method InstantTimer (line 206) | func (RealClock) InstantTimer(when time.Time) InstantTimer {
  function WithClock (line 211) | func WithClock(cl ClockWithInstantTimer) Option {
  function WithMinInterval (line 220) | func WithMinInterval(interval time.Duration) Option {
  function WithMetricsTracer (line 228) | func WithMetricsTracer(mt MetricsTracer) Option {

FILE: p2p/host/autorelay/relay_finder.go
  constant protoIDv2 (line 27) | protoIDv2 = circuitv2_proto.ProtoIDv2Hop
  constant rsvpRefreshInterval (line 38) | rsvpRefreshInterval = time.Minute
  constant rsvpExpirationSlack (line 39) | rsvpExpirationSlack = 2 * time.Minute
  constant autorelayTag (line 41) | autorelayTag  = "autorelay"
  constant maxRelayAddrs (line 42) | maxRelayAddrs = 100
  type candidate (line 45) | type candidate struct
  type relayFinder (line 52) | type relayFinder struct
    method cleanupDisconnectedPeers (line 129) | func (rf *relayFinder) cleanupDisconnectedPeers(ctx context.Context) {
    method background (line 168) | func (rf *relayFinder) background(ctx context.Context) {
    method updateAddrs (line 237) | func (rf *relayFinder) updateAddrs() {
    method getCircuitAddrs (line 253) | func (rf *relayFinder) getCircuitAddrs() []ma.Multiaddr {
    method runScheduledWork (line 275) | func (rf *relayFinder) runScheduledWork(ctx context.Context, now time....
    method clearOldCandidates (line 331) | func (rf *relayFinder) clearOldCandidates(now time.Time) time.Time {
    method clearBackoff (line 359) | func (rf *relayFinder) clearBackoff(now time.Time) time.Time {
    method findNodes (line 384) | func (rf *relayFinder) findNodes(ctx context.Context, peerSourceRateLi...
    method notifyMaybeConnectToRelay (line 451) | func (rf *relayFinder) notifyMaybeConnectToRelay() {
    method notifyMaybeNeedNewCandidates (line 458) | func (rf *relayFinder) notifyMaybeNeedNewCandidates() {
    method notifyNewCandidate (line 465) | func (rf *relayFinder) notifyNewCandidate() {
    method notifyRelayReservationUpdated (line 472) | func (rf *relayFinder) notifyRelayReservationUpdated() {
    method handleNewNode (line 483) | func (rf *relayFinder) handleNewNode(ctx context.Context, pi peer.Addr...
    method tryNode (line 522) | func (rf *relayFinder) tryNode(ctx context.Context, pi peer.AddrInfo) ...
    method handleNewCandidates (line 573) | func (rf *relayFinder) handleNewCandidates(ctx context.Context) {
    method maybeConnectToRelay (line 584) | func (rf *relayFinder) maybeConnectToRelay(ctx context.Context) {
    method connectToRelay (line 648) | func (rf *relayFinder) connectToRelay(ctx context.Context, cand *candi...
    method refreshReservations (line 682) | func (rf *relayFinder) refreshReservations(ctx context.Context, now ti...
    method refreshRelayReservation (line 705) | func (rf *relayFinder) refreshRelayReservation(ctx context.Context, p ...
    method usingRelay (line 729) | func (rf *relayFinder) usingRelay(p peer.ID) bool {
    method addCandidate (line 735) | func (rf *relayFinder) addCandidate(cand *candidate) {
    method removeCandidate (line 743) | func (rf *relayFinder) removeCandidate(id peer.ID) {
    method selectCandidates (line 753) | func (rf *relayFinder) selectCandidates() []*candidate {
    method Start (line 770) | func (rf *relayFinder) Start() error {
    method Stop (line 790) | func (rf *relayFinder) Stop() error {
    method initMetrics (line 804) | func (rf *relayFinder) initMetrics() {
    method resetMetrics (line 816) | func (rf *relayFinder) resetMetrics() {
  function newRelayFinder (line 93) | func newRelayFinder(host host.Host, conf *config) (*relayFinder, error) {
  type scheduledWorkTimes (line 121) | type scheduledWorkTimes struct
  function areSortedAddrsDifferent (line 829) | func areSortedAddrsDifferent(a, b []ma.Multiaddr) bool {

FILE: p2p/host/basic/addrs_manager.go
  constant maxObservedAddrsPerListenAddr (line 25) | maxObservedAddrsPerListenAddr = 3
  constant maxPeerRecordSize (line 30) | maxPeerRecordSize = 8 * 1024
  type addrStore (line 33) | type addrStore interface
  type ObservedAddrsManager (line 38) | type ObservedAddrsManager interface
  type hostAddrs (line 43) | type hostAddrs struct
  type addrsManager (line 52) | type addrsManager struct
    method Start (line 137) | func (a *addrsManager) Start() error {
    method Close (line 154) | func (a *addrsManager) Close() {
    method NetNotifee (line 171) | func (a *addrsManager) NetNotifee() network.Notifiee {
    method updateAddrsSync (line 178) | func (a *addrsManager) updateAddrsSync() {
    method startBackgroundWorker (line 194) | func (a *addrsManager) startBackgroundWorker() (retErr error) {
    method background (line 231) | func (a *addrsManager) background(
    method updateAddrs (line 309) | func (a *addrsManager) updateAddrs(prevHostAddrs hostAddrs, relayAddrs...
    method updatePeerStore (line 345) | func (a *addrsManager) updatePeerStore(currentAddrs []ma.Multiaddr, re...
    method notifyAddrsUpdated (line 369) | func (a *addrsManager) notifyAddrsUpdated(emitter event.Emitter, local...
    method Addrs (line 409) | func (a *addrsManager) Addrs() []ma.Multiaddr {
    method getDialableAddrs (line 418) | func (a *addrsManager) getDialableAddrs(localAddrs, reachableAddrs, un...
    method applyAddrsFactory (line 437) | func (a *addrsManager) applyAddrsFactory(addrs []ma.Multiaddr) []ma.Mu...
    method HolePunchAddrs (line 449) | func (a *addrsManager) HolePunchAddrs() []ma.Multiaddr {
    method DirectAddrs (line 463) | func (a *addrsManager) DirectAddrs() []ma.Multiaddr {
    method ConfirmedAddrs (line 470) | func (a *addrsManager) ConfirmedAddrs() (reachable []ma.Multiaddr, unr...
    method getConfirmedAddrs (line 476) | func (a *addrsManager) getConfirmedAddrs(localAddrs []ma.Multiaddr) (r...
    method getLocalAddrs (line 483) | func (a *addrsManager) getLocalAddrs() []ma.Multiaddr {
    method appendInterfaceAddrs (line 521) | func (a *addrsManager) appendInterfaceAddrs(dst []ma.Multiaddr, listen...
    method appendNATAddrs (line 533) | func (a *addrsManager) appendNATAddrs(dst []ma.Multiaddr, listenAddrs ...
    method appendObservedAddrs (line 543) | func (a *addrsManager) appendObservedAddrs(dst []ma.Multiaddr, listenA...
    method makeSignedPeerRecord (line 572) | func (a *addrsManager) makeSignedPeerRecord(addrs []ma.Multiaddr) (*re...
    method emitLocalAddrsUpdated (line 596) | func (a *addrsManager) emitLocalAddrsUpdated(emitter event.Emitter, cu...
  function newAddrsManager (line 84) | func newAddrsManager(
  function areAddrsDifferent (line 641) | func areAddrsDifferent(prev, current []ma.Multiaddr) bool {
  function diffAddrs (line 660) | func diffAddrs(prev, current []ma.Multiaddr) (added, maintained, removed...
  function trimHostAddrList (line 688) | func trimHostAddrList(addrs []ma.Multiaddr, maxSize int) []ma.Multiaddr {
  constant interfaceAddrsCacheTTL (line 740) | interfaceAddrsCacheTTL = time.Minute
  type interfaceAddrsCache (line 742) | type interfaceAddrsCache struct
    method All (line 748) | func (i *interfaceAddrsCache) All() []ma.Multiaddr {
    method update (line 758) | func (i *interfaceAddrsCache) update() []ma.Multiaddr {
    method updateUnlocked (line 769) | func (i *interfaceAddrsCache) updateUnlocked() {
  function removeNotInSource (line 788) | func removeNotInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
  function removeInSource (line 818) | func removeInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
  type multiCloser (line 844) | type multiCloser
    method Close (line 846) | func (mc *multiCloser) Close() error {

FILE: p2p/host/basic/addrs_manager_test.go
  type mockNatManager (line 27) | type mockNatManager struct
    method Close (line 31) | func (*mockNatManager) Close() error {
    method GetMapping (line 35) | func (m *mockNatManager) GetMapping(addr ma.Multiaddr) ma.Multiaddr {
    method HasDiscoveredNAT (line 42) | func (*mockNatManager) HasDiscoveredNAT() bool {
  type mockObservedAddrs (line 48) | type mockObservedAddrs struct
    method Addrs (line 53) | func (m *mockObservedAddrs) Addrs(int) []ma.Multiaddr { return m.Addrs...
    method AddrsFor (line 55) | func (m *mockObservedAddrs) AddrsFor(local ma.Multiaddr) []ma.Multiadd...
  type addrStoreArgs (line 59) | type addrStoreArgs struct
  type addrsManagerArgs (line 66) | type addrsManagerArgs struct
  type addrsManagerTestCase (line 77) | type addrsManagerTestCase struct
  function newAddrsManagerTestCase (line 83) | func newAddrsManagerTestCase(tb testing.TB, args addrsManagerArgs) addrs...
  function TestAddrsManager (line 148) | func TestAddrsManager(t *testing.T) {
  function TestAddrsManagerReachabilityEvent (line 389) | func TestAddrsManagerReachabilityEvent(t *testing.T) {
  function TestAddrsManagerPeerstoreUpdated (line 450) | func TestAddrsManagerPeerstoreUpdated(t *testing.T) {
  function TestRemoveIfNotInSource (line 491) | func TestRemoveIfNotInSource(t *testing.T) {
  function BenchmarkAreAddrsDifferent (line 518) | func BenchmarkAreAddrsDifferent(b *testing.B) {
  function BenchmarkRemoveIfNotInSource (line 532) | func BenchmarkRemoveIfNotInSource(b *testing.B) {

FILE: p2p/host/basic/addrs_metrics.go
  constant metricNamespace (line 12) | metricNamespace = "libp2p_host_addrs"
  type MetricsTracker (line 47) | type MetricsTracker interface
  type metricsTracker (line 54) | type metricsTracker struct
    method ReachabilityTrackerClosed (line 102) | func (t *metricsTracker) ReachabilityTrackerClosed() {
    method ConfirmedAddrsChanged (line 109) | func (t *metricsTracker) ConfirmedAddrsChanged(reachable, unreachable,...
  type metricsTrackerSetting (line 65) | type metricsTrackerSetting struct
  type metricsTrackerOption (line 69) | type metricsTrackerOption
  function withRegisterer (line 72) | func withRegisterer(reg prometheus.Registerer) metricsTrackerOption {
  type metricKey (line 80) | type metricKey struct
  function newMetricsTracker (line 86) | func newMetricsTracker(opts ...metricsTrackerOption) MetricsTracker {
  function updateMetric (line 115) | func updateMetric(metric *prometheus.GaugeVec, addrs []ma.Multiaddr, cur...
  function resetMetric (line 144) | func resetMetric(metric *prometheus.GaugeVec, current map[metricKey]int,...

FILE: p2p/host/basic/addrs_metrics_test.go
  function TestMetricsNoAllocNoCover (line 13) | func TestMetricsNoAllocNoCover(t *testing.T) {

FILE: p2p/host/basic/addrs_reachability_tracker.go
  type autonatv2Client (line 20) | type autonatv2Client interface
  constant maxAddrsPerRequest (line 27) | maxAddrsPerRequest = 10
  constant maxTrackedAddrs (line 30) | maxTrackedAddrs = 50
  constant defaultMaxConcurrency (line 32) | defaultMaxConcurrency = 5
  constant newAddrsProbeDelay (line 34) | newAddrsProbeDelay = 1 * time.Second
  type addrsReachabilityTracker (line 40) | type addrsReachabilityTracker struct
    method UpdateAddrs (line 82) | func (r *addrsReachabilityTracker) UpdateAddrs(addrs []ma.Multiaddr) {
    method ConfirmedAddrs (line 89) | func (r *addrsReachabilityTracker) ConfirmedAddrs() (reachableAddrs, u...
    method Start (line 95) | func (r *addrsReachabilityTracker) Start() error {
    method Close (line 101) | func (r *addrsReachabilityTracker) Close() error {
    method background (line 121) | func (r *addrsReachabilityTracker) background() {
    method appendConfirmedAddrs (line 209) | func (r *addrsReachabilityTracker) appendConfirmedAddrs(reachable, unr...
    method notify (line 220) | func (r *addrsReachabilityTracker) notify() {
    method updateTrackedAddrs (line 227) | func (r *addrsReachabilityTracker) updateTrackedAddrs(addrs []ma.Multi...
    method refreshReachability (line 251) | func (r *addrsReachabilityTracker) refreshReachability() reachabilityT...
  function newAddrsReachabilityTracker (line 63) | func newAddrsReachabilityTracker(client autonatv2Client, reachabilityUpd...
  constant defaultReachabilityRefreshInterval (line 112) | defaultReachabilityRefreshInterval = 5 * time.Minute
  constant maxBackoffInterval (line 116) | maxBackoffInterval = 5 * time.Minute
  constant backoffStartInterval (line 118) | backoffStartInterval = 5 * time.Second
  function newBackoffInterval (line 198) | func newBackoffInterval(current time.Duration) time.Duration {
  constant probeTimeout (line 240) | probeTimeout = 30 * time.Second
  type reachabilityTask (line 244) | type reachabilityTask struct
  type errCountingClient (line 304) | type errCountingClient struct
    method GetReachability (line 311) | func (c *errCountingClient) GetReachability(ctx context.Context, reqs ...
  constant maxConsecutiveErrors (line 329) | maxConsecutiveErrors = 20
  function isErrorPersistent (line 332) | func isErrorPersistent(err error) bool {
  constant recentProbeInterval (line 344) | recentProbeInterval = 10 * time.Minute
  constant maxConsecutiveRefusals (line 347) | maxConsecutiveRefusals = 5
  constant maxRecentDialsPerAddr (line 350) | maxRecentDialsPerAddr = 10
  constant targetConfidence (line 354) | targetConfidence = 3
  constant minConfidence (line 357) | minConfidence = 2
  constant maxRecentDialsWindow (line 363) | maxRecentDialsWindow = targetConfidence + 2
  constant highConfidenceAddrProbeInterval (line 365) | highConfidenceAddrProbeInterval = 1 * time.Hour
  constant highConfidenceSecondaryAddrProbeInterval (line 367) | highConfidenceSecondaryAddrProbeInterval = 3 * time.Hour
  constant maxProbeResultTTL (line 369) | maxProbeResultTTL = maxRecentDialsWindow * highConfidenceAddrProbeInterval
  type probeManager (line 378) | type probeManager struct
    method AppendConfirmedAddrs (line 399) | func (m *probeManager) AppendConfirmedAddrs(reachable, unreachable, un...
    method UpdateAddrs (line 432) | func (m *probeManager) UpdateAddrs(addrs []ma.Multiaddr) {
    method GetProbe (line 464) | func (m *probeManager) GetProbe() probe {
    method getFirstProbeAddrIdx (line 501) | func (m *probeManager) getFirstProbeAddrIdx(addrs []ma.Multiaddr, now ...
    method appendRequestsToProbe (line 514) | func (m *probeManager) appendRequestsToProbe(reqs probe, addrs []ma.Mu...
    method MarkProbeInProgress (line 536) | func (m *probeManager) MarkProbeInProgress(reqs probe) {
    method InProgressProbes (line 547) | func (m *probeManager) InProgressProbes() int {
    method CompleteProbe (line 554) | func (m *probeManager) CompleteProbe(reqs probe, res autonatv2.Result,...
  function newProbeManager (line 390) | func newProbeManager(now func() time.Time) *probeManager {
  type dialOutcome (line 599) | type dialOutcome struct
  type addrStatus (line 604) | type addrStatus struct
    method Reachability (line 613) | func (s *addrStatus) Reachability() network.Reachability {
    method RequiredProbeCount (line 618) | func (s *addrStatus) RequiredProbeCount(now time.Time) int {
    method requiredProbeCountForConfirmation (line 650) | func (s *addrStatus) requiredProbeCountForConfirmation(now time.Time) ...
    method AddRefusal (line 689) | func (s *addrStatus) AddRefusal(now time.Time) {
    method AddOutcome (line 694) | func (s *addrStatus) AddOutcome(at time.Time, rch network.Reachability...
    method RemoveBefore (line 723) | func (s *addrStatus) RemoveBefore(t time.Time) {
    method recentDialCount (line 733) | func (s *addrStatus) recentDialCount(now time.Time) int {
    method reachabilityAndCounts (line 744) | func (s *addrStatus) reachabilityAndCounts() (rch network.Reachability...
  function thinWaistPart (line 809) | func thinWaistPart(a ma.Multiaddr) (ma.Multiaddr, error) {
  function assignPrimaryAddrs (line 819) | func assignPrimaryAddrs(statuses map[string]*addrStatus) {

FILE: p2p/host/basic/addrs_reachability_tracker_test.go
  function TestProbeManager (line 27) | func TestProbeManager(t *testing.T) {
  type mockAutoNATClient (line 297) | type mockAutoNATClient struct
    method GetReachability (line 301) | func (m mockAutoNATClient) GetReachability(ctx context.Context, reqs [...
  function TestAddrsReachabilityTracker (line 307) | func TestAddrsReachabilityTracker(t *testing.T) {
  function TestRefreshReachability (line 601) | func TestRefreshReachability(t *testing.T) {
  function TestAddrStatusProbeCount (line 749) | func TestAddrStatusProbeCount(t *testing.T) {
  function TestAssignPrimaryAddress (line 822) | func TestAssignPrimaryAddress(t *testing.T) {
  function BenchmarkAddrTracker (line 880) | func BenchmarkAddrTracker(b *testing.B) {
  function FuzzAddrsReachabilityTracker (line 902) | func FuzzAddrsReachabilityTracker(f *testing.F) {

FILE: p2p/host/basic/basic_host.go
  type AddrsFactory (line 47) | type AddrsFactory
  type BasicHost (line 54) | type BasicHost struct
    method Start (line 295) | func (h *BasicHost) Start() {
    method newStreamHandler (line 315) | func (h *BasicHost) newStreamHandler(s network.Stream) {
    method ID (line 362) | func (h *BasicHost) ID() peer.ID {
    method Peerstore (line 367) | func (h *BasicHost) Peerstore() peerstore.Peerstore {
    method Network (line 372) | func (h *BasicHost) Network() network.Network {
    method Mux (line 377) | func (h *BasicHost) Mux() protocol.Switch {
    method IDService (line 382) | func (h *BasicHost) IDService() identify.IDService {
    method EventBus (line 386) | func (h *BasicHost) EventBus() event.Bus {
    method SetStreamHandler (line 396) | func (h *BasicHost) SetStreamHandler(pid protocol.ID, handler network....
    method SetStreamHandlerMatch (line 409) | func (h *BasicHost) SetStreamHandlerMatch(pid protocol.ID, m func(prot...
    method RemoveStreamHandler (line 421) | func (h *BasicHost) RemoveStreamHandler(pid protocol.ID) {
    method NewStream (line 432) | func (h *BasicHost) NewStream(ctx context.Context, p peer.ID, pids ......
    method preferredProtocol (line 518) | func (h *BasicHost) preferredProtocol(p peer.ID, pids []protocol.ID) (...
    method Connect (line 536) | func (h *BasicHost) Connect(ctx context.Context, pi peer.AddrInfo) err...
    method dialPeer (line 554) | func (h *BasicHost) dialPeer(ctx context.Context, p peer.ID) error {
    method ConnManager (line 576) | func (h *BasicHost) ConnManager() connmgr.ConnManager {
    method Addrs (line 584) | func (h *BasicHost) Addrs() []ma.Multiaddr {
    method AllAddrs (line 589) | func (h *BasicHost) AllAddrs() []ma.Multiaddr {
    method ConfirmedAddrs (line 599) | func (h *BasicHost) ConfirmedAddrs() (reachable []ma.Multiaddr, unreac...
    method SetAutoNat (line 604) | func (h *BasicHost) SetAutoNat(a autonat.AutoNAT) {
    method GetAutoNat (line 615) | func (h *BasicHost) GetAutoNat() autonat.AutoNAT {
    method Reachability (line 622) | func (h *BasicHost) Reachability() network.Reachability {
    method Close (line 627) | func (h *BasicHost) Close() error {
  type HostOpts (line 89) | type HostOpts struct
  function NewHost (line 149) | func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) {
  type streamWrapper (line 672) | type streamWrapper struct
    method Read (line 677) | func (s *streamWrapper) Read(b []byte) (int, error) {
    method Write (line 681) | func (s *streamWrapper) Write(b []byte) (int, error) {
    method Close (line 685) | func (s *streamWrapper) Close() error {
    method CloseWrite (line 694) | func (s *streamWrapper) CloseWrite() error {

FILE: p2p/host/basic/basic_host_synctest_test.go
  function TestStreamCloseDoesNotHangOnUnresponsivePeer_synctest (line 21) | func TestStreamCloseDoesNotHangOnUnresponsivePeer_synctest(t *testing.T) {

FILE: p2p/host/basic/basic_host_test.go
  function TestHostDoubleClose (line 35) | func TestHostDoubleClose(t *testing.T) {
  function TestHostSimple (line 42) | func TestHostSimple(t *testing.T) {
  function TestMultipleClose (line 85) | func TestMultipleClose(t *testing.T) {
  function TestSignedPeerRecordWithNoListenAddrs (line 102) | func TestSignedPeerRecordWithNoListenAddrs(t *testing.T) {
  function TestProtocolHandlerEvents (line 128) | func TestProtocolHandlerEvents(t *testing.T) {
  function TestHostAddrsFactory (line 182) | func TestHostAddrsFactory(t *testing.T) {
  function TestAllAddrs (line 211) | func TestAllAddrs(t *testing.T) {
  function TestAllAddrsUnique (line 234) | func TestAllAddrsUnique(t *testing.T) {
  function getHostPair (line 293) | func getHostPair(t *testing.T) (host.Host, host.Host) {
  function assertWait (line 310) | func assertWait(t *testing.T, c chan protocol.ID, exp protocol.ID) {
  function TestHostProtoPreference (line 322) | func TestHostProtoPreference(t *testing.T) {
  function TestHostProtoMismatch (line 377) | func TestHostProtoMismatch(t *testing.T) {
  function TestHostProtoPreknowledge (line 395) | func TestHostProtoPreknowledge(t *testing.T) {
  function TestNewDialOld (line 465) | func TestNewDialOld(t *testing.T) {
  function TestNewStreamResolve (line 489) | func TestNewStreamResolve(t *testing.T) {
  function TestProtoDowngrade (line 536) | func TestProtoDowngrade(t *testing.T) {
  function TestAddrChangeImmediatelyIfAddressNonEmpty (line 591) | func TestAddrChangeImmediatelyIfAddressNonEmpty(t *testing.T) {
  function TestStatefulAddrEvents (line 632) | func TestStatefulAddrEvents(t *testing.T) {
  function TestHostAddrChangeDetection (line 652) | func TestHostAddrChangeDetection(t *testing.T) {
  function TestNegotiationCancel (line 742) | func TestNegotiationCancel(t *testing.T) {
  function waitForAddrChangeEvent (line 784) | func waitForAddrChangeEvent(ctx context.Context, sub event.Subscription,...
  function updatedAddrsEqual (line 803) | func updatedAddrsEqual(a, b []event.UpdatedAddress) bool {
  function updatedAddrEventsEqual (line 834) | func updatedAddrEventsEqual(a, b event.EvtLocalAddressesUpdated) bool {
  function peerRecordFromEnvelope (line 840) | func peerRecordFromEnvelope(t *testing.T, ev *record.Envelope) *peer.Pee...
  function TestTrimHostAddrList (line 855) | func TestTrimHostAddrList(t *testing.T) {
  function TestHostTimeoutNewStream (line 907) | func TestHostTimeoutNewStream(t *testing.T) {

FILE: p2p/host/basic/mock_nat_test.go
  type MockNAT (line 21) | type MockNAT struct
    method EXPECT (line 40) | func (m *MockNAT) EXPECT() *MockNATMockRecorder {
    method AddMapping (line 45) | func (m *MockNAT) AddMapping(ctx context.Context, protocol string, por...
    method Close (line 59) | func (m *MockNAT) Close() error {
    method GetMapping (line 73) | func (m *MockNAT) GetMapping(protocol string, port int) (netip.AddrPor...
    method RemoveMapping (line 88) | func (m *MockNAT) RemoveMapping(ctx context.Context, protocol string, ...
  type MockNATMockRecorder (line 28) | type MockNATMockRecorder struct
    method AddMapping (line 53) | func (mr *MockNATMockRecorder) AddMapping(ctx, protocol, port any) *go...
    method Close (line 67) | func (mr *MockNATMockRecorder) Close() *gomock.Call {
    method GetMapping (line 82) | func (mr *MockNATMockRecorder) GetMapping(protocol, port any) *gomock....
    method RemoveMapping (line 96) | func (mr *MockNATMockRecorder) RemoveMapping(ctx, protocol, port any) ...
  function NewMockNAT (line 33) | func NewMockNAT(ctrl *gomock.Controller) *MockNAT {

FILE: p2p/host/basic/mocks.go
  type NAT (line 6) | type NAT

FILE: p2p/host/basic/natmgr.go
  type NATManager (line 21) | type NATManager interface
  function NewNATManager (line 28) | func NewNATManager(net network.Network) NATManager {
  type entry (line 32) | type entry struct
  type nat (line 37) | type nat interface
  type natManager (line 53) | type natManager struct
    method Close (line 83) | func (nmgr *natManager) Close() error {
    method HasDiscoveredNAT (line 89) | func (nmgr *natManager) HasDiscoveredNAT() bool {
    method background (line 95) | func (nmgr *natManager) background(ctx context.Context) {
    method sync (line 136) | func (nmgr *natManager) sync() {
    method doSync (line 145) | func (nmgr *natManager) doSync() {
    method GetMapping (line 217) | func (nmgr *natManager) GetMapping(addr ma.Multiaddr) ma.Multiaddr {
  function newNATManager (line 67) | func newNATManager(net network.Network) *natManager {
  type nmgrNetNotifiee (line 292) | type nmgrNetNotifiee
    method natManager (line 294) | func (nn *nmgrNetNotifiee) natManager() *natManager                   ...
    method Listen (line 295) | func (nn *nmgrNetNotifiee) Listen(network.Network, ma.Multiaddr)      ...
    method ListenClose (line 296) | func (nn *nmgrNetNotifiee) ListenClose(_ network.Network, _ ma.Multiad...
    method Connected (line 297) | func (nn *nmgrNetNotifiee) Connected(network.Network, network.Conn)   ...
    method Disconnected (line 298) | func (nn *nmgrNetNotifiee) Disconnected(network.Network, network.Conn)...

FILE: p2p/host/basic/natmgr_test.go
  function setupMockNAT (line 18) | func setupMockNAT(t *testing.T) (mockNAT *MockNAT, reset func()) {
  function TestMapping (line 30) | func TestMapping(t *testing.T) {
  function TestAddAndRemoveListeners (line 64) | func TestAddAndRemoveListeners(t *testing.T) {

FILE: p2p/host/blank/blank.go
  type BlankHost (line 28) | type BlankHost struct
    method initSignedRecord (line 94) | func (bh *BlankHost) initSignedRecord() error {
    method Addrs (line 116) | func (bh *BlankHost) Addrs() []ma.Multiaddr {
    method Close (line 126) | func (bh *BlankHost) Close() error {
    method Connect (line 130) | func (bh *BlankHost) Connect(ctx context.Context, ai peer.AddrInfo) er...
    method Peerstore (line 146) | func (bh *BlankHost) Peerstore() peerstore.Peerstore {
    method ID (line 150) | func (bh *BlankHost) ID() peer.ID {
    method NewStream (line 154) | func (bh *BlankHost) NewStream(ctx context.Context, p peer.ID, protos ...
    method RemoveStreamHandler (line 172) | func (bh *BlankHost) RemoveStreamHandler(pid protocol.ID) {
    method SetStreamHandler (line 179) | func (bh *BlankHost) SetStreamHandler(pid protocol.ID, handler network...
    method SetStreamHandlerMatch (line 191) | func (bh *BlankHost) SetStreamHandlerMatch(pid protocol.ID, m func(pro...
    method newStreamHandler (line 204) | func (bh *BlankHost) newStreamHandler(s network.Stream) {
    method Mux (line 218) | func (bh *BlankHost) Mux() protocol.Switch {
    method Network (line 223) | func (bh *BlankHost) Network() network.Network {
    method ConnManager (line 227) | func (bh *BlankHost) ConnManager() connmgr.ConnManager {
    method EventBus (line 231) | func (bh *BlankHost) EventBus() event.Bus {
  type config (line 38) | type config struct
  function WithConnectionManager (line 45) | func WithConnectionManager(cmgr connmgr.ConnManager) Option {
  function WithEventBus (line 51) | func WithEventBus(eventBus event.Bus) Option {
  function NewBlankHost (line 57) | func NewBlankHost(n network.Network, options ...Option) *BlankHost {

FILE: p2p/host/eventbus/basic.go
  constant slowConsumerWarningTimeout (line 17) | slowConsumerWarningTimeout = time.Second
  type basicBus (line 23) | type basicBus struct
    method withNode (line 76) | func (b *basicBus) withNode(typ reflect.Type, cb func(*node), async fu...
    method tryDropNode (line 100) | func (b *basicBus) tryDropNode(typ reflect.Type) {
    method Subscribe (line 210) | func (b *basicBus) Subscribe(evtTypes any, opts ...event.SubscriptionO...
    method Emitter (line 290) | func (b *basicBus) Emitter(evtType any, opts ...event.EmitterOpt) (e e...
    method GetAllEventTypes (line 318) | func (b *basicBus) GetAllEventTypes() []reflect.Type {
  type emitter (line 32) | type emitter struct
    method Emit (line 41) | func (e *emitter) Emit(evt any) error {
    method Close (line 55) | func (e *emitter) Close() error {
  function NewBus (line 65) | func NewBus(opts ...Option) event.Bus {
  type wildcardSub (line 120) | type wildcardSub struct
    method Out (line 128) | func (w *wildcardSub) Out() <-chan any {
    method Close (line 132) | func (w *wildcardSub) Close() error {
    method Name (line 143) | func (w *wildcardSub) Name() string {
  type namedSink (line 147) | type namedSink struct
  type sub (line 152) | type sub struct
    method Name (line 161) | func (s *sub) Name() string {
    method Out (line 165) | func (s *sub) Out() <-chan any {
    method Close (line 169) | func (s *sub) Close() error {
  type wildcardNode (line 332) | type wildcardNode struct
    method addSink (line 341) | func (n *wildcardNode) addSink(sink *namedSink) {
    method removeSink (line 352) | func (n *wildcardNode) removeSink(ch chan any) {
    method emit (line 373) | func (n *wildcardNode) emit(evt any) {
  type node (line 399) | type node struct
    method emit (line 424) | func (n *node) emit(evt any) {
  function newNode (line 417) | func newNode(typ reflect.Type, metricsTracer MetricsTracer) *node {
  function emitAndLogError (line 449) | func emitAndLogError(timer *time.Timer, typ reflect.Type, evt any, sink ...
  function sendSubscriberMetrics (line 471) | func sendSubscriberMetrics(metricsTracer MetricsTracer, sink *namedSink) {

FILE: p2p/host/eventbus/basic_metrics.go
  constant metricNamespace (line 12) | metricNamespace = "libp2p_eventbus"
  type MetricsTracer (line 65) | type MetricsTracer interface
  type metricsTracer (line 86) | type metricsTracer struct
    method EventEmitted (line 113) | func (m *metricsTracer) EventEmitted(typ reflect.Type) {
    method AddSubscriber (line 121) | func (m *metricsTracer) AddSubscriber(typ reflect.Type) {
    method RemoveSubscriber (line 129) | func (m *metricsTracer) RemoveSubscriber(typ reflect.Type) {
    method SubscriberQueueLength (line 137) | func (m *metricsTracer) SubscriberQueueLength(name string, n int) {
    method SubscriberQueueFull (line 145) | func (m *metricsTracer) SubscriberQueueFull(name string, isFull bool) {
    method SubscriberEventQueued (line 158) | func (m *metricsTracer) SubscriberEventQueued(name string) {
  type metricsTracerSetting (line 90) | type metricsTracerSetting struct
  type MetricsTracerOption (line 94) | type MetricsTracerOption
  function WithRegisterer (line 96) | func WithRegisterer(reg prometheus.Registerer) MetricsTracerOption {
  function NewMetricsTracer (line 104) | func NewMetricsTracer(opts ...MetricsTracerOption) MetricsTracer {

FILE: p2p/host/eventbus/basic_metrics_test.go
  function BenchmarkEventEmitted (line 13) | func BenchmarkEventEmitted(b *testing.B) {
  function BenchmarkSubscriberQueueLength (line 26) | func BenchmarkSubscriberQueueLength(b *testing.B) {
  function TestMetricsNoAllocNoCover (line 50) | func TestMetricsNoAllocNoCover(t *testing.T) {

FILE: p2p/host/eventbus/basic_test.go
  type EventA (line 23) | type EventA struct
    method String (line 35) | func (EventA) String() string {
  type EventB (line 24) | type EventB
  function getN (line 27) | func getN() int {
  function TestDefaultSubIsBuffered (line 39) | func TestDefaultSubIsBuffered(t *testing.T) {
  function TestEmit (line 50) | func TestEmit(t *testing.T) {
  function TestSub (line 71) | func TestSub(t *testing.T) {
  function TestGetAllEventTypes (line 103) | func TestGetAllEventTypes(t *testing.T) {
  function TestEmitNoSubNoBlock (line 127) | func TestEmitNoSubNoBlock(t *testing.T) {
  type mockLogger (line 139) | type mockLogger struct
    method Write (line 144) | func (m *mockLogger) Write(p []byte) (n int, err error) {
    method Logs (line 151) | func (m *mockLogger) Logs() []string {
    method Clear (line 157) | func (m *mockLogger) Clear() {
  function TestEmitLogsErrorOnStall (line 163) | func TestEmitLogsErrorOnStall(t *testing.T) {
  function TestEmitOnClosed (line 219) | func TestEmitOnClosed(t *testing.T) {
  function TestClosingRaces (line 236) | func TestClosingRaces(t *testing.T) {
  function TestSubMany (line 283) | func TestSubMany(t *testing.T) {
  function TestWildcardSubscription (line 324) | func TestWildcardSubscription(t *testing.T) {
  function TestManyWildcardSubscriptions (line 367) | func TestManyWildcardSubscriptions(t *testing.T) {
  function TestWildcardValidations (line 423) | func TestWildcardValidations(t *testing.T) {
  function TestSubType (line 433) | func TestSubType(t *testing.T) {
  function TestNonStateful (line 465) | func TestNonStateful(t *testing.T) {
  function TestStateful (line 509) | func TestStateful(t *testing.T) {
  function TestCloseBlocking (line 530) | func TestCloseBlocking(t *testing.T) {
  function TestSubFailFully (line 551) | func TestSubFailFully(t *testing.T) {
  function TestSubCloseMultiple (line 576) | func TestSubCloseMultiple(t *testing.T) {
  function testMany (line 587) | func testMany(t testing.TB, subs, emits, msgs int, stateful bool) {
  function TestBothMany (line 649) | func TestBothMany(t *testing.T) {
  type benchCase (line 653) | type benchCase struct
    method name (line 659) | func (bc benchCase) name() string {
  function genTestCases (line 663) | func genTestCases() []benchCase {
  function BenchmarkEvents (line 675) | func BenchmarkEvents(b *testing.B) {
  function benchMany (line 681) | func benchMany(bc benchCase) func(*testing.B) {
  function BenchmarkSubscribe (line 742) | func BenchmarkSubscribe(b *testing.B) {
  function BenchmarkEmitter (line 752) | func BenchmarkEmitter(b *testing.B) {
  function BenchmarkSubscribeAndEmitter (line 762) | func BenchmarkSubscribeAndEmitter(b *testing.B) {

FILE: p2p/host/eventbus/opts.go
  type subSettings (line 10) | type subSettings struct
  function newSubSettings (line 23) | func newSubSettings() subSettings {
  function BufSize (line 42) | func BufSize(n int) func(any) error {
  function Name (line 49) | func Name(name string) func(any) error {
  type emitterSettings (line 56) | type emitterSettings struct
  function Stateful (line 67) | func Stateful(s any) error {
  type Option (line 72) | type Option
  function WithMetricsTracer (line 74) | func WithMetricsTracer(metricsTracer MetricsTracer) Option {

FILE: p2p/host/observedaddrs/manager.go
  constant maxExternalThinWaistAddrsPerLocalAddr (line 40) | maxExternalThinWaistAddrsPerLocalAddr = 3
  type thinWaist (line 43) | type thinWaist struct
  function thinWaistForm (line 49) | func thinWaistForm(a ma.Multiaddr) (thinWaist, error) {
  function getObserver (line 62) | func getObserver(a ma.Multiaddr) (string, error) {
  type connMultiaddrs (line 75) | type connMultiaddrs interface
  constant observerSetCacheSize (line 82) | observerSetCacheSize = 10
  type observerSet (line 85) | type observerSet struct
    method cacheMultiaddr (line 93) | func (s *observerSet) cacheMultiaddr(addr ma.Multiaddr) ma.Multiaddr {
  type observation (line 126) | type observation struct
  type Manager (line 132) | type Manager struct
    method Start (line 188) | func (o *Manager) Start(n network.Network) {
    method AddrsFor (line 219) | func (o *Manager) AddrsFor(addr ma.Multiaddr) (addrs []ma.Multiaddr) {
    method appendInferredAddrs (line 244) | func (o *Manager) appendInferredAddrs(twToObserverSets map[string][]*o...
    method Addrs (line 272) | func (o *Manager) Addrs(minObservers int) []ma.Multiaddr {
    method getTopExternalAddrs (line 289) | func (o *Manager) getTopExternalAddrs(localTWStr string, minObservers ...
    method eventHandler (line 311) | func (o *Manager) eventHandler(identifySub event.Subscription, natEmit...
    method worker (line 352) | func (o *Manager) worker() {
    method shouldRecordObservation (line 364) | func (o *Manager) shouldRecordObservation(conn connMultiaddrs, observe...
    method maybeRecordObservation (line 422) | func (o *Manager) maybeRecordObservation(conn connMultiaddrs, observed...
    method recordObservationUnlocked (line 434) | func (o *Manager) recordObservationUnlocked(conn connMultiaddrs, local...
    method removeExternalAddrsUnlocked (line 460) | func (o *Manager) removeExternalAddrsUnlocked(observer, localTWStr, ob...
    method addExternalAddrsUnlocked (line 477) | func (o *Manager) addExternalAddrsUnlocked(observedTWAddr ma.Multiaddr...
    method removeConn (line 492) | func (o *Manager) removeConn(conn connMultiaddrs) {
    method getNATType (line 518) | func (o *Manager) getNATType() (tcpNATType, udpNATType network.NATDevi...
    method Close (line 578) | func (o *Manager) Close() error {
  function NewManager (line 156) | func NewManager(eventbus event.Bus, net network.Network) (*Manager, erro...
  function newManagerWithListenAddrs (line 174) | func newManagerWithListenAddrs(bus event.Bus, listenAddrs func() []ma.Mu...
  function hasConsistentTransport (line 587) | func hasConsistentTransport(aTW, bTW ma.Multiaddr) bool {
  function isRelayedAddress (line 599) | func isRelayedAddress(a ma.Multiaddr) bool {

FILE: p2p/host/observedaddrs/manager_glass_test.go
  type mockConn (line 16) | type mockConn struct
    method LocalMultiaddr (line 22) | func (c *mockConn) LocalMultiaddr() ma.Multiaddr {
    method RemoteMultiaddr (line 27) | func (c *mockConn) RemoteMultiaddr() ma.Multiaddr {
    method Close (line 31) | func (c *mockConn) Close() {
    method IsClosed (line 35) | func (c *mockConn) IsClosed() bool {
  function TestShouldRecordObservationWithWebTransport (line 39) | func TestShouldRecordObservationWithWebTransport(t *testing.T) {
  function TestShouldNotRecordObservationWithRelayedAddr (line 54) | func TestShouldNotRecordObservationWithRelayedAddr(t *testing.T) {
  function TestShouldRecordObservationWithNAT64Addr (line 69) | func TestShouldRecordObservationWithNAT64Addr(t *testing.T) {
  function TestThinWaistForm (line 119) | func TestThinWaistForm(t *testing.T) {

FILE: p2p/host/observedaddrs/manager_test.go
  function requireAddrsMatch (line 22) | func requireAddrsMatch(t *testing.T, a, b []ma.Multiaddr) {
  function requireEqualAddrs (line 29) | func requireEqualAddrs(t *testing.T, a, b []ma.Multiaddr) {
  function newConn (line 41) | func newConn(local, remote ma.Multiaddr) *mockConn {
  function TestObservedAddrsManager (line 45) | func TestObservedAddrsManager(t *testing.T) {
  function genIPMultiaddr (line 536) | func genIPMultiaddr(ip6 bool) ma.Multiaddr {
  function FuzzObservedAddrsManager (line 549) | func FuzzObservedAddrsManager(f *testing.F) {
  function TestObserver (line 607) | func TestObserver(t *testing.T) {

FILE: p2p/host/peerstore/metrics.go
  type metrics (line 15) | type metrics struct
    method RecordLatency (line 27) | func (m *metrics) RecordLatency(p peer.ID, next time.Duration) {
    method LatencyEWMA (line 48) | func (m *metrics) LatencyEWMA(p peer.ID) time.Duration {
    method RemovePeer (line 54) | func (m *metrics) RemovePeer(p peer.ID) {
  function NewMetrics (line 20) | func NewMetrics() *metrics {

FILE: p2p/host/peerstore/metrics_test.go
  function TestLatencyEWMAFun (line 12) | func TestLatencyEWMAFun(t *testing.T) {
  function TestLatencyEWMA (line 39) | func TestLatencyEWMA(t *testing.T) {

FILE: p2p/host/peerstore/peerstore.go
  function PeerInfos (line 8) | func PeerInfos(ps pstore.Peerstore, peers peer.IDSlice) []peer.AddrInfo {
  function PeerInfoIDs (line 16) | func PeerInfoIDs(pis []peer.AddrInfo) peer.IDSlice {

FILE: p2p/host/peerstore/pstoreds/addr_book.go
  type ttlWriteMode (line 26) | type ttlWriteMode
  constant ttlOverride (line 29) | ttlOverride ttlWriteMode = iota
  constant ttlExtend (line 30) | ttlExtend
  type addrsRecord (line 42) | type addrsRecord struct
    method flush (line 50) | func (r *addrsRecord) flush(write ds.Write) (err error) {
    method clean (line 87) | func (r *addrsRecord) clean(now time.Time) (chgd bool) {
    method hasExpiredAddrs (line 113) | func (r *addrsRecord) hasExpiredAddrs(now int64) bool {
  function removeExpired (line 120) | func removeExpired(entries []*pb.AddrBookRecord_AddrEntry, now int64) []...
  type dsAddrBook (line 136) | type dsAddrBook struct
    method Close (line 219) | func (ab *dsAddrBook) Close() error {
    method loadRecord (line 232) | func (ab *dsAddrBook) loadRecord(id peer.ID, cache bool, update bool) ...
    method AddAddr (line 270) | func (ab *dsAddrBook) AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.D...
    method AddAddrs (line 275) | func (ab *dsAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl ti...
    method ConsumePeerRecord (line 286) | func (ab *dsAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelop...
    method latestPeerRecordSeq (line 318) | func (ab *dsAddrBook) latestPeerRecordSeq(p peer.ID) uint64 {
    method storeSignedPeerRecord (line 335) | func (ab *dsAddrBook) storeSignedPeerRecord(p peer.ID, envelope *recor...
    method GetPeerRecord (line 362) | func (ab *dsAddrBook) GetPeerRecord(p peer.ID) *record.Envelope {
    method SetAddr (line 382) | func (ab *dsAddrBook) SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.D...
    method SetAddrs (line 387) | func (ab *dsAddrBook) SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl ti...
    method UpdateAddrs (line 398) | func (ab *dsAddrBook) UpdateAddrs(p peer.ID, oldTTL time.Duration, new...
    method Addrs (line 423) | func (ab *dsAddrBook) Addrs(p peer.ID) []ma.Multiaddr {
    method PeersWithAddrs (line 446) | func (ab *dsAddrBook) PeersWithAddrs() peer.IDSlice {
    method AddrStream (line 458) | func (ab *dsAddrBook) AddrStream(ctx context.Context, p peer.ID) <-cha...
    method ClearAddrs (line 464) | func (ab *dsAddrBook) ClearAddrs(p peer.ID) {
    method setAddrs (line 473) | func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl ti...
    method deleteAddrs (line 581) | func (ab *dsAddrBook) deleteAddrs(p peer.ID, addrs []ma.Multiaddr) (er...
  type clock (line 152) | type clock interface
  type realclock (line 157) | type realclock struct
    method Now (line 159) | func (rc realclock) Now() time.Time {
    method After (line 163) | func (rc realclock) After(d time.Duration) <-chan time.Time {
  function NewAddrBook (line 189) | func NewAddrBook(ctx context.Context, store ds.Batching, opts Options) (...
  function deleteInPlace (line 557) | func deleteInPlace(s []*pb.AddrBookRecord_AddrEntry, addrs []ma.Multiadd...
  function cleanAddrs (line 601) | func cleanAddrs(addrs []ma.Multiaddr, pid peer.ID) []ma.Multiaddr {

FILE: p2p/host/peerstore/pstoreds/addr_book_gc.go
  type dsAddrBookGc (line 46) | type dsAddrBookGc struct
    method background (line 94) | func (gc *dsAddrBookGc) background() {
    method purgeLookahead (line 132) | func (gc *dsAddrBookGc) purgeLookahead() {
    method purgeStore (line 255) | func (gc *dsAddrBookGc) purgeStore() {
    method populateLookahead (line 306) | func (gc *dsAddrBookGc) populateLookahead() {
  function newAddressBookGc (line 55) | func newAddressBookGc(ctx context.Context, ab *dsAddrBook) (*dsAddrBookG...
  function orderByTimestampInKey (line 391) | func orderByTimestampInKey(a, b query.Entry) int {

FILE: p2p/host/peerstore/pstoreds/addr_book_gc_test.go
  type testProbe (line 19) | type testProbe struct
    method countLookaheadEntries (line 24) | func (tp *testProbe) countLookaheadEntries() (i int) {
    method clearCache (line 37) | func (tp *testProbe) clearCache() {
  function TestGCLookahead (line 43) | func TestGCLookahead(t *testing.T) {
  function TestGCPurging (line 90) | func TestGCPurging(t *testing.T) {
  function TestGCDelay (line 157) | func TestGCDelay(t *testing.T) {
  function TestGCLookaheadDisabled (line 188) | func TestGCLookaheadDisabled(t *testing.T) {
  function BenchmarkLookaheadCycle (line 235) | func BenchmarkLookaheadCycle(b *testing.B) {

FILE: p2p/host/peerstore/pstoreds/cache.go
  type cache (line 5) | type cache interface
  type noopCache (line 15) | type noopCache struct
  method Get (line 20) | func (*noopCache[K, V]) Get(_ K) (value V, ok bool) {
  method Add (line 24) | func (*noopCache[K, V]) Add(_ K, _ V) {
  method Remove (line 27) | func (*noopCache[K, V]) Remove(_ K) {
  method Contains (line 30) | func (*noopCache[K, V]) Contains(_ K) bool {
  method Peek (line 34) | func (*noopCache[K, V]) Peek(_ K) (value V, ok bool) {
  method Keys (line 38) | func (*noopCache[K, V]) Keys() (keys []K) {

FILE: p2p/host/peerstore/pstoreds/cyclic_batch.go
  type cyclicBatch (line 19) | type cyclicBatch struct
    method cycle (line 34) | func (cb *cyclicBatch) cycle() (err error) {
    method Put (line 52) | func (cb *cyclicBatch) Put(ctx context.Context, key ds.Key, val []byte...
    method Delete (line 60) | func (cb *cyclicBatch) Delete(ctx context.Context, key ds.Key) error {
    method Commit (line 68) | func (cb *cyclicBatch) Commit(ctx context.Context) error {
  function newCyclicBatch (line 26) | func newCyclicBatch(ds ds.Batching, _ int) (ds.Batch, error) {

FILE: p2p/host/peerstore/pstoreds/ds_test.go
  function mapDBStore (line 17) | func mapDBStore(_ testing.TB) (ds.Batching, func()) {
  type datastoreFactory (line 25) | type datastoreFactory
  function TestDsPeerstore (line 31) | func TestDsPeerstore(t *testing.T) {
  function TestDsAddrBook (line 51) | func TestDsAddrBook(t *testing.T) {
  function TestDsKeyBook (line 75) | func TestDsKeyBook(t *testing.T) {
  function BenchmarkDsKeyBook (line 83) | func BenchmarkDsKeyBook(b *testing.B) {
  function BenchmarkDsPeerstore (line 91) | func BenchmarkDsPeerstore(b *testing.B) {
  function peerstoreFactory (line 108) | func peerstoreFactory(tb testing.TB, storeFactory datastoreFactory, opts...
  function addressBookFactory (line 123) | func addressBookFactory(tb testing.TB, storeFactory datastoreFactory, op...
  function keyBookFactory (line 138) | func keyBookFactory(tb testing.TB, storeFactory datastoreFactory, opts O...

FILE: p2p/host/peerstore/pstoreds/keybook.go
  type dsKeyBook (line 24) | type dsKeyBook struct
    method PubKey (line 34) | func (kb *dsKeyBook) PubKey(p peer.ID) ic.PubKey {
    method AddPubKey (line 69) | func (kb *dsKeyBook) AddPubKey(p peer.ID, pk ic.PubKey) error {
    method PrivKey (line 87) | func (kb *dsKeyBook) PrivKey(p peer.ID) ic.PrivKey {
    method AddPrivKey (line 99) | func (kb *dsKeyBook) AddPrivKey(p peer.ID, sk ic.PrivKey) error {
    method PeersWithKeys (line 119) | func (kb *dsKeyBook) PeersWithKeys() peer.IDSlice {
    method RemovePeer (line 129) | func (kb *dsKeyBook) RemovePeer(p peer.ID) {
  function NewKeyBook (line 30) | func NewKeyBook(_ context.Context, store ds.Datastore, _ Options) (*dsKe...
  function peerToKey (line 134) | func peerToKey(p peer.ID, suffix ds.Key) ds.Key {

FILE: p2p/host/peerstore/pstoreds/metadata.go
  type dsPeerMetadata (line 22) | type dsPeerMetadata struct
    method Get (line 44) | func (pm *dsPeerMetadata) Get(p peer.ID, key string) (any, error) {
    method Put (line 61) | func (pm *dsPeerMetadata) Put(p peer.ID, key string, val any) error {
    method RemovePeer (line 70) | func (pm *dsPeerMetadata) RemovePeer(p peer.ID) {
  function init (line 28) | func init() {
  function NewPeerMetadata (line 40) | func NewPeerMetadata(_ context.Context, store ds.Datastore, _ Options) (...

FILE: p2p/host/peerstore/pstoreds/pb/pstore.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type AddrBookRecord (line 25) | type AddrBookRecord struct
    method Reset (line 37) | func (x *AddrBookRecord) Reset() {
    method String (line 44) | func (x *AddrBookRecord) String() string {
    method ProtoMessage (line 48) | func (*AddrBookRecord) ProtoMessage() {}
    method ProtoReflect (line 50) | func (x *AddrBookRecord) ProtoReflect() protoreflect.Message {
    method Descriptor (line 63) | func (*AddrBookRecord) Descriptor() ([]byte, []int) {
    method GetId (line 67) | func (x *AddrBookRecord) GetId() []byte {
    method GetAddrs (line 74) | func (x *AddrBookRecord) GetAddrs() []*AddrBookRecord_AddrEntry {
    method GetCertifiedRecord (line 81) | func (x *AddrBookRecord) GetCertifiedRecord() *AddrBookRecord_Certifie...
  type AddrBookRecord_AddrEntry (line 89) | type AddrBookRecord_AddrEntry struct
    method Reset (line 100) | func (x *AddrBookRecord_AddrEntry) Reset() {
    method String (line 107) | func (x *AddrBookRecord_AddrEntry) String() string {
    method ProtoMessage (line 111) | func (*AddrBookRecord_AddrEntry) ProtoMessage() {}
    method ProtoReflect (line 113) | func (x *AddrBookRecord_AddrEntry) ProtoReflect() protoreflect.Message {
    method Descriptor (line 126) | func (*AddrBookRecord_AddrEntry) Descriptor() ([]byte, []int) {
    method GetAddr (line 130) | func (x *AddrBookRecord_AddrEntry) GetAddr() []byte {
    method GetExpiry (line 137) | func (x *AddrBookRecord_AddrEntry) GetExpiry() int64 {
    method GetTtl (line 144) | func (x *AddrBookRecord_AddrEntry) GetTtl() int64 {
  type AddrBookRecord_CertifiedRecord (line 153) | type AddrBookRecord_CertifiedRecord struct
    method Reset (line 163) | func (x *AddrBookRecord_CertifiedRecord) Reset() {
    method String (line 170) | func (x *AddrBookRecord_CertifiedRecord) String() string {
    method ProtoMessage (line 174) | func (*AddrBookRecord_CertifiedRecord) ProtoMessage() {}
    method ProtoReflect (line 176) | func (x *AddrBookRecord_CertifiedRecord) ProtoReflect() protoreflect.M...
    method Descriptor (line 189) | func (*AddrBookRecord_CertifiedRecord) Descriptor() ([]byte, []int) {
    method GetSeq (line 193) | func (x *AddrBookRecord_CertifiedRecord) GetSeq() uint64 {
    method GetRaw (line 200) | func (x *AddrBookRecord_CertifiedRecord) GetRaw() []byte {
  constant file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDesc (line 209) | file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDesc = "" +
  function file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescGZIP (line 229) | func file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescGZIP() []by...
  function init (line 252) | func init() { file_p2p_host_peerstore_pstoreds_pb_pstore_proto_init() }
  function file_p2p_host_peerstore_pstoreds_pb_pstore_proto_init (line 253) | func file_p2p_host_peerstore_pstoreds_pb_pstore_proto_init() {

FILE: p2p/host/peerstore/pstoreds/peerstore.go
  type Options (line 19) | type Options struct
  function DefaultOpts (line 48) | func DefaultOpts() Options {
  type pstoreds (line 59) | type pstoreds struct
    method Close (line 137) | func (ps *pstoreds) Close() (err error) {
    method Peers (line 157) | func (ps *pstoreds) Peers() peer.IDSlice {
    method PeerInfo (line 173) | func (ps *pstoreds) PeerInfo(p peer.ID) peer.AddrInfo {
    method RemovePeer (line 186) | func (ps *pstoreds) RemovePeer(p peer.ID) {
  function NewPeerstore (line 73) | func NewPeerstore(ctx context.Context, store ds.Batching, opts Options) ...
  function uniquePeerIds (line 104) | func uniquePeerIds(ds ds.Datastore, prefix ds.Key, extractor func(result...

FILE: p2p/host/peerstore/pstoreds/protobook.go
  type protoSegment (line 13) | type protoSegment struct
  type protoSegments (line 17) | type protoSegments
    method get (line 19) | func (s *protoSegments) get(p peer.ID) *protoSegment {
  type ProtoBookOption (line 25) | type ProtoBookOption
  function WithMaxProtocols (line 27) | func WithMaxProtocols(num int) ProtoBookOption {
  type dsProtoBook (line 34) | type dsProtoBook struct
    method SetProtocols (line 62) | func (pb *dsProtoBook) SetProtocols(p peer.ID, protos ...protocol.ID) ...
    method AddProtocols (line 79) | func (pb *dsProtoBook) AddProtocols(p peer.ID, protos ...protocol.ID) ...
    method GetProtocols (line 99) | func (pb *dsProtoBook) GetProtocols(p peer.ID) ([]protocol.ID, error) {
    method SupportsProtocols (line 117) | func (pb *dsProtoBook) SupportsProtocols(p peer.ID, protos ...protocol...
    method FirstSupportedProtocol (line 137) | func (pb *dsProtoBook) FirstSupportedProtocol(p peer.ID, protos ...pro...
    method RemoveProtocols (line 155) | func (pb *dsProtoBook) RemoveProtocols(p peer.ID, protos ...protocol.I...
    method getProtocolMap (line 177) | func (pb *dsProtoBook) getProtocolMap(p peer.ID) (map[protocol.ID]stru...
    method RemovePeer (line 194) | func (pb *dsProtoBook) RemovePeer(p peer.ID) {
  function NewProtoBook (line 42) | func NewProtoBook(meta pstore.PeerMetadata, opts ...ProtoBookOption) (*d...

FILE: p2p/host/peerstore/pstoremem/addr_book.go
  type expiringAddr (line 22) | type expiringAddr struct
    method ExpiredBy (line 31) | func (e *expiringAddr) ExpiredBy(t time.Time) bool {
    method IsConnected (line 35) | func (e *expiringAddr) IsConnected() bool {
  function ttlIsConnected (line 41) | func ttlIsConnected(ttl time.Duration) bool {
  type peerRecordState (line 45) | type peerRecordState struct
  type peerAddrs (line 53) | type peerAddrs struct
    method Len (line 66) | func (pa *peerAddrs) Len() int { return len(pa.expiringHeap) }
    method Less (line 67) | func (pa *peerAddrs) Less(i, j int) bool {
    method Swap (line 70) | func (pa *peerAddrs) Swap(i, j int) {
    method Push (line 75) | func (pa *peerAddrs) Push(x any) {
    method Pop (line 80) | func (pa *peerAddrs) Pop() any {
    method Delete (line 87) | func (pa *peerAddrs) Delete(a *expiringAddr) {
    method FindAddr (line 99) | func (pa *peerAddrs) FindAddr(p peer.ID, addr ma.Multiaddr) (*expiring...
    method NextExpiry (line 107) | func (pa *peerAddrs) NextExpiry() time.Time {
    method PopIfExpired (line 114) | func (pa *peerAddrs) PopIfExpired(now time.Time) (*expiringAddr, bool) {
    method Update (line 127) | func (pa *peerAddrs) Update(a *expiringAddr) {
    method Insert (line 138) | func (pa *peerAddrs) Insert(a *expiringAddr) {
    method NumUnconnectedAddrs (line 151) | func (pa *peerAddrs) NumUnconnectedAddrs() int {
  function newPeerAddrs (line 60) | func newPeerAddrs() peerAddrs {
  type clock (line 155) | type clock interface
  type realclock (line 159) | type realclock struct
    method Now (line 161) | func (rc realclock) Now() time.Time {
  constant defaultMaxSignedPeerRecords (line 166) | defaultMaxSignedPeerRecords = 100_000
  constant defaultMaxUnconnectedAddrs (line 167) | defaultMaxUnconnectedAddrs  = 1_000_000
  type memoryAddrBook (line 171) | type memoryAddrBook struct
    method background (line 236) | func (mab *memoryAddrBook) background(ctx context.Context) {
    method Close (line 251) | func (mab *memoryAddrBook) Close() error {
    method gc (line 258) | func (mab *memoryAddrBook) gc() {
    method PeersWithAddrs (line 271) | func (mab *memoryAddrBook) PeersWithAddrs() peer.IDSlice {
    method AddAddr (line 282) | func (mab *memoryAddrBook) AddAddr(p peer.ID, addr ma.Multiaddr, ttl t...
    method AddAddrs (line 288) | func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, t...
    method ConsumePeerRecord (line 294) | func (mab *memoryAddrBook) ConsumePeerRecord(recordEnvelope *record.En...
    method maybeDeleteSignedPeerRecordUnlocked (line 327) | func (mab *memoryAddrBook) maybeDeleteSignedPeerRecordUnlocked(p peer....
    method addAddrs (line 333) | func (mab *memoryAddrBook) addAddrs(p peer.ID, addrs []ma.Multiaddr, t...
    method addAddrsUnlocked (line 340) | func (mab *memoryAddrBook) addAddrsUnlocked(p peer.ID, addrs []ma.Mult...
    method SetAddr (line 390) | func (mab *memoryAddrBook) SetAddr(p peer.ID, addr ma.Multiaddr, ttl t...
    method SetAddrs (line 396) | func (mab *memoryAddrBook) SetAddrs(p peer.ID, addrs []ma.Multiaddr, t...
    method UpdateAddrs (line 443) | func (mab *memoryAddrBook) UpdateAddrs(p peer.ID, oldTTL time.Duration...
    method Addrs (line 469) | func (mab *memoryAddrBook) Addrs(p peer.ID) []ma.Multiaddr {
    method GetPeerRecord (line 494) | func (mab *memoryAddrBook) GetPeerRecord(p peer.ID) *record.Envelope {
    method ClearAddrs (line 514) | func (mab *memoryAddrBook) ClearAddrs(p peer.ID) {
    method AddrStream (line 526) | func (mab *memoryAddrBook) AddrStream(ctx context.Context, p peer.ID) ...
  function NewAddrBook (line 188) | func NewAddrBook(opts ...AddrBookOption) *memoryAddrBook {
  type AddrBookOption (line 209) | type AddrBookOption
  function WithClock (line 211) | func WithClock(clock clock) AddrBookOption {
  function WithMaxAddresses (line 221) | func WithMaxAddresses(n int) AddrBookOption {
  function WithMaxSignedPeerRecords (line 228) | func WithMaxSignedPeerRecords(n int) AddrBookOption {
  function validAddrs (line 478) | func validAddrs(now time.Time, amap map[string]*expiringAddr) []ma.Multi...
  type addrSub (line 541) | type addrSub struct
    method pubAddr (line 546) | func (s *addrSub) pubAddr(a ma.Multiaddr) {
  type AddrSubManager (line 555) | type AddrSubManager struct
    method removeSub (line 569) | func (mgr *AddrSubManager) removeSub(p peer.ID, s *addrSub) {
    method BroadcastAddr (line 593) | func (mgr *AddrSubManager) BroadcastAddr(p peer.ID, addr ma.Multiaddr) {
    method AddrStream (line 606) | func (mgr *AddrSubManager) AddrStream(ctx context.Context, p peer.ID, ...
  function NewAddrSubManager (line 561) | func NewAddrSubManager() *AddrSubManager {

FILE: p2p/host/peerstore/pstoremem/addr_book_test.go
  function TestPeerAddrsNextExpiry (line 16) | func TestPeerAddrsNextExpiry(t *testing.T) {
  function peerAddrsInput (line 33) | func peerAddrsInput(n int) []*expiringAddr {
  function TestPeerAddrsHeapProperty (line 45) | func TestPeerAddrsHeapProperty(t *testing.T) {
  function TestPeerAddrsHeapPropertyDeletions (line 66) | func TestPeerAddrsHeapPropertyDeletions(t *testing.T) {
  function TestPeerAddrsHeapPropertyUpdates (line 97) | func TestPeerAddrsHeapPropertyUpdates(t *testing.T) {
  function TestPeerAddrsExpiry (line 137) | func TestPeerAddrsExpiry(t *testing.T) {
  function TestPeerLimits (line 177) | func TestPeerLimits(t *testing.T) {
  function BenchmarkPeerAddrs (line 189) | func BenchmarkPeerAddrs(b *testing.B) {

FILE: p2p/host/peerstore/pstoremem/inmem_test.go
  function TestInvalidOption (line 18) | func TestInvalidOption(t *testing.T) {
  function TestFuzzInMemoryPeerstore (line 23) | func TestFuzzInMemoryPeerstore(t *testing.T) {
  function TestInMemoryPeerstore (line 33) | func TestInMemoryPeerstore(t *testing.T) {
  function TestPeerstoreProtoStoreLimits (line 41) | func TestPeerstoreProtoStoreLimits(t *testing.T) {
  function TestInMemoryAddrBook (line 49) | func TestInMemoryAddrBook(t *testing.T) {
  function TestInMemoryKeyBook (line 58) | func TestInMemoryKeyBook(t *testing.T) {
  function BenchmarkInMemoryPeerstore (line 66) | func BenchmarkInMemoryPeerstore(b *testing.B) {
  function BenchmarkInMemoryKeyBook (line 74) | func BenchmarkInMemoryKeyBook(b *testing.B) {
  function TestMain (line 82) | func TestMain(m *testing.M) {
  function BenchmarkGC (line 90) | func BenchmarkGC(b *testing.B) {

FILE: p2p/host/peerstore/pstoremem/keybook.go
  type memoryKeyBook (line 12) | type memoryKeyBook struct
    method PeersWithKeys (line 27) | func (mkb *memoryKeyBook) PeersWithKeys() peer.IDSlice {
    method PubKey (line 42) | func (mkb *memoryKeyBook) PubKey(p peer.ID) ic.PubKey {
    method AddPubKey (line 58) | func (mkb *memoryKeyBook) AddPubKey(p peer.ID, pk ic.PubKey) error {
    method PrivKey (line 70) | func (mkb *memoryKeyBook) PrivKey(p peer.ID) ic.PrivKey {
    method AddPrivKey (line 76) | func (mkb *memoryKeyBook) AddPrivKey(p peer.ID, sk ic.PrivKey) error {
    method RemovePeer (line 92) | func (mkb *memoryKeyBook) RemovePeer(p peer.ID) {
  function NewKeyBook (line 20) | func NewKeyBook() *memoryKeyBook {

FILE: p2p/host/peerstore/pstoremem/metadata.go
  type memoryPeerMetadata (line 10) | type memoryPeerMetadata struct
    method Put (line 24) | func (ps *memoryPeerMetadata) Put(p peer.ID, key string, val any) error {
    method Get (line 36) | func (ps *memoryPeerMetadata) Get(p peer.ID, key string) (any, error) {
    method RemovePeer (line 50) | func (ps *memoryPeerMetadata) RemovePeer(p peer.ID) {
  function NewPeerMetadata (line 18) | func NewPeerMetadata() *memoryPeerMetadata {

FILE: p2p/host/peerstore/pstoremem/peerstore.go
  type pstoremem (line 12) | type pstoremem struct
    method Close (line 58) | func (ps *pstoremem) Close() (err error) {
    method Peers (line 78) | func (ps *pstoremem) Peers() peer.IDSlice {
    method PeerInfo (line 94) | func (ps *pstoremem) PeerInfo(p peer.ID) peer.AddrInfo {
    method RemovePeer (line 107) | func (ps *pstoremem) RemovePeer(p peer.ID) {
  type Option (line 23) | type Option
  function NewPeerstore (line 28) | func NewPeerstore(opts ...Option) (ps *pstoremem, err error) {

FILE: p2p/host/peerstore/pstoremem/peerstore_test.go
  function TestPeerStoreAddrBookOpts (line 11) | func TestPeerStoreAddrBookOpts(t *testing.T) {

FILE: p2p/host/peerstore/pstoremem/protobook.go
  type protoSegment (line 12) | type protoSegment struct
  type protoSegments (line 17) | type protoSegments
    method get (line 19) | func (s *protoSegments) get(p peer.ID) *protoSegment {
  type memoryProtoBook (line 25) | type memoryProtoBook struct
    method SetProtocols (line 63) | func (pb *memoryProtoBook) SetProtocols(p peer.ID, protos ...protocol....
    method AddProtocols (line 81) | func (pb *memoryProtoBook) AddProtocols(p peer.ID, protos ...protocol....
    method GetProtocols (line 101) | func (pb *memoryProtoBook) GetProtocols(p peer.ID) ([]protocol.ID, err...
    method RemoveProtocols (line 114) | func (pb *memoryProtoBook) RemoveProtocols(p peer.ID, protos ...protoc...
    method SupportsProtocols (line 134) | func (pb *memoryProtoBook) SupportsProtocols(p peer.ID, protos ...prot...
    method FirstSupportedProtocol (line 149) | func (pb *memoryProtoBook) FirstSupportedProtocol(p peer.ID, protos .....
    method RemovePeer (line 162) | func (pb *memoryProtoBook) RemovePeer(p peer.ID) {
  type ProtoBookOption (line 33) | type ProtoBookOption
  function WithMaxProtocols (line 35) | func WithMaxProtocols(num int) ProtoBookOption {
  function NewProtoBook (line 42) | func NewProtoBook(opts ...ProtoBookOption) (*memoryProtoBook, error) {

FILE: p2p/host/peerstore/pstoremem/sorting.go
  function isFDCostlyTransport (line 11) | func isFDCostlyTransport(a ma.Multiaddr) bool {
  type addrList (line 15) | type addrList
    method Len (line 17) | func (al addrList) Len() int      { return len(al) }
    method Swap (line 18) | func (al addrList) Swap(i, j int) { al[i], al[j] = al[j], al[i] }
    method Less (line 20) | func (al addrList) Less(i, j int) bool {

FILE: p2p/host/peerstore/pstoremem/sorting_test.go
  function TestAddressSorting (line 11) | func TestAddressSorting(t *testing.T) {

FILE: p2p/host/peerstore/test/addr_book_suite.go
  type AddrBookFactory (line 29) | type AddrBookFactory
  function TestAddrBook (line 31) | func TestAddrBook(t *testing.T, factory AddrBookFactory, clk *mockClock....
  function testAddAddress (line 46) | func testAddAddress(ab pstore.AddrBook, clk *mockClock.Mock) func(*testi...
  function testClearWorks (line 165) | func testClearWorks(ab pstore.AddrBook, _ *mockClock.Mock) func(t *testi...
  function testSetNegativeTTLClears (line 186) | func testSetNegativeTTLClears(m pstore.AddrBook, _ *mockClock.Mock) func...
  function testUpdateTTLs (line 230) | func testUpdateTTLs(m pstore.AddrBook, clk *mockClock.Mock) func(t *test...
  function testNilAddrsDontBreak (line 296) | func testNilAddrsDontBreak(m pstore.AddrBook, _ *mockClock.Mock) func(t ...
  function testAddressesExpire (line 305) | func testAddressesExpire(m pstore.AddrBook, clk *mockClock.Mock) func(t ...
  function testClearWithIterator (line 350) | func testClearWithIterator(m pstore.AddrBook, _ *mockClock.Mock) func(t ...
  function testPeersWithAddrs (line 377) | func testPeersWithAddrs(m pstore.AddrBook, _ *mockClock.Mock) func(t *te...
  function testCertifiedAddresses (line 403) | func testCertifiedAddresses(m pstore.AddrBook, clk *mockClock.Mock) func...

FILE: p2p/host/peerstore/test/benchmarks_suite.go
  function BenchmarkPeerstore (line 10) | func BenchmarkPeerstore(b *testing.B, factory PeerstoreFactory, _ string) {

FILE: p2p/host/peerstore/test/keybook_suite.go
  type KeyBookFactory (line 23) | type KeyBookFactory
  function TestKeyBook (line 25) | func TestKeyBook(t *testing.T, factory KeyBookFactory) {
  function testKeybookPrivKey (line 40) | func testKeybookPrivKey(kb pstore.KeyBook) func(t *testing.T) {
  function testKeyBookPubKey (line 75) | func testKeyBookPubKey(kb pstore.KeyBook) func(t *testing.T) {
  function testKeyBookPeers (line 110) | func testKeyBookPeers(kb pstore.KeyBook) func(t *testing.T) {
  function testInlinedPubKeyAddedOnRetrieve (line 155) | func testInlinedPubKeyAddedOnRetrieve(kb pstore.KeyBook) func(t *testing...
  function testKeyBookDelete (line 181) | func testKeyBookDelete(kb pstore.KeyBook) func(t *testing.T) {
  function BenchmarkKeyBook (line 206) | func BenchmarkKeyBook(b *testing.B, factory KeyBookFactory) {
  function benchmarkPubKey (line 224) | func benchmarkPubKey(kb pstore.KeyBook) func(*testing.B) {
  function benchmarkAddPubKey (line 248) | func benchmarkAddPubKey(kb pstore.KeyBook) func(*testing.B) {
  function benchmarkPrivKey (line 267) | func benchmarkPrivKey(kb pstore.KeyBook) func(*testing.B) {
  function benchmarkAddPrivKey (line 291) | func benchmarkAddPrivKey(kb pstore.KeyBook) func(*testing.B) {
  function benchmarkPeersWithKeys (line 310) | func benchmarkPeersWithKeys(kb pstore.KeyBook) func(*testing.B) {

FILE: p2p/host/peerstore/test/peerstore_suite.go
  type PeerstoreFactory (line 31) | type PeerstoreFactory
  function TestPeerstore (line 33) | func TestPeerstore(t *testing.T, factory PeerstoreFactory) {
  function sortProtos (line 48) | func sortProtos(protos []protocol.ID) {
  function testAddrStream (line 52) | func testAddrStream(ps pstore.Peerstore) func(t *testing.T) {
  function testGetStreamBeforePeerAdded (line 126) | func testGetStreamBeforePeerAdded(ps pstore.Peerstore) func(t *testing.T) {
  function testAddrStreamDuplicates (line 175) | func testAddrStreamDuplicates(ps pstore.Peerstore) func(t *testing.T) {
  function testPeerstoreProtoStore (line 213) | func testPeerstoreProtoStore(ps pstore.Peerstore) func(t *testing.T) {
  function testBasicPeerstore (line 292) | func testBasicPeerstore(ps pstore.Peerstore) func(t *testing.T) {
  function testMetadata (line 322) | func testMetadata(ps pstore.Peerstore) func(t *testing.T) {
  function testCertifiedAddrBook (line 367) | func testCertifiedAddrBook(ps pstore.Peerstore) func(*testing.T) {
  function getAddrs (line 376) | func getAddrs(t *testing.T, n int) []ma.Multiaddr {
  function TestPeerstoreProtoStoreLimits (line 389) | func TestPeerstoreProtoStoreLimits(t *testing.T, ps pstore.Peerstore, li...

FILE: p2p/host/peerstore/test/utils.go
  function Multiaddr (line 14) | func Multiaddr(m string) ma.Multiaddr {
  type peerpair (line 22) | type peerpair struct
  function RandomPeer (line 27) | func RandomPeer(b *testing.B, addrCount int) *peerpair {
  function getPeerPairs (line 48) | func getPeerPairs(b *testing.B, n int, addrsPerPeer int) []*peerpair {
  function GenerateAddrs (line 56) | func GenerateAddrs(count int) []ma.Multiaddr {
  function GeneratePeerIDs (line 64) | func GeneratePeerIDs(count int) []peer.ID {
  function AssertAddressesEqual (line 72) | func AssertAddressesEqual(t *testing.T, exp, act []ma.Multiaddr) {

FILE: p2p/host/pstoremanager/mock_peerstore_test.go
  type MockPeerstore (line 25) | type MockPeerstore struct
    method EXPECT (line 44) | func (m *MockPeerstore) EXPECT() *MockPeerstoreMockRecorder {
    method AddAddr (line 49) | func (m *MockPeerstore) AddAddr(p peer.ID, addr multiaddr.Multiaddr, t...
    method AddAddrs (line 61) | func (m *MockPeerstore) AddAddrs(p peer.ID, addrs []multiaddr.Multiadd...
    method AddPrivKey (line 73) | func (m *MockPeerstore) AddPrivKey(arg0 peer.ID, arg1 crypto.PrivKey) ...
    method AddProtocols (line 87) | func (m *MockPeerstore) AddProtocols(arg0 peer.ID, arg1 ...protocol.ID...
    method AddPubKey (line 106) | func (m *MockPeerstore) AddPubKey(arg0 peer.ID, arg1 crypto.PubKey) er...
    method AddrStream (line 120) | func (m *MockPeerstore) AddrStream(arg0 context.Context, arg1 peer.ID)...
    method Addrs (line 134) | func (m *MockPeerstore) Addrs(p peer.ID) []multiaddr.Multiaddr {
    method ClearAddrs (line 148) | func (m *MockPeerstore) ClearAddrs(p peer.ID) {
    method Close (line 160) | func (m *MockPeerstore) Close() error {
    method FirstSupportedProtocol (line 174) | func (m *MockPeerstore) FirstSupportedProtocol(arg0 peer.ID, arg1 ...p...
    method Get (line 194) | func (m *MockPeerstore) Get(p peer.ID, key string) (any, error) {
    method GetProtocols (line 209) | func (m *MockPeerstore) GetProtocols(arg0 peer.ID) ([]protocol.ID, err...
    method LatencyEWMA (line 224) | func (m *MockPeerstore) LatencyEWMA(arg0 peer.ID) time.Duration {
    method PeerInfo (line 238) | func (m *MockPeerstore) PeerInfo(arg0 peer.ID) peer.AddrInfo {
    method Peers (line 252) | func (m *MockPeerstore) Peers() peer.IDSlice {
    method PeersWithAddrs (line 266) | func (m *MockPeerstore) PeersWithAddrs() peer.IDSlice {
    method PeersWithKeys (line 280) | func (m *MockPeerstore) PeersWithKeys() peer.IDSlice {
    method PrivKey (line 294) | func (m *MockPeerstore) PrivKey(arg0 peer.ID) crypto.PrivKey {
    method PubKey (line 308) | func (m *MockPeerstore) PubKey(arg0 peer.ID) crypto.PubKey {
    method Put (line 322) | func (m *MockPeerstore) Put(p peer.ID, key string, val any) error {
    method RecordLatency (line 336) | func (m *MockPeerstore) RecordLatency(arg0 peer.ID, arg1 time.Duration) {
    method RemovePeer (line 348) | func (m *MockPeerstore) RemovePeer(arg0 peer.ID) {
    method RemoveProtocols (line 360) | func (m *MockPeerstore) RemoveProtocols(arg0 peer.ID, arg1 ...protocol...
    method SetAddr (line 379) | func (m *MockPeerstore) SetAddr(p peer.ID, addr multiaddr.Multiaddr, t...
    method SetAddrs (line 391) | func (m *MockPeerstore) SetAddrs(p peer.ID, addrs []multiaddr.Multiadd...
    method SetProtocols (line 403) | func (m *MockPeerstore) SetProtocols(arg0 peer.ID, arg1 ...protocol.ID...
    method SupportsProtocols (line 422) | func (m *MockPeerstore) SupportsProtocols(arg0 peer.ID, arg1 ...protoc...
    method UpdateAddrs (line 442) | func (m *MockPeerstore) UpdateAddrs(p peer.ID, oldTTL, newTTL time.Dur...
  type MockPeerstoreMockRecorder (line 32) | type MockPeerstoreMockRecorder struct
    method AddAddr (line 55) | func (mr *MockPeerstoreMockRecorder) AddAddr(p, addr, ttl any) *gomock...
    method AddAddrs (line 67) | func (mr *MockPeerstoreMockRecorder) AddAddrs(p, addrs, ttl any) *gomo...
    method AddPrivKey (line 81) | func (mr *MockPeerstoreMockRecorder) AddPrivKey(arg0, arg1 any) *gomoc...
    method AddProtocols (line 99) | func (mr *MockPeerstoreMockRecorder) AddProtocols(arg0 any, arg1 ...an...
    method AddPubKey (line 114) | func (mr *MockPeerstoreMockRecorder) AddPubKey(arg0, arg1 any) *gomock...
    method AddrStream (line 128) | func (mr *MockPeerstoreMockRecorder) AddrStream(arg0, arg1 any) *gomoc...
    method Addrs (line 142) | func (mr *MockPeerstoreMockRecorder) Addrs(p any) *gomock.Call {
    method ClearAddrs (line 154) | func (mr *MockPeerstoreMockRecorder) ClearAddrs(p any) *gomock.Call {
    method Close (line 168) | func (mr *MockPeerstoreMockRecorder) Close() *gomock.Call {
    method FirstSupportedProtocol (line 187) | func (mr *MockPeerstoreMockRecorder) FirstSupportedProtocol(arg0 any, ...
    method Get (line 203) | func (mr *MockPeerstoreMockRecorder) Get(p, key any) *gomock.Call {
    method GetProtocols (line 218) | func (mr *MockPeerstoreMockRecorder) GetProtocols(arg0 any) *gomock.Ca...
    method LatencyEWMA (line 232) | func (mr *MockPeerstoreMockRecorder) LatencyEWMA(arg0 any) *gomock.Call {
    method PeerInfo (line 246) | func (mr *MockPeerstoreMockRecorder) PeerInfo(arg0 any) *gomock.Call {
    method Peers (line 260) | func (mr *MockPeerstoreMockRecorder) Peers() *gomock.Call {
    method PeersWithAddrs (line 274) | func (mr *MockPeerstoreMockRecorder) PeersWithAddrs() *gomock.Call {
    method PeersWithKeys (line 288) | func (mr *MockPeerstoreMockRecorder) PeersWithKeys() *gomock.Call {
    method PrivKey (line 302) | func (mr *MockPeerstoreMockRecorder) PrivKey(arg0 any) *gomock.Call {
    method PubKey (line 316) | func (mr *MockPeerstoreMockRecorder) PubKey(arg0 any) *gomock.Call {
    method Put (line 330) | func (mr *MockPeerstoreMockRecorder) Put(p, key, val any) *gomock.Call {
    method RecordLatency (line 342) | func (mr *MockPeerstoreMockRecorder) RecordLatency(arg0, arg1 any) *go...
    method RemovePeer (line 354) | func (mr *MockPeerstoreMockRecorder) RemovePeer(arg0 any) *gomock.Call {
    method RemoveProtocols (line 372) | func (mr *MockPeerstoreMockRecorder) RemoveProtocols(arg0 any, arg1 .....
    method SetAddr (line 385) | func (mr *MockPeerstoreMockRecorder) SetAddr(p, addr, ttl any) *gomock...
    method SetAddrs (line 397) | func (mr *MockPeerstoreMockRecorder) SetAddrs(p, addrs, ttl any) *gomo...
    method SetProtocols (line 415) | func (mr *MockPeerstoreMockRecorder) SetProtocols(arg0 any, arg1 ...an...
    method SupportsProtocols (line 435) | func (mr *MockPeerstoreMockRecorder) SupportsProtocols(arg0 any, arg1 ...
    method UpdateAddrs (line 448) | func (mr *MockPeerstoreMockRecorder) UpdateAddrs(p, oldTTL, newTTL any...
  function NewMockPeerstore (line 37) | func NewMockPeerstore(ctrl *gomock.Controller) *MockPeerstore {

FILE: p2p/host/pstoremanager/pstoremanager.go
  type Option (line 19) | type Option
  function WithGracePeriod (line 24) | func WithGracePeriod(p time.Duration) Option {
  function WithCleanupInterval (line 34) | func WithCleanupInterval(t time.Duration) Option {
  type PeerstoreManager (line 41) | type PeerstoreManager struct
    method Start (line 71) | func (m *PeerstoreManager) Start() {
    method background (line 83) | func (m *PeerstoreManager) background(ctx context.Context, sub event.S...
    method Close (line 138) | func (m *PeerstoreManager) Close() error {
  function NewPeerstoreManager (line 53) | func NewPeerstoreManager(pstore peerstore.Peerstore, eventBus event.Bus,...

FILE: p2p/host/pstoremanager/pstoremanager_test.go
  function TestGracePeriod (line 20) | func TestGracePeriod(t *testing.T) {
  function TestReconnect (line 49) | func TestReconnect(t *testing.T) {
  function TestClose (line 75) | func TestClose(t *testing.T) {

FILE: p2p/host/relaysvc/relay.go
  type RelayManager (line 14) | type RelayManager struct
    method background (line 37) | func (m *RelayManager) background(ctx context.Context) {
    method reachabilityChanged (line 65) | func (m *RelayManager) reachabilityChanged(r network.Reachability) err...
    method Close (line 92) | func (m *RelayManager) Close() error {
  function NewRelayManager (line 25) | func NewRelayManager(host host.Host, opts ...relayv2.Option) *RelayManag...

FILE: p2p/host/relaysvc/relay_test.go
  function TestReachabilityChangeEvent (line 16) | func TestReachabilityChangeEvent(t *testing.T) {

FILE: p2p/host/resource-manager/allowlist.go
  type Allowlist (line 16) | type Allowlist struct
    method Add (line 107) | func (al *Allowlist) Add(ma multiaddr.Multiaddr) error {
    method Remove (line 127) | func (al *Allowlist) Remove(ma multiaddr.Multiaddr) error {
    method Allowed (line 167) | func (al *Allowlist) Allowed(ma multiaddr.Multiaddr) bool {
    method AllowedPeerAndMultiaddr (line 192) | func (al *Allowlist) AllowedPeerAndMultiaddr(peerID peer.ID, ma multia...
  function WithAllowlistedMultiaddrs (line 31) | func WithAllowlistedMultiaddrs(mas []multiaddr.Multiaddr) Option {
  function newAllowlist (line 43) | func newAllowlist() Allowlist {
  function toIPNet (line 49) | func toIPNet(ma multiaddr.Multiaddr) (*net.IPNet, peer.ID, error) {

FILE: p2p/host/resource-manager/allowlist_test.go
  function ExampleWithAllowlistedMultiaddrs (line 15) | func ExampleWithAllowlistedMultiaddrs() {
  function TestAllowedSimple (line 38) | func TestAllowedSimple(t *testing.T) {
  function TestAllowedWithPeer (line 51) | func TestAllowedWith
Condensed preview — 657 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,236K chars).
[
  {
    "path": ".codecov.yml",
    "chars": 36,
    "preview": "github_checks:\n  annotations: false\n"
  },
  {
    "path": ".githooks/README.md",
    "chars": 155,
    "preview": "# Git Hooks\n\nThis directory contains useful Git hooks for working with go-libp2p.\n\nInstall them by running\n```bash\ngit c"
  },
  {
    "path": ".githooks/pre-commit",
    "chars": 247,
    "preview": "#!/bin/bash\n\npushd ./test-plans > /dev/null\ngo mod tidy\nif [[ -n $(git diff --name-only -- \"go.mod\" \"go.sum\") ]]; then\n "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.md",
    "chars": 585,
    "preview": "---\nname: 'Bug Report'\nabout: 'Report a bug in go-libp2p.'\nlabels: bug\n---\n\n<!-- This is where you get to tell us what w"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 373,
    "preview": "blank_issues_enabled: true\ncontact_links:\n  - name: Technical Questions\n    url: https://github.com/libp2p/go-libp2p/dis"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/doc.md",
    "chars": 355,
    "preview": "---\nname: 'Documentation Issue'\nabout: 'Report missing/erroneous documentation, propose new documentation, report broken"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/enhancement.md",
    "chars": 492,
    "preview": "---\nname: 'Enhancement'\nabout: 'Suggest an improvement to an existing go-libp2p feature.'\nlabels: enhancement\n---\n\n<!--\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.md",
    "chars": 543,
    "preview": "---\nname: 'Feature'\nabout: 'Suggest a new feature in go-libp2p.'\nlabels: feature\n---\n\n<!--\nNote: If you'd like to sugges"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "chars": 389,
    "preview": "---\nname: 'Question/Support'\nabout: 'Ask a question about go-libp2p or request support.'\nlabels: question, invalid\n---\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/release.md",
    "chars": 1595,
    "preview": "---\nname: 'Libp2p Release'\nabout: 'Start a new libp2p release.'\n---\n\n## 🗺 What's left for release\n\n<List of items with r"
  },
  {
    "path": ".github/actions/go-check-setup/action.yml",
    "chars": 402,
    "preview": "runs:\n  using: \"composite\"\n  steps:\n    - name: Install Protoc\n      uses: trail-of-forks/setup-protoc@a97892a429d98fae7"
  },
  {
    "path": ".github/actions/go-test-setup/action.yml",
    "chars": 1032,
    "preview": "runs:\n  using: \"composite\"\n  steps:\n    - name: increase the UDP receive buffer size # see https://github.com/lucas-clem"
  },
  {
    "path": ".github/workflows/generated-pr.yml",
    "chars": 246,
    "preview": "name: Close Generated PRs\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n  workflow_dispatch:\n\npermissions:\n  issues: write\n  "
  },
  {
    "path": ".github/workflows/go-check-config.json",
    "chars": 25,
    "preview": "{\n  \"gogenerate\": true\n}\n"
  },
  {
    "path": ".github/workflows/go-check.yml",
    "chars": 469,
    "preview": "name: Go Checks\n\non:\n  pull_request:\n  push:\n    branches: [\"master\", \"release-v0[0-9][0-9]\"]\n  workflow_dispatch:\n\nperm"
  },
  {
    "path": ".github/workflows/go-test-config.json",
    "chars": 26,
    "preview": "{\n    \"skip32bit\": true\n}\n"
  },
  {
    "path": ".github/workflows/go-test-template.yml",
    "chars": 6671,
    "preview": "name: Go Test\non:\n  workflow_call:\n    inputs:\n      go-versions:\n        required: false\n        type: string\n        d"
  },
  {
    "path": ".github/workflows/go-test.yml",
    "chars": 489,
    "preview": "name: Go Test\n\non:\n  pull_request:\n  push:\n    branches: [\"master\", \"release-v0[0-9][0-9]\"]\n  workflow_dispatch:\n\npermis"
  },
  {
    "path": ".github/workflows/interop-test.yml",
    "chars": 1496,
    "preview": "name: Interoperability Testing\n\non:\n  workflow_dispatch:\n  pull_request:\n    paths:\n      - \"config/**\"\n      - \"core/**"
  },
  {
    "path": ".github/workflows/link-check.yml",
    "chars": 449,
    "preview": "name: Markdown Link Checking\non:\n  pull_request:\n  push:\n    branches:\n      - \"master\"\n\njobs:\n  check-links:\n    runs-o"
  },
  {
    "path": ".github/workflows/markdown-links-config.json",
    "chars": 362,
    "preview": "{\n  \"ignorePatterns\": [\n    {\n        \"pattern\": \"^http://localhost\"\n    },\n    {\n        \"pattern\": \"^https://twitter.c"
  },
  {
    "path": ".github/workflows/release-check.yml",
    "chars": 419,
    "preview": "name: Release Checker\n\non:\n  pull_request_target:\n    paths: [ 'version.json' ]\n    types: [ opened, synchronize, reopen"
  },
  {
    "path": ".github/workflows/releaser.yml",
    "chars": 299,
    "preview": "name: Releaser\n\non:\n  push:\n    paths: [ 'version.json' ]\n  workflow_dispatch:\n\npermissions:\n  contents: write\n\nconcurre"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 244,
    "preview": "name: Close Stale Issues\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n  workflow_dispatch:\n\npermissions:\n  issues: write\n  p"
  },
  {
    "path": ".github/workflows/tagpush.yml",
    "chars": 291,
    "preview": "name: Tag Push Checker\n\non:\n  push:\n    tags:\n      - v*\n\npermissions:\n  contents: read\n  issues: write\n\nconcurrency:\n  "
  },
  {
    "path": ".github/workflows/upstream.yml",
    "chars": 1616,
    "preview": "on:\n  pull_request:\n    branches:\n      - master\n  push:\n    branches:\n      - master\nname: Upstream Test\n\njobs:\n  unit:"
  },
  {
    "path": ".gitignore",
    "chars": 70,
    "preview": "*.swp\n.idea\n*.qlog\n*.sqlog\n*.qlog.zst\n*.sqlog.zst\ngo.work\ngo.work.sum\n"
  },
  {
    "path": ".golangci.yml",
    "chars": 421,
    "preview": "version: \"2\"\n\nrun:\n  timeout: 5m\n\nissues:\n  max-issues-per-linter: 0\n  max-same-issues: 0\n  exclude-rules:\n    - path: _"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 23073,
    "preview": "# Table Of Contents <!-- omit in toc -->\n- [v0.28.0](#v0280)\n- [v0.27.0](#v0270)\n- [v0.26.4](#v0264)\n- [v0.26.3](#v0263)"
  },
  {
    "path": "FUNDING.json",
    "chars": 231,
    "preview": "{\n    \"opRetro\": {\n      \"projectId\": \"0xc71faa1bcb4ceb785816c3f22823377e9e5e7c48649badd9f0a0ce491f20d4b3\"\n    },\n    \"d"
  },
  {
    "path": "LICENSE",
    "chars": 1083,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Juan Batiz-Benet\n\nPermission is hereby granted, free of charge, to any person "
  },
  {
    "path": "README.md",
    "chars": 9208,
    "preview": "\n<h1 align=\"center\">\n  <a href=\"https://libp2p.io/\"><img width=\"250\" src=\"https://github.com/libp2p/libp2p/blob/master/l"
  },
  {
    "path": "SECURITY.md",
    "chars": 939,
    "preview": "# Security Policy\n\ngo-libp2p is still in development. This means that there may be problems in our protocols,\nor there m"
  },
  {
    "path": "config/config.go",
    "chars": 23713,
    "preview": "package config\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"slices\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-lib"
  },
  {
    "path": "config/config_test.go",
    "chars": 399,
    "preview": "package config\n\nimport (\n\t\"testing\"\n)\n\nfunc TestNilOption(t *testing.T) {\n\tvar cfg Config\n\toptsRun := 0\n\topt := func(_ *"
  },
  {
    "path": "config/host.go",
    "chars": 701,
    "preview": "package config\n\nimport (\n\t\"context\"\n\n\tbasichost \"github.com/libp2p/go-libp2p/p2p/host/basic\"\n\trouted \"github.com/libp2p/"
  },
  {
    "path": "config/quic.go",
    "chars": 1108,
    "preview": "package config\n\nimport (\n\t\"crypto/sha256\"\n\t\"io\"\n\n\t\"golang.org/x/crypto/hkdf\"\n\n\t\"github.com/libp2p/go-libp2p/core/crypto\""
  },
  {
    "path": "core/alias.go",
    "chars": 1309,
    "preview": "// Package core provides convenient access to foundational, central go-libp2p primitives via type aliases.\npackage core\n"
  },
  {
    "path": "core/connmgr/decay.go",
    "chars": 4087,
    "preview": "package connmgr\n\nimport (\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n)\n\n// Decayer is implemented by connec"
  },
  {
    "path": "core/connmgr/gater.go",
    "chars": 4160,
    "preview": "package connmgr\n\nimport (\n\tma \"github.com/multiformats/go-multiaddr\"\n\n\t\"github.com/libp2p/go-libp2p/core/control\"\n\t\"gith"
  },
  {
    "path": "core/connmgr/manager.go",
    "chars": 3903,
    "preview": "// Package connmgr provides connection tracking and management interfaces for libp2p.\n//\n// The ConnManager interface ex"
  },
  {
    "path": "core/connmgr/null.go",
    "chars": 1064,
    "preview": "package connmgr\n\nimport (\n\t\"context\"\n\n\t\"github.com/libp2p/go-libp2p/core/network\"\n\t\"github.com/libp2p/go-libp2p/core/pee"
  },
  {
    "path": "core/connmgr/presets.go",
    "chars": 1720,
    "preview": "package connmgr\n\nimport (\n\t\"math\"\n\t\"time\"\n)\n\n// DecayNone applies no decay.\nfunc DecayNone() DecayFn {\n\treturn func(valu"
  },
  {
    "path": "core/control/disconnect.go",
    "chars": 296,
    "preview": "package control\n\n// DisconnectReason communicates the reason why a connection is being closed.\n//\n// A zero value stands"
  },
  {
    "path": "core/crypto/bench_test.go",
    "chars": 3143,
    "preview": "package crypto\n\nimport \"testing\"\n\nfunc BenchmarkSignRSA1B(b *testing.B)      { RunBenchmarkSignRSA(b, 1) }\nfunc Benchmar"
  },
  {
    "path": "core/crypto/ecdsa.go",
    "chars": 5342,
    "preview": "package crypto\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"encoding/as"
  },
  {
    "path": "core/crypto/ecdsa_test.go",
    "chars": 2391,
    "preview": "package crypto\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/rand\"\n\t\"testing\"\n)\n\nfunc TestECDSABasicSignAndVerify(t *testing.T) {\n\t"
  },
  {
    "path": "core/crypto/ed25519.go",
    "chars": 3959,
    "preview": "package crypto\n\nimport (\n\t\"bytes\"\n\t\"crypto/ed25519\"\n\t\"crypto/subtle\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\tpb \"github.com/libp2p/go-l"
  },
  {
    "path": "core/crypto/ed25519_test.go",
    "chars": 4379,
    "preview": "package crypto\n\nimport (\n\t\"crypto/ed25519\"\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/crypto/pb\"\n\n\t\"g"
  },
  {
    "path": "core/crypto/fixture_test.go",
    "chars": 2923,
    "preview": "package crypto_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/"
  },
  {
    "path": "core/crypto/key.go",
    "chars": 6138,
    "preview": "// Package crypto implements various cryptographic utilities used by libp2p.\n// This includes a Public and Private key i"
  },
  {
    "path": "core/crypto/key_test.go",
    "chars": 5856,
    "preview": "package crypto_test\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"c"
  },
  {
    "path": "core/crypto/key_to_stdlib.go",
    "chars": 1864,
    "preview": "package crypto\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\n\t\"github.com/decred/dcrd/dcrec/secp2"
  },
  {
    "path": "core/crypto/pb/crypto.pb.go",
    "chars": 7478,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.6\n// \tprotoc        v5.29.2\n// sou"
  },
  {
    "path": "core/crypto/pb/crypto.proto",
    "chars": 331,
    "preview": "syntax = \"proto2\";\n\npackage crypto.pb;\n\noption go_package = \"github.com/libp2p/go-libp2p/core/crypto/pb\";\n\nenum KeyType "
  },
  {
    "path": "core/crypto/rsa_common.go",
    "chars": 739,
    "preview": "package crypto\n\nimport (\n\t\"fmt\"\n\t\"os\"\n)\n\n// WeakRsaKeyEnv is an environment variable which, when set, lowers the\n// mini"
  },
  {
    "path": "core/crypto/rsa_go.go",
    "chars": 3966,
    "preview": "package crypto\n\nimport (\n\t\"crypto\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"io\"\n\n\tpb \"gi"
  },
  {
    "path": "core/crypto/rsa_test.go",
    "chars": 3480,
    "preview": "package crypto\n\nimport (\n\t\"crypto/rand\"\n\t\"testing\"\n)\n\nfunc TestRSABasicSignAndVerify(t *testing.T) {\n\tpriv, pub, err := "
  },
  {
    "path": "core/crypto/secp256k1.go",
    "chars": 3589,
    "preview": "package crypto\n\nimport (\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n\n\tpb \"github.com/libp2p/go-libp2p/core/crypto/pb\"\n\t\"github.com/li"
  },
  {
    "path": "core/crypto/secp256k1_test.go",
    "chars": 1576,
    "preview": "package crypto\n\nimport (\n\t\"crypto/rand\"\n\t\"testing\"\n)\n\nfunc TestSecp256k1BasicSignAndVerify(t *testing.T) {\n\tpriv, pub, e"
  },
  {
    "path": "core/crypto/test_data/2.priv",
    "chars": 21,
    "preview": "\b\u0002\u0012 1A`jPLD4\u0017N[\u001f-\u0007XFX"
  },
  {
    "path": "core/crypto/test_data/2.pub",
    "chars": 19,
    "preview": "\b\u0002\u0012!\u00025@*5QMU&PkS\u0003\u0016֢"
  },
  {
    "path": "core/crypto/test_data/2.sig",
    "chars": 33,
    "preview": "0D\u0002 13Z\u0016\u0012Cu\u001aܛ@L\u0002 I!EGuCꏲpCG5I<@;Y"
  },
  {
    "path": "core/discovery/discovery.go",
    "chars": 745,
    "preview": "// Package discovery provides service advertisement and peer discovery interfaces for libp2p.\npackage discovery\n\nimport "
  },
  {
    "path": "core/discovery/options.go",
    "chars": 874,
    "preview": "package discovery\n\nimport \"time\"\n\n// DiscoveryOpt is a single discovery option.\ntype Option func(opts *Options) error\n\n/"
  },
  {
    "path": "core/event/addrs.go",
    "chars": 3520,
    "preview": "package event\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/record\"\n\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\n// Add"
  },
  {
    "path": "core/event/bus.go",
    "chars": 3019,
    "preview": "package event\n\nimport (\n\t\"io\"\n\t\"reflect\"\n)\n\n// SubscriptionOpt represents a subscriber option. Use the options exposed b"
  },
  {
    "path": "core/event/dht.go",
    "chars": 722,
    "preview": "package event\n\n// RawJSON is a type that contains a raw JSON string.\ntype RawJSON string\n\n// GenericDHTEvent is a type t"
  },
  {
    "path": "core/event/doc.go",
    "chars": 636,
    "preview": "// Package event contains the abstractions for a local event bus, along with the standard events\n// that libp2p subsyste"
  },
  {
    "path": "core/event/identify.go",
    "chars": 1570,
    "preview": "package event\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/network\"\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n\t\"github.co"
  },
  {
    "path": "core/event/nattype.go",
    "chars": 1050,
    "preview": "package event\n\nimport \"github.com/libp2p/go-libp2p/core/network\"\n\n// EvtNATDeviceTypeChanged is an event struct to be em"
  },
  {
    "path": "core/event/network.go",
    "chars": 2066,
    "preview": "package event\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/network\"\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n)\n\n// EvtPe"
  },
  {
    "path": "core/event/protocol.go",
    "chars": 991,
    "preview": "package event\n\nimport (\n\tpeer \"github.com/libp2p/go-libp2p/core/peer\"\n\tprotocol \"github.com/libp2p/go-libp2p/core/protoc"
  },
  {
    "path": "core/event/reachability.go",
    "chars": 786,
    "preview": "package event\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/network\"\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\n// Evt"
  },
  {
    "path": "core/host/helpers.go",
    "chars": 259,
    "preview": "package host\n\nimport \"github.com/libp2p/go-libp2p/core/peer\"\n\n// InfoFromHost returns a peer.AddrInfo struct with the Ho"
  },
  {
    "path": "core/host/host.go",
    "chars": 2678,
    "preview": "// Package host provides the core Host interface for libp2p.\n//\n// Host represents a single libp2p node in a peer-to-pee"
  },
  {
    "path": "core/internal/catch/catch.go",
    "chars": 346,
    "preview": "package catch\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime/debug\"\n)\n\nvar panicWriter io.Writer = os.Stderr\n\n// HandlePanic han"
  },
  {
    "path": "core/internal/catch/catch_test.go",
    "chars": 540,
    "preview": "package catch\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCatch(t *testing.T) {\n\tb"
  },
  {
    "path": "core/metrics/bandwidth.go",
    "chars": 5365,
    "preview": "// Package metrics provides metrics collection and reporting interfaces for libp2p.\npackage metrics\n\nimport (\n\t\"time\"\n\n\t"
  },
  {
    "path": "core/metrics/bandwidth_test.go",
    "chars": 3899,
    "preview": "package metrics\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n\t\"github.com/libp2"
  },
  {
    "path": "core/metrics/reporter.go",
    "chars": 991,
    "preview": "// Package metrics provides metrics collection and reporting interfaces for libp2p.\npackage metrics\n\nimport (\n\t\"github.c"
  },
  {
    "path": "core/network/conn.go",
    "chars": 4952,
    "preview": "package network\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\n\tic \"github.com/libp2p/go-libp2p/core/crypto\"\n\n\t\"github.com/libp2p/go"
  },
  {
    "path": "core/network/context.go",
    "chars": 4457,
    "preview": "package network\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\n// DialPeerTimeout is the default timeout for a single call to `DialPeer"
  },
  {
    "path": "core/network/context_test.go",
    "chars": 1427,
    "preview": "package network\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDefaultTimeo"
  },
  {
    "path": "core/network/errors.go",
    "chars": 1466,
    "preview": "package network\n\nimport (\n\t\"errors\"\n\t\"net\"\n)\n\ntype temporaryError string\n\nfunc (e temporaryError) Error() string   { ret"
  },
  {
    "path": "core/network/mocks/mock_conn_management_scope.go",
    "chars": 4748,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ConnManageme"
  },
  {
    "path": "core/network/mocks/mock_peer_scope.go",
    "chars": 3500,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/libp2p/go-libp2p/core/network (interfaces: PeerScope)\n/"
  },
  {
    "path": "core/network/mocks/mock_protocol_scope.go",
    "chars": 3680,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ProtocolScop"
  },
  {
    "path": "core/network/mocks/mock_resource_manager.go",
    "chars": 6454,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ResourceMana"
  },
  {
    "path": "core/network/mocks/mock_resource_scope_span.go",
    "chars": 3662,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ResourceScop"
  },
  {
    "path": "core/network/mocks/mock_stream_management_scope.go",
    "chars": 6446,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/libp2p/go-libp2p/core/network (interfaces: StreamManage"
  },
  {
    "path": "core/network/mocks/network.go",
    "chars": 1052,
    "preview": "package mocknetwork\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -package mocknetwork -destination mock_resourc"
  },
  {
    "path": "core/network/mux.go",
    "chars": 5537,
    "preview": "package network\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n// ErrReset is returned when reading or wr"
  },
  {
    "path": "core/network/nattype.go",
    "chars": 2445,
    "preview": "package network\n\n// NATDeviceType indicates the type of the NAT device.\ntype NATDeviceType int\n\nconst (\n\t// NATDeviceTyp"
  },
  {
    "path": "core/network/network.go",
    "chars": 7063,
    "preview": "// Package network provides core networking abstractions for libp2p.\n//\n// The network package provides the high-level N"
  },
  {
    "path": "core/network/notifee.go",
    "chars": 1977,
    "preview": "package network\n\nimport (\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\n// Notifiee is an interface for an object wishin"
  },
  {
    "path": "core/network/notifee_test.go",
    "chars": 1627,
    "preview": "package network\n\nimport (\n\t\"testing\"\n\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\nfunc TestListen(T *testing.T) {\n\tvar"
  },
  {
    "path": "core/network/rcmgr.go",
    "chars": 15262,
    "preview": "package network\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n\t\"github.com/libp2p/go-l"
  },
  {
    "path": "core/network/stream.go",
    "chars": 960,
    "preview": "package network\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/protocol\"\n)\n\n// Stream represents a bidirectional channel b"
  },
  {
    "path": "core/peer/addrinfo.go",
    "chars": 3355,
    "preview": "package peer\n\nimport (\n\t\"fmt\"\n\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\n// AddrInfo is a small struct used to pass "
  },
  {
    "path": "core/peer/addrinfo_serde.go",
    "chars": 1060,
    "preview": "package peer\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/libp2p/go-libp2p/core/internal/catch\"\n\n\tma \"github.com/multiformat"
  },
  {
    "path": "core/peer/addrinfo_test.go",
    "chars": 4150,
    "preview": "package peer_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/libp2p/go-libp2p/core/peer\"\n\t\"github.com/stretchr/testify/require"
  },
  {
    "path": "core/peer/pb/peer_record.pb.go",
    "chars": 6895,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.6\n// \tprotoc        v5.29.2\n// sou"
  },
  {
    "path": "core/peer/pb/peer_record.proto",
    "chars": 1156,
    "preview": "syntax = \"proto3\";\n\npackage peer.pb;\n\noption go_package = \"github.com/libp2p/go-libp2p/core/peer/pb\";\n\n// PeerRecord mes"
  },
  {
    "path": "core/peer/peer.go",
    "chars": 5462,
    "preview": "// Package peer implements an object used to represent peers in the libp2p network.\npackage peer\n\nimport (\n\t\"errors\"\n\t\"f"
  },
  {
    "path": "core/peer/peer_serde.go",
    "chars": 1743,
    "preview": "// Package peer contains Protobuf and JSON serialization/deserialization methods for peer IDs.\npackage peer\n\nimport (\n\t\""
  },
  {
    "path": "core/peer/peer_serde_test.go",
    "chars": 1401,
    "preview": "package peer_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n\t. \"github.com/libp2p/go-libp2p/core/te"
  },
  {
    "path": "core/peer/peer_test.go",
    "chars": 6842,
    "preview": "package peer_test\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\tic \"github.com/libp2p/go-li"
  },
  {
    "path": "core/peer/record.go",
    "chars": 7674,
    "preview": "package peer\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/internal/catch\"\n\t\"github.com/libp2p/go"
  },
  {
    "path": "core/peer/record_test.go",
    "chars": 2001,
    "preview": "package peer_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/crypto\"\n\t. \"github.com/libp2p/go-lib"
  },
  {
    "path": "core/peerstore/helpers.go",
    "chars": 316,
    "preview": "package peerstore\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n)\n\n// AddrInfos returns an AddrInfo for each specif"
  },
  {
    "path": "core/peerstore/peerstore.go",
    "chars": 8840,
    "preview": "// Package peerstore provides types and interfaces for local storage of address information,\n// metadata, and public key"
  },
  {
    "path": "core/pnet/codec.go",
    "chars": 1324,
    "preview": "package pnet\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n)\n\nvar (\n\tpathPSKv1  = []byte(\""
  },
  {
    "path": "core/pnet/codec_test.go",
    "chars": 1960,
    "preview": "package pnet\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"testing\"\n)\n\nfunc bufWithBase(base string, windows bool) *bytes.Buff"
  },
  {
    "path": "core/pnet/env.go",
    "chars": 687,
    "preview": "package pnet\n\nimport \"os\"\n\n// EnvKey defines environment variable name for forcing usage of PNet in libp2p\n// When envir"
  },
  {
    "path": "core/pnet/error.go",
    "chars": 784,
    "preview": "package pnet\n\n// ErrNotInPrivateNetwork is an error that should be returned by libp2p when it\n// tries to dial with Forc"
  },
  {
    "path": "core/pnet/error_test.go",
    "chars": 409,
    "preview": "package pnet\n\nimport (\n\t\"errors\"\n\t\"testing\"\n)\n\nfunc TestIsPnetErr(t *testing.T) {\n\terr := NewError(\"test\")\n\n\tif err.Erro"
  },
  {
    "path": "core/pnet/protector.go",
    "chars": 290,
    "preview": "// Package pnet provides interfaces for private networking in libp2p.\npackage pnet\n\n// A PSK enables private network imp"
  },
  {
    "path": "core/protocol/id.go",
    "chars": 738,
    "preview": "package protocol\n\n// ID is an identifier used to write protocol headers in streams.\ntype ID string\n\n// These are reserve"
  },
  {
    "path": "core/protocol/switch.go",
    "chars": 3019,
    "preview": "// Package protocol provides core interfaces for protocol routing and negotiation in libp2p.\npackage protocol\n\nimport (\n"
  },
  {
    "path": "core/record/envelope.go",
    "chars": 9378,
    "preview": "package record\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/libp2p/go-libp2p/core/crypto"
  },
  {
    "path": "core/record/envelope_test.go",
    "chars": 7937,
    "preview": "package record_test\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/crypto\"\n\t. \"github.com/l"
  },
  {
    "path": "core/record/pb/envelope.pb.go",
    "chars": 5737,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.6\n// \tprotoc        v5.29.2\n// sou"
  },
  {
    "path": "core/record/pb/envelope.proto",
    "chars": 1090,
    "preview": "syntax = \"proto3\";\n\npackage record.pb;\n\nimport \"core/crypto/pb/crypto.proto\";\n\noption go_package = \"github.com/libp2p/go"
  },
  {
    "path": "core/record/record.go",
    "chars": 3731,
    "preview": "package record\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\n\t\"github.com/libp2p/go-libp2p/core/internal/catch\"\n)\n\nvar (\n\t// ErrPayloa"
  },
  {
    "path": "core/record/record_test.go",
    "chars": 1337,
    "preview": "package record\n\nimport \"testing\"\n\nvar testPayloadType = []byte(\"/libp2p/test/record/payload-type\")\n\ntype testPayload str"
  },
  {
    "path": "core/routing/options.go",
    "chars": 1191,
    "preview": "package routing\n\nimport \"maps\"\n\n// Option is a single routing option.\ntype Option func(opts *Options) error\n\n// Options "
  },
  {
    "path": "core/routing/query.go",
    "chars": 2844,
    "preview": "package routing\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n)\n\n// QueryEventType indicates th"
  },
  {
    "path": "core/routing/query_serde.go",
    "chars": 742,
    "preview": "package routing\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n)\n\nfunc (qe *QueryEvent) MarshalJSO"
  },
  {
    "path": "core/routing/query_test.go",
    "chars": 800,
    "preview": "package routing\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"testing\"\n)\n\nfunc TestEventsCancel(t *testing.T) {\n\tctx, cancel := "
  },
  {
    "path": "core/routing/routing.go",
    "chars": 4705,
    "preview": "// Package routing provides interfaces for peer routing and content routing in libp2p.\npackage routing\n\nimport (\n\t\"conte"
  },
  {
    "path": "core/sec/security.go",
    "chars": 1222,
    "preview": "// Package sec provides secure connection and transport interfaces for libp2p.\npackage sec\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t"
  },
  {
    "path": "core/test/addrs.go",
    "chars": 659,
    "preview": "package test\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"testing\"\n\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\nfunc GenerateTestAddrs"
  },
  {
    "path": "core/test/crypto.go",
    "chars": 484,
    "preview": "package test\n\nimport (\n\t\"math/rand\"\n\t\"sync/atomic\"\n\n\tci \"github.com/libp2p/go-libp2p/core/crypto\"\n)\n\nvar globalSeed atom"
  },
  {
    "path": "core/test/errors.go",
    "chars": 264,
    "preview": "package test\n\nimport (\n\t\"testing\"\n)\n\nfunc AssertNilError(t *testing.T, err error) {\n\tt.Helper()\n\tif err != nil {\n\t\tt.Err"
  },
  {
    "path": "core/test/mockclock.go",
    "chars": 3138,
    "preview": "package test\n\nimport (\n\t\"sort\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype MockClock struct {\n\tmu           sync.Mutex\n\tnow          time.Ti"
  },
  {
    "path": "core/test/mockclock_test.go",
    "chars": 713,
    "preview": "package test\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestMockClock(t *testing.T) {\n\tcl := NewMockClock()\n\tt1 := cl.InstantT"
  },
  {
    "path": "core/test/peer.go",
    "chars": 397,
    "preview": "package test\n\nimport (\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n\n\tmh \"github.com/multiformats"
  },
  {
    "path": "core/transport/transport.go",
    "chars": 8124,
    "preview": "// Package transport provides the Transport interface, which represents\n// the devices and network protocols used to sen"
  },
  {
    "path": "dashboards/README.md",
    "chars": 2610,
    "preview": "# Grafana Dashboards\n\nThis directory contains prebuilt dashboards (provided as JSON files) for various components.\nFor s"
  },
  {
    "path": "dashboards/autonat/autonat.json",
    "chars": 17396,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "dashboards/autonatv2/autonatv2.json",
    "chars": 17757,
    "preview": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n  "
  },
  {
    "path": "dashboards/autorelay/autorelay.json",
    "chars": 25112,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "dashboards/dashboard.yml",
    "chars": 266,
    "preview": "apiVersion: 1\n\nproviders:\n  - name: \"libp2p dashboard provider\"\n    orgId: 1\n    type: file\n    disableDeletion: false\n "
  },
  {
    "path": "dashboards/datasources.yml",
    "chars": 207,
    "preview": "apiVersion: 1\n\ndeleteDatasources:\n  - name: Prometheus\n    orgId: 1\n\ndatasources:\n  - name: Prometheus\n    orgId: 1\n    "
  },
  {
    "path": "dashboards/docker-compose-linux.yml",
    "chars": 401,
    "preview": "version: \"3.7\"\nservices:\n  prometheus:\n    network_mode: \"host\"\n    extra_hosts:\n      # define a host.docker.internal a"
  },
  {
    "path": "dashboards/docker-compose.base.yml",
    "chars": 1195,
    "preview": "version: \"3.7\"\nservices:\n  prometheus:\n    image: prom/prometheus:latest\n    ports:\n      - \"9090:9090\"\n    volumes:\n   "
  },
  {
    "path": "dashboards/eventbus/eventbus.json",
    "chars": 13528,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "dashboards/holepunch/holepunch.json",
    "chars": 26668,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "dashboards/host-addrs/host-addrs.json",
    "chars": 6297,
    "preview": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n  "
  },
  {
    "path": "dashboards/identify/identify.json",
    "chars": 21407,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "dashboards/prometheus.yml",
    "chars": 609,
    "preview": "global:\n  scrape_interval: 15s\n  scrape_timeout: 10s\n  evaluation_interval: 15s\nalerting:\n  alertmanagers:\n  - scheme: h"
  },
  {
    "path": "dashboards/relaysvc/relaysvc.json",
    "chars": 29624,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "dashboards/resource-manager/README.md",
    "chars": 699,
    "preview": "# Ready to go Grafana Dashboard\n\nHere are some prebuilt dashboards that you can add to your Grafana instance. To\nimport "
  },
  {
    "path": "dashboards/resource-manager/resource-manager.json",
    "chars": 47677,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "dashboards/swarm/swarm.json",
    "chars": 89992,
    "preview": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type"
  },
  {
    "path": "defaults.go",
    "chars": 7470,
    "preview": "package libp2p\n\n// This file contains all the default configuration options.\n\nimport (\n\t\"crypto/rand\"\n\n\t\"github.com/libp"
  },
  {
    "path": "docs/flaky-tests.md",
    "chars": 1521,
    "preview": "# Debugging Flaky Tests\n\nIf a test is flaky in CI it's probably because there's some timing issue. The\ntest probably dep"
  },
  {
    "path": "examples/README.md",
    "chars": 1343,
    "preview": "# go-libp2p examples and tutorials\n\nIn this folder, you can find a variety of examples to help you get started in using "
  },
  {
    "path": "examples/go.mod",
    "chars": 6672,
    "preview": "module github.com/libp2p/go-libp2p/examples\n\ngo 1.24\n\nrequire (\n\tgithub.com/caddyserver/certmagic v0.21.6\n\tgithub.com/go"
  },
  {
    "path": "examples/go.sum",
    "chars": 64004,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.31.0/go.mod h1"
  },
  {
    "path": "examples/ipfs-camp-2019/README.md",
    "chars": 937,
    "preview": "# IPFS Camp 2019 - Course B\nWe've included some scaffolding to help you through the workshop. The folders\nin this reposi"
  },
  {
    "path": "examples/ipfs-camp-2019/go.mod",
    "chars": 5453,
    "preview": "module github.com/libp2p/go-libp2p/examples/ipfs-camp-2019\n\ngo 1.24\n\nrequire (\n\tgithub.com/gogo/protobuf v1.3.2\n\tgithub."
  },
  {
    "path": "examples/ipfs-camp-2019/go.sum",
    "chars": 57018,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.31.0/go.mod h1"
  },
  {
    "path": "examples/metrics-and-dashboards/README.md",
    "chars": 405,
    "preview": "# Metrics and Dashboards\n\nAn example to demonstrate using Prometheus and Grafana to view go-libp2p\nmetrics. Sets up a Pr"
  },
  {
    "path": "examples/metrics-and-dashboards/compose.yml",
    "chars": 369,
    "preview": "services:\n  prometheus:\n    image: prom/prometheus:latest\n    ports:\n      - \"9090:9090\"\n    volumes:\n      - ../example"
  },
  {
    "path": "examples/metrics-and-dashboards/go-libp2p-node.Dockerfile",
    "chars": 146,
    "preview": "FROM golang:alpine\nWORKDIR /app\nCOPY ./main.go .\nRUN go mod init example.com/m/v2\nRUN go mod tidy\nRUN go build main.go\nE"
  },
  {
    "path": "examples/metrics-and-dashboards/main.go",
    "chars": 2067,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p\""
  },
  {
    "path": "examples/metrics-and-dashboards/prometheus.yml",
    "chars": 367,
    "preview": "global:\n  scrape_interval: 1m\n\nscrape_configs:\n  - job_name: \"prometheus\"\n    scrape_interval: 1m\n    static_configs:\n  "
  },
  {
    "path": "examples/pubsub/README.md",
    "chars": 535,
    "preview": "# go-libp2p-pubsub examples\n\nThis directory contains example projects that use [go-libp2p-pubsub](https://github.com/lib"
  },
  {
    "path": "examples/pubsub/basic-chat-with-rendezvous/.gitignore",
    "chars": 5,
    "preview": "chat\n"
  },
  {
    "path": "examples/pubsub/basic-chat-with-rendezvous/README.md",
    "chars": 921,
    "preview": "# go-libp2p-pubsub chat with rendezvous example\n\nThis example project allows multiple peers to chat among each other usi"
  },
  {
    "path": "examples/pubsub/basic-chat-with-rendezvous/go.mod",
    "chars": 5424,
    "preview": "module github.com/libp2p/go-libp2p/examples/pubsub/chat\n\ngo 1.24\n\nrequire (\n\tgithub.com/libp2p/go-libp2p v0.33.0\n\tgithub"
  },
  {
    "path": "examples/pubsub/basic-chat-with-rendezvous/go.sum",
    "chars": 56356,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.31.0/go.mod h1"
  },
  {
    "path": "examples/pubsub/basic-chat-with-rendezvous/main.go",
    "chars": 3030,
    "preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/libp2p/go-libp2p\"\n\tdht \"github.com"
  },
  {
    "path": "examples/testutils/logharness.go",
    "chars": 2923,
    "preview": "package testutils\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n)\n\n// A LogHarness runs sets of "
  },
  {
    "path": "examples/testutils/net.go",
    "chars": 693,
    "preview": "package testutils\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"testing\"\n)\n\n// FindFreePort attempts to find an unused tcp port\nfunc FindFre"
  },
  {
    "path": "fx_options_test.go",
    "chars": 1063,
    "preview": "package libp2p\n\nimport (\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/event\"\n\t\"github.com/libp2p/go-libp2p/core/host\"\n"
  },
  {
    "path": "go.mod",
    "chars": 4348,
    "preview": "module github.com/libp2p/go-libp2p\n\ngo 1.25.7\n\nretract v0.26.1 // Tag was applied incorrectly due to a bug in the releas"
  },
  {
    "path": "go.sum",
    "chars": 22113,
    "preview": "filippo.io/bigmod v0.1.1-0.20260103110540-f8a47775ebe5 h1:JA0fFr+kxpqTdxR9LOBiTWpGNchqmkcsgmdeJZRclZ0=\nfilippo.io/bigmod"
  },
  {
    "path": "gologshim/gologshim.go",
    "chars": 6864,
    "preview": "// Package gologshim provides slog-based logging for go-libp2p that works\n// standalone or integrates with go-log for un"
  },
  {
    "path": "gologshim/gologshim_test.go",
    "chars": 7490,
    "preview": "package gologshim\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"log/slog\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n)\n\n// mockBridge simulat"
  },
  {
    "path": "leaky_tests/README.md",
    "chars": 136,
    "preview": "Tests that leak goroutines for various reasons. Mostly because libp2p node shutdown logic doesn't run if we fail to cons"
  },
  {
    "path": "leaky_tests/leaky_test.go",
    "chars": 357,
    "preview": "package leaky_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p\"\n)\n\nfunc TestBadTransportConstructor(t"
  },
  {
    "path": "libp2p.go",
    "chars": 2137,
    "preview": "package libp2p\n\nimport (\n\t\"github.com/libp2p/go-libp2p/config\"\n\t\"github.com/libp2p/go-libp2p/core/host\"\n)\n\n// Config des"
  },
  {
    "path": "libp2p_test.go",
    "chars": 26997,
    "preview": "package libp2p\n\nimport (\n\t\"context\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"cry"
  },
  {
    "path": "limits.go",
    "chars": 4519,
    "preview": "package libp2p\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/protocol\"\n\t\"github.com/libp2p/go-libp2p/p2p/host/autonat\"\n\tr"
  },
  {
    "path": "options.go",
    "chars": 21462,
    "preview": "package libp2p\n\n// This file contains all libp2p configuration options (except the defaults,\n// those are in defaults.go"
  },
  {
    "path": "options_filter.go",
    "chars": 1186,
    "preview": "package libp2p\n\nimport (\n\t\"github.com/libp2p/go-libp2p/core/connmgr\"\n\t\"github.com/libp2p/go-libp2p/core/control\"\n\t\"githu"
  },
  {
    "path": "p2p/canonicallog/canonicallog.go",
    "chars": 3102,
    "preview": "package canonicallog\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"math/rand\"\n\t\"net\"\n\t\"os\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/libp2p/"
  },
  {
    "path": "p2p/canonicallog/canonicallog_test.go",
    "chars": 821,
    "preview": "package canonicallog\n\nimport (\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/libp2p/go-libp2p/core/test\"\n\n\t\"g"
  },
  {
    "path": "p2p/discovery/backoff/backoff.go",
    "chars": 6129,
    "preview": "package backoff\n\nimport (\n\t\"math\"\n\t\"math/rand\"\n\t\"sync\"\n\t\"time\"\n\n\tlogging \"github.com/libp2p/go-libp2p/gologshim\"\n)\n\nvar "
  },
  {
    "path": "p2p/discovery/backoff/backoff_test.go",
    "chars": 4507,
    "preview": "package backoff\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n)\n\nfunc checkDelay(bkf B"
  },
  {
    "path": "p2p/discovery/backoff/backoffcache.go",
    "chars": 7549,
    "preview": "package backoff\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/discovery\"\n\t\"github.com/"
  },
  {
    "path": "p2p/discovery/backoff/backoffcache_test.go",
    "chars": 7723,
    "preview": "package backoff\n\nimport (\n\t\"context\"\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/p2p/discovery/mocks\""
  },
  {
    "path": "p2p/discovery/backoff/backoffconnector.go",
    "chars": 2634,
    "preview": "package backoff\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/host\"\n\t\"github.com/libp2p/go-li"
  },
  {
    "path": "p2p/discovery/backoff/backoffconnector_test.go",
    "chars": 2641,
    "preview": "package backoff\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/host\"\n\t\"githu"
  },
  {
    "path": "p2p/discovery/mdns/mdns.go",
    "chars": 6415,
    "preview": "package mdns\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/libp2p/go-libp2p/core/ho"
  },
  {
    "path": "p2p/discovery/mdns/mdns_test.go",
    "chars": 4322,
    "preview": "package mdns\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"slices\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p\"\n\t\"github.co"
  },
  {
    "path": "p2p/discovery/mocks/mocks.go",
    "chars": 2388,
    "preview": "package mocks\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/discovery\"\n\t\"github.com/libp2p/go"
  }
]

// ... and 457 more files (download for full content)

About this extraction

This page contains the full source code of the libp2p/go-libp2p GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 657 files (3.7 MB), approximately 999.3k tokens, and a symbol index with 5856 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!