diff --git a/perf/README.md b/perf/README.md new file mode 100644 index 000000000..5463f410b --- /dev/null +++ b/perf/README.md @@ -0,0 +1,49 @@ +# libp2p performance benchmarking + +This project includes the following components: + +- `terraform/`: a Terraform scripts to provision infrastructure +- `impl/`: implementations of the [libp2p perf protocol](https://github.com/libp2p/specs/pull/478) running on top of e.g. go-libp2p, rust-libp2p or Go's std-library https stack +- `runner/`: a set of scripts building and running the above implementations on the above infrastructure, reporting the results in `benchmark-results.json` + +Benchmark results can be visualized with https://observablehq.com/@mxinden-workspace/libp2p-perf. + +## Provision infrastructure + +1. `cd terraform` +2. Save your public SSH key as the file `./user.pub`. +3. `terraform init` +4. `terraform apply` + +## Build and run implementations + +1. `cd runner` +2. `npm ci` +3. `npm run start -- --client-public-ip $(terraform output -raw -state ../terraform/terraform.tfstate client_public_ip) --server-public-ip $(terraform output -raw -state ../terraform/terraform.tfstate server_public_ip)` + +## Deprovision infrastructure + +1. `cd terraform` +3. `terraform destroy` + +## Adding a new implementation + +1. Add implementation to `impl/`. Requirements for the binary: + - Running as a libp2p-perf server + - Command line flags + - `--run-server` + - `--secret-key-seed` unsigned integer to be used as a seed by libp2p-based implementations. Likely to go away in future iterations. + - Running as a libp2p-perf client + - Input via command line + - `--server-ip-address` + - `--transport` (see `runner/versions.ts` for possible variants) + - `--upload-bytes` number of bytes to upload per stream. + - `--download-bytes` number of bytes to upload per stream. + - Output + - Logging MUST go to stderr. + - Measurement output is printed to stdout as JSON in the form of: + ```json + {"connectionEstablishedSeconds":0.246442851,"uploadSeconds":0.000002077,"downloadSeconds":0.060712241} + ``` + +2. Reference implementation in `runner/src/versions.ts`. diff --git a/perf/impl/Makefile b/perf/impl/Makefile new file mode 100644 index 000000000..29e9ea363 --- /dev/null +++ b/perf/impl/Makefile @@ -0,0 +1,24 @@ +GO_SUBDIRS := $(wildcard go-libp2p/*/.) +RUST_SUBDIRS := $(wildcard rust-libp2p/*/.) +RUST_QUINN_SUBDIRS := $(wildcard rust-libp2p-quinn/*/.) +HTTPS_SUBDIRS := $(wildcard https/*/.) +QUIC_GO_SUBDIRS := $(wildcard quic-go/*/.) + +all: $(RUST_SUBDIRS) $(RUST_QUINN_SUBDIRS) $(GO_SUBDIRS) $(HTTPS_SUBDIRS) $(QUIC_GO_SUBDIRS) +$(RUST_SUBDIRS): + $(MAKE) -C $@ +$(RUST_QUINN_SUBDIRS): + $(MAKE) -C $@ +$(GO_SUBDIRS): + $(MAKE) -C $@ +$(HTTPS_SUBDIRS): + $(MAKE) -C $@ +$(QUIC_GO_SUBDIRS): + $(MAKE) -C $@ + +clean: $(RUST_SUBDIRS:%=%clean) $(RUST_QUINN_SUBDIRS:%=%clean) $(GO_SUBDIRS:%=%clean) $(HTTPS_SUBDIRS:%=%clean) $(QUIC_GO_SUBDIRS:%=%clean) + +%clean: + $(MAKE) -C $* clean + +.PHONY: $(RUST_SUBDIRS) $(RUST_QUINN_SUBDIRS) $(GO_SUBDIRS) $(HTTPS_SUBDIRS) $(QUIC_GO_SUBDIRS) all clean diff --git a/perf/impl/go-libp2p/.gitignore b/perf/impl/go-libp2p/.gitignore new file mode 100644 index 000000000..6652a25c1 --- /dev/null +++ b/perf/impl/go-libp2p/.gitignore @@ -0,0 +1,4 @@ +go-libp2p-*.zip +go-libp2p-* +go-libp2p-*/* +image.json diff --git a/perf/impl/go-libp2p/v0.27/.gitignore b/perf/impl/go-libp2p/v0.27/.gitignore new file mode 100644 index 000000000..d06b4219a --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/.gitignore @@ -0,0 +1,3 @@ +perf +.cache +v0.27 \ No newline at end of file diff --git a/perf/impl/go-libp2p/v0.27/Dockerfile b/perf/impl/go-libp2p/v0.27/Dockerfile new file mode 100644 index 000000000..5bb5b5aae --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/Dockerfile @@ -0,0 +1,14 @@ +# Build Go Binary +FROM golang:1.20-alpine AS builder + +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download +COPY *.go ./ +RUN go build -o perf . + +FROM alpine + +COPY --from=builder /app/perf /app/perf + +ENTRYPOINT [ "/app/perf" ] diff --git a/perf/impl/go-libp2p/v0.27/Makefile b/perf/impl/go-libp2p/v0.27/Makefile new file mode 100644 index 000000000..061ec78ef --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/Makefile @@ -0,0 +1,13 @@ +GO_FILES := $(wildcard *.go) + +all: perf + +perf: $(GO_FILES) + docker run --rm --user "$(shell id -u):$(shell id -g)" -v "$(shell pwd)":/usr/src/myapp -w /usr/src/myapp -e GOCACHE=/usr/src/myapp/.cache golang:1.20 go build -o perf . + +clean: + rm perf + rm .cache + rm v0.27 + +.PHONY: all clean diff --git a/perf/impl/go-libp2p/v0.27/README.md b/perf/impl/go-libp2p/v0.27/README.md new file mode 100644 index 000000000..99b140243 --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/README.md @@ -0,0 +1,12 @@ +1. Build with `docker build .` + +Run with: + +``` +docker run --rm -it +``` + +Run server with +``` +docker run --rm -it --entrypoint /app/server +``` diff --git a/perf/impl/go-libp2p/v0.27/go.mod b/perf/impl/go-libp2p/v0.27/go.mod new file mode 100644 index 000000000..1ddbb04de --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/go.mod @@ -0,0 +1,98 @@ +module github.com/libp2p/test-plans/perf/go/v0.27/v2 + +go 1.19 + +require ( + github.com/ipfs/go-log/v2 v2.5.1 + github.com/libp2p/go-buffer-pool v0.1.0 + github.com/libp2p/go-libp2p v0.27.0 + github.com/multiformats/go-multiaddr v0.9.0 + github.com/stretchr/testify v1.8.2 +) + +require ( + github.com/benbjohnson/clock v1.3.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/containerd/cgroups v1.1.0 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/elastic/gosigar v0.14.2 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect + github.com/huin/goupnp v1.1.0 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect + github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect + github.com/libp2p/go-msgio v0.3.0 // indirect + github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.1 // indirect + github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect + github.com/mattn/go-isatty v0.0.18 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/dns v1.1.53 // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multicodec v0.8.1 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect + github.com/onsi/ginkgo/v2 v2.9.2 // indirect + github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-19 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect + github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/dig v1.16.1 // indirect + go.uber.org/fx v1.19.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.7.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/blake3 v1.1.7 // indirect + nhooyr.io/websocket v1.8.7 // indirect +) diff --git a/perf/impl/go-libp2p/v0.27/go.sum b/perf/impl/go-libp2p/v0.27/go.sum new file mode 100644 index 000000000..6709fc64f --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/go.sum @@ -0,0 +1,506 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= +github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= +github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= +github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= +github.com/libp2p/go-libp2p v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= +github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= +github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= +github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= +github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= +github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= +github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= +github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= +github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= +github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= +github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= +github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= +github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= +github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= +github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= +github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= +go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= +go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= +go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/perf/impl/go-libp2p/v0.27/main.go b/perf/impl/go-libp2p/v0.27/main.go new file mode 100644 index 000000000..a1538d362 --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/main.go @@ -0,0 +1,143 @@ +package main + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "strings" + "time" + + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + tls "github.com/libp2p/go-libp2p/p2p/security/tls" + quic "github.com/libp2p/go-libp2p/p2p/transport/quic" + "github.com/libp2p/go-libp2p/p2p/transport/tcp" + "github.com/multiformats/go-multiaddr" +) + +func main() { + runServer := flag.Bool("run-server", false, "Should run as server") + serverAddr := flag.String("server-address", "", "Server address") + transport := flag.String("transport", "tcp", "Transport to use") + secretKeySeed := flag.Uint64("secret-key-seed", 0, "Server secret key seed") + uploadBytes := flag.Uint64("upload-bytes", 0, "Upload bytes") + downloadBytes := flag.Uint64("download-bytes", 0, "Download bytes") + flag.Parse() + + ipPort := strings.Split(*serverAddr, ":") + if len(ipPort) != 2 { + fmt.Println("Invalid server address format. Expected format: 'ip:port'") + return + } + ip := ipPort[0] + port := ipPort[1] + + tcpMultiAddrStr := fmt.Sprintf("/ip4/%s/tcp/%s", ip, port) + quicMultiAddrStr := fmt.Sprintf("/ip4/%s/udp/%s/quic-v1", ip, port) + + opts := []libp2p.Option{ + // Use TLS only instead of both TLS and Noise. Removes the + // additional multistream-select security protocol negotiation. + // Thus makes it easier to compare with TCP+TLS+HTTP/2 + libp2p.Security(tls.ID, tls.New), + + libp2p.DefaultListenAddrs, + libp2p.Transport(tcp.NewTCPTransport), + libp2p.Transport(quic.NewTransport), + libp2p.DefaultMuxers, + libp2p.DefaultPeerstore, + libp2p.DefaultResourceManager, + libp2p.DefaultConnectionManager, + libp2p.DefaultMultiaddrResolver, + libp2p.DefaultPrometheusRegisterer, + } + + if *runServer { + opts = append(opts, libp2p.ListenAddrStrings(tcpMultiAddrStr, quicMultiAddrStr)) + + // TODO: Fake identity. For testing only. + priv, _, err := crypto.GenerateEd25519Key(&simpleReader{seed: uint8(*secretKeySeed)}) + if err != nil { + panic(err) + } + opts = append(opts, libp2p.Identity(priv)) + } else { + opts = append(opts, libp2p.RandomIdentity) + } + + h, err := libp2p.NewWithoutDefaults(opts...) + if err != nil { + panic(err) + } + + perf := NewPerfService(h) + if *runServer { + for _, a := range h.Addrs() { + fmt.Println(a.Encapsulate(multiaddr.StringCast("/p2p/" + h.ID().String()))) + } + + select {} // run forever, exit on interrupt + } + + var multiAddrStr string + switch *transport { + case "tcp": + multiAddrStr = tcpMultiAddrStr + case "quic-v1": + multiAddrStr = quicMultiAddrStr + default: + fmt.Println("Invalid transport. Accepted values: 'tcp' or 'quic-v1'") + return + } + multiAddrStr = multiAddrStr + "/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN" + serverInfo, err := peer.AddrInfoFromString(multiAddrStr) + if err != nil { + panic(err) + } + + start := time.Now() + h.Peerstore().AddAddrs(serverInfo.ID, serverInfo.Addrs, peerstore.TempAddrTTL) + // Use h.Network().DialPeer() instead of h.Connect to skip waiting for + // identify protocol to finish. + _, err = h.Network().DialPeer(context.Background(), serverInfo.ID) + if err != nil { + panic(err) + } + connectionEstablished := time.Since(start) + + upload, download, err := perf.RunPerf(context.Background(), serverInfo.ID, uint64(*uploadBytes), uint64(*downloadBytes)) + if err != nil { + panic(err) + } + + jsonB, err := json.Marshal(Result{ + ConnectionEstablishedSeconds: connectionEstablished.Seconds(), + UploadSeconds: upload.Seconds(), + DownloadSeconds: download.Seconds(), + }) + if err != nil { + panic(err) + } + + fmt.Println(string(jsonB)) +} + +type Result struct { + ConnectionEstablishedSeconds float64 `json:"connectionEstablishedSeconds"` + UploadSeconds float64 `json:"uploadSeconds"` + DownloadSeconds float64 `json:"downloadSeconds"` +} + +type simpleReader struct { + seed uint8 +} + +func (r *simpleReader) Read(p []byte) (n int, err error) { + for i := range p { + p[i] = r.seed + } + return len(p), nil +} diff --git a/perf/impl/go-libp2p/v0.27/perf.go b/perf/impl/go-libp2p/v0.27/perf.go new file mode 100644 index 000000000..d620abd76 --- /dev/null +++ b/perf/impl/go-libp2p/v0.27/perf.go @@ -0,0 +1,171 @@ +package main + +import ( + "context" + "encoding/binary" + "fmt" + "io" + "time" + + logging "github.com/ipfs/go-log/v2" + pool "github.com/libp2p/go-buffer-pool" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + msmux "github.com/multiformats/go-multistream" +) + +var log = logging.Logger("perf") + +const ( + BlockSize = 64 << 10 + + ID = "/perf/1.0.0" +) + +type PerfService struct { + Host host.Host +} + +func NewPerfService(h host.Host) *PerfService { + ps := &PerfService{h} + h.SetStreamHandler(ID, ps.PerfHandler) + return ps +} + +func (p *PerfService) PerfHandler(s network.Stream) { + buf := pool.Get(BlockSize) + defer pool.Put(buf) + + u64Buf := make([]byte, 8) + _, err := io.ReadFull(s, u64Buf) + if err != nil { + log.Errorw("err", err) + s.Reset() + return + } + + bytesToSend := binary.BigEndian.Uint64(u64Buf) + + _, err = p.drainStream(context.Background(), s, buf) + if err != nil { + log.Errorw("err", err) + s.Reset() + return + } + + err = p.sendBytes(context.Background(), s, bytesToSend, buf) + if err != nil { + log.Errorw("err", err) + s.Reset() + return + } + +} + +func (ps *PerfService) sendBytes(ctx context.Context, s network.Stream, bytesToSend uint64, buf []byte) error { + for bytesToSend > 0 { + toSend := buf + if bytesToSend < BlockSize { + toSend = buf[:bytesToSend] + } + + n, err := s.Write(toSend) + if err != nil { + return err + } + bytesToSend -= uint64(n) + } + s.CloseWrite() + + return nil +} + +func (ps *PerfService) drainStream(ctx context.Context, s network.Stream, buf []byte) (uint64, error) { + var recvd uint64 + for { + n, err := s.Read(buf) + recvd += uint64(n) + if err == io.EOF { + return recvd, nil + } else if err != nil { + s.Reset() + return recvd, err + } + } +} + +func (ps *PerfService) RunPerf(ctx context.Context, p peer.ID, bytesToSend uint64, bytesToRecv uint64) (time.Duration, time.Duration, error) { + // Use ps.Host.Network().NewStream() instead of ps.Host.NewStream() to + // skip waiting for identify protocol to finish. + s, err := ps.Host.Network().NewStream(network.WithNoDial(ctx, "already dialed"), p) + if err != nil { + return 0, 0, err + } + s.SetProtocol(ID) + lzcon := msmux.NewMSSelect(s, ID) + s = &streamWrapper{ + Stream: s, + rw: lzcon, + } + + buf := pool.Get(BlockSize) + defer pool.Put(buf) + + sizeBuf := make([]byte, 8) + binary.BigEndian.PutUint64(sizeBuf, bytesToRecv) + + _, err = s.Write(sizeBuf) + if err != nil { + return 0, 0, err + } + + sendStart := time.Now() + err = ps.sendBytes(ctx, s, bytesToSend, buf) + if err != nil { + return 0, 0, err + } + sendDuration := time.Since(sendStart) + + recvStart := time.Now() + recvd, err := ps.drainStream(ctx, s, buf) + if err != nil { + return sendDuration, 0, err + } + recvDuration := time.Since(recvStart) + + if recvd != bytesToRecv { + return sendDuration, recvDuration, fmt.Errorf("expected to recv %d bytes, got %d", bytesToRecv, recvd) + } + + return sendDuration, recvDuration, nil +} + +type streamWrapper struct { + network.Stream + rw io.ReadWriteCloser +} + +func (s *streamWrapper) Read(b []byte) (int, error) { + return s.rw.Read(b) +} + +func (s *streamWrapper) Write(b []byte) (int, error) { + return s.rw.Write(b) +} + +func (s *streamWrapper) Close() error { + return s.rw.Close() +} + +func (s *streamWrapper) CloseWrite() error { + // Flush the handshake before closing, but ignore the error. The other + // end may have closed their side for reading. + // + // If something is wrong with the stream, the user will get on error on + // read instead. + if flusher, ok := s.rw.(interface{ Flush() error }); ok { + _ = flusher.Flush() + } + return s.Stream.CloseWrite() +} diff --git a/perf/impl/https/.gitignore b/perf/impl/https/.gitignore new file mode 100644 index 000000000..819c818b2 --- /dev/null +++ b/perf/impl/https/.gitignore @@ -0,0 +1,5 @@ +go-libp2p-*.zip +go-libp2p-* +go-libp2p-*/* +image.json +https diff --git a/perf/impl/https/v0.1/Makefile b/perf/impl/https/v0.1/Makefile new file mode 100644 index 000000000..7df62c287 --- /dev/null +++ b/perf/impl/https/v0.1/Makefile @@ -0,0 +1,11 @@ +GO_FILES := $(wildcard *.go) + +all: perf + +perf: $(GO_FILES) + docker run --rm --user "$(shell id -u):$(shell id -g)" -v "$(shell pwd)":/usr/src/myapp -w /usr/src/myapp -e GOCACHE=/usr/src/myapp/.cache golang:1.20 go build -o perf . + +clean: + rm perf + +.PHONY: all diff --git a/perf/impl/https/v0.1/go.mod b/perf/impl/https/v0.1/go.mod new file mode 100644 index 000000000..8d6dc86b2 --- /dev/null +++ b/perf/impl/https/v0.1/go.mod @@ -0,0 +1,20 @@ +module github.com/libp2p/test-plans/perf/go/https + +go 1.20 + +require ( + github.com/ipfs/go-cid v0.0.7 // indirect + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 // indirect + github.com/mr-tron/base58 v1.1.3 // indirect + github.com/multiformats/go-base32 v0.0.3 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.9.0 // indirect + github.com/multiformats/go-multiaddr-net v0.2.0 // indirect + github.com/multiformats/go-multibase v0.0.3 // indirect + github.com/multiformats/go-multihash v0.0.14 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + golang.org/x/crypto v0.1.0 // indirect + golang.org/x/sys v0.1.0 // indirect +) diff --git a/perf/impl/https/v0.1/go.sum b/perf/impl/https/v0.1/go.sum new file mode 100644 index 000000000..7adcab44b --- /dev/null +++ b/perf/impl/https/v0.1/go.sum @@ -0,0 +1,38 @@ +github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= +github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= +github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= +github.com/multiformats/go-multiaddr-net v0.2.0 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEnKgQNvVfCX5VDJk= +github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= +github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/perf/impl/https/v0.1/main.go b/perf/impl/https/v0.1/main.go new file mode 100644 index 000000000..fc1e97eac --- /dev/null +++ b/perf/impl/https/v0.1/main.go @@ -0,0 +1,200 @@ +package main + +import ( + "bytes" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/binary" + "encoding/json" + "encoding/pem" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "math/big" + "net" + "net/http" + "time" +) + +const ( + BlockSize = 64 << 10 +) + +func handleRequest(w http.ResponseWriter, r *http.Request) { + // Read the big-endian bytesToSend value + var bytesToSend uint64 + if err := binary.Read(r.Body, binary.BigEndian, &bytesToSend); err != nil { + http.Error(w, "failed to read uint64 value", http.StatusBadRequest) + return + } + + // Read and discard the remaining bytes in the request + io.Copy(io.Discard, r.Body) + + buf := make([]byte, BlockSize) + + for bytesToSend > 0 { + toSend := buf + if bytesToSend < BlockSize { + toSend = buf[:bytesToSend] + } + + n, err := w.Write(toSend) + if err != nil { + http.Error(w, "Failed write", http.StatusInternalServerError) + return + } + bytesToSend -= uint64(n) + } +} + +func runClient(serverAddr string, uploadBytes, downloadBytes uint64) (time.Duration, time.Duration, error) { + client := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + } + + reqBody := make([]byte, 8+uploadBytes) + binary.BigEndian.PutUint64(reqBody, uint64(downloadBytes)) + + startTime := time.Now() + resp, err := client.Post(fmt.Sprintf("https://%s/", serverAddr), "application/octet-stream", bytes.NewReader(reqBody)) + if err != nil { + return 0, 0, err + } + uploadDoneTime := time.Now() + + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return 0, 0, fmt.Errorf("error reading response: %w\n", err) + } + defer resp.Body.Close() + if uint64(len(respBody)) != downloadBytes { + return 0, 0, fmt.Errorf("expected %d bytes in response, but received %d\n", downloadBytes, len(respBody)) + } + + return uploadDoneTime.Sub(startTime), time.Since(uploadDoneTime), nil +} + +func generateEphemeralCertificate() (tls.Certificate, error) { + // Generate an ECDSA private key + privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return tls.Certificate{}, err + } + + // Set up the certificate template + template := x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + Organization: []string{"Ephemeral Cert"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(24 * time.Hour), + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + }, + BasicConstraintsValid: true, + } + + // Set the IP address if required + ip := net.ParseIP("127.0.0.1") + if ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } + + // Create a self-signed certificate + certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey) + if err != nil { + return tls.Certificate{}, err + } + + // PEM encode the certificate and private key + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) + privKeyBytes, err := x509.MarshalECPrivateKey(privKey) + if err != nil { + return tls.Certificate{}, err + } + privKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: privKeyBytes}) + + // Create a tls.Certificate from the PEM encoded certificate and private key + cert, err := tls.X509KeyPair(certPEM, privKeyPEM) + if err != nil { + return tls.Certificate{}, err + } + + return cert, nil +} + +type Result struct { + ConnectionEstablishedSeconds float64 `json:"connectionEstablishedSeconds"` + UploadSeconds float64 `json:"uploadSeconds"` + DownloadSeconds float64 `json:"downloadSeconds"` +} + +func main() { + runServer := flag.Bool("run-server", false, "Should run as server") + serverAddr := flag.String("server-address", "", "Server address") + _ = flag.String("transport", "", "Transport to use") + _ = flag.Uint64("secret-key-seed", 0, "Server secret key seed") + uploadBytes := flag.Uint64("upload-bytes", 0, "Upload bytes") + downloadBytes := flag.Uint64("download-bytes", 0, "Download bytes") + flag.Parse() + + if *runServer { + // Generate an ephemeral TLS certificate and private key + cert, err := generateEphemeralCertificate() + if err != nil { + log.Fatalf("Error generating ephemeral certificate: %v\n", err) + } + + // Create a new HTTPS server with the ephemeral certificate + tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} + server := &http.Server{ + Addr: ":4001", + TLSConfig: tlsConfig, + } + + http.HandleFunc("/", handleRequest) + + // Start the HTTPS server + fmt.Println("Starting HTTPS server on port 4001") + err = server.ListenAndServeTLS("", "") + if err != nil { + fmt.Printf("Error starting HTTPS server: %v\n", err) + } + } else { + // Client mode + if *serverAddr == "" { + flag.Usage() + log.Fatal("Error: Please provide valid server-address flags for client mode.") + } + + // Run the client and print the results + upload, download, err := runClient(*serverAddr, *uploadBytes, *downloadBytes) + if err != nil { + log.Fatal(err) + } + + jsonB, err := json.Marshal(Result{ + // TODO: Ideally we would be able to measure the Go std TCP+TLS connection establishment time. + ConnectionEstablishedSeconds: 0, + UploadSeconds: upload.Seconds(), + DownloadSeconds: download.Seconds(), + }) + if err != nil { + panic(err) + } + fmt.Println(string(jsonB)) + } +} diff --git a/perf/impl/quic-go/.gitignore b/perf/impl/quic-go/.gitignore new file mode 100644 index 000000000..6652a25c1 --- /dev/null +++ b/perf/impl/quic-go/.gitignore @@ -0,0 +1,4 @@ +go-libp2p-*.zip +go-libp2p-* +go-libp2p-*/* +image.json diff --git a/perf/impl/quic-go/v0.34/Makefile b/perf/impl/quic-go/v0.34/Makefile new file mode 100644 index 000000000..1a9b335f6 --- /dev/null +++ b/perf/impl/quic-go/v0.34/Makefile @@ -0,0 +1,24 @@ +commitSha := bdfafffc8b7ec786ff41ea245f24920930eec720 + +all: perf + +perf: perf-${commitSha} + docker run --rm --user "$(shell id -u):$(shell id -g)" -v "$(shell pwd)/perf-${commitSha}":/usr/src/myapp -w /usr/src/myapp -e GOCACHE=/usr/src/myapp/.cache golang:1.20 go build -o perf cmd/main.go + cp perf-${commitSha}/perf . + +perf-${commitSha}: perf-${commitSha}.zip + unzip -o perf-${commitSha}.zip + +perf-${commitSha}.zip: + wget -O $@ "https://github.com/quic-go/perf/archive/${commitSha}.zip" + +clean: + rm perf-*.zip + rm -rf perf-* + rm perf + rm .cache + rm v0.27 + +.PHONY: all clean + + diff --git a/perf/impl/rust-libp2p-quinn/v0.52/Makefile b/perf/impl/rust-libp2p-quinn/v0.52/Makefile new file mode 100644 index 000000000..8c429563d --- /dev/null +++ b/perf/impl/rust-libp2p-quinn/v0.52/Makefile @@ -0,0 +1,22 @@ +commitSha := df5180aab0ca44129e195d6030a9cf20eb593376 + +all: perf + +perf: rust-libp2p-${commitSha}/target/release/perf + cp ./rust-libp2p-${commitSha}/target/release/perf . + +rust-libp2p-${commitSha}/target/release/perf: rust-libp2p-${commitSha} + docker run --rm --user "$(shell id -u):$(shell id -g)" -v "$(shell pwd)/rust-libp2p-${commitSha}":/usr/src/myapp -w /usr/src/myapp rust:1.69 cargo build --release --bin perf + +rust-libp2p-${commitSha}: rust-libp2p-${commitSha}.zip + unzip -o rust-libp2p-${commitSha}.zip + +rust-libp2p-${commitSha}.zip: +# TODO: Change to libp2p + wget -O $@ "https://github.com/mxinden/rust-libp2p/archive/${commitSha}.zip" + +clean: + rm rust-libp2p-*.zip + rm -rf rust-libp2p-* + +.PHONY: all clean run diff --git a/perf/impl/rust-libp2p/.gitignore b/perf/impl/rust-libp2p/.gitignore new file mode 100644 index 000000000..3162eca5c --- /dev/null +++ b/perf/impl/rust-libp2p/.gitignore @@ -0,0 +1,4 @@ +rust-libp2p-*.zip +rust-libp2p-* +rust-libp2p-*/* +image.json \ No newline at end of file diff --git a/perf/impl/rust-libp2p/v0.52/Makefile b/perf/impl/rust-libp2p/v0.52/Makefile new file mode 100644 index 000000000..95b91269d --- /dev/null +++ b/perf/impl/rust-libp2p/v0.52/Makefile @@ -0,0 +1,22 @@ +commitSha := 488f0072cb937394d6c5c4678a5504b63403316e + +all: perf + +perf: rust-libp2p-${commitSha}/target/release/perf + cp ./rust-libp2p-${commitSha}/target/release/perf . + +rust-libp2p-${commitSha}/target/release/perf: rust-libp2p-${commitSha} + docker run --rm --user "$(shell id -u):$(shell id -g)" -v "$(shell pwd)/rust-libp2p-${commitSha}":/usr/src/myapp -w /usr/src/myapp rust:1.69 cargo build --release --bin perf + +rust-libp2p-${commitSha}: rust-libp2p-${commitSha}.zip + unzip -o rust-libp2p-${commitSha}.zip + +rust-libp2p-${commitSha}.zip: +# TODO: Change to libp2p + wget -O $@ "https://github.com/mxinden/rust-libp2p/archive/${commitSha}.zip" + +clean: + rm rust-libp2p-*.zip + rm -rf rust-libp2p-* + +.PHONY: all clean run diff --git a/perf/runner/.gitignore b/perf/runner/.gitignore new file mode 100644 index 000000000..6a7f7218f --- /dev/null +++ b/perf/runner/.gitignore @@ -0,0 +1,2 @@ +# Ignore built ts files +dist/**/* \ No newline at end of file diff --git a/perf/runner/benchmark-results.json b/perf/runner/benchmark-results.json new file mode 100644 index 000000000..0657c4781 --- /dev/null +++ b/perf/runner/benchmark-results.json @@ -0,0 +1,4203 @@ +{ + "benchmarks": [ + { + "name": "Single Connection throughput – Upload 100 MiB", + "unit": "bit/s", + "results": [ + { + "result": [ + { + "connectionEstablishedSeconds": 0.070297314, + "uploadSeconds": 0.976105831, + "downloadSeconds": 1.28e-7 + }, + { + "connectionEstablishedSeconds": 0.061534425, + "uploadSeconds": 0.957481414, + "downloadSeconds": 8.1e-8 + }, + { + "connectionEstablishedSeconds": 0.060021929, + "uploadSeconds": 0.937863027, + "downloadSeconds": 7.4e-8 + }, + { + "connectionEstablishedSeconds": 0.063701509, + "uploadSeconds": 0.991100676, + "downloadSeconds": 5.1e-8 + }, + { + "connectionEstablishedSeconds": 0.066541962, + "uploadSeconds": 1.038524336, + "downloadSeconds": 1.21e-7 + } + ], + "implementation": "quic-go", + "version": "v0.34", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.12788271, + "uploadSeconds": 36.401081612, + "downloadSeconds": 0.062981043 + }, + { + "connectionEstablishedSeconds": 0.122861416, + "uploadSeconds": 34.449560649, + "downloadSeconds": 0.061166454 + }, + { + "connectionEstablishedSeconds": 0.129370637, + "uploadSeconds": 36.264773908, + "downloadSeconds": 0.0644781 + }, + { + "connectionEstablishedSeconds": 0.129144197, + "uploadSeconds": 36.257968261, + "downloadSeconds": 0.064331182 + }, + { + "connectionEstablishedSeconds": 0.129576206, + "uploadSeconds": 36.411659002, + "downloadSeconds": 0.064808922 + } + ], + "implementation": "rust-libp2p", + "version": "v0.52", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.070141303, + "uploadSeconds": 14.198241062, + "downloadSeconds": 0.000052912 + }, + { + "connectionEstablishedSeconds": 0.064929592, + "uploadSeconds": 10.68151263, + "downloadSeconds": 0.000059917 + }, + { + "connectionEstablishedSeconds": 0.064462749, + "uploadSeconds": 26.327155321, + "downloadSeconds": 0.00011333 + }, + { + "connectionEstablishedSeconds": 0.06161635, + "uploadSeconds": 9.109610004, + "downloadSeconds": 0.000124202 + }, + { + "connectionEstablishedSeconds": 0.063525618, + "uploadSeconds": 21.079123439, + "downloadSeconds": 0.000105298 + } + ], + "implementation": "rust-libp2p", + "version": "v0.52", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.065954244, + "uploadSeconds": 1.402745274, + "downloadSeconds": 0.000211507 + }, + { + "connectionEstablishedSeconds": 0.065088775, + "uploadSeconds": 1.449638775, + "downloadSeconds": 0.000058087 + }, + { + "connectionEstablishedSeconds": 0.063314602, + "uploadSeconds": 1.3934497750000001, + "downloadSeconds": 0.000127509 + }, + { + "connectionEstablishedSeconds": 0.065340678, + "uploadSeconds": 1.438934371, + "downloadSeconds": 0.000109151 + }, + { + "connectionEstablishedSeconds": 0.063592102, + "uploadSeconds": 1.395796978, + "downloadSeconds": 0.00008171 + } + ], + "implementation": "rust-libp2p-quinn", + "version": "v0.52", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 2.7865382739999998, + "downloadSeconds": 0.000018388 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 2.621148716, + "downloadSeconds": 0.000002242 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 2.760585642, + "downloadSeconds": 0.000004662 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 2.806644015, + "downloadSeconds": 0.000019645 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 2.9810749899999998, + "downloadSeconds": 0.000002576 + } + ], + "implementation": "https", + "version": "v0.1", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.187666955, + "uploadSeconds": 2.824455271, + "downloadSeconds": 0.123028053 + }, + { + "connectionEstablishedSeconds": 0.19545875, + "uploadSeconds": 2.93147859, + "downloadSeconds": 0.127536761 + }, + { + "connectionEstablishedSeconds": 0.18985107, + "uploadSeconds": 2.85914096, + "downloadSeconds": 0.124491918 + }, + { + "connectionEstablishedSeconds": 0.181920988, + "uploadSeconds": 2.7478558299999998, + "downloadSeconds": 0.119709 + }, + { + "connectionEstablishedSeconds": 0.195685163, + "uploadSeconds": 2.955947802, + "downloadSeconds": 0.129634301 + } + ], + "implementation": "go-libp2p", + "version": "v0.27", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.068654638, + "uploadSeconds": 1.252551193, + "downloadSeconds": 0.064037004 + }, + { + "connectionEstablishedSeconds": 0.064522167, + "uploadSeconds": 1.239043305, + "downloadSeconds": 0.060060905 + }, + { + "connectionEstablishedSeconds": 0.06527666, + "uploadSeconds": 1.279113568, + "downloadSeconds": 0.061957179 + }, + { + "connectionEstablishedSeconds": 0.06920229, + "uploadSeconds": 1.3390372, + "downloadSeconds": 0.064796753 + }, + { + "connectionEstablishedSeconds": 0.066522893, + "uploadSeconds": 1.320509869, + "downloadSeconds": 0.064084372 + } + ], + "implementation": "go-libp2p", + "version": "v0.27", + "transportStack": "quic-v1" + } + ], + "parameters": { + "uploadBytes": 104857600, + "downloadBytes": 0 + } + }, + { + "name": "Single Connection throughput – Download 100 MiB", + "unit": "bit/s", + "results": [ + { + "result": [ + { + "connectionEstablishedSeconds": 0.066102425, + "uploadSeconds": 6.05e-7, + "downloadSeconds": 1.079131029 + }, + { + "connectionEstablishedSeconds": 0.063745934, + "uploadSeconds": 6.87e-7, + "downloadSeconds": 1.045033606 + }, + { + "connectionEstablishedSeconds": 0.064553974, + "uploadSeconds": 5.13e-7, + "downloadSeconds": 1.05987753 + }, + { + "connectionEstablishedSeconds": 0.06553008, + "uploadSeconds": 6.43e-7, + "downloadSeconds": 1.076902353 + }, + { + "connectionEstablishedSeconds": 0.062761144, + "uploadSeconds": 6.02e-7, + "downloadSeconds": 1.030542493 + } + ], + "implementation": "quic-go", + "version": "v0.34", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.13057814, + "uploadSeconds": 0.06504925, + "downloadSeconds": 36.728523097 + }, + { + "connectionEstablishedSeconds": 0.124944384, + "uploadSeconds": 0.062065698, + "downloadSeconds": 35.961353068 + }, + { + "connectionEstablishedSeconds": 0.130586181, + "uploadSeconds": 0.064887786, + "downloadSeconds": 42.21106346 + }, + { + "connectionEstablishedSeconds": 0.126708476, + "uploadSeconds": 0.062921055, + "downloadSeconds": 41.79504972 + }, + { + "connectionEstablishedSeconds": 0.126277922, + "uploadSeconds": 0.062710965, + "downloadSeconds": 41.416179838 + } + ], + "implementation": "rust-libp2p", + "version": "v0.52", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.063571426, + "uploadSeconds": 0.122524527, + "downloadSeconds": 14.688501904 + }, + { + "connectionEstablishedSeconds": 0.061588969, + "uploadSeconds": 0.119751648, + "downloadSeconds": 13.676063442 + }, + { + "connectionEstablishedSeconds": 0.062454824, + "uploadSeconds": 0.121421404, + "downloadSeconds": 28.953030009 + }, + { + "connectionEstablishedSeconds": 0.064480155, + "uploadSeconds": 0.125556611, + "downloadSeconds": 13.615676327 + }, + { + "connectionEstablishedSeconds": 0.063835283, + "uploadSeconds": 0.124031403, + "downloadSeconds": 24.377706009 + } + ], + "implementation": "rust-libp2p", + "version": "v0.52", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.06377155, + "uploadSeconds": 0.123363888, + "downloadSeconds": 1.341300474 + }, + { + "connectionEstablishedSeconds": 0.063434258, + "uploadSeconds": 0.123371646, + "downloadSeconds": 1.3334225210000001 + }, + { + "connectionEstablishedSeconds": 0.062023495, + "uploadSeconds": 0.120662695, + "downloadSeconds": 1.317308826 + }, + { + "connectionEstablishedSeconds": 0.066228473, + "uploadSeconds": 0.128940994, + "downloadSeconds": 1.397749371 + }, + { + "connectionEstablishedSeconds": 0.063049748, + "uploadSeconds": 0.122582746, + "downloadSeconds": 1.341124802 + } + ], + "implementation": "rust-libp2p-quinn", + "version": "v0.52", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186073896, + "downloadSeconds": 2.6670878609999997 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.193873239, + "downloadSeconds": 3.019374899 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.184416829, + "downloadSeconds": 2.793003994 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.192357858, + "downloadSeconds": 2.810105741 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.190407138, + "downloadSeconds": 2.76563917 + } + ], + "implementation": "https", + "version": "v0.1", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.187946812, + "uploadSeconds": 0.000002542, + "downloadSeconds": 3.352702091 + }, + { + "connectionEstablishedSeconds": 0.18968377, + "uploadSeconds": 0.000004511, + "downloadSeconds": 2.947320389 + }, + { + "connectionEstablishedSeconds": 0.193786619, + "uploadSeconds": 0.000026, + "downloadSeconds": 3.02479625 + }, + { + "connectionEstablishedSeconds": 0.188444252, + "uploadSeconds": 0.000002602, + "downloadSeconds": 3.136940616 + }, + { + "connectionEstablishedSeconds": 0.181702222, + "uploadSeconds": 0.000002266, + "downloadSeconds": 2.92347864 + } + ], + "implementation": "go-libp2p", + "version": "v0.27", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.068277261, + "uploadSeconds": 0.000018181, + "downloadSeconds": 1.375710908 + }, + { + "connectionEstablishedSeconds": 0.068015565, + "uploadSeconds": 0.000001609, + "downloadSeconds": 1.378146646 + }, + { + "connectionEstablishedSeconds": 0.0642284, + "uploadSeconds": 0.00000254, + "downloadSeconds": 1.293543339 + }, + { + "connectionEstablishedSeconds": 0.064465047, + "uploadSeconds": 0.000001623, + "downloadSeconds": 1.447395593 + }, + { + "connectionEstablishedSeconds": 0.064851976, + "uploadSeconds": 0.000001697, + "downloadSeconds": 1.350367435 + } + ], + "implementation": "go-libp2p", + "version": "v0.27", + "transportStack": "quic-v1" + } + ], + "parameters": { + "uploadBytes": 0, + "downloadBytes": 104857600 + } + }, + { + "name": "Connection establishment + 1 byte round trip latencies", + "unit": "s", + "results": [ + { + "result": [ + { + "connectionEstablishedSeconds": 0.064751978, + "uploadSeconds": 0.000001965, + "downloadSeconds": 0.062446835 + }, + { + "connectionEstablishedSeconds": 0.064369628, + "uploadSeconds": 9.78e-7, + "downloadSeconds": 0.062578705 + }, + { + "connectionEstablishedSeconds": 0.064172156, + "uploadSeconds": 0.000002109, + "downloadSeconds": 0.062397217 + }, + { + "connectionEstablishedSeconds": 0.062744165, + "uploadSeconds": 0.000001819, + "downloadSeconds": 0.060947384 + }, + { + "connectionEstablishedSeconds": 0.063608696, + "uploadSeconds": 0.000002409, + "downloadSeconds": 0.061858335 + }, + { + "connectionEstablishedSeconds": 0.064578852, + "uploadSeconds": 0.000001965, + "downloadSeconds": 0.062762314 + }, + { + "connectionEstablishedSeconds": 0.063750336, + "uploadSeconds": 0.000002109, + "downloadSeconds": 0.061983581 + }, + { + "connectionEstablishedSeconds": 0.062759314, + "uploadSeconds": 0.000001921, + "downloadSeconds": 0.060979078 + }, + { + "connectionEstablishedSeconds": 0.06165765, + "uploadSeconds": 9.47e-7, + "downloadSeconds": 0.060007441 + }, + { + "connectionEstablishedSeconds": 0.065447388, + "uploadSeconds": 0.000001973, + "downloadSeconds": 0.063719339 + }, + { + "connectionEstablishedSeconds": 0.065495014, + "uploadSeconds": 9.32e-7, + "downloadSeconds": 0.063662471 + }, + { + "connectionEstablishedSeconds": 0.064261877, + "uploadSeconds": 0.000002008, + "downloadSeconds": 0.062547339 + }, + { + "connectionEstablishedSeconds": 0.066444556, + "uploadSeconds": 0.000001956, + "downloadSeconds": 0.064616305 + }, + { + "connectionEstablishedSeconds": 0.065927723, + "uploadSeconds": 0.000001918, + "downloadSeconds": 0.064011682 + }, + { + "connectionEstablishedSeconds": 0.065767091, + "uploadSeconds": 8.66e-7, + "downloadSeconds": 0.063979506 + }, + { + "connectionEstablishedSeconds": 0.06644492, + "uploadSeconds": 0.000001964, + "downloadSeconds": 0.064624779 + }, + { + "connectionEstablishedSeconds": 0.067616685, + "uploadSeconds": 9.93e-7, + "downloadSeconds": 0.064315283 + }, + { + "connectionEstablishedSeconds": 0.064648078, + "uploadSeconds": 8.86e-7, + "downloadSeconds": 0.062781844 + }, + { + "connectionEstablishedSeconds": 0.060107655, + "uploadSeconds": 0.000001963, + "downloadSeconds": 0.058309479 + }, + { + "connectionEstablishedSeconds": 0.065304135, + "uploadSeconds": 0.000001949, + "downloadSeconds": 0.063783022 + }, + { + "connectionEstablishedSeconds": 0.065603339, + "uploadSeconds": 0.000001949, + "downloadSeconds": 0.063819812 + }, + { + "connectionEstablishedSeconds": 0.065066854, + "uploadSeconds": 0.000001909, + "downloadSeconds": 0.063351459 + }, + { + "connectionEstablishedSeconds": 0.062264515, + "uploadSeconds": 0.000002194, + "downloadSeconds": 0.060431368 + }, + { + "connectionEstablishedSeconds": 0.063081703, + "uploadSeconds": 8.1e-7, + "downloadSeconds": 0.061449283 + }, + { + "connectionEstablishedSeconds": 0.062678158, + "uploadSeconds": 0.000001858, + "downloadSeconds": 0.060888549 + }, + { + "connectionEstablishedSeconds": 0.065686849, + "uploadSeconds": 0.000001959, + "downloadSeconds": 0.063887908 + }, + { + "connectionEstablishedSeconds": 0.065484867, + "uploadSeconds": 7.72e-7, + "downloadSeconds": 0.063815737 + }, + { + "connectionEstablishedSeconds": 0.062981089, + "uploadSeconds": 0.000001946, + "downloadSeconds": 0.061245878 + }, + { + "connectionEstablishedSeconds": 0.063169451, + "uploadSeconds": 0.000001903, + "downloadSeconds": 0.061477289 + }, + { + "connectionEstablishedSeconds": 0.064226782, + "uploadSeconds": 0.000002021, + "downloadSeconds": 0.062439107 + }, + { + "connectionEstablishedSeconds": 0.067262367, + "uploadSeconds": 0.000001891, + "downloadSeconds": 0.065454886 + }, + { + "connectionEstablishedSeconds": 0.064497, + "uploadSeconds": 9.22e-7, + "downloadSeconds": 0.062909674 + }, + { + "connectionEstablishedSeconds": 0.063489099, + "uploadSeconds": 0.000001997, + "downloadSeconds": 0.061678745 + }, + { + "connectionEstablishedSeconds": 0.064675257, + "uploadSeconds": 8.04e-7, + "downloadSeconds": 0.062282573 + }, + { + "connectionEstablishedSeconds": 0.065565437, + "uploadSeconds": 0.00000195, + "downloadSeconds": 0.063750759 + }, + { + "connectionEstablishedSeconds": 0.063480697, + "uploadSeconds": 0.000002012, + "downloadSeconds": 0.061626039 + }, + { + "connectionEstablishedSeconds": 0.065412879, + "uploadSeconds": 7.45e-7, + "downloadSeconds": 0.063621641 + }, + { + "connectionEstablishedSeconds": 0.063473789, + "uploadSeconds": 0.0000019, + "downloadSeconds": 0.061745584 + }, + { + "connectionEstablishedSeconds": 0.064495907, + "uploadSeconds": 0.000001982, + "downloadSeconds": 0.062785263 + }, + { + "connectionEstablishedSeconds": 0.065840125, + "uploadSeconds": 0.00000209, + "downloadSeconds": 0.064120456 + }, + { + "connectionEstablishedSeconds": 0.065706276, + "uploadSeconds": 0.000001058, + "downloadSeconds": 0.063804527 + }, + { + "connectionEstablishedSeconds": 0.064814525, + "uploadSeconds": 0.000001968, + "downloadSeconds": 0.06296256 + }, + { + "connectionEstablishedSeconds": 0.061032044, + "uploadSeconds": 0.000001839, + "downloadSeconds": 0.059348977 + }, + { + "connectionEstablishedSeconds": 0.065201914, + "uploadSeconds": 7.97e-7, + "downloadSeconds": 0.063409635 + }, + { + "connectionEstablishedSeconds": 0.064642434, + "uploadSeconds": 0.00000181, + "downloadSeconds": 0.062844688 + }, + { + "connectionEstablishedSeconds": 0.066077649, + "uploadSeconds": 0.000001935, + "downloadSeconds": 0.064318069 + }, + { + "connectionEstablishedSeconds": 0.063682445, + "uploadSeconds": 8.42e-7, + "downloadSeconds": 0.061896631 + }, + { + "connectionEstablishedSeconds": 0.063308459, + "uploadSeconds": 0.000001795, + "downloadSeconds": 0.061484441 + }, + { + "connectionEstablishedSeconds": 0.059922386, + "uploadSeconds": 0.000001914, + "downloadSeconds": 0.058065268 + }, + { + "connectionEstablishedSeconds": 0.064627417, + "uploadSeconds": 0.000001823, + "downloadSeconds": 0.062800746 + }, + { + "connectionEstablishedSeconds": 0.064167577, + "uploadSeconds": 0.00000198, + "downloadSeconds": 0.062405582 + }, + { + "connectionEstablishedSeconds": 0.063558256, + "uploadSeconds": 7.7e-7, + "downloadSeconds": 0.06180833 + }, + { + "connectionEstablishedSeconds": 0.063632947, + "uploadSeconds": 0.000002043, + "downloadSeconds": 0.061918028 + }, + { + "connectionEstablishedSeconds": 0.063844984, + "uploadSeconds": 0.000001799, + "downloadSeconds": 0.062247867 + }, + { + "connectionEstablishedSeconds": 0.065057619, + "uploadSeconds": 0.000001961, + "downloadSeconds": 0.063216681 + }, + { + "connectionEstablishedSeconds": 0.062540966, + "uploadSeconds": 8.96e-7, + "downloadSeconds": 0.060688495 + }, + { + "connectionEstablishedSeconds": 0.064904633, + "uploadSeconds": 0.000001967, + "downloadSeconds": 0.063127793 + }, + { + "connectionEstablishedSeconds": 0.063064295, + "uploadSeconds": 7.88e-7, + "downloadSeconds": 0.060478559 + }, + { + "connectionEstablishedSeconds": 0.064051755, + "uploadSeconds": 0.00000179, + "downloadSeconds": 0.062258241 + }, + { + "connectionEstablishedSeconds": 0.065675425, + "uploadSeconds": 0.000001966, + "downloadSeconds": 0.06396088 + }, + { + "connectionEstablishedSeconds": 0.066136074, + "uploadSeconds": 8.33e-7, + "downloadSeconds": 0.064474014 + }, + { + "connectionEstablishedSeconds": 0.064002243, + "uploadSeconds": 8.18e-7, + "downloadSeconds": 0.062341859 + }, + { + "connectionEstablishedSeconds": 0.063851631, + "uploadSeconds": 0.000001997, + "downloadSeconds": 0.0621131 + }, + { + "connectionEstablishedSeconds": 0.064506957, + "uploadSeconds": 0.00000189, + "downloadSeconds": 0.062899723 + }, + { + "connectionEstablishedSeconds": 0.062909183, + "uploadSeconds": 0.000001904, + "downloadSeconds": 0.061122555 + }, + { + "connectionEstablishedSeconds": 0.065556422, + "uploadSeconds": 0.00000199, + "downloadSeconds": 0.06383543 + }, + { + "connectionEstablishedSeconds": 0.06365363, + "uploadSeconds": 0.000002292, + "downloadSeconds": 0.062093565 + }, + { + "connectionEstablishedSeconds": 0.064333966, + "uploadSeconds": 0.000001921, + "downloadSeconds": 0.062500201 + }, + { + "connectionEstablishedSeconds": 0.063589419, + "uploadSeconds": 0.000002079, + "downloadSeconds": 0.061868455 + }, + { + "connectionEstablishedSeconds": 0.062189631, + "uploadSeconds": 0.00000193, + "downloadSeconds": 0.0606924 + }, + { + "connectionEstablishedSeconds": 0.063825349, + "uploadSeconds": 6.95e-7, + "downloadSeconds": 0.06204725 + }, + { + "connectionEstablishedSeconds": 0.063109212, + "uploadSeconds": 0.000001852, + "downloadSeconds": 0.061355714 + }, + { + "connectionEstablishedSeconds": 0.062551758, + "uploadSeconds": 0.000001978, + "downloadSeconds": 0.060794018 + }, + { + "connectionEstablishedSeconds": 0.064215033, + "uploadSeconds": 8.48e-7, + "downloadSeconds": 0.062380982 + }, + { + "connectionEstablishedSeconds": 0.064608427, + "uploadSeconds": 0.000001923, + "downloadSeconds": 0.062862131 + }, + { + "connectionEstablishedSeconds": 0.063678964, + "uploadSeconds": 0.000001883, + "downloadSeconds": 0.061903887 + }, + { + "connectionEstablishedSeconds": 0.066294745, + "uploadSeconds": 0.000001903, + "downloadSeconds": 0.064500571 + }, + { + "connectionEstablishedSeconds": 0.061508703, + "uploadSeconds": 0.000001906, + "downloadSeconds": 0.059627627 + }, + { + "connectionEstablishedSeconds": 0.062808156, + "uploadSeconds": 0.00000188, + "downloadSeconds": 0.060939134 + }, + { + "connectionEstablishedSeconds": 0.061670305, + "uploadSeconds": 0.000002104, + "downloadSeconds": 0.059862602 + }, + { + "connectionEstablishedSeconds": 0.064523911, + "uploadSeconds": 0.000001819, + "downloadSeconds": 0.062845514 + }, + { + "connectionEstablishedSeconds": 0.062908637, + "uploadSeconds": 0.000001962, + "downloadSeconds": 0.06119366 + }, + { + "connectionEstablishedSeconds": 0.064118052, + "uploadSeconds": 8.67e-7, + "downloadSeconds": 0.062346119 + }, + { + "connectionEstablishedSeconds": 0.062284829, + "uploadSeconds": 8.69e-7, + "downloadSeconds": 0.060471826 + }, + { + "connectionEstablishedSeconds": 0.065628805, + "uploadSeconds": 9.51e-7, + "downloadSeconds": 0.064255004 + }, + { + "connectionEstablishedSeconds": 0.063255442, + "uploadSeconds": 0.000001919, + "downloadSeconds": 0.061307355 + }, + { + "connectionEstablishedSeconds": 0.062338916, + "uploadSeconds": 0.000001877, + "downloadSeconds": 0.060713508 + }, + { + "connectionEstablishedSeconds": 0.066092234, + "uploadSeconds": 8.77e-7, + "downloadSeconds": 0.064241899 + }, + { + "connectionEstablishedSeconds": 0.065546715, + "uploadSeconds": 8.61e-7, + "downloadSeconds": 0.063785994 + }, + { + "connectionEstablishedSeconds": 0.065282245, + "uploadSeconds": 8.22e-7, + "downloadSeconds": 0.063577701 + }, + { + "connectionEstablishedSeconds": 0.066437563, + "uploadSeconds": 8.53e-7, + "downloadSeconds": 0.064542893 + }, + { + "connectionEstablishedSeconds": 0.062982522, + "uploadSeconds": 0.000001949, + "downloadSeconds": 0.061157305 + }, + { + "connectionEstablishedSeconds": 0.064840196, + "uploadSeconds": 9.37e-7, + "downloadSeconds": 0.063083308 + }, + { + "connectionEstablishedSeconds": 0.062328395, + "uploadSeconds": 8.67e-7, + "downloadSeconds": 0.060646891 + }, + { + "connectionEstablishedSeconds": 0.065517896, + "uploadSeconds": 8.26e-7, + "downloadSeconds": 0.063675396 + }, + { + "connectionEstablishedSeconds": 0.06468413, + "uploadSeconds": 0.000002081, + "downloadSeconds": 0.062942522 + }, + { + "connectionEstablishedSeconds": 0.062145911, + "uploadSeconds": 0.000002038, + "downloadSeconds": 0.060389068 + }, + { + "connectionEstablishedSeconds": 0.06232188, + "uploadSeconds": 0.000002008, + "downloadSeconds": 0.059270087 + }, + { + "connectionEstablishedSeconds": 0.064469934, + "uploadSeconds": 0.000001808, + "downloadSeconds": 0.062752466 + }, + { + "connectionEstablishedSeconds": 0.062709635, + "uploadSeconds": 0.000002034, + "downloadSeconds": 0.060945351 + } + ], + "implementation": "quic-go", + "version": "v0.34", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.120934675, + "uploadSeconds": 0.060318856, + "downloadSeconds": 0.060104499 + }, + { + "connectionEstablishedSeconds": 0.128061517, + "uploadSeconds": 0.063605463, + "downloadSeconds": 0.063664715 + }, + { + "connectionEstablishedSeconds": 0.127658799, + "uploadSeconds": 0.063452656, + "downloadSeconds": 0.063454888 + }, + { + "connectionEstablishedSeconds": 0.125617667, + "uploadSeconds": 0.062401489, + "downloadSeconds": 0.062467259 + }, + { + "connectionEstablishedSeconds": 0.124154207, + "uploadSeconds": 0.061699826, + "downloadSeconds": 0.061724492 + }, + { + "connectionEstablishedSeconds": 0.127846138, + "uploadSeconds": 0.063515977, + "downloadSeconds": 0.063531759 + }, + { + "connectionEstablishedSeconds": 0.120729252, + "uploadSeconds": 0.059916196, + "downloadSeconds": 0.060001179 + }, + { + "connectionEstablishedSeconds": 0.127417463, + "uploadSeconds": 0.063285207, + "downloadSeconds": 0.063336793 + }, + { + "connectionEstablishedSeconds": 0.121040576, + "uploadSeconds": 0.060114305, + "downloadSeconds": 0.060168989 + }, + { + "connectionEstablishedSeconds": 0.124943479, + "uploadSeconds": 0.062034017, + "downloadSeconds": 0.062080267 + }, + { + "connectionEstablishedSeconds": 0.122475451, + "uploadSeconds": 0.060855996, + "downloadSeconds": 0.060879618 + }, + { + "connectionEstablishedSeconds": 0.1236592, + "uploadSeconds": 0.0611343, + "downloadSeconds": 0.061200789 + }, + { + "connectionEstablishedSeconds": 0.123640147, + "uploadSeconds": 0.061384688, + "downloadSeconds": 0.061466515 + }, + { + "connectionEstablishedSeconds": 0.118841315, + "uploadSeconds": 0.05895918, + "downloadSeconds": 0.059036116 + }, + { + "connectionEstablishedSeconds": 0.129343271, + "uploadSeconds": 0.064244239, + "downloadSeconds": 0.064332254 + }, + { + "connectionEstablishedSeconds": 0.126433629, + "uploadSeconds": 0.062770414, + "downloadSeconds": 0.062846733 + }, + { + "connectionEstablishedSeconds": 0.123173028, + "uploadSeconds": 0.061131114, + "downloadSeconds": 0.061217306 + }, + { + "connectionEstablishedSeconds": 0.125137804, + "uploadSeconds": 0.062109799, + "downloadSeconds": 0.062277841 + }, + { + "connectionEstablishedSeconds": 0.122518993, + "uploadSeconds": 0.060827891, + "downloadSeconds": 0.060882129 + }, + { + "connectionEstablishedSeconds": 0.127896226, + "uploadSeconds": 0.063507707, + "downloadSeconds": 0.063647707 + }, + { + "connectionEstablishedSeconds": 0.126060862, + "uploadSeconds": 0.062561714, + "downloadSeconds": 0.062696571 + }, + { + "connectionEstablishedSeconds": 0.120696113, + "uploadSeconds": 0.059911559, + "downloadSeconds": 0.059996766 + }, + { + "connectionEstablishedSeconds": 0.129053947, + "uploadSeconds": 0.064217787, + "downloadSeconds": 0.064187147 + }, + { + "connectionEstablishedSeconds": 0.124066876, + "uploadSeconds": 0.061617166, + "downloadSeconds": 0.061736398 + }, + { + "connectionEstablishedSeconds": 0.125927228, + "uploadSeconds": 0.062530847, + "downloadSeconds": 0.062595748 + }, + { + "connectionEstablishedSeconds": 0.128120761, + "uploadSeconds": 0.063630588, + "downloadSeconds": 0.063702889 + }, + { + "connectionEstablishedSeconds": 0.120337392, + "uploadSeconds": 0.059725874, + "downloadSeconds": 0.059786297 + }, + { + "connectionEstablishedSeconds": 0.125247067, + "uploadSeconds": 0.062183868, + "downloadSeconds": 0.281597541 + }, + { + "connectionEstablishedSeconds": 0.123262912, + "uploadSeconds": 0.061193402, + "downloadSeconds": 0.061281943 + }, + { + "connectionEstablishedSeconds": 0.125235129, + "uploadSeconds": 0.062211734, + "downloadSeconds": 0.062275937 + }, + { + "connectionEstablishedSeconds": 0.123164681, + "uploadSeconds": 0.061163995, + "downloadSeconds": 0.061252078 + }, + { + "connectionEstablishedSeconds": 0.12804124, + "uploadSeconds": 0.063571143, + "downloadSeconds": 0.063657599 + }, + { + "connectionEstablishedSeconds": 0.123137264, + "uploadSeconds": 0.061164433, + "downloadSeconds": 0.061262922 + }, + { + "connectionEstablishedSeconds": 0.124465393, + "uploadSeconds": 0.061852565, + "downloadSeconds": 0.061908292 + }, + { + "connectionEstablishedSeconds": 0.125980795, + "uploadSeconds": 0.062563852, + "downloadSeconds": 0.062633138 + }, + { + "connectionEstablishedSeconds": 0.124921288, + "uploadSeconds": 0.062041248, + "downloadSeconds": 0.062088885 + }, + { + "connectionEstablishedSeconds": 0.121878166, + "uploadSeconds": 0.060482514, + "downloadSeconds": 0.060604527 + }, + { + "connectionEstablishedSeconds": 0.125525756, + "uploadSeconds": 0.062363834, + "downloadSeconds": 0.062414314 + }, + { + "connectionEstablishedSeconds": 0.128761013, + "uploadSeconds": 0.063946436, + "downloadSeconds": 0.064037895 + }, + { + "connectionEstablishedSeconds": 0.122879624, + "uploadSeconds": 0.060991367, + "downloadSeconds": 0.061087944 + }, + { + "connectionEstablishedSeconds": 0.123025618, + "uploadSeconds": 0.061063762, + "downloadSeconds": 0.06114214 + }, + { + "connectionEstablishedSeconds": 0.127292488, + "uploadSeconds": 0.06321786, + "downloadSeconds": 0.063284921 + }, + { + "connectionEstablishedSeconds": 0.122220021, + "uploadSeconds": 0.060705551, + "downloadSeconds": 0.060791717 + }, + { + "connectionEstablishedSeconds": 0.130945698, + "uploadSeconds": 0.065055162, + "downloadSeconds": 0.065136451 + }, + { + "connectionEstablishedSeconds": 0.126904364, + "uploadSeconds": 0.062972605, + "downloadSeconds": 0.062994862 + }, + { + "connectionEstablishedSeconds": 0.127727215, + "uploadSeconds": 0.063402176, + "downloadSeconds": 0.06346753 + }, + { + "connectionEstablishedSeconds": 0.121838446, + "uploadSeconds": 0.060497519, + "downloadSeconds": 0.060547155 + }, + { + "connectionEstablishedSeconds": 0.122744381, + "uploadSeconds": 0.060963721, + "downloadSeconds": 0.061094253 + }, + { + "connectionEstablishedSeconds": 0.127691052, + "uploadSeconds": 0.063357898, + "downloadSeconds": 0.063426201 + }, + { + "connectionEstablishedSeconds": 0.120310544, + "uploadSeconds": 0.059725696, + "downloadSeconds": 0.059788932 + }, + { + "connectionEstablishedSeconds": 0.122420557, + "uploadSeconds": 0.060766143, + "downloadSeconds": 0.060826232 + }, + { + "connectionEstablishedSeconds": 0.125849669, + "uploadSeconds": 0.062454754, + "downloadSeconds": 0.062558146 + }, + { + "connectionEstablishedSeconds": 0.124735161, + "uploadSeconds": 0.061991959, + "downloadSeconds": 0.062021647 + }, + { + "connectionEstablishedSeconds": 0.131121068, + "uploadSeconds": 0.065110347, + "downloadSeconds": 0.065198194 + }, + { + "connectionEstablishedSeconds": 0.123359776, + "uploadSeconds": 0.061250163, + "downloadSeconds": 0.06132682 + }, + { + "connectionEstablishedSeconds": 0.118813692, + "uploadSeconds": 0.058992344, + "downloadSeconds": 0.059054347 + }, + { + "connectionEstablishedSeconds": 0.119864335, + "uploadSeconds": 0.059497153, + "downloadSeconds": 0.059581931 + }, + { + "connectionEstablishedSeconds": 0.126542452, + "uploadSeconds": 0.06282126, + "downloadSeconds": 0.062886158 + }, + { + "connectionEstablishedSeconds": 0.123810888, + "uploadSeconds": 0.061499964, + "downloadSeconds": 0.06154741 + }, + { + "connectionEstablishedSeconds": 0.12587658, + "uploadSeconds": 0.062511492, + "downloadSeconds": 0.062575783 + }, + { + "connectionEstablishedSeconds": 0.128565419, + "uploadSeconds": 0.06385599, + "downloadSeconds": 0.063953685 + }, + { + "connectionEstablishedSeconds": 0.124656418, + "uploadSeconds": 0.061917427, + "downloadSeconds": 0.061976147 + }, + { + "connectionEstablishedSeconds": 0.125494283, + "uploadSeconds": 0.06232114, + "downloadSeconds": 0.062370385 + }, + { + "connectionEstablishedSeconds": 0.124625158, + "uploadSeconds": 0.061885121, + "downloadSeconds": 0.061940325 + }, + { + "connectionEstablishedSeconds": 0.125954686, + "uploadSeconds": 0.062569357, + "downloadSeconds": 0.06262672 + }, + { + "connectionEstablishedSeconds": 0.12927773, + "uploadSeconds": 0.064277478, + "downloadSeconds": 0.064313302 + }, + { + "connectionEstablishedSeconds": 0.127408792, + "uploadSeconds": 0.063302092, + "downloadSeconds": 0.063400735 + }, + { + "connectionEstablishedSeconds": 0.127741644, + "uploadSeconds": 0.063456966, + "downloadSeconds": 0.063505067 + }, + { + "connectionEstablishedSeconds": 0.128843782, + "uploadSeconds": 0.063830003, + "downloadSeconds": 0.06391866 + }, + { + "connectionEstablishedSeconds": 0.123434963, + "uploadSeconds": 0.061278556, + "downloadSeconds": 0.061338622 + }, + { + "connectionEstablishedSeconds": 0.127779544, + "uploadSeconds": 0.063336665, + "downloadSeconds": 0.063413851 + }, + { + "connectionEstablishedSeconds": 0.124132235, + "uploadSeconds": 0.061671306, + "downloadSeconds": 0.061763426 + }, + { + "connectionEstablishedSeconds": 0.119273985, + "uploadSeconds": 0.059135882, + "downloadSeconds": 0.059188158 + }, + { + "connectionEstablishedSeconds": 0.129304256, + "uploadSeconds": 0.064229577, + "downloadSeconds": 0.064292811 + }, + { + "connectionEstablishedSeconds": 0.127846291, + "uploadSeconds": 0.063498451, + "downloadSeconds": 0.063584271 + }, + { + "connectionEstablishedSeconds": 0.127631297, + "uploadSeconds": 0.063379055, + "downloadSeconds": 0.063459619 + }, + { + "connectionEstablishedSeconds": 0.128862305, + "uploadSeconds": 0.064011224, + "downloadSeconds": 0.064089416 + }, + { + "connectionEstablishedSeconds": 0.123898529, + "uploadSeconds": 0.061647949, + "downloadSeconds": 0.061704126 + }, + { + "connectionEstablishedSeconds": 0.126427652, + "uploadSeconds": 0.062780577, + "downloadSeconds": 0.062850221 + }, + { + "connectionEstablishedSeconds": 0.12041383, + "uploadSeconds": 0.059765423, + "downloadSeconds": 0.05985171 + }, + { + "connectionEstablishedSeconds": 0.122487266, + "uploadSeconds": 0.060804338, + "downloadSeconds": 0.060884063 + }, + { + "connectionEstablishedSeconds": 0.12405444, + "uploadSeconds": 0.061615829, + "downloadSeconds": 0.0617448 + }, + { + "connectionEstablishedSeconds": 0.1252939, + "uploadSeconds": 0.062233868, + "downloadSeconds": 0.062298883 + }, + { + "connectionEstablishedSeconds": 0.127402042, + "uploadSeconds": 0.063241467, + "downloadSeconds": 0.063342943 + }, + { + "connectionEstablishedSeconds": 0.126685079, + "uploadSeconds": 0.06292761, + "downloadSeconds": 0.062982324 + }, + { + "connectionEstablishedSeconds": 0.121871274, + "uploadSeconds": 0.060740917, + "downloadSeconds": 0.060584697 + }, + { + "connectionEstablishedSeconds": 0.119699832, + "uploadSeconds": 0.059455631, + "downloadSeconds": 0.059498272 + }, + { + "connectionEstablishedSeconds": 0.129019714, + "uploadSeconds": 0.064098047, + "downloadSeconds": 0.064190354 + }, + { + "connectionEstablishedSeconds": 0.119018863, + "uploadSeconds": 0.059229123, + "downloadSeconds": 0.059185492 + }, + { + "connectionEstablishedSeconds": 0.125366127, + "uploadSeconds": 0.062341426, + "downloadSeconds": 0.062342015 + }, + { + "connectionEstablishedSeconds": 0.125611461, + "uploadSeconds": 0.062410843, + "downloadSeconds": 0.062456794 + }, + { + "connectionEstablishedSeconds": 0.123740612, + "uploadSeconds": 0.061438856, + "downloadSeconds": 0.061487596 + }, + { + "connectionEstablishedSeconds": 0.130171847, + "uploadSeconds": 0.064657351, + "downloadSeconds": 0.064722367 + }, + { + "connectionEstablishedSeconds": 0.121008144, + "uploadSeconds": 0.060096855, + "downloadSeconds": 0.060141129 + }, + { + "connectionEstablishedSeconds": 0.122261724, + "uploadSeconds": 0.060685092, + "downloadSeconds": 0.060783431 + }, + { + "connectionEstablishedSeconds": 0.12198358, + "uploadSeconds": 0.060587308, + "downloadSeconds": 0.060621551 + }, + { + "connectionEstablishedSeconds": 0.129276378, + "uploadSeconds": 0.064217955, + "downloadSeconds": 0.064279332 + }, + { + "connectionEstablishedSeconds": 0.117664798, + "uploadSeconds": 0.058423073, + "downloadSeconds": 0.058481222 + }, + { + "connectionEstablishedSeconds": 0.122264693, + "uploadSeconds": 0.060714713, + "downloadSeconds": 0.060778335 + }, + { + "connectionEstablishedSeconds": 0.12435423, + "uploadSeconds": 0.061728479, + "downloadSeconds": 0.061809844 + } + ], + "implementation": "rust-libp2p", + "version": "v0.52", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.062228087, + "uploadSeconds": 0.120893191, + "downloadSeconds": 0.000099165 + }, + { + "connectionEstablishedSeconds": 0.063734208, + "uploadSeconds": 0.123902018, + "downloadSeconds": 0.000045828 + }, + { + "connectionEstablishedSeconds": 0.064510474, + "uploadSeconds": 0.125358969, + "downloadSeconds": 0.000105478 + }, + { + "connectionEstablishedSeconds": 0.065255394, + "uploadSeconds": 0.127108206, + "downloadSeconds": 0.000088449 + }, + { + "connectionEstablishedSeconds": 0.066390359, + "uploadSeconds": 0.129048959, + "downloadSeconds": 0.000087506 + }, + { + "connectionEstablishedSeconds": 0.062640027, + "uploadSeconds": 0.121685794, + "downloadSeconds": 0.000085337 + }, + { + "connectionEstablishedSeconds": 0.064499552, + "uploadSeconds": 0.125410019, + "downloadSeconds": 0.000087664 + }, + { + "connectionEstablishedSeconds": 0.065494969, + "uploadSeconds": 0.127446356, + "downloadSeconds": 0.000085126 + }, + { + "connectionEstablishedSeconds": 0.06453883, + "uploadSeconds": 0.125435273, + "downloadSeconds": 0.00008866 + }, + { + "connectionEstablishedSeconds": 0.065465495, + "uploadSeconds": 0.127337886, + "downloadSeconds": 0.000088228 + }, + { + "connectionEstablishedSeconds": 0.065497585, + "uploadSeconds": 0.127547688, + "downloadSeconds": 0.000048445 + }, + { + "connectionEstablishedSeconds": 0.062053488, + "uploadSeconds": 0.120570934, + "downloadSeconds": 0.000051426 + }, + { + "connectionEstablishedSeconds": 0.065189638, + "uploadSeconds": 0.126649956, + "downloadSeconds": 0.000079552 + }, + { + "connectionEstablishedSeconds": 0.064666342, + "uploadSeconds": 0.125720425, + "downloadSeconds": 0.000089942 + }, + { + "connectionEstablishedSeconds": 0.062484754, + "uploadSeconds": 0.121424687, + "downloadSeconds": 0.0000493 + }, + { + "connectionEstablishedSeconds": 0.064606624, + "uploadSeconds": 0.125707048, + "downloadSeconds": 0.0000876 + }, + { + "connectionEstablishedSeconds": 0.066222267, + "uploadSeconds": 0.128878726, + "downloadSeconds": 0.00008468 + }, + { + "connectionEstablishedSeconds": 0.063119375, + "uploadSeconds": 0.122659138, + "downloadSeconds": 0.000105409 + }, + { + "connectionEstablishedSeconds": 0.064945702, + "uploadSeconds": 0.125868481, + "downloadSeconds": 0.000085921 + }, + { + "connectionEstablishedSeconds": 0.061924524, + "uploadSeconds": 0.120503709, + "downloadSeconds": 0.00007517 + }, + { + "connectionEstablishedSeconds": 0.063605631, + "uploadSeconds": 0.123602947, + "downloadSeconds": 0.000102754 + }, + { + "connectionEstablishedSeconds": 0.065523997, + "uploadSeconds": 0.127420361, + "downloadSeconds": 0.000106991 + }, + { + "connectionEstablishedSeconds": 0.063640155, + "uploadSeconds": 0.123723695, + "downloadSeconds": 0.000076951 + }, + { + "connectionEstablishedSeconds": 0.064030146, + "uploadSeconds": 0.124476116, + "downloadSeconds": 0.000083057 + }, + { + "connectionEstablishedSeconds": 0.063251595, + "uploadSeconds": 0.123027875, + "downloadSeconds": 0.000107909 + }, + { + "connectionEstablishedSeconds": 0.06472421, + "uploadSeconds": 0.125950818, + "downloadSeconds": 0.000050403 + }, + { + "connectionEstablishedSeconds": 0.063615584, + "uploadSeconds": 0.123676684, + "downloadSeconds": 0.000100003 + }, + { + "connectionEstablishedSeconds": 0.064527459, + "uploadSeconds": 0.125573941, + "downloadSeconds": 0.000142577 + }, + { + "connectionEstablishedSeconds": 0.065239512, + "uploadSeconds": 0.127007647, + "downloadSeconds": 0.000102753 + }, + { + "connectionEstablishedSeconds": 0.065002136, + "uploadSeconds": 0.126428268, + "downloadSeconds": 0.000100366 + }, + { + "connectionEstablishedSeconds": 0.064491103, + "uploadSeconds": 0.125496774, + "downloadSeconds": 0.000082914 + }, + { + "connectionEstablishedSeconds": 0.061470431, + "uploadSeconds": 0.119681012, + "downloadSeconds": 0.000092367 + }, + { + "connectionEstablishedSeconds": 0.066128934, + "uploadSeconds": 0.128684243, + "downloadSeconds": 0.000050939 + }, + { + "connectionEstablishedSeconds": 0.062860625, + "uploadSeconds": 0.122331128, + "downloadSeconds": 0.000077326 + }, + { + "connectionEstablishedSeconds": 0.065758037, + "uploadSeconds": 0.128014455, + "downloadSeconds": 0.000049593 + }, + { + "connectionEstablishedSeconds": 0.064911288, + "uploadSeconds": 0.126244849, + "downloadSeconds": 0.00008702 + }, + { + "connectionEstablishedSeconds": 0.060500391, + "uploadSeconds": 0.117433404, + "downloadSeconds": 0.000098985 + }, + { + "connectionEstablishedSeconds": 0.064570379, + "uploadSeconds": 0.125612761, + "downloadSeconds": 0.000052489 + }, + { + "connectionEstablishedSeconds": 0.061610704, + "uploadSeconds": 0.119766429, + "downloadSeconds": 0.000049095 + }, + { + "connectionEstablishedSeconds": 0.063889781, + "uploadSeconds": 0.124191347, + "downloadSeconds": 0.000102015 + }, + { + "connectionEstablishedSeconds": 0.063067354, + "uploadSeconds": 0.122699173, + "downloadSeconds": 0.000089304 + }, + { + "connectionEstablishedSeconds": 0.063439324, + "uploadSeconds": 0.123255208, + "downloadSeconds": 0.000085337 + }, + { + "connectionEstablishedSeconds": 0.065063968, + "uploadSeconds": 0.126475373, + "downloadSeconds": 0.000126626 + }, + { + "connectionEstablishedSeconds": 0.066271463, + "uploadSeconds": 0.128935528, + "downloadSeconds": 0.000046158 + }, + { + "connectionEstablishedSeconds": 0.063950299, + "uploadSeconds": 0.124443584, + "downloadSeconds": 0.000051703 + }, + { + "connectionEstablishedSeconds": 0.064774385, + "uploadSeconds": 0.126063081, + "downloadSeconds": 0.00007508 + }, + { + "connectionEstablishedSeconds": 0.065636329, + "uploadSeconds": 0.127636465, + "downloadSeconds": 0.000090008 + }, + { + "connectionEstablishedSeconds": 0.063451078, + "uploadSeconds": 0.123364682, + "downloadSeconds": 0.000101472 + }, + { + "connectionEstablishedSeconds": 0.06323798, + "uploadSeconds": 0.122975014, + "downloadSeconds": 0.000070985 + }, + { + "connectionEstablishedSeconds": 0.064770406, + "uploadSeconds": 0.126004915, + "downloadSeconds": 0.000072125 + }, + { + "connectionEstablishedSeconds": 0.065279787, + "uploadSeconds": 0.126962819, + "downloadSeconds": 0.000097796 + }, + { + "connectionEstablishedSeconds": 0.064901942, + "uploadSeconds": 0.125585521, + "downloadSeconds": 0.000049299 + }, + { + "connectionEstablishedSeconds": 0.061443554, + "uploadSeconds": 0.119494502, + "downloadSeconds": 0.000091291 + }, + { + "connectionEstablishedSeconds": 0.063441921, + "uploadSeconds": 0.123328693, + "downloadSeconds": 0.000049731 + }, + { + "connectionEstablishedSeconds": 0.062608409, + "uploadSeconds": 0.121783217, + "downloadSeconds": 0.000091694 + }, + { + "connectionEstablishedSeconds": 0.063711363, + "uploadSeconds": 0.123972621, + "downloadSeconds": 0.000103791 + }, + { + "connectionEstablishedSeconds": 0.064214588, + "uploadSeconds": 0.125143771, + "downloadSeconds": 0.000020481 + }, + { + "connectionEstablishedSeconds": 0.060506092, + "uploadSeconds": 0.117461449, + "downloadSeconds": 0.00009433 + }, + { + "connectionEstablishedSeconds": 0.06548947, + "uploadSeconds": 0.12762932, + "downloadSeconds": 0.000019611 + }, + { + "connectionEstablishedSeconds": 0.06343756, + "uploadSeconds": 0.12326629, + "downloadSeconds": 0.000080451 + }, + { + "connectionEstablishedSeconds": 0.064497925, + "uploadSeconds": 0.125432572, + "downloadSeconds": 0.000053455 + }, + { + "connectionEstablishedSeconds": 0.064198009, + "uploadSeconds": 0.124789315, + "downloadSeconds": 0.000102881 + }, + { + "connectionEstablishedSeconds": 0.065856671, + "uploadSeconds": 0.128240388, + "downloadSeconds": 0.000053864 + }, + { + "connectionEstablishedSeconds": 0.066265894, + "uploadSeconds": 0.129040126, + "downloadSeconds": 0.000090861 + }, + { + "connectionEstablishedSeconds": 0.064372464, + "uploadSeconds": 0.12513222, + "downloadSeconds": 0.00010157 + }, + { + "connectionEstablishedSeconds": 0.063916167, + "uploadSeconds": 0.124636789, + "downloadSeconds": 0.000073509 + }, + { + "connectionEstablishedSeconds": 0.061572516, + "uploadSeconds": 0.119719968, + "downloadSeconds": 0.000085707 + }, + { + "connectionEstablishedSeconds": 0.065074184, + "uploadSeconds": 0.126698852, + "downloadSeconds": 0.00008027 + }, + { + "connectionEstablishedSeconds": 0.06569187, + "uploadSeconds": 0.127787894, + "downloadSeconds": 0.000095077 + }, + { + "connectionEstablishedSeconds": 0.063378177, + "uploadSeconds": 0.123475499, + "downloadSeconds": 0.000103336 + }, + { + "connectionEstablishedSeconds": 0.064730038, + "uploadSeconds": 0.125953752, + "downloadSeconds": 0.000061881 + }, + { + "connectionEstablishedSeconds": 0.06603802, + "uploadSeconds": 0.128568222, + "downloadSeconds": 0.000022934 + }, + { + "connectionEstablishedSeconds": 0.062661405, + "uploadSeconds": 0.121714334, + "downloadSeconds": 0.000078985 + }, + { + "connectionEstablishedSeconds": 0.066337935, + "uploadSeconds": 0.129140541, + "downloadSeconds": 0.000086636 + }, + { + "connectionEstablishedSeconds": 0.063668639, + "uploadSeconds": 0.123844589, + "downloadSeconds": 0.000050411 + }, + { + "connectionEstablishedSeconds": 0.064122074, + "uploadSeconds": 0.12476925, + "downloadSeconds": 0.000075981 + }, + { + "connectionEstablishedSeconds": 0.065372135, + "uploadSeconds": 0.127211626, + "downloadSeconds": 0.000091012 + }, + { + "connectionEstablishedSeconds": 0.059813543, + "uploadSeconds": 0.116184542, + "downloadSeconds": 0.000076299 + }, + { + "connectionEstablishedSeconds": 0.064338913, + "uploadSeconds": 0.125357074, + "downloadSeconds": 0.000048772 + }, + { + "connectionEstablishedSeconds": 0.061904241, + "uploadSeconds": 0.120371589, + "downloadSeconds": 0.000085246 + }, + { + "connectionEstablishedSeconds": 0.062849555, + "uploadSeconds": 0.122130636, + "downloadSeconds": 0.00005213 + }, + { + "connectionEstablishedSeconds": 0.063626359, + "uploadSeconds": 0.123786209, + "downloadSeconds": 0.000073933 + }, + { + "connectionEstablishedSeconds": 0.065144197, + "uploadSeconds": 0.126835146, + "downloadSeconds": 0.000080652 + }, + { + "connectionEstablishedSeconds": 0.063006839, + "uploadSeconds": 0.122330209, + "downloadSeconds": 0.000100892 + }, + { + "connectionEstablishedSeconds": 0.0656745, + "uploadSeconds": 0.12785452, + "downloadSeconds": 0.000056427 + }, + { + "connectionEstablishedSeconds": 0.065664141, + "uploadSeconds": 0.127793254, + "downloadSeconds": 0.000089199 + }, + { + "connectionEstablishedSeconds": 0.063336824, + "uploadSeconds": 0.123224446, + "downloadSeconds": 0.00009833 + }, + { + "connectionEstablishedSeconds": 0.063508944, + "uploadSeconds": 0.123534801, + "downloadSeconds": 0.000090801 + }, + { + "connectionEstablishedSeconds": 0.063052371, + "uploadSeconds": 0.12258054, + "downloadSeconds": 0.000099776 + }, + { + "connectionEstablishedSeconds": 0.063967578, + "uploadSeconds": 0.12440295, + "downloadSeconds": 0.00009315 + }, + { + "connectionEstablishedSeconds": 0.064650102, + "uploadSeconds": 0.125943909, + "downloadSeconds": 0.000095094 + }, + { + "connectionEstablishedSeconds": 0.063100822, + "uploadSeconds": 0.122738159, + "downloadSeconds": 0.00005022 + }, + { + "connectionEstablishedSeconds": 0.062892339, + "uploadSeconds": 0.122973305, + "downloadSeconds": 0.000109195 + }, + { + "connectionEstablishedSeconds": 0.062691186, + "uploadSeconds": 0.121850273, + "downloadSeconds": 0.000046814 + }, + { + "connectionEstablishedSeconds": 0.065547722, + "uploadSeconds": 0.127526939, + "downloadSeconds": 0.000086215 + }, + { + "connectionEstablishedSeconds": 0.063465129, + "uploadSeconds": 0.123536217, + "downloadSeconds": 0.000049009 + }, + { + "connectionEstablishedSeconds": 0.066192294, + "uploadSeconds": 0.12883507, + "downloadSeconds": 0.00010391 + }, + { + "connectionEstablishedSeconds": 0.06537651, + "uploadSeconds": 0.1272119, + "downloadSeconds": 0.000073702 + }, + { + "connectionEstablishedSeconds": 0.062524589, + "uploadSeconds": 0.121543935, + "downloadSeconds": 0.000089477 + }, + { + "connectionEstablishedSeconds": 0.065393812, + "uploadSeconds": 0.127120697, + "downloadSeconds": 0.000077362 + } + ], + "implementation": "rust-libp2p", + "version": "v0.52", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.062965213, + "uploadSeconds": 0.122682753, + "downloadSeconds": 0.000096943 + }, + { + "connectionEstablishedSeconds": 0.065489033, + "uploadSeconds": 0.127334506, + "downloadSeconds": 0.00005148 + }, + { + "connectionEstablishedSeconds": 0.064780118, + "uploadSeconds": 0.125533161, + "downloadSeconds": 0.000179768 + }, + { + "connectionEstablishedSeconds": 0.064576145, + "uploadSeconds": 0.125430556, + "downloadSeconds": 0.000079431 + }, + { + "connectionEstablishedSeconds": 0.06390552, + "uploadSeconds": 0.12410876, + "downloadSeconds": 0.000056454 + }, + { + "connectionEstablishedSeconds": 0.06475562, + "uploadSeconds": 0.125875636, + "downloadSeconds": 0.000046953 + }, + { + "connectionEstablishedSeconds": 0.064233033, + "uploadSeconds": 0.124969035, + "downloadSeconds": 0.000048843 + }, + { + "connectionEstablishedSeconds": 0.066038617, + "uploadSeconds": 0.128523885, + "downloadSeconds": 0.000048385 + }, + { + "connectionEstablishedSeconds": 0.062580181, + "uploadSeconds": 0.121513512, + "downloadSeconds": 0.000058131 + }, + { + "connectionEstablishedSeconds": 0.065504828, + "uploadSeconds": 0.127820586, + "downloadSeconds": 0.000048425 + }, + { + "connectionEstablishedSeconds": 0.064665241, + "uploadSeconds": 0.12597723, + "downloadSeconds": 0.000052844 + }, + { + "connectionEstablishedSeconds": 0.064701557, + "uploadSeconds": 0.125833183, + "downloadSeconds": 0.000092905 + }, + { + "connectionEstablishedSeconds": 0.06448686, + "uploadSeconds": 0.125395967, + "downloadSeconds": 0.000085099 + }, + { + "connectionEstablishedSeconds": 0.065915145, + "uploadSeconds": 0.12835944, + "downloadSeconds": 0.000050811 + }, + { + "connectionEstablishedSeconds": 0.064480849, + "uploadSeconds": 0.125422879, + "downloadSeconds": 0.000067528 + }, + { + "connectionEstablishedSeconds": 0.06609195, + "uploadSeconds": 0.12874033, + "downloadSeconds": 0.000051072 + }, + { + "connectionEstablishedSeconds": 0.065812462, + "uploadSeconds": 0.128129494, + "downloadSeconds": 0.000050144 + }, + { + "connectionEstablishedSeconds": 0.063794081, + "uploadSeconds": 0.124079512, + "downloadSeconds": 0.000075582 + }, + { + "connectionEstablishedSeconds": 0.065288735, + "uploadSeconds": 0.127120097, + "downloadSeconds": 0.000045388 + }, + { + "connectionEstablishedSeconds": 0.064935727, + "uploadSeconds": 0.126263076, + "downloadSeconds": 0.0000764 + }, + { + "connectionEstablishedSeconds": 0.064595678, + "uploadSeconds": 0.125849896, + "downloadSeconds": 0.000051446 + }, + { + "connectionEstablishedSeconds": 0.064087762, + "uploadSeconds": 0.124715294, + "downloadSeconds": 0.000085901 + }, + { + "connectionEstablishedSeconds": 0.064889148, + "uploadSeconds": 0.126489863, + "downloadSeconds": 0.000049797 + }, + { + "connectionEstablishedSeconds": 0.062467826, + "uploadSeconds": 0.121297594, + "downloadSeconds": 0.00005279 + }, + { + "connectionEstablishedSeconds": 0.062480328, + "uploadSeconds": 0.121542251, + "downloadSeconds": 0.000071948 + }, + { + "connectionEstablishedSeconds": 0.065630362, + "uploadSeconds": 0.127637877, + "downloadSeconds": 0.000053017 + }, + { + "connectionEstablishedSeconds": 0.062966299, + "uploadSeconds": 0.122626191, + "downloadSeconds": 0.000100311 + }, + { + "connectionEstablishedSeconds": 0.065212714, + "uploadSeconds": 0.126882573, + "downloadSeconds": 0.000103539 + }, + { + "connectionEstablishedSeconds": 0.063160796, + "uploadSeconds": 0.122707305, + "downloadSeconds": 0.000091295 + }, + { + "connectionEstablishedSeconds": 0.065610229, + "uploadSeconds": 0.127561854, + "downloadSeconds": 0.000044342 + }, + { + "connectionEstablishedSeconds": 0.062578162, + "uploadSeconds": 0.121752053, + "downloadSeconds": 0.0000859 + }, + { + "connectionEstablishedSeconds": 0.066255772, + "uploadSeconds": 0.127226144, + "downloadSeconds": 0.000048046 + }, + { + "connectionEstablishedSeconds": 0.064441426, + "uploadSeconds": 0.125328846, + "downloadSeconds": 0.000055709 + }, + { + "connectionEstablishedSeconds": 0.063287629, + "uploadSeconds": 0.123149429, + "downloadSeconds": 0.000052619 + }, + { + "connectionEstablishedSeconds": 0.062782396, + "uploadSeconds": 0.122141871, + "downloadSeconds": 0.000053622 + }, + { + "connectionEstablishedSeconds": 0.066718479, + "uploadSeconds": 0.130087424, + "downloadSeconds": 0.000046998 + }, + { + "connectionEstablishedSeconds": 0.065404341, + "uploadSeconds": 0.127412669, + "downloadSeconds": 0.000053589 + }, + { + "connectionEstablishedSeconds": 0.062921035, + "uploadSeconds": 0.12245603, + "downloadSeconds": 0.000048439 + }, + { + "connectionEstablishedSeconds": 0.063269545, + "uploadSeconds": 0.12313399, + "downloadSeconds": 0.000046705 + }, + { + "connectionEstablishedSeconds": 0.064657458, + "uploadSeconds": 0.12558721, + "downloadSeconds": 0.000089519 + }, + { + "connectionEstablishedSeconds": 0.064372159, + "uploadSeconds": 0.125307848, + "downloadSeconds": 0.000056282 + }, + { + "connectionEstablishedSeconds": 0.063471511, + "uploadSeconds": 0.123603874, + "downloadSeconds": 0.000053637 + }, + { + "connectionEstablishedSeconds": 0.064454589, + "uploadSeconds": 0.125511651, + "downloadSeconds": 0.000064808 + }, + { + "connectionEstablishedSeconds": 0.064763882, + "uploadSeconds": 0.126017266, + "downloadSeconds": 0.000047926 + }, + { + "connectionEstablishedSeconds": 0.065445739, + "uploadSeconds": 0.127456516, + "downloadSeconds": 0.000050466 + }, + { + "connectionEstablishedSeconds": 0.063431453, + "uploadSeconds": 0.123508824, + "downloadSeconds": 0.000050062 + }, + { + "connectionEstablishedSeconds": 0.064876121, + "uploadSeconds": 0.126287247, + "downloadSeconds": 0.000086023 + }, + { + "connectionEstablishedSeconds": 0.063792115, + "uploadSeconds": 0.12380564, + "downloadSeconds": 0.000059282 + }, + { + "connectionEstablishedSeconds": 0.064643853, + "uploadSeconds": 0.12569494, + "downloadSeconds": 0.000055511 + }, + { + "connectionEstablishedSeconds": 0.064326266, + "uploadSeconds": 0.125203995, + "downloadSeconds": 0.00005376 + }, + { + "connectionEstablishedSeconds": 0.063819705, + "uploadSeconds": 0.124362927, + "downloadSeconds": 0.000049904 + }, + { + "connectionEstablishedSeconds": 0.062724828, + "uploadSeconds": 0.121708761, + "downloadSeconds": 0.000086279 + }, + { + "connectionEstablishedSeconds": 0.064082258, + "uploadSeconds": 0.124765938, + "downloadSeconds": 0.00006986 + }, + { + "connectionEstablishedSeconds": 0.061541865, + "uploadSeconds": 0.119683336, + "downloadSeconds": 0.000046545 + }, + { + "connectionEstablishedSeconds": 0.0639851, + "uploadSeconds": 0.124269542, + "downloadSeconds": 0.000072711 + }, + { + "connectionEstablishedSeconds": 0.060457326, + "uploadSeconds": 0.117418959, + "downloadSeconds": 0.000071158 + }, + { + "connectionEstablishedSeconds": 0.06312529, + "uploadSeconds": 0.122446747, + "downloadSeconds": 0.000065805 + }, + { + "connectionEstablishedSeconds": 0.062976684, + "uploadSeconds": 0.122669083, + "downloadSeconds": 0.000093549 + }, + { + "connectionEstablishedSeconds": 0.065746472, + "uploadSeconds": 0.128321234, + "downloadSeconds": 0.000051595 + }, + { + "connectionEstablishedSeconds": 0.066366627, + "uploadSeconds": 0.129283919, + "downloadSeconds": 0.000050745 + }, + { + "connectionEstablishedSeconds": 0.065415799, + "uploadSeconds": 0.127190661, + "downloadSeconds": 0.000062322 + }, + { + "connectionEstablishedSeconds": 0.063648161, + "uploadSeconds": 0.123781895, + "downloadSeconds": 0.000046654 + }, + { + "connectionEstablishedSeconds": 0.06167661, + "uploadSeconds": 0.119790221, + "downloadSeconds": 0.000047639 + }, + { + "connectionEstablishedSeconds": 0.065250442, + "uploadSeconds": 0.127054158, + "downloadSeconds": 0.00006243 + }, + { + "connectionEstablishedSeconds": 0.063930895, + "uploadSeconds": 0.124296611, + "downloadSeconds": 0.000048271 + }, + { + "connectionEstablishedSeconds": 0.063170568, + "uploadSeconds": 0.122844096, + "downloadSeconds": 0.000059985 + }, + { + "connectionEstablishedSeconds": 0.064963847, + "uploadSeconds": 0.126469775, + "downloadSeconds": 0.00009783 + }, + { + "connectionEstablishedSeconds": 0.062416817, + "uploadSeconds": 0.121274763, + "downloadSeconds": 0.000063675 + }, + { + "connectionEstablishedSeconds": 0.06274952, + "uploadSeconds": 0.121991328, + "downloadSeconds": 0.00004915 + }, + { + "connectionEstablishedSeconds": 0.062530976, + "uploadSeconds": 0.121535015, + "downloadSeconds": 0.000053865 + }, + { + "connectionEstablishedSeconds": 0.064192983, + "uploadSeconds": 0.12497331, + "downloadSeconds": 0.000053834 + }, + { + "connectionEstablishedSeconds": 0.063269385, + "uploadSeconds": 0.122713127, + "downloadSeconds": 0.000051999 + }, + { + "connectionEstablishedSeconds": 0.063591056, + "uploadSeconds": 0.123664118, + "downloadSeconds": 0.000047505 + }, + { + "connectionEstablishedSeconds": 0.064500664, + "uploadSeconds": 0.125451392, + "downloadSeconds": 0.000052342 + }, + { + "connectionEstablishedSeconds": 0.064386192, + "uploadSeconds": 0.125257624, + "downloadSeconds": 0.000055289 + }, + { + "connectionEstablishedSeconds": 0.063064753, + "uploadSeconds": 0.122466459, + "downloadSeconds": 0.000069603 + }, + { + "connectionEstablishedSeconds": 0.065334896, + "uploadSeconds": 0.127050874, + "downloadSeconds": 0.000065784 + }, + { + "connectionEstablishedSeconds": 0.06524476, + "uploadSeconds": 0.127040032, + "downloadSeconds": 0.000047416 + }, + { + "connectionEstablishedSeconds": 0.062676442, + "uploadSeconds": 0.121891488, + "downloadSeconds": 0.000056458 + }, + { + "connectionEstablishedSeconds": 0.064216517, + "uploadSeconds": 0.124848172, + "downloadSeconds": 0.000089715 + }, + { + "connectionEstablishedSeconds": 0.06513872, + "uploadSeconds": 0.126780996, + "downloadSeconds": 0.000065766 + }, + { + "connectionEstablishedSeconds": 0.065030584, + "uploadSeconds": 0.12662517, + "downloadSeconds": 0.000053753 + }, + { + "connectionEstablishedSeconds": 0.062538152, + "uploadSeconds": 0.12168764, + "downloadSeconds": 0.00011266 + }, + { + "connectionEstablishedSeconds": 0.066310676, + "uploadSeconds": 0.129074605, + "downloadSeconds": 0.000053125 + }, + { + "connectionEstablishedSeconds": 0.066263897, + "uploadSeconds": 0.129142804, + "downloadSeconds": 0.000049113 + }, + { + "connectionEstablishedSeconds": 0.066270579, + "uploadSeconds": 0.129054171, + "downloadSeconds": 0.000092392 + }, + { + "connectionEstablishedSeconds": 0.066166914, + "uploadSeconds": 0.128875248, + "downloadSeconds": 0.000052999 + }, + { + "connectionEstablishedSeconds": 0.064122605, + "uploadSeconds": 0.124866938, + "downloadSeconds": 0.000066255 + }, + { + "connectionEstablishedSeconds": 0.061991146, + "uploadSeconds": 0.120611253, + "downloadSeconds": 0.000046815 + }, + { + "connectionEstablishedSeconds": 0.06589036, + "uploadSeconds": 0.128228162, + "downloadSeconds": 0.000047445 + }, + { + "connectionEstablishedSeconds": 0.064135612, + "uploadSeconds": 0.12479438, + "downloadSeconds": 0.000052391 + }, + { + "connectionEstablishedSeconds": 0.065295866, + "uploadSeconds": 0.127137163, + "downloadSeconds": 0.000046542 + }, + { + "connectionEstablishedSeconds": 0.06473605, + "uploadSeconds": 0.126032657, + "downloadSeconds": 0.000050489 + }, + { + "connectionEstablishedSeconds": 0.063691798, + "uploadSeconds": 0.123769338, + "downloadSeconds": 0.000060976 + }, + { + "connectionEstablishedSeconds": 0.064162208, + "uploadSeconds": 0.124859646, + "downloadSeconds": 0.000090241 + }, + { + "connectionEstablishedSeconds": 0.062561977, + "uploadSeconds": 0.121690886, + "downloadSeconds": 0.000047624 + }, + { + "connectionEstablishedSeconds": 0.064724475, + "uploadSeconds": 0.125989931, + "downloadSeconds": 0.000079598 + }, + { + "connectionEstablishedSeconds": 0.063654223, + "uploadSeconds": 0.123738224, + "downloadSeconds": 0.000054464 + }, + { + "connectionEstablishedSeconds": 0.064422792, + "uploadSeconds": 0.125386097, + "downloadSeconds": 0.00005014 + }, + { + "connectionEstablishedSeconds": 0.063905178, + "uploadSeconds": 0.124427918, + "downloadSeconds": 0.000093924 + } + ], + "implementation": "rust-libp2p-quinn", + "version": "v0.52", + "transportStack": "quic-v1" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.1821398, + "downloadSeconds": 0.000026881 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.195773944, + "downloadSeconds": 0.000025118 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.183498433, + "downloadSeconds": 0.000031034 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.192985197, + "downloadSeconds": 0.000023865 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.184632175, + "downloadSeconds": 0.000023122 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187860929, + "downloadSeconds": 0.000025513 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.18858002, + "downloadSeconds": 0.000025404 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186972658, + "downloadSeconds": 0.000024657 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.188982188, + "downloadSeconds": 0.000027395 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191543178, + "downloadSeconds": 0.000023934 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.193977061, + "downloadSeconds": 0.000022836 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191907741, + "downloadSeconds": 0.000033653 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.190081621, + "downloadSeconds": 0.000025243 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187260309, + "downloadSeconds": 0.000026162 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.18507505, + "downloadSeconds": 0.000029837 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.175075255, + "downloadSeconds": 0.000023352 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.189134819, + "downloadSeconds": 0.000025628 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.188676944, + "downloadSeconds": 0.000024155 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.185896518, + "downloadSeconds": 0.000021262 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186597685, + "downloadSeconds": 0.000025792 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.176832111, + "downloadSeconds": 0.000022594 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.17509324, + "downloadSeconds": 0.000024377 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.189129547, + "downloadSeconds": 0.000025202 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.185398974, + "downloadSeconds": 0.000022065 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187933492, + "downloadSeconds": 0.000023911 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.189684911, + "downloadSeconds": 0.000023018 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191771551, + "downloadSeconds": 0.000022407 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186256005, + "downloadSeconds": 0.000027753 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.175575956, + "downloadSeconds": 0.000025303 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.183450944, + "downloadSeconds": 0.000026464 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.190320051, + "downloadSeconds": 0.000023076 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.192783509, + "downloadSeconds": 0.000026041 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.184762516, + "downloadSeconds": 0.000040371 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191807584, + "downloadSeconds": 0.000023094 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.181300724, + "downloadSeconds": 0.000023035 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.181617298, + "downloadSeconds": 0.000022889 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186888535, + "downloadSeconds": 0.000025779 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191734437, + "downloadSeconds": 0.000025407 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.1870718, + "downloadSeconds": 0.000025818 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.190846856, + "downloadSeconds": 0.000023349 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.188427418, + "downloadSeconds": 0.000026628 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.180998284, + "downloadSeconds": 0.000025526 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.185872193, + "downloadSeconds": 0.000028614 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.193576062, + "downloadSeconds": 0.000023458 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.194089134, + "downloadSeconds": 0.000021827 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.178674659, + "downloadSeconds": 0.000026203 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.185130393, + "downloadSeconds": 0.000024973 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.178811065, + "downloadSeconds": 0.000023368 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187995598, + "downloadSeconds": 0.00002634 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.195339953, + "downloadSeconds": 0.000020748 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186196457, + "downloadSeconds": 0.000036929 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.188973136, + "downloadSeconds": 0.000024914 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.192528886, + "downloadSeconds": 0.000025572 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.193148886, + "downloadSeconds": 0.000027763 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.193900042, + "downloadSeconds": 0.000021874 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.195939328, + "downloadSeconds": 0.000026014 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191246907, + "downloadSeconds": 0.000026981 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.18417502, + "downloadSeconds": 0.000026181 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191423524, + "downloadSeconds": 0.000021579 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.183943936, + "downloadSeconds": 0.000022064 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.182280169, + "downloadSeconds": 0.000024752 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.184413819, + "downloadSeconds": 0.000024742 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191802659, + "downloadSeconds": 0.000023783 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.192117827, + "downloadSeconds": 0.000024709 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.18619131, + "downloadSeconds": 0.000024901 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187654897, + "downloadSeconds": 0.000032967 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187674364, + "downloadSeconds": 0.000025345 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187036773, + "downloadSeconds": 0.000024928 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.18494965, + "downloadSeconds": 0.000027452 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.180378838, + "downloadSeconds": 0.000023578 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187225719, + "downloadSeconds": 0.000022053 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191425341, + "downloadSeconds": 0.000024108 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.184853694, + "downloadSeconds": 0.000028837 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.181655026, + "downloadSeconds": 0.000025577 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.192752062, + "downloadSeconds": 0.000027913 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.19259968, + "downloadSeconds": 0.00002855 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.188552023, + "downloadSeconds": 0.000024955 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.183730429, + "downloadSeconds": 0.000023694 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.177422708, + "downloadSeconds": 0.000022784 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.187951807, + "downloadSeconds": 0.000024424 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.185678393, + "downloadSeconds": 0.000024968 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191673411, + "downloadSeconds": 0.000023488 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.181048061, + "downloadSeconds": 0.000020906 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.185683204, + "downloadSeconds": 0.000023901 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.182405216, + "downloadSeconds": 0.00002517 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.193882525, + "downloadSeconds": 0.000025305 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.190209202, + "downloadSeconds": 0.000031225 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.185653646, + "downloadSeconds": 0.000025465 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.191666166, + "downloadSeconds": 0.000025486 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.18358427, + "downloadSeconds": 0.000026064 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.189650703, + "downloadSeconds": 0.000024602 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186723161, + "downloadSeconds": 0.000026009 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.184713584, + "downloadSeconds": 0.000025332 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.192077544, + "downloadSeconds": 0.00002107 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.189386708, + "downloadSeconds": 0.000039476 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.19138384, + "downloadSeconds": 0.000024091 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.183304304, + "downloadSeconds": 0.000025534 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.190941356, + "downloadSeconds": 0.000023583 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186071754, + "downloadSeconds": 0.000026885 + }, + { + "connectionEstablishedSeconds": 0, + "uploadSeconds": 0.186465452, + "downloadSeconds": 0.000024554 + } + ], + "implementation": "https", + "version": "v0.1", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.189865033, + "uploadSeconds": 0.000003755, + "downloadSeconds": 0.063326819 + }, + { + "connectionEstablishedSeconds": 0.190167163, + "uploadSeconds": 0.000003405, + "downloadSeconds": 0.06291947 + }, + { + "connectionEstablishedSeconds": 0.19127148, + "uploadSeconds": 0.000003459, + "downloadSeconds": 0.063311819 + }, + { + "connectionEstablishedSeconds": 0.191882774, + "uploadSeconds": 0.00000357, + "downloadSeconds": 0.063451717 + }, + { + "connectionEstablishedSeconds": 0.191717471, + "uploadSeconds": 0.000003752, + "downloadSeconds": 0.063499436 + }, + { + "connectionEstablishedSeconds": 0.178632645, + "uploadSeconds": 0.000003283, + "downloadSeconds": 0.059170141 + }, + { + "connectionEstablishedSeconds": 0.186360132, + "uploadSeconds": 0.000003649, + "downloadSeconds": 0.061683229 + }, + { + "connectionEstablishedSeconds": 0.18410758, + "uploadSeconds": 0.000003259, + "downloadSeconds": 0.060973875 + }, + { + "connectionEstablishedSeconds": 0.188355392, + "uploadSeconds": 0.000003324, + "downloadSeconds": 0.062420337 + }, + { + "connectionEstablishedSeconds": 0.192853788, + "uploadSeconds": 0.000004574, + "downloadSeconds": 0.063856996 + }, + { + "connectionEstablishedSeconds": 0.19061551, + "uploadSeconds": 0.00000336, + "downloadSeconds": 0.063080255 + }, + { + "connectionEstablishedSeconds": 0.194515365, + "uploadSeconds": 0.000003426, + "downloadSeconds": 0.063687147 + }, + { + "connectionEstablishedSeconds": 0.192444206, + "uploadSeconds": 0.000003363, + "downloadSeconds": 0.063767405 + }, + { + "connectionEstablishedSeconds": 0.185178857, + "uploadSeconds": 0.000003962, + "downloadSeconds": 0.061233797 + }, + { + "connectionEstablishedSeconds": 0.189486458, + "uploadSeconds": 0.000003111, + "downloadSeconds": 0.062118443 + }, + { + "connectionEstablishedSeconds": 0.196167145, + "uploadSeconds": 0.000003706, + "downloadSeconds": 0.064887836 + }, + { + "connectionEstablishedSeconds": 0.192284557, + "uploadSeconds": 0.000003459, + "downloadSeconds": 0.063691101 + }, + { + "connectionEstablishedSeconds": 0.188827342, + "uploadSeconds": 0.000003991, + "downloadSeconds": 0.061963325 + }, + { + "connectionEstablishedSeconds": 0.185525831, + "uploadSeconds": 0.000006237, + "downloadSeconds": 0.061254952 + }, + { + "connectionEstablishedSeconds": 0.193967423, + "uploadSeconds": 0.000003491, + "downloadSeconds": 0.064179438 + }, + { + "connectionEstablishedSeconds": 0.187580283, + "uploadSeconds": 0.000003175, + "downloadSeconds": 0.06221106 + }, + { + "connectionEstablishedSeconds": 0.185444221, + "uploadSeconds": 0.000003223, + "downloadSeconds": 0.061453914 + }, + { + "connectionEstablishedSeconds": 0.191583765, + "uploadSeconds": 0.0000033, + "downloadSeconds": 0.063420643 + }, + { + "connectionEstablishedSeconds": 0.188379636, + "uploadSeconds": 0.000030857, + "downloadSeconds": 0.062499979 + }, + { + "connectionEstablishedSeconds": 0.195192589, + "uploadSeconds": 0.000003374, + "downloadSeconds": 0.064022674 + }, + { + "connectionEstablishedSeconds": 0.186875039, + "uploadSeconds": 0.000005618, + "downloadSeconds": 0.061720819 + }, + { + "connectionEstablishedSeconds": 0.192027134, + "uploadSeconds": 0.000003157, + "downloadSeconds": 0.063552229 + }, + { + "connectionEstablishedSeconds": 0.186630503, + "uploadSeconds": 0.000004785, + "downloadSeconds": 0.061890439 + }, + { + "connectionEstablishedSeconds": 0.182287487, + "uploadSeconds": 0.00000373, + "downloadSeconds": 0.060437908 + }, + { + "connectionEstablishedSeconds": 0.190073749, + "uploadSeconds": 0.000003001, + "downloadSeconds": 0.062892605 + }, + { + "connectionEstablishedSeconds": 0.187970588, + "uploadSeconds": 0.000004204, + "downloadSeconds": 0.062110529 + }, + { + "connectionEstablishedSeconds": 0.185083699, + "uploadSeconds": 0.00000318, + "downloadSeconds": 0.061196717 + }, + { + "connectionEstablishedSeconds": 0.184069718, + "uploadSeconds": 0.000004065, + "downloadSeconds": 0.060306442 + }, + { + "connectionEstablishedSeconds": 0.185998883, + "uploadSeconds": 0.00000313, + "downloadSeconds": 0.061513072 + }, + { + "connectionEstablishedSeconds": 0.192536728, + "uploadSeconds": 0.000003128, + "downloadSeconds": 0.063119368 + }, + { + "connectionEstablishedSeconds": 0.185464008, + "uploadSeconds": 0.000004191, + "downloadSeconds": 0.060725965 + }, + { + "connectionEstablishedSeconds": 0.180226658, + "uploadSeconds": 0.000003442, + "downloadSeconds": 0.059633921 + }, + { + "connectionEstablishedSeconds": 0.194965481, + "uploadSeconds": 0.000005938, + "downloadSeconds": 0.064359458 + }, + { + "connectionEstablishedSeconds": 0.182439182, + "uploadSeconds": 0.000003614, + "downloadSeconds": 0.060362038 + }, + { + "connectionEstablishedSeconds": 0.192508667, + "uploadSeconds": 0.000003412, + "downloadSeconds": 0.063704292 + }, + { + "connectionEstablishedSeconds": 0.186931537, + "uploadSeconds": 0.000003467, + "downloadSeconds": 0.061294501 + }, + { + "connectionEstablishedSeconds": 0.191518338, + "uploadSeconds": 0.000004447, + "downloadSeconds": 0.062653135 + }, + { + "connectionEstablishedSeconds": 0.19192684, + "uploadSeconds": 0.000003705, + "downloadSeconds": 0.062893242 + }, + { + "connectionEstablishedSeconds": 0.185394753, + "uploadSeconds": 0.000004483, + "downloadSeconds": 0.061331984 + }, + { + "connectionEstablishedSeconds": 0.185708486, + "uploadSeconds": 0.000003951, + "downloadSeconds": 0.0607885 + }, + { + "connectionEstablishedSeconds": 0.183875796, + "uploadSeconds": 0.0000047, + "downloadSeconds": 0.060791407 + }, + { + "connectionEstablishedSeconds": 0.192025954, + "uploadSeconds": 0.000006376, + "downloadSeconds": 0.063456396 + }, + { + "connectionEstablishedSeconds": 0.196378458, + "uploadSeconds": 0.000003546, + "downloadSeconds": 0.065019283 + }, + { + "connectionEstablishedSeconds": 0.181342825, + "uploadSeconds": 0.00000346, + "downloadSeconds": 0.059890191 + }, + { + "connectionEstablishedSeconds": 0.182238767, + "uploadSeconds": 0.000017619, + "downloadSeconds": 0.060241578 + }, + { + "connectionEstablishedSeconds": 0.185472707, + "uploadSeconds": 0.000010933, + "downloadSeconds": 0.060708375 + }, + { + "connectionEstablishedSeconds": 0.188838896, + "uploadSeconds": 0.000003734, + "downloadSeconds": 0.061928968 + }, + { + "connectionEstablishedSeconds": 0.185193048, + "uploadSeconds": 0.000003366, + "downloadSeconds": 0.061215954 + }, + { + "connectionEstablishedSeconds": 0.187592679, + "uploadSeconds": 0.000004438, + "downloadSeconds": 0.061473994 + }, + { + "connectionEstablishedSeconds": 0.193636801, + "uploadSeconds": 0.000004524, + "downloadSeconds": 0.064099879 + }, + { + "connectionEstablishedSeconds": 0.184201271, + "uploadSeconds": 0.000003432, + "downloadSeconds": 0.060985428 + }, + { + "connectionEstablishedSeconds": 0.194326728, + "uploadSeconds": 0.000003155, + "downloadSeconds": 0.064259504 + }, + { + "connectionEstablishedSeconds": 0.194445779, + "uploadSeconds": 0.000004119, + "downloadSeconds": 0.064261936 + }, + { + "connectionEstablishedSeconds": 0.185737118, + "uploadSeconds": 0.00000329, + "downloadSeconds": 0.060933254 + }, + { + "connectionEstablishedSeconds": 0.191702829, + "uploadSeconds": 0.000003619, + "downloadSeconds": 0.06283655 + }, + { + "connectionEstablishedSeconds": 0.193856428, + "uploadSeconds": 0.000003181, + "downloadSeconds": 0.064125639 + }, + { + "connectionEstablishedSeconds": 0.197002058, + "uploadSeconds": 0.000003796, + "downloadSeconds": 0.065150551 + }, + { + "connectionEstablishedSeconds": 0.188234771, + "uploadSeconds": 0.000002842, + "downloadSeconds": 0.062380961 + }, + { + "connectionEstablishedSeconds": 0.189238149, + "uploadSeconds": 0.000002815, + "downloadSeconds": 0.062670946 + }, + { + "connectionEstablishedSeconds": 0.190280679, + "uploadSeconds": 0.000003373, + "downloadSeconds": 0.063065695 + }, + { + "connectionEstablishedSeconds": 0.186700069, + "uploadSeconds": 0.000003589, + "downloadSeconds": 0.061838272 + }, + { + "connectionEstablishedSeconds": 0.188825445, + "uploadSeconds": 0.000026162, + "downloadSeconds": 0.062522361 + }, + { + "connectionEstablishedSeconds": 0.184322559, + "uploadSeconds": 0.000003948, + "downloadSeconds": 0.060868078 + }, + { + "connectionEstablishedSeconds": 0.183973916, + "uploadSeconds": 0.000010764, + "downloadSeconds": 0.060144183 + }, + { + "connectionEstablishedSeconds": 0.193049526, + "uploadSeconds": 0.000003917, + "downloadSeconds": 0.063845259 + }, + { + "connectionEstablishedSeconds": 0.191696109, + "uploadSeconds": 0.000003516, + "downloadSeconds": 0.063412521 + }, + { + "connectionEstablishedSeconds": 0.186839716, + "uploadSeconds": 0.000003305, + "downloadSeconds": 0.061833216 + }, + { + "connectionEstablishedSeconds": 0.191809822, + "uploadSeconds": 0.000003792, + "downloadSeconds": 0.063403856 + }, + { + "connectionEstablishedSeconds": 0.194129095, + "uploadSeconds": 0.00001352, + "downloadSeconds": 0.06352246 + }, + { + "connectionEstablishedSeconds": 0.181180001, + "uploadSeconds": 0.000004572, + "downloadSeconds": 0.059934202 + }, + { + "connectionEstablishedSeconds": 0.180661281, + "uploadSeconds": 0.000003547, + "downloadSeconds": 0.059755159 + }, + { + "connectionEstablishedSeconds": 0.190152936, + "uploadSeconds": 0.000003181, + "downloadSeconds": 0.063054685 + }, + { + "connectionEstablishedSeconds": 0.186944328, + "uploadSeconds": 0.000003496, + "downloadSeconds": 0.061904523 + }, + { + "connectionEstablishedSeconds": 0.190184668, + "uploadSeconds": 0.000003288, + "downloadSeconds": 0.062883361 + }, + { + "connectionEstablishedSeconds": 0.187276895, + "uploadSeconds": 0.000003031, + "downloadSeconds": 0.061909398 + }, + { + "connectionEstablishedSeconds": 0.196410805, + "uploadSeconds": 0.000003343, + "downloadSeconds": 0.064392076 + }, + { + "connectionEstablishedSeconds": 0.186942448, + "uploadSeconds": 0.000003256, + "downloadSeconds": 0.061798213 + }, + { + "connectionEstablishedSeconds": 0.195507958, + "uploadSeconds": 0.000004205, + "downloadSeconds": 0.06431094 + }, + { + "connectionEstablishedSeconds": 0.188729854, + "uploadSeconds": 0.000003247, + "downloadSeconds": 0.062861007 + }, + { + "connectionEstablishedSeconds": 0.176308767, + "uploadSeconds": 0.000003269, + "downloadSeconds": 0.058376847 + }, + { + "connectionEstablishedSeconds": 0.185853802, + "uploadSeconds": 0.000034454, + "downloadSeconds": 0.060993945 + }, + { + "connectionEstablishedSeconds": 0.195486075, + "uploadSeconds": 0.000003437, + "downloadSeconds": 0.064021667 + }, + { + "connectionEstablishedSeconds": 0.189181712, + "uploadSeconds": 0.000003585, + "downloadSeconds": 0.062231455 + }, + { + "connectionEstablishedSeconds": 0.189533428, + "uploadSeconds": 0.000003974, + "downloadSeconds": 0.061964976 + }, + { + "connectionEstablishedSeconds": 0.196418242, + "uploadSeconds": 0.000004446, + "downloadSeconds": 0.064289062 + }, + { + "connectionEstablishedSeconds": 0.185007671, + "uploadSeconds": 0.000003875, + "downloadSeconds": 0.061191973 + }, + { + "connectionEstablishedSeconds": 0.194761992, + "uploadSeconds": 0.000003472, + "downloadSeconds": 0.064167683 + }, + { + "connectionEstablishedSeconds": 0.189410553, + "uploadSeconds": 0.000003401, + "downloadSeconds": 0.062670457 + }, + { + "connectionEstablishedSeconds": 0.184269226, + "uploadSeconds": 0.000003269, + "downloadSeconds": 0.061020116 + }, + { + "connectionEstablishedSeconds": 0.191795192, + "uploadSeconds": 0.000003046, + "downloadSeconds": 0.063424398 + }, + { + "connectionEstablishedSeconds": 0.187122482, + "uploadSeconds": 0.000003171, + "downloadSeconds": 0.061827626 + }, + { + "connectionEstablishedSeconds": 0.187808498, + "uploadSeconds": 0.000004047, + "downloadSeconds": 0.061480245 + }, + { + "connectionEstablishedSeconds": 0.189174617, + "uploadSeconds": 0.000003394, + "downloadSeconds": 0.062532492 + }, + { + "connectionEstablishedSeconds": 0.189730447, + "uploadSeconds": 0.000003184, + "downloadSeconds": 0.062915557 + }, + { + "connectionEstablishedSeconds": 0.194496172, + "uploadSeconds": 0.00000356, + "downloadSeconds": 0.064392806 + } + ], + "implementation": "go-libp2p", + "version": "v0.27", + "transportStack": "tcp" + }, + { + "result": [ + { + "connectionEstablishedSeconds": 0.066922628, + "uploadSeconds": 0.000005352, + "downloadSeconds": 0.063030899 + }, + { + "connectionEstablishedSeconds": 0.06707135, + "uploadSeconds": 0.000002129, + "downloadSeconds": 0.063328551 + }, + { + "connectionEstablishedSeconds": 0.067132787, + "uploadSeconds": 0.000001963, + "downloadSeconds": 0.063505627 + }, + { + "connectionEstablishedSeconds": 0.065440265, + "uploadSeconds": 0.000009053, + "downloadSeconds": 0.06154525 + }, + { + "connectionEstablishedSeconds": 0.06621482, + "uploadSeconds": 0.000002119, + "downloadSeconds": 0.062139616 + }, + { + "connectionEstablishedSeconds": 0.065910382, + "uploadSeconds": 0.000012239, + "downloadSeconds": 0.062562526 + }, + { + "connectionEstablishedSeconds": 0.065909146, + "uploadSeconds": 0.000002035, + "downloadSeconds": 0.0621534 + }, + { + "connectionEstablishedSeconds": 0.06801384, + "uploadSeconds": 0.000002923, + "downloadSeconds": 0.064059605 + }, + { + "connectionEstablishedSeconds": 0.067818056, + "uploadSeconds": 0.000002197, + "downloadSeconds": 0.064130496 + }, + { + "connectionEstablishedSeconds": 0.06785023, + "uploadSeconds": 0.000002279, + "downloadSeconds": 0.063949204 + }, + { + "connectionEstablishedSeconds": 0.064979961, + "uploadSeconds": 0.000002137, + "downloadSeconds": 0.06111793 + }, + { + "connectionEstablishedSeconds": 0.063004329, + "uploadSeconds": 0.000002053, + "downloadSeconds": 0.060985052 + }, + { + "connectionEstablishedSeconds": 0.067792429, + "uploadSeconds": 0.000002436, + "downloadSeconds": 0.063913122 + }, + { + "connectionEstablishedSeconds": 0.067990841, + "uploadSeconds": 0.000002295, + "downloadSeconds": 0.06444806 + }, + { + "connectionEstablishedSeconds": 0.066343242, + "uploadSeconds": 0.000002096, + "downloadSeconds": 0.062580386 + }, + { + "connectionEstablishedSeconds": 0.065857475, + "uploadSeconds": 0.00000196, + "downloadSeconds": 0.06216352 + }, + { + "connectionEstablishedSeconds": 0.065371853, + "uploadSeconds": 0.000023269, + "downloadSeconds": 0.063442293 + }, + { + "connectionEstablishedSeconds": 0.068804013, + "uploadSeconds": 0.00000206, + "downloadSeconds": 0.064941111 + }, + { + "connectionEstablishedSeconds": 0.063637443, + "uploadSeconds": 0.000002768, + "downloadSeconds": 0.059679162 + }, + { + "connectionEstablishedSeconds": 0.065207434, + "uploadSeconds": 0.000001918, + "downloadSeconds": 0.061318134 + }, + { + "connectionEstablishedSeconds": 0.06569069, + "uploadSeconds": 0.000001914, + "downloadSeconds": 0.063650073 + }, + { + "connectionEstablishedSeconds": 0.065767399, + "uploadSeconds": 0.00000194, + "downloadSeconds": 0.061918382 + }, + { + "connectionEstablishedSeconds": 0.064315928, + "uploadSeconds": 0.000001921, + "downloadSeconds": 0.062339162 + }, + { + "connectionEstablishedSeconds": 0.062556024, + "uploadSeconds": 0.00000372, + "downloadSeconds": 0.059064693 + }, + { + "connectionEstablishedSeconds": 0.063431722, + "uploadSeconds": 0.000001945, + "downloadSeconds": 0.059542485 + }, + { + "connectionEstablishedSeconds": 0.06581807, + "uploadSeconds": 0.000002505, + "downloadSeconds": 0.062084981 + }, + { + "connectionEstablishedSeconds": 0.065171919, + "uploadSeconds": 0.000002065, + "downloadSeconds": 0.061944794 + }, + { + "connectionEstablishedSeconds": 0.065486746, + "uploadSeconds": 0.000002186, + "downloadSeconds": 0.061692866 + }, + { + "connectionEstablishedSeconds": 0.065934792, + "uploadSeconds": 0.000001834, + "downloadSeconds": 0.062104727 + }, + { + "connectionEstablishedSeconds": 0.066978153, + "uploadSeconds": 0.000009043, + "downloadSeconds": 0.063348551 + }, + { + "connectionEstablishedSeconds": 0.065119357, + "uploadSeconds": 0.000002436, + "downloadSeconds": 0.061256806 + }, + { + "connectionEstablishedSeconds": 0.062444797, + "uploadSeconds": 0.000002411, + "downloadSeconds": 0.059050465 + }, + { + "connectionEstablishedSeconds": 0.065695197, + "uploadSeconds": 0.000001928, + "downloadSeconds": 0.061853956 + }, + { + "connectionEstablishedSeconds": 0.064993491, + "uploadSeconds": 0.000002038, + "downloadSeconds": 0.061670047 + }, + { + "connectionEstablishedSeconds": 0.065312902, + "uploadSeconds": 0.000002547, + "downloadSeconds": 0.061374028 + }, + { + "connectionEstablishedSeconds": 0.065156961, + "uploadSeconds": 0.000001894, + "downloadSeconds": 0.061883038 + }, + { + "connectionEstablishedSeconds": 0.067970966, + "uploadSeconds": 0.000002151, + "downloadSeconds": 0.064037572 + }, + { + "connectionEstablishedSeconds": 0.063205386, + "uploadSeconds": 0.000001849, + "downloadSeconds": 0.061184034 + }, + { + "connectionEstablishedSeconds": 0.064585287, + "uploadSeconds": 0.000002009, + "downloadSeconds": 0.061121857 + }, + { + "connectionEstablishedSeconds": 0.066126302, + "uploadSeconds": 0.000002709, + "downloadSeconds": 0.062159423 + }, + { + "connectionEstablishedSeconds": 0.066305019, + "uploadSeconds": 0.000002026, + "downloadSeconds": 0.062225233 + }, + { + "connectionEstablishedSeconds": 0.064983252, + "uploadSeconds": 0.000002131, + "downloadSeconds": 0.061307883 + }, + { + "connectionEstablishedSeconds": 0.065947013, + "uploadSeconds": 0.00000197, + "downloadSeconds": 0.062179803 + }, + { + "connectionEstablishedSeconds": 0.066676695, + "uploadSeconds": 0.000002067, + "downloadSeconds": 0.064400947 + }, + { + "connectionEstablishedSeconds": 0.06638853, + "uploadSeconds": 0.000002339, + "downloadSeconds": 0.062730715 + }, + { + "connectionEstablishedSeconds": 0.063345535, + "uploadSeconds": 0.000002166, + "downloadSeconds": 0.059499311 + }, + { + "connectionEstablishedSeconds": 0.065428625, + "uploadSeconds": 0.000001985, + "downloadSeconds": 0.061408008 + }, + { + "connectionEstablishedSeconds": 0.06867818, + "uploadSeconds": 0.000001867, + "downloadSeconds": 0.06490522 + }, + { + "connectionEstablishedSeconds": 0.065678468, + "uploadSeconds": 0.000002841, + "downloadSeconds": 0.063536271 + }, + { + "connectionEstablishedSeconds": 0.065225608, + "uploadSeconds": 0.000002395, + "downloadSeconds": 0.061372583 + }, + { + "connectionEstablishedSeconds": 0.063468774, + "uploadSeconds": 0.000002418, + "downloadSeconds": 0.060022087 + }, + { + "connectionEstablishedSeconds": 0.066156549, + "uploadSeconds": 0.00000233, + "downloadSeconds": 0.062415564 + }, + { + "connectionEstablishedSeconds": 0.065140902, + "uploadSeconds": 0.000001934, + "downloadSeconds": 0.061305908 + }, + { + "connectionEstablishedSeconds": 0.065056648, + "uploadSeconds": 0.000002397, + "downloadSeconds": 0.061307842 + }, + { + "connectionEstablishedSeconds": 0.066963459, + "uploadSeconds": 0.00000545, + "downloadSeconds": 0.063221831 + }, + { + "connectionEstablishedSeconds": 0.065800288, + "uploadSeconds": 0.000003101, + "downloadSeconds": 0.062124241 + }, + { + "connectionEstablishedSeconds": 0.064775748, + "uploadSeconds": 0.000002067, + "downloadSeconds": 0.061071155 + }, + { + "connectionEstablishedSeconds": 0.067344037, + "uploadSeconds": 0.000002334, + "downloadSeconds": 0.063530574 + }, + { + "connectionEstablishedSeconds": 0.067101632, + "uploadSeconds": 0.000001963, + "downloadSeconds": 0.063331796 + }, + { + "connectionEstablishedSeconds": 0.066652538, + "uploadSeconds": 0.000002026, + "downloadSeconds": 0.063471765 + }, + { + "connectionEstablishedSeconds": 0.065557726, + "uploadSeconds": 0.000002198, + "downloadSeconds": 0.06225219 + }, + { + "connectionEstablishedSeconds": 0.062330938, + "uploadSeconds": 0.000002131, + "downloadSeconds": 0.058568864 + }, + { + "connectionEstablishedSeconds": 0.068259918, + "uploadSeconds": 0.000001937, + "downloadSeconds": 0.064531738 + }, + { + "connectionEstablishedSeconds": 0.068372289, + "uploadSeconds": 0.000004991, + "downloadSeconds": 0.064424253 + }, + { + "connectionEstablishedSeconds": 0.0678853, + "uploadSeconds": 0.000002062, + "downloadSeconds": 0.06454054 + }, + { + "connectionEstablishedSeconds": 0.065395706, + "uploadSeconds": 0.000001855, + "downloadSeconds": 0.061657675 + }, + { + "connectionEstablishedSeconds": 0.06675671, + "uploadSeconds": 0.000002136, + "downloadSeconds": 0.063114776 + }, + { + "connectionEstablishedSeconds": 0.065232293, + "uploadSeconds": 0.000002104, + "downloadSeconds": 0.06195556 + }, + { + "connectionEstablishedSeconds": 0.065495674, + "uploadSeconds": 0.000008899, + "downloadSeconds": 0.063826287 + }, + { + "connectionEstablishedSeconds": 0.063829334, + "uploadSeconds": 0.000001837, + "downloadSeconds": 0.060089253 + }, + { + "connectionEstablishedSeconds": 0.06529261, + "uploadSeconds": 0.000028577, + "downloadSeconds": 0.061037682 + }, + { + "connectionEstablishedSeconds": 0.063842091, + "uploadSeconds": 0.000002584, + "downloadSeconds": 0.061806972 + }, + { + "connectionEstablishedSeconds": 0.068373301, + "uploadSeconds": 0.000002235, + "downloadSeconds": 0.064564059 + }, + { + "connectionEstablishedSeconds": 0.067130341, + "uploadSeconds": 0.000006149, + "downloadSeconds": 0.063393923 + }, + { + "connectionEstablishedSeconds": 0.067629003, + "uploadSeconds": 0.000002073, + "downloadSeconds": 0.063739106 + }, + { + "connectionEstablishedSeconds": 0.063323175, + "uploadSeconds": 0.000001912, + "downloadSeconds": 0.060204556 + }, + { + "connectionEstablishedSeconds": 0.065988954, + "uploadSeconds": 0.000002086, + "downloadSeconds": 0.063942446 + }, + { + "connectionEstablishedSeconds": 0.065993252, + "uploadSeconds": 0.000001936, + "downloadSeconds": 0.061955874 + }, + { + "connectionEstablishedSeconds": 0.065754517, + "uploadSeconds": 0.00000236, + "downloadSeconds": 0.06190852 + }, + { + "connectionEstablishedSeconds": 0.068200333, + "uploadSeconds": 0.00000205, + "downloadSeconds": 0.064447659 + }, + { + "connectionEstablishedSeconds": 0.067581364, + "uploadSeconds": 0.000005537, + "downloadSeconds": 0.064519643 + }, + { + "connectionEstablishedSeconds": 0.067438544, + "uploadSeconds": 0.000002636, + "downloadSeconds": 0.063958896 + }, + { + "connectionEstablishedSeconds": 0.064491387, + "uploadSeconds": 0.000002088, + "downloadSeconds": 0.060455355 + }, + { + "connectionEstablishedSeconds": 0.066671158, + "uploadSeconds": 0.000026897, + "downloadSeconds": 0.063500121 + }, + { + "connectionEstablishedSeconds": 0.064514258, + "uploadSeconds": 0.000002129, + "downloadSeconds": 0.062438357 + }, + { + "connectionEstablishedSeconds": 0.063022356, + "uploadSeconds": 0.000002118, + "downloadSeconds": 0.059175326 + }, + { + "connectionEstablishedSeconds": 0.068643807, + "uploadSeconds": 0.000001978, + "downloadSeconds": 0.064998081 + }, + { + "connectionEstablishedSeconds": 0.065079035, + "uploadSeconds": 0.000002169, + "downloadSeconds": 0.061898486 + }, + { + "connectionEstablishedSeconds": 0.066517253, + "uploadSeconds": 0.000001859, + "downloadSeconds": 0.064493146 + }, + { + "connectionEstablishedSeconds": 0.06317092, + "uploadSeconds": 0.000002025, + "downloadSeconds": 0.061145378 + }, + { + "connectionEstablishedSeconds": 0.065386759, + "uploadSeconds": 0.000001972, + "downloadSeconds": 0.061464088 + }, + { + "connectionEstablishedSeconds": 0.065555644, + "uploadSeconds": 0.000002253, + "downloadSeconds": 0.061802737 + }, + { + "connectionEstablishedSeconds": 0.066860035, + "uploadSeconds": 0.000001965, + "downloadSeconds": 0.06360708 + }, + { + "connectionEstablishedSeconds": 0.066994728, + "uploadSeconds": 0.000002868, + "downloadSeconds": 0.063096596 + }, + { + "connectionEstablishedSeconds": 0.064946091, + "uploadSeconds": 0.000001994, + "downloadSeconds": 0.062688798 + }, + { + "connectionEstablishedSeconds": 0.067006589, + "uploadSeconds": 0.000002901, + "downloadSeconds": 0.063116296 + }, + { + "connectionEstablishedSeconds": 0.068036808, + "uploadSeconds": 0.000002707, + "downloadSeconds": 0.063847827 + }, + { + "connectionEstablishedSeconds": 0.066680459, + "uploadSeconds": 0.000002029, + "downloadSeconds": 0.062822478 + }, + { + "connectionEstablishedSeconds": 0.065744865, + "uploadSeconds": 0.000002751, + "downloadSeconds": 0.062387904 + }, + { + "connectionEstablishedSeconds": 0.065077772, + "uploadSeconds": 0.000001905, + "downloadSeconds": 0.061134873 + } + ], + "implementation": "go-libp2p", + "version": "v0.27", + "transportStack": "quic-v1" + } + ], + "parameters": { + "uploadBytes": 1, + "downloadBytes": 1 + } + } + ], + "pings": { + "unit": "s", + "results": [ + 0.0631, + 0.0628, + 0.0628, + 0.0628, + 0.0629, + 0.0631, + 0.0632, + 0.0628, + 0.0628, + 0.0678, + 0.0681, + 0.0681, + 0.0681, + 0.0681, + 0.0681, + 0.0681, + 0.0624, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0634, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.063, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0631, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629, + 0.0628, + 0.06420000000000001, + 0.0629, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.063, + 0.0629, + 0.0629, + 0.063, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0632, + 0.0628, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629, + 0.0629, + 0.0629, + 0.0628, + 0.0629, + 0.0629 + ] + }, + "iperf": { + "unit": "bit/s", + "results": [ + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3340000000, + 3340000000, + 3330000000, + 3340000000, + 3340000000, + 3340000000, + 3330000000, + 3300000000, + 3290000000, + 3280000000, + 3280000000, + 3280000000, + 3310000000, + 3330000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3330000000, + 3340000000, + 3330000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3340000000, + 3330000000, + 3120000000 + ] + } +} \ No newline at end of file diff --git a/perf/runner/package-lock.json b/perf/runner/package-lock.json new file mode 100644 index 000000000..20894f50c --- /dev/null +++ b/perf/runner/package-lock.json @@ -0,0 +1,650 @@ +{ + "name": "runner", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "runner", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "yargs": "^17.7.1" + }, + "devDependencies": { + "@types/node": "^18.15.11", + "@types/yargs": "^17.0.24", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@types/node": { + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/perf/runner/package.json b/perf/runner/package.json new file mode 100644 index 000000000..bc320c2ec --- /dev/null +++ b/perf/runner/package.json @@ -0,0 +1,20 @@ +{ + "name": "runner", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "ts-node src/index.ts" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@types/node": "^18.15.11", + "@types/yargs": "^17.0.24", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" + }, + "dependencies": { + "yargs": "^17.7.1" + } +} diff --git a/perf/runner/src/benchmark-result-type.ts b/perf/runner/src/benchmark-result-type.ts new file mode 100644 index 000000000..34d1088ef --- /dev/null +++ b/perf/runner/src/benchmark-result-type.ts @@ -0,0 +1,47 @@ +export type BenchmarkResults = { + benchmarks: Benchmark[], + pings: PingResults, + iperf: IperfResults, + // For referencing this schema in JSON + "$schema"?: string +}; + +export type PingResults = { + unit: "s", + results: number[] +}; + +export type IperfResults = { + unit: "bit/s", + results: number[] +}; + +export type Benchmark = { + name: string, + unit: "bit/s" | "s", + results: Result[], + parameters: +} + +export type Parameters = { + uploadBytes: number, + downloadBytes: number, +} + +export type Result = { + implementation: string, + transportStack: string, + version: string + result: ResultValue[], +}; + +export type ResultValue = { + connectionEstablishedSeconds: number, + uploadSeconds: number, + downloadSeconds: number, +}; + +export type Comparison = { + name: string, + result: number, +} diff --git a/perf/runner/src/index.ts b/perf/runner/src/index.ts new file mode 100644 index 000000000..48b706903 --- /dev/null +++ b/perf/runner/src/index.ts @@ -0,0 +1,238 @@ +import { execSync } from 'child_process'; +import { versions } from './versions'; +import yargs from 'yargs'; +import fs from 'fs'; +import { BenchmarkResults, Benchmark, Result, IperfResults, PingResults, ResultValue } from './benchmark-result-type'; + +async function main(clientPublicIP: string, serverPublicIP: string) { + const pings = runPing(clientPublicIP, serverPublicIP); + const iperf = runIPerf(clientPublicIP, serverPublicIP); + + copyAndBuildPerfImplementations(serverPublicIP); + copyAndBuildPerfImplementations(clientPublicIP); + + const benchmarks = [ + runBenchmarkAcrossVersions({ + name: "Single Connection throughput – Upload 100 MiB", + clientPublicIP, + serverPublicIP, + uploadBytes: 100 << 20, + downloadBytes: 0, + unit: "bit/s", + iterations: 5, + }), + runBenchmarkAcrossVersions({ + name: "Single Connection throughput – Download 100 MiB", + clientPublicIP, + serverPublicIP, + uploadBytes: 0, + downloadBytes: 100 << 20, + unit: "bit/s", + iterations: 5, + }), + runBenchmarkAcrossVersions({ + name: "Connection establishment + 1 byte round trip latencies", + clientPublicIP, + serverPublicIP, + uploadBytes: 1, + downloadBytes: 1, + unit: "s", + iterations: 100, + }), + ]; + + const benchmarkResults: BenchmarkResults = { + benchmarks, + pings, + iperf, + }; + + // Save results to benchmark-results.json + fs.writeFileSync('./benchmark-results.json', JSON.stringify(benchmarkResults, null, 2)); + + console.error("== done"); +} + +function runPing(clientPublicIP: string, serverPublicIP: string): PingResults { + console.error(`= run 100 pings from client to server`); + + let cmd = `ssh -o StrictHostKeyChecking=no ec2-user@${clientPublicIP} 'ping -c 100 ${serverPublicIP}'`; + const stdout = execCommand(cmd).toString(); + + // Extract the time from each ping + const lines = stdout.split('\n'); + const times = lines + .map(line => { + const match = line.match(/time=(.*) ms/); + return match ? parseFloat(match[1]) / 1000 : null; // Convert from ms to s + }) + .filter((time): time is number => time !== null); // Remove any null values and ensure that array contains only numbers + + return { unit: "s", results: times } +} + +function runIPerf(clientPublicIP: string, serverPublicIP: string): IperfResults { + console.error(`= run 60 iPerf UDP from client to server`); + + let killCMD = `ssh -o StrictHostKeyChecking=no ec2-user@${serverPublicIP} 'kill $(cat pidfile); rm pidfile; rm server.log || true'`; + const killSTDOUT = execCommand(killCMD); + console.error(killSTDOUT); + + let serverCMD = `ssh -o StrictHostKeyChecking=no ec2-user@${serverPublicIP} 'nohup iperf3 -s > server.log 2>&1 & echo \$! > pidfile '`; + const serverSTDOUT = execCommand(serverCMD); + console.error(serverSTDOUT); + + let cmd = `ssh -o StrictHostKeyChecking=no ec2-user@${clientPublicIP} 'iperf3 -c ${serverPublicIP} -u -b 25g -t 60'`; + const stdout = execSync(cmd).toString(); + + // Extract the bitrate from each relevant line + const lines = stdout.split('\n'); + const bitrates = lines + .map(line => { + const match = line.match(/(\d+(?:\.\d+)?) (\w)bits\/sec/); // Matches and captures the number and unit before "bits/sec" + if (match) { + const value = parseFloat(match[1]); + const unit = match[2]; + // Convert value to bits/sec + const multiplier = unit === 'G' ? 1e9 : unit === 'M' ? 1e6 : unit === 'K' ? 1e3 : 1; + return value * multiplier; + } + return null; + }) + .filter((bitrate): bitrate is number => bitrate !== null); // Remove any null values + + return { unit: "bit/s", results: bitrates} +} + +interface ArgsRunBenchmarkAcrossVersions { + name: string, + clientPublicIP: string; + serverPublicIP: string; + uploadBytes: number, + downloadBytes: number, + unit: "bit/s" | "s", + iterations: number, +} + +function runBenchmarkAcrossVersions(args: ArgsRunBenchmarkAcrossVersions): Benchmark { + console.error(`= Benchmark ${args.name}`) + + const results: Result[] = []; + + for (const version of versions) { + console.error(`== Version ${version.implementation}/${version.id}`) + + console.error(`=== Starting server ${version.implementation}/${version.id}`); + + let killCMD = `ssh -o StrictHostKeyChecking=no ec2-user@${args.serverPublicIP} 'kill $(cat pidfile); rm pidfile; rm server.log || true'`; + const killSTDOUT = execCommand(killCMD); + console.error(killSTDOUT); + + let serverCMD = `ssh -o StrictHostKeyChecking=no ec2-user@${args.serverPublicIP} 'nohup ./impl/${version.implementation}/${version.id}/perf --run-server --server-address 0.0.0.0:4001 --secret-key-seed 0 > server.log 2>&1 & echo \$! > pidfile '`; + const serverSTDOUT = execCommand(serverCMD); + console.error(serverSTDOUT); + + for (const transportStack of version.transportStacks) { + const result = runClient({ + clientPublicIP: args.clientPublicIP, + serverPublicIP: args.serverPublicIP, + id: version.id, + implementation: version.implementation, + transportStack: transportStack, + uploadBytes: args.uploadBytes, + downloadBytes: args.downloadBytes, + iterations: args.iterations, + }); + + results.push({ + result, + implementation: version.implementation, + version: version.id, + transportStack: transportStack, + }); + } + }; + + return { + name: args.name, + unit: args.unit, + results, + parameters: { + uploadBytes: args.uploadBytes, + downloadBytes: args.downloadBytes, + } + }; +} + +interface ArgsRunBenchmark { + clientPublicIP: string; + serverPublicIP: string; + serverAddress?: string; + id: string, + implementation: string, + transportStack: string, + uploadBytes: number, + downloadBytes: number, + iterations: number, +} + +function runClient(args: ArgsRunBenchmark): ResultValue[] { + console.error(`=== Starting client ${args.implementation}/${args.id}/${args.transportStack}`); + + const perfCMD = `./impl/${args.implementation}/${args.id}/perf --server-address ${args.serverPublicIP}:4001 --transport ${args.transportStack} --upload-bytes ${args.uploadBytes} --download-bytes ${args.downloadBytes}` + const cmd = `ssh -o StrictHostKeyChecking=no ec2-user@${args.clientPublicIP} 'for i in {1..${args.iterations}}; do ${perfCMD}; done'` + + const stdout = execCommand(cmd); + + const lines = stdout.toString().trim().split('\n'); + + const combined: ResultValue[]= []; + + for (const line of lines) { + const result = JSON.parse(line) as ResultValue; + combined.push(result); + } + + return combined; +} + +function execCommand(cmd: string): string { + try { + const stdout = execSync(cmd, { + encoding: 'utf8', + stdio: [process.stdin, 'pipe', process.stderr], + }); + return stdout; + } catch (error) { + console.error((error as Error).message); + process.exit(1); + } +} + +function copyAndBuildPerfImplementations(ip: string) { + console.error(`= Building implementations on ${ip}`); + + const stdout = execCommand(`rsync -avz --progress --filter=':- .gitignore' -e "ssh -o StrictHostKeyChecking=no" ../impl ec2-user@${ip}:/home/ec2-user`); + console.error(stdout.toString()); + + const stdout2 = execCommand(`ssh -o StrictHostKeyChecking=no ec2-user@${ip} 'cd impl && make'`); + console.error(stdout2.toString()); +} + +const argv = yargs + .options({ + 'client-public-ip': { + type: 'string', + demandOption: true, + description: 'Client public IP address', + }, + 'server-public-ip': { + type: 'string', + demandOption: true, + description: 'Server public IP address', + }, + }) + .command('help', 'Print usage information', yargs.help) + .parseSync(); + +main(argv['client-public-ip'] as string, argv['server-public-ip'] as string); diff --git a/perf/runner/src/versions.ts b/perf/runner/src/versions.ts new file mode 100644 index 000000000..11aa98a3a --- /dev/null +++ b/perf/runner/src/versions.ts @@ -0,0 +1,38 @@ +export type Version = { + id: string, + implementation: "go-libp2p" | "js-libp2p" | "nim-libp2p" | "rust-libp2p" | "rust-libp2p-quinn" | "zig-libp2p" | "https" | "quic-go", + transportStacks: string[], +} + +export const versions: Array = [ + { + id: "v0.34", + implementation: "quic-go", + transportStacks: ["quic-v1"] + }, + { + id: "v0.52", + implementation: "rust-libp2p", + transportStacks: ["tcp", "quic-v1"] + }, + { + id: "v0.52", + implementation: "rust-libp2p-quinn", + transportStacks: ["quic-v1"] + }, + { + id: "v0.1", + implementation: "https", + transportStacks: ["tcp"] + }, + { + id: "v0.27", + implementation: "go-libp2p", + transportStacks: ["tcp", "quic-v1"] + }, + // { + // id: "zig-libp2p-v0.0.1", + // implementation: "zig-libp2p", + // transportStacks: ["quic-v1"], + // }, +] diff --git a/perf/runner/tsconfig.json b/perf/runner/tsconfig.json new file mode 100644 index 000000000..183dbe70f --- /dev/null +++ b/perf/runner/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "commonjs", + "outDir": "./dist", + "strict": true, + "resolveJsonModule": true, + "esModuleInterop": true + }, + "include": [ + "./src/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/perf/runner/util/.gitignore b/perf/runner/util/.gitignore new file mode 100644 index 000000000..3c3629e64 --- /dev/null +++ b/perf/runner/util/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/perf/runner/util/README.md b/perf/runner/util/README.md new file mode 100644 index 000000000..997c9782a --- /dev/null +++ b/perf/runner/util/README.md @@ -0,0 +1,3 @@ +# Util + +Helper to generate schemas for benchmark data. \ No newline at end of file diff --git a/perf/runner/util/main.ts b/perf/runner/util/main.ts new file mode 100644 index 000000000..e113efc2e --- /dev/null +++ b/perf/runner/util/main.ts @@ -0,0 +1,18 @@ +import * as tsj from "ts-json-schema-generator"; +import * as fs from "fs"; +// const fs = require("fs"); + +/** @type {import('ts-json-schema-generator/dist/src/Config').Config} */ +const config = { + path: "../benchmark-result-type.ts", + tsconfig: "./tsconfig.json", + type: "BenchmarkResults", // Or if you want to generate schema for that one type only +}; + +const output_path = "../benchmarks.schema.json"; + +const schema = tsj.createGenerator(config).createSchema(config.type); +const schemaString = JSON.stringify(schema, null, 2); +fs.writeFile(output_path, schemaString, (err) => { + if (err) throw err; +}); \ No newline at end of file diff --git a/perf/runner/util/package-lock.json b/perf/runner/util/package-lock.json new file mode 100644 index 000000000..7c6b8b01b --- /dev/null +++ b/perf/runner/util/package-lock.json @@ -0,0 +1,559 @@ +{ + "name": "util", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "ts-json-schema-generator": "^1.2.0", + "ts-node": "^10.9.1", + "typescript": "^5.0.2" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "node_modules/@types/node": { + "version": "18.15.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", + "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==", + "peer": true + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-json-schema-generator": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-json-schema-generator/-/ts-json-schema-generator-1.2.0.tgz", + "integrity": "sha512-tUMeO3ZvA12d3HHh7T/AK8W5hmUhDRNtqWRHSMN3ZRbUFt+UmV0oX8k1RK4SA+a+BKNHpmW2v06MS49e8Fi3Yg==", + "dependencies": { + "@types/json-schema": "^7.0.11", + "commander": "^9.4.1", + "glob": "^8.0.3", + "json5": "^2.2.1", + "normalize-path": "^3.0.0", + "safe-stable-stringify": "^2.4.1", + "typescript": "~4.9.3" + }, + "bin": { + "ts-json-schema-generator": "bin/ts-json-schema-generator" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ts-json-schema-generator/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "@types/node": { + "version": "18.15.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", + "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==", + "peer": true + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" + }, + "ts-json-schema-generator": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-json-schema-generator/-/ts-json-schema-generator-1.2.0.tgz", + "integrity": "sha512-tUMeO3ZvA12d3HHh7T/AK8W5hmUhDRNtqWRHSMN3ZRbUFt+UmV0oX8k1RK4SA+a+BKNHpmW2v06MS49e8Fi3Yg==", + "requires": { + "@types/json-schema": "^7.0.11", + "commander": "^9.4.1", + "glob": "^8.0.3", + "json5": "^2.2.1", + "normalize-path": "^3.0.0", + "safe-stable-stringify": "^2.4.1", + "typescript": "~4.9.3" + }, + "dependencies": { + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" + } + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/perf/runner/util/package.json b/perf/runner/util/package.json new file mode 100644 index 000000000..e4f320e3e --- /dev/null +++ b/perf/runner/util/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "ts-json-schema-generator": "^1.2.0", + "ts-node": "^10.9.1", + "typescript": "^5.0.2" + }, + "scripts": { + "gen-schema": "ts-node main.ts" + } +} \ No newline at end of file diff --git a/perf/runner/util/tsconfig.json b/perf/runner/util/tsconfig.json new file mode 100644 index 000000000..e075f973c --- /dev/null +++ b/perf/runner/util/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/perf/terraform/.gitignore b/perf/terraform/.gitignore new file mode 100644 index 000000000..bb09c5300 --- /dev/null +++ b/perf/terraform/.gitignore @@ -0,0 +1,36 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +*.pub diff --git a/perf/terraform/.terraform.lock.hcl b/perf/terraform/.terraform.lock.hcl new file mode 100644 index 000000000..e54d18d34 --- /dev/null +++ b/perf/terraform/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "4.61.0" + constraints = "~> 4.0" + hashes = [ + "h1:mJSchOA6VkYwEsi+tuspadRmyyE+FGZGYJFUt5kHV+M=", + "zh:051e2588410b7448a5c4c30d668948dd6fdfa8037700bfc00fb228986ccbf3a5", + "zh:082fbcf9706b48d0880ba552a11c29527e228dadd6d83668d0789abda24e5922", + "zh:0e0e72f214fb24f4f9c601cab088a2d8e00ec3327c451bc753911951d773214a", + "zh:3af6d38ca733ca66cce15c6a5735ded7c18348ad26040ebd9a59778b2cd9cf6c", + "zh:404898bc2258bbb9527fa06c72cb927ca011fd9bc3f4b90931c0912652c3f9e9", + "zh:4f617653b0f17a7708bc896f029c4ab0b677a1a1c987bd77166acad1d82db469", + "zh:5dbe393355ac137aa3fd329e3d24871f27012d3ba93d714485b55820df240349", + "zh:6067c2127eb5c879227aca671f101de6dcba909d0d8d15d5711480351962a248", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:a939f94461f91aa3b7ec7096271e2714309bd917fe9a03e02f68afb556d65e0f", + "zh:b21227b9082e5fafe8b7c415dc6a99c0d82da05492457377a5fe7d4acaed80e2", + "zh:b8d9f09ed5fc8c654b768b7bee1237eaf1e2287c898249e740695055fb0fe072", + "zh:d360e1e185b148ff6b1d0ed4f7d574e08f2391697ab43df62085b04a1a5b1284", + "zh:da962da17ddda744911cb1e92b983fa3874d73a28f3ee72faa9ddb6680a63774", + "zh:e2f1c4f5ebeb4fd7ef690178168a4c529025b54a91bb7a087dcea48e0b82737a", + ] +} diff --git a/perf/terraform/region/main.tf b/perf/terraform/region/main.tf new file mode 100644 index 000000000..81a3db2bc --- /dev/null +++ b/perf/terraform/region/main.tf @@ -0,0 +1,143 @@ +variable "region" { + description = "The AWS region to create resources in" +} + +variable "ami" { + description = "The Amazon Machine Image to use" +} + +variable "common_tags" { + type = map(string) + description = "Common tags to apply to all resources" +} + +locals { + availability_zone = "${var.region}a" +} + +provider "aws" { + region = var.region +} + +resource "aws_vpc" "perf" { + cidr_block = "10.0.0.0/16" + + tags = merge(var.common_tags, { + Name = "perf" + }) +} + +resource "aws_subnet" "perf" { + vpc_id = aws_vpc.perf.id + cidr_block = "10.0.0.0/16" + availability_zone = local.availability_zone + map_public_ip_on_launch = true + + tags = merge(var.common_tags, { + Name = "perf" + }) +} + +resource "aws_internet_gateway" "perf" { + vpc_id = aws_vpc.perf.id + + tags = merge(var.common_tags, { + Name = "perf-igw" + }) +} + +resource "aws_route_table" "perf" { + vpc_id = aws_vpc.perf.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.perf.id + } + + tags = merge(var.common_tags, { + Name = "perf-route-table" + }) +} + +resource "aws_route_table_association" "perf" { + subnet_id = aws_subnet.perf.id + route_table_id = aws_route_table.perf.id +} + +resource "aws_security_group" "restricted_inbound" { + name = "restricted_inbound" + description = "Allow SSH and port 4001 inbound traffic (TCP and UDP), allow all outbound traffic" + vpc_id = aws_vpc.perf.id + + # ICMP + ingress { + from_port = -1 + to_port = -1 + protocol = "icmp" + cidr_blocks = ["0.0.0.0/0"] + } + + # SSH (TCP) + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 1 + to_port = 65535 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 1 + to_port = 65535 + protocol = "udp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = merge(var.common_tags, { + Name = "restricted_inbound_sg" + }) +} + +resource "aws_key_pair" "perf" { + key_name = "user-public-key" + public_key = file("./user.pub") +} + +resource "aws_instance" "node" { + ami = var.ami + instance_type = "m5n.8xlarge" + + subnet_id = aws_subnet.perf.id + + key_name = aws_key_pair.perf.key_name + + vpc_security_group_ids = [aws_security_group.restricted_inbound.id] + + # Debug via: + # - /var/log/cloud-init.log and + # - /var/log/cloud-init-output.log + user_data = file("./user-data.sh") + user_data_replace_on_change = true + + tags = merge(var.common_tags, { + Name = "node" + }) +} + +output "node_public_ip" { + value = aws_instance.node.public_ip + description = "Public IP address of the node instance" +} diff --git a/perf/terraform/terraform.tf b/perf/terraform/terraform.tf new file mode 100644 index 000000000..79ad18050 --- /dev/null +++ b/perf/terraform/terraform.tf @@ -0,0 +1,38 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.0" + } + } +} + +module "server_region" { + source = "./region" + region = "us-west-2" + ami = "ami-0747e613a2a1ff483" + + common_tags = { + Project = "perf" + } +} + +module "client_region" { + source = "./region" + region = "us-east-1" + ami = "ami-06e46074ae430fba6" + + common_tags = { + Project = "perf" + } +} + +output "server_public_ip" { + value = module.server_region.node_public_ip + description = "Public IP address of the server instance" +} + +output "client_public_ip" { + value = module.client_region.node_public_ip + description = "Public IP address of the client instance" +} diff --git a/perf/terraform/user-data.sh b/perf/terraform/user-data.sh new file mode 100644 index 000000000..d1026af3d --- /dev/null +++ b/perf/terraform/user-data.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +sudo yum install make -y + +sudo yum -y install iperf3 + +# Bump UDP receive buffer size. See https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size. +sudo sysctl -w net.core.rmem_max=2500000 + +sudo yum update -y +sudo yum install docker -y +sudo systemctl enable docker +sudo systemctl start docker +sudo usermod -aG docker ec2-user