diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0236472 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +./analyzer/ +./docs/ +CITATION.cff +README.md + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d47a926 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +# Create a go image to compile the tool +FROM golang:1.19.7-buster AS builder + +# Install git for building the dependencies +WORKDIR / +RUN apt-get install git + +# Copy the relevant code into the Ipfs-Cid-Hoarder folder +# and compile the tool +COPY ./ /ipfs-cid-hoarder +WORKDIR /ipfs-cid-hoarder +RUN make dependencies +RUN make build + +# Bring the binary into a low profile debian image +FROM debian:buster-slim + +# Copy the hoarder's binary into the new image +WORKDIR / +COPY --from=builder /ipfs-cid-hoarder/build/ /cli + +# Expose the port for the Libp2p hosts +EXPOSE 9010 + +# define the endpoint +ENTRYPOINT ["/cli/ipfs-cid-hoarder"] + + diff --git a/cmd/run_cmd.go b/cmd/run_cmd.go index 0b775b7..6fee463 100644 --- a/cmd/run_cmd.go +++ b/cmd/run_cmd.go @@ -3,12 +3,13 @@ package cmd import ( "net/http" _ "net/http/pprof" + "os" + "os/signal" + "syscall" "github.com/cortze/ipfs-cid-hoarder/pkg/config" "github.com/cortze/ipfs-cid-hoarder/pkg/hoarder" - "github.com/pkg/errors" - log "github.com/sirupsen/logrus" cli "github.com/urfave/cli/v2" ) @@ -19,9 +20,10 @@ var RunCmd = &cli.Command{ Action: RunHoarder, Flags: []cli.Flag{ &cli.StringFlag{ - Name: "port", - Usage: "port number where the hoarder will be spawned", - EnvVars: []string{"IPFS_CID_HOARDER_PORT"}, + Name: "port", + Usage: "port number where the hoarder will be spawned", + EnvVars: []string{"IPFS_CID_HOARDER_PORT"}, + DefaultText: "9010", }, &cli.StringFlag{ Name: "log-level", @@ -36,34 +38,29 @@ var RunCmd = &cli.Command{ DefaultText: "postgresql://user:password@localhost:5432/database", Required: true, }, - &cli.StringFlag{ - Name: "cid-source", - Usage: "defines the mode where we want to run the tool [random-content-gen, text-file, json-file,bitswap]", - DefaultText: "text", - }, - &cli.StringFlag{ - Name: "cid-file", - Usage: "link to the file containing the files to track (txt/json files)", - EnvVars: []string{"IPFS_CID_HOARDER_CID_FILE"}, - DefaultText: "cids/test.txt", - }, &cli.IntFlag{ Name: "cid-content-size", Usage: "size in KB of the random block generated", EnvVars: []string{"IPFS_CID_HOARDER_CID_CONTENT_SIZE"}, - DefaultText: "1MB", + DefaultText: "1024 (1KB)", }, &cli.IntFlag{ Name: "cid-number", - Usage: "number of CIDs that will be generated for the study", + Usage: "number of CIDs that will be generated for the study, (set to -1 for a contineous measurement)", EnvVars: []string{"IPFS_CID_HOARDER_CID_NUMBER"}, - DefaultText: "1000 CIDs", + DefaultText: "Undefined CIDs", }, &cli.IntFlag{ Name: "workers", Usage: "max number of CIDs publish and ping workers", EnvVars: []string{"IPFS_CID_HOARDER_BATCH_SIZE"}, - DefaultText: "250 CIDs", + DefaultText: "1 worker", + }, + &cli.BoolFlag{ + Name: "single-publisher", + Usage: "defines whether the hoarderder uses only a single publisher worker (improves publish time accuracy)", + EnvVars: []string{"IPFS_CID_HOARDER_SINGLE_PUBLISHER"}, + DefaultText: "false", }, &cli.StringFlag{ Name: "req-interval", @@ -72,9 +69,9 @@ var RunCmd = &cli.Command{ DefaultText: "30m", }, &cli.StringFlag{ - Name: "study-duration", - Usage: "max time for the study to run (example '24h', '35h', '48h')", - EnvVars: []string{"IPFS_CID_HOARDER_STUDY_DURATION"}, + Name: "cid-ping-time", + Usage: "max time that each CID will be track for (example '24h', '35h', '48h')", + EnvVars: []string{"IPFS_CID_HOARDER_CID_PING_TIME"}, DefaultText: "48h", }, &cli.IntFlag{ @@ -84,55 +81,30 @@ var RunCmd = &cli.Command{ DefaultText: "K=20", }, &cli.StringFlag{ - Name: "already-published-cids", - Usage: "if the cids are already published in the network the tool has to only ping them and not publish them", - EnvVars: []string{"IPFS_CID_HOARDER_PUBLISHED_CIDS"}, - DefaultText: "false", - }, - &cli.StringFlag{ - Name: "config-file", - Usage: "reads a config struct from the specified json file(not yet tested might not work)", - EnvVars: []string{"IPFS_CID_HOARDER_CONFIG_FILE"}, - DefaultText: "config.json", - }, - &cli.BoolFlag{ - Name: "hydra-filter", - Usage: "boolean representation to activate or not the filter to avoid connections to hydras", - EnvVars: []string{"IPFS_CID_HOARDER_HYDRA_FILTER"}, - DefaultText: "false", + Name: "blacklisted-ua", + Usage: "user agent that wants to be balcklisted from having interactions with", + EnvVars: []string{"IPFS_CID_HOARDER_BLACKLISTED_UA"}, + DefaultText: "no-blacklisting", }, }, } func RunHoarder(ctx *cli.Context) error { // here goes all the magic - // generate config from the urfave/cli context - conf, err := config.NewConfig(ctx) - if err != nil { - return errors.Wrap(err, "unable to generate config from arguments") - } + conf := &config.DefaultConfig + conf.Apply(ctx) file, err := config.ParseLogOutput("terminal") - if err != nil { return err } - // set the logs configurations log.SetFormatter(config.ParseLogFormatter("text")) log.SetOutput(file) // log.SetOutput(config.ParseLogOutput("terminal")) log.SetLevel(config.ParseLogLevel(conf.LogLevel)) - jsonConf, err := conf.JsonConfig() - - if err != nil { - log.Errorf("error %s while converting config into json", err) - } - - log.Debug(string(jsonConf)) - // expose the pprof and prometheus metrics go func() { pprofAddres := config.PprofIp + ":" + config.PprofPort @@ -144,11 +116,52 @@ func RunHoarder(ctx *cli.Context) error { }() // Initialize the CidHoarder - log.Info("Running Cid-Hoarder on mode") + log.WithFields(log.Fields{ + "log-level": conf.LogLevel, + "port": conf.Port, + "database": conf.Database, + "cid-size": conf.CidContentSize, + "cid-number": conf.CidNumber, + "workers": conf.Workers, + "single-publisher": conf.SinglePublisher, + "req-interval": conf.ReqInterval, + "cid-ping-time": conf.CidPingTime, + "k": conf.K, + "blacklisted-ua": conf.BlacklistedUA, + + }).Info("running cid-hoarder") cidHoarder, err := hoarder.NewCidHoarder(ctx.Context, conf) if err != nil { return err } - return cidHoarder.Run() + signalC := make(chan os.Signal, 1) + signal.Notify(signalC, syscall.SIGKILL, syscall.SIGTERM, os.Interrupt) + + // lauch the Hoarder + err = cidHoarder.Run() + if err != nil { + return err + } + + // wait until Hoarder finishes, or untill a stop signal comes + hoarderLoop: + for { + select { + case <- signalC: + log.Info("cntr-C detected, closing hoarder peacefully") + cidHoarder.Close() + break hoarderLoop + + case <- ctx.Context.Done(): + log.Info("context died, closing hoarder peacefully") + cidHoarder.Close() + break hoarderLoop + + case <- cidHoarder.FinishedC: + log.Info("cid hoarder sucessfully finished") + break hoarderLoop + } + } + return nil } diff --git a/examplejsonfiles/providers.json b/examplejsonfiles/providers.json deleted file mode 100644 index 4de22e9..0000000 --- a/examplejsonfiles/providers.json +++ /dev/null @@ -1,5522 +0,0 @@ -{ - "ProviderRecords": [ - { - "PeerID": "12D3KooWLTJe3h6r9BV49qDkhxWvNCmT8jRAVExTDnzmgkS4dkS6", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "kubo/0.16.0/38117db", - "PeerMultiaddresses": [ - "/ip4/165.22.83.135/tcp/26184", - "/ip4/165.22.83.135/tcp/29254/ws" - ] - }, - { - "PeerID": "12D3KooWLJWJTv6wmtDaXHHJD8xXNE9PmVz8zS6GSrwdJ3ZYqfak", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.1.193/udp/30010/quic", - "/ip4/127.0.0.1/tcp/30010", - "/ip4/3.12.154.21/udp/30010/quic", - "/ip4/3.12.154.21/tcp/30010", - "/ip4/127.0.0.1/udp/30010/quic", - "/ip4/172.31.1.193/tcp/30010" - ] - }, - { - "PeerID": "12D3KooWH41wFWpjKB2fDVkanqH61CtkkKzs8wYYcVzk5e9fyn5J", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/194.163.182.35/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/194.163.182.35/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWC6HsWVFEqUUvGNYEd7PbqwJwLWpHN3nY9jVu4rrALE9B", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/167.86.67.116/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/167.86.67.116/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWSF1ptkvSbWDDJjaW2af9NPyGJT4vueApK6W6MNGjcE73", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/141.164.50.5/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/141.164.50.5/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWNc11W8eMngKULT9dD7d3gxnVYuWRWN6zTxN7ncj49Fh4", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/212.90.121.189/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/212.90.121.189/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWJrpAjzgW8nEDFvVCTjUGVk3exdtJqjFyenUJrVTmR97M", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/173.212.203.230/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/173.212.203.230/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWCMMw5BKA5XHDJiuFitwparaYbMkidmxTCsJa8vXjt3yW", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/2604:1380:4601:bf00::f/tcp/4002/ws", - "/ip4/145.40.96.83/tcp/4001", - "/ip6/2604:1380:4601:bf00::f/tcp/4001", - "/ip4/145.40.96.83/tcp/4002/ws" - ] - }, - { - "PeerID": "12D3KooWJGiMLeXbEFSeJs6i8tpFwyDDtsujpZX6ma4yZnBu2iJ5", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30009", - "/ip4/172.31.10.61/udp/30009/quic", - "/ip4/127.0.0.1/udp/30009/quic", - "/ip4/18.220.246.63/udp/30009/quic", - "/ip4/18.220.246.63/tcp/30009", - "/ip4/172.31.10.61/tcp/30009" - ] - }, - { - "PeerID": "12D3KooWRCzPib4DJoaKomZxRqpRti3ARjvEXtdqgwtpWhGZPRLR", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.12.2/0e8b121", - "PeerMultiaddresses": [ - "/ip4/23.147.225.34/udp/4001/quic", - "/ip4/23.147.225.34/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWQcLXEXhoagXdj6gvtNeruLbPapHJPGjdt8YfArgwJ5vb", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/149.28.120.142/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/149.28.120.142/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWAVGuFhhvF2dKC4ntgCZWjgWX6zw7VQLaFyEPdJvhdNsV", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.9.1/", - "PeerMultiaddresses": [ - "/ip6/2600:3c01::f03c:92ff:feed:4fb8/udp/4001/quic", - "/ip4/45.79.110.78/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2600:3c01::f03c:92ff:feed:4fb8/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/45.79.110.78/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWNTd6SHbLaazhQKT7QepdFiEuB7NZM3NZ2JqMLkoG8p8R", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::68e9:f42c/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/104.233.244.44/tcp/4001", - "/ip4/104.233.244.44/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWPkB9KfEvau1ov6RU8K8Hy9YRbJEjznt4Z9fWJwpTtpnQ", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.2.122/udp/30004/quic", - "/ip4/3.145.196.50/udp/30004/quic", - "/ip4/3.145.196.50/tcp/30004", - "/ip4/127.0.0.1/udp/30004/quic", - "/ip4/172.31.2.122/tcp/30004", - "/ip4/127.0.0.1/tcp/30004" - ] - }, - { - "PeerID": "QmdLEXtHyhTJ8wjiCGJGw2JRzAFVAwdC6FYCrMJYpZvd2p", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/45.140.235.244/tcp/55713", - "/ip4/127.0.0.1/tcp/55713" - ] - }, - { - "PeerID": "Qme3AuDXMLrhk5FdC97w88WCnzoHGQNDnhcR1PRXu4mAQ1", - "ContentID": "QmdDSXzCtT1PCSKVtqGhDHodaPNCCGmpdQ1BW8s4mH9ATg", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "9.1617986s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/14.43.193.160/tcp/48938", - "/ip4/127.0.0.1/tcp/48938" - ] - }, - { - "PeerID": "12D3KooWBz1d3dG9MLiUHA33xQ958UgBgtCC8a4NKhAzbsmhYPJZ", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/15.204.175.21/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2604:2dc0:101:200::1b5a/tcp/4001", - "/ip4/15.204.175.21/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/2604:2dc0:101:200::1b5a/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWDLM6rVtmmBncRCc4cUezmv268U8VbNyS79G65sqjWDeg", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/213.136.87.164/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/213.136.87.164/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWAxZ5mioaQFkqgLsU9Evh8QkwhXQQpWkWx72e4dG2wkJU", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::68ee:85f5/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/104.238.133.245/udp/4001/quic", - "/ip4/104.238.133.245/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWErRwP21vdVD7rkaivnMfxXAnXs3djX4D5JNfzAYFmrCM", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip4/15.204.161.17/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWSSviJg2LM7boHwYHyEDGPFtJPX6ebcvKbJnsPiFyRcMg", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30012", - "/ip4/127.0.0.1/udp/30012/quic", - "/ip4/3.139.236.118/udp/30012/quic", - "/ip4/172.31.13.122/tcp/30012", - "/ip4/172.31.13.122/udp/30012/quic", - "/ip4/3.139.236.118/tcp/30012" - ] - }, - { - "PeerID": "12D3KooWMgr1ksnGYnvb6VnBBHmYse9BnzjZB2ks86WzfmQMCvef", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/136.244.107.114/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/136.244.107.114/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "QmSuCtRNSE6smwmtA9x3mkhwtPv7jLaPq6h4AczBPZaoej", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.6.0/", - "PeerMultiaddresses": [ - "/ip4/83.208.14.203/udp/4001/quic", - "/ip4/10.0.0.2/tcp/4001", - "/ip4/83.208.14.203/tcp/4001", - "/ip4/10.0.0.2/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "QmfRqEAhFA48ZWBeeWc39utbxmpJyvms2NQM1cK2jLb4id", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.4.23/6ce9a35", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/3.91.89.120/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/169.254.172.2/tcp/4001", - "/ip4/10.0.12.11/tcp/4001" - ] - }, - { - "PeerID": "QmVZ2CK2xPhvt6dYyg181NSZnJuptAz1NTekovJEJSZz7Y", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/155.186.69.123/tcp/44826", - "/ip4/127.0.0.1/tcp/44826" - ] - }, - { - "PeerID": "QmPr247gsyNs9rZ1VdZsy1qN2M7JANTVNfV1GxxWKUdk8F", - "ContentID": "QmPbxTgEzc3GoXwbq6AvRZCevzgbCptqKqBeRdcwowu6rb", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.5610224s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/44236", - "/ip4/106.105.78.208/tcp/44236" - ] - }, - { - "PeerID": "12D3KooWNnbiKEsWqmLsTF47dpDSaMA1myihY5QxcsvwTwQV41VK", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4002/ws", - "/ip4/10.200.0.4/tcp/4001", - "/ip4/10.200.0.4/udp/4001/quic", - "/ip4/34.155.213.124/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/34.155.213.124/tcp/4001", - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::229b:d57c/udp/4001/quic", - "/ip6/64:ff9b::229b:d57c/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/10.200.0.4/tcp/4002/ws" - ] - }, - { - "PeerID": "12D3KooWHLW3LY5Z5eUKtnjdJMUaXtchqbpQa2RbXz2QfantzuPf", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/161.97.102.65/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/161.97.102.65/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWH3ro77TbC9bosnBvYed6XZbhCWbRZksjZeeRmkyy6PZ7", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/188.166.95.122/tcp/4001", - "/ip4/188.166.95.122/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWNa9upMn4Foknx7MV9nki8r4KbLJ1W6pxJprQTUr4EBxW", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/64.92.5.111/tcp/4001", - "/ip6/64:ff9b::405c:56f/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/64.92.5.111/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWT3dCAgHpMCSscSw4EKzNqcSjutEeB7TVqfedsK29CjfR", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip4/147.28.146.9/tcp/4001", - "/ip6/2604:1380:45f1:3f00::1/udp/4001/quic", - "/ip4/147.28.146.9/tcp/4002/ws", - "/ip6/2604:1380:45f1:3f00::1/tcp/4001", - "/ip4/147.28.146.9/udp/4001/quic", - "/ip6/2604:1380:45f1:3f00::1/tcp/4002/ws" - ] - }, - { - "PeerID": "12D3KooWNas7WejMfFhiavBEuQJwLNZaQUAJyvsyKLESae8S6ZXs", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30014", - "/ip4/127.0.0.1/udp/30014/quic", - "/ip4/18.191.208.128/tcp/30014", - "/ip4/172.31.9.71/tcp/30014", - "/ip4/18.191.208.128/udp/30014/quic", - "/ip4/172.31.9.71/udp/30014/quic" - ] - }, - { - "PeerID": "12D3KooWAZBXQpoRkUqS3BvtVRXTk5X2uYs3Ym1GWG5hpHwQupWU", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "go-ipfs/0.12.2/", - "PeerMultiaddresses": [ - "/ip4/205.178.177.107/udp/4001/quic", - "/ip6/64:ff9b::cdb2:b16b/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/205.178.177.107/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWFHVfeVp9dQyUL1NcrSXjLLRa8DmVrjL28uknFuHZLQ5n", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "kubo/0.16.0/38117db", - "PeerMultiaddresses": [ - "/ip4/82.100.92.12/udp/14942/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/82.100.92.12/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWRgPJ3mYHp8k9NYaitKKn2oKhSL3zgtDqq9r2Ae7BzvEa", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/45.32.161.134/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/45.32.161.134/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmdAwGXkbdGspCh3vFFXrzrancsJVqyo2ADRbtRn98roaK", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/121.142.134.113/tcp/39057", - "/ip4/127.0.0.1/tcp/39057" - ] - }, - { - "PeerID": "12D3KooWJydF8Jf9iCh6c1sVLK4C519jaPKN1j6N92obxtqv9h3c", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.119.124.65/tcp/30005", - "/ip4/172.31.1.71/udp/30005/quic", - "/ip4/127.0.0.1/udp/30005/quic", - "/ip4/18.119.124.65/udp/30005/quic", - "/ip4/127.0.0.1/tcp/30005", - "/ip4/172.31.1.71/tcp/30005" - ] - }, - { - "PeerID": "QmZYpf4BasragpXk9HHGP8MHju1diyE6WaHQcjw6ojT77P", - "ContentID": "QmYu9NaLNh7zTQsCi9F8MM55AMLVaufjKf6PLguyggVvRQ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "53.9066308s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a02:c207:2028:7710:6ee4::7/udp/4001/quic", - "/ip6/2a02:c207:2028:7710:2786::6/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c207:2028:7710:6ee4::7/tcp/4001", - "/ip4/164.68.112.221/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:c207:2028:7710:b78a::5/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/164.68.112.221/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWBjZDo13fgdQyxr13NTtmJQfukoNEKyj6TMdQuFRuABWs", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/64.225.53.245/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::40e1:35f5/udp/4001/quic", - "/ip4/64.225.53.245/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWFowr8nzoaZLza9kmcrC4TgSrNMs5czeLXehMBWdetfjq", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip4/10.0.0.35/udp/4001/quic", - "/ip4/10.0.0.35/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/67.161.149.119/tcp/10190", - "/ip4/67.161.149.119/udp/10190/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWF9LqZMUFRfPru5f6mGfY48MEb87F7oCgRnvJGS2qGLNo", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2603:8090:200:145:be30:5bff:fef4:c024/tcp/4001", - "/ip6/2603:8090:200:145:be30:5bff:fef4:c024/udp/4001/quic", - "/ip4/67.52.229.202/tcp/4001", - "/ip4/67.52.229.202/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWE8oEpmbLveXuL1xkdJgjiDDanu2JvKY8rTpctBj1ZTx6", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30010", - "/ip4/172.31.4.120/tcp/30010", - "/ip4/3.145.177.134/udp/30010/quic", - "/ip4/3.145.177.134/tcp/30010", - "/ip4/172.31.4.120/udp/30010/quic", - "/ip4/127.0.0.1/udp/30010/quic" - ] - }, - { - "PeerID": "12D3KooWF1od3udacc8pZSWMoBdFWoVGNFtRKDquAgJpLtPfiiAh", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/70.34.201.194/tcp/4001", - "/ip4/70.34.201.194/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWDbNpaH7mZAmVnW9DPKooYTfHBon8zcUSSwsavyFkT6W3", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/208.87.131.110/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2602:ff16:2:0:1:14a:0:1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/208.87.131.110/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2602:ff16:2:0:1:14a:0:1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLK1UMMortMhrNUzVTR8Nwp1dG7HUzzpgdQrQFpaSAuEw", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30006", - "/ip4/172.31.9.159/udp/30006/quic", - "/ip4/127.0.0.1/udp/30006/quic", - "/ip4/3.144.96.119/udp/30006/quic", - "/ip4/3.144.96.119/tcp/30006", - "/ip4/172.31.9.159/tcp/30006" - ] - }, - { - "PeerID": "12D3KooWJ59N9z5CyLTtcUTnuTKnRTEVxiztijiEAYbP16aZjQ3D", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/147.75.84.155/tcp/4001", - "/ip4/147.75.84.155/tcp/4002/ws", - "/ip6/2604:1380:4601:bf00::13/tcp/4001", - "/ip6/2604:1380:4601:bf00::13/tcp/4002/ws" - ] - }, - { - "PeerID": "12D3KooWFJKPRWgUSuqsZTDCj3nCaqUYADqDKLvuxrAkrEtDAews", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/23.94.168.24/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWGigoYz2cMCQm7eCcQNdNBjiA4E3NCbTEHXQ9B4W7H4hJ", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip4/185.132.178.100/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/185.132.178.100/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::b984:b264/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWQ9s5sCvbRRRN4tfZXGMrXhEUWXwdqC2PbabWve2DvqDf", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30001/quic", - "/ip4/172.31.9.62/udp/30001/quic", - "/ip4/18.118.24.61/udp/30001/quic", - "/ip4/18.118.24.61/tcp/30001", - "/ip4/172.31.9.62/tcp/30001", - "/ip4/127.0.0.1/tcp/30001" - ] - }, - { - "PeerID": "12D3KooWKp7EGWpubButGk4A2woJa9eqtdyisoBBs8tuuixsLym8", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/207.148.69.195/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/207.148.69.195/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "QmSZwZsbLTHfqjwDvzZ7BJh3WwYXcSgJKtyvxytVDZpu2L", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/37.205.84.92/tcp/40439", - "/ip4/127.0.0.1/tcp/40439" - ] - }, - { - "PeerID": "QmUmHgmkTWMo8aY6BsrujwhKmmWEkumujnn9mQy6Poapha", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.12.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/210.23.25.13/tcp/4001", - "/ip4/210.23.25.13/udp/4001/quic", - "/ip6/64:ff9b::d217:190d/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWBeFq78kSqPZyi72QP4zddb388JMRJLtz19pLQ6ovUXJv", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.12.1/da2b9bd", - "PeerMultiaddresses": [ - "/ip4/16.162.106.221/tcp/4001", - "/ip4/172.17.0.3/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/16.162.106.221/udp/4001/quic", - "/ip4/16.162.106.221/udp/4126/quic", - "/ip4/172.17.0.3/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmeC6gBRSjj9sp7jJLWyHcKPkZHLABctx7saVYsnyGEYD8", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/211.230.145.237/tcp/40596", - "/ip4/127.0.0.1/tcp/40596" - ] - }, - { - "PeerID": "12D3KooWPfgtaAvFMBa23uYic6V7P6AdEXFKwKcZg1ggtQuima2e", - "ContentID": "QmZVBpED3ZaJiZqAi9EQnVUCxrBCQbi9nqBsRrT3Do4ij2", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.2435673s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/69.133.50.18/udp/47593/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/fd00::28e4:30ff:fe0d:f6b/tcp/4001", - "/ip4/69.133.50.18/udp/4001/quic", - "/ip4/10.0.2.100/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/fd00::28e4:30ff:fe0d:f6b/udp/4001/quic", - "/ip6/2603:6011:2201:2f6e:201:6cff:fe52:b204/udp/38755/quic", - "/ip6/::1/tcp/4001", - "/ip4/10.0.2.100/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWJuUg9SUFz4WDGcudUpCqeSYAnr7tbkvmEqhHz2a86UYp", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a01:4f9:3a:26d2::2/tcp/4001", - "/ip4/135.181.208.237/tcp/4001", - "/ip4/135.181.208.237/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a01:4f9:3a:26d2::2/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWP4qjCAV3RT6taJS51CGVXAuqTTeLukzUdX4PPuDVaFYS", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip6/2a01:4f8:c0c:b795::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/94.130.177.126/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/94.130.177.126/udp/4001/quic", - "/ip6/64:ff9b::5e82:b17e/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/2a01:4f8:c0c:b795::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWDzFn955ZeFGBKxP6cj7esrN41CrM4Emddv8NczzYxkEr", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/85.14.200.36/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a01:480:1000::40/udp/4001/quic", - "/ip4/85.14.200.36/tcp/4001", - "/ip6/2a01:480:1000::40/tcp/4001", - "/ip6/64:ff9b::550e:c824/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWSRBQceHR7vk9EWcRAxLGaussQuxx6PwCNjsHhDi6CQuC", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "kubo/0.14.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/185.130.47.36/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2a07:e03:100:100::1/tcp/4001", - "/ip6/2a07:e03:100:100::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/185.130.47.36/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWAC9ZaYdc3KJtoxdRGsyJzDS2XQdnHzyh6PCUJhB74zGq", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "go-ipfs/0.10.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/173.212.200.61/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/173.212.200.61/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWFZcAEoRoFUvvvoesP4Sff4stK53euVHVXcooH9UzphhN", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/188.34.146.164/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::bc22:92a4/tcp/4001", - "/ip6/64:ff9b::bc22:92a4/udp/4001/quic", - "/ip4/188.34.146.164/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWA1XKc4Km3bSLFMnWjBvMf48G7gLobh4pXok6wLsEtypm", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/38.242.198.247/tcp/4001", - "/ip4/38.242.198.247/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWEf9MsWzXaqe2DQggdjJRoSEkjogwyXKzuS5ntbsAZWsz", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.2.148/udp/30012/quic", - "/ip4/3.138.170.1/udp/30012/quic", - "/ip4/172.31.2.148/tcp/30012", - "/ip4/127.0.0.1/tcp/30012", - "/ip4/3.138.170.1/tcp/30012", - "/ip4/127.0.0.1/udp/30012/quic" - ] - }, - { - "PeerID": "12D3KooWChWAJfSLf4UzY63MucRkivrivKpaeSc6L6VacMTirGDW", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/52.14.146.89/tcp/30009", - "/ip4/172.31.9.37/udp/30009/quic", - "/ip4/52.14.146.89/udp/30009/quic", - "/ip4/127.0.0.1/udp/30009/quic", - "/ip4/127.0.0.1/tcp/30009", - "/ip4/172.31.9.37/tcp/30009" - ] - }, - { - "PeerID": "QmeopCzdEWE43UpT8Ch5eF83vDJsjssvfeT5ZLtCYnJrLW", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip6/2a02:c207:2025:6602:f3a5::17/tcp/4001", - "/ip6/2a02:c207:2025:6602:1f0d::1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/167.86.97.6/tcp/4001", - "/ip6/2a02:c207:2025:6602:9a90::17/tcp/4001", - "/ip6/2a02:c207:2025:6602:4003::7/udp/4001/quic", - "/ip6/2a02:c207:2025:6602:5432::16/tcp/4001", - "/ip6/2a02:c207:2025:6602:5574::16/tcp/4001", - "/ip6/2a02:c207:2025:6602:9dfe::3/tcp/4001", - "/ip6/2a02:c207:2025:6602:5306::14/tcp/4001", - "/ip6/2a02:c207:2025:6602:307f::2/tcp/4001", - "/ip6/2a02:c207:2025:6602:e99a::5/tcp/4001", - "/ip6/2a02:c207:2025:6602:48f8::17/tcp/4001", - "/ip6/2a02:c207:2025:6602:47c3::6/tcp/4001", - "/ip6/2a02:c207:2025:6602:f90e::14/tcp/4001", - "/ip6/2a02:c207:2025:6602:4003::7/tcp/4001", - "/ip6/2a02:c207:2025:6602:6de4::4/tcp/4001", - "/ip6/2a02:c207:2025:6602:1552::5/tcp/4001", - "/ip6/64:ff9b::a756:6106/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/167.86.97.6/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c207:2025:6602:de1d::5/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWNv6rqf1d4iHHwv1pyfU4b3Rji9oL7zJ7fdsTuewbRe9b", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.2.122/udp/30011/quic", - "/ip4/127.0.0.1/tcp/30011", - "/ip4/127.0.0.1/udp/30011/quic", - "/ip4/172.31.2.122/tcp/30011", - "/ip4/3.145.196.50/udp/30011/quic", - "/ip4/3.145.196.50/tcp/30011" - ] - }, - { - "PeerID": "12D3KooWKP9WP1MAhWGnMrUB1cPfjD1F98dEpkmUkse7teNMq7H3", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.0.225/tcp/30009", - "/ip4/127.0.0.1/udp/30009/quic", - "/ip4/18.119.105.44/udp/30009/quic", - "/ip4/172.31.0.225/udp/30009/quic", - "/ip4/127.0.0.1/tcp/30009", - "/ip4/18.119.105.44/tcp/30009" - ] - }, - { - "PeerID": "12D3KooWN23aqCCKR6JB2HKghFieGvTKiRmP1C9UKLeNbroPiFfb", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "ioi", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/11713/ws", - "/ip4/126.13.206.216/tcp/35696/ws", - "/ip4/126.13.206.216/tcp/50195", - "/ip6/::1/udp/58597/quic", - "/ip6/::1/tcp/11712", - "/ip4/192.168.11.2/tcp/11711", - "/ip4/192.168.11.2/udp/58596/quic", - "/ip4/126.13.206.216/tcp/20864/ws", - "/ip4/192.168.11.2/tcp/11713/ws", - "/ip4/126.13.206.216/udp/41552/quic", - "/ip4/127.0.0.1/udp/58596/quic", - "/ip4/127.0.0.1/tcp/11711", - "/ip4/126.13.206.216/tcp/21917", - "/ip6/::1/tcp/11714/ws", - "/ip4/126.13.206.216/udp/37290/quic" - ] - }, - { - "PeerID": "QmdVNbrwsGXGghixGxhEshGdYM6YjxYwpmGTjA4uJ5JU3Q", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/192.168.0.10/tcp/58469", - "/ip4/127.0.0.1/tcp/58469", - "/ip4/46.71.4.129/tcp/58469" - ] - }, - { - "PeerID": "12D3KooWAwBM4E1BWihNgySSqrvgSAkQu4CzxR9ZM8VKhqwSocrq", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.14.194/udp/30010/quic", - "/ip4/127.0.0.1/tcp/30010", - "/ip4/3.135.218.2/udp/30010/quic", - "/ip4/172.31.14.194/tcp/30010", - "/ip4/3.135.218.2/tcp/30010", - "/ip4/127.0.0.1/udp/30010/quic" - ] - }, - { - "PeerID": "12D3KooWMRkwpybiShn8t6E3gpNY4qr36s2VERaXpQPu86W2ab7i", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "kubo/0.16.0/38117db", - "PeerMultiaddresses": [ - "/ip4/172.18.0.2/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/5.161.139.193/tcp/4001", - "/ip4/5.161.139.193/udp/4001/quic", - "/ip6/64:ff9b::5a1:8bc1/tcp/4001", - "/ip4/172.18.0.2/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWEF7U3j9dPdxMJAe7yApk8y2kBAcPAKGrVDY6QJjMRmFH", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "go-ipfs/0.12.0/", - "PeerMultiaddresses": [ - "/ip4/15.235.132.69/tcp/4001", - "/ip4/15.235.132.69/udp/12736/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/15.235.132.69/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.17.0.2/udp/4001/quic", - "/ip4/172.17.0.2/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWMxxq322hvZFBqg8iwGdCbMaobRhPCbWJ2mHNLV24VJVy", - "ContentID": "QmdRyoYZcEnbFJnhsF3ToLYUnMeaAMfyU4wNe6qq4Pr95V", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "2.455429s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/167.99.208.41/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a03:b0c0:2:d0::d97:d001/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/167.99.208.41/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a03:b0c0:2:d0::d97:d001/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWHfyePm8oVPtHQuEPhwxtayB7iMRaQmJGJfWbmhNGWWQU", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/38.242.207.212/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/38.242.207.212/tcp/4001" - ] - }, - { - "PeerID": "QmNMs4C2taBgMP716bgaN6wyyLRMTzLSVC5aqXrNjHE33Z", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/147.75.100.113/udp/4001/quic", - "/ip4/147.75.100.113/tcp/4002/ws", - "/ip6/2604:1380:2001:2b00::1/tcp/4002/ws", - "/ip4/147.75.100.113/tcp/4001", - "/ip6/2604:1380:2001:2b00::1/udp/4001/quic", - "/ip6/2604:1380:2001:2b00::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWR2PYhZy38K3s9V7Avw8soPF4sXa8bw37DuC5Qw8wR31u", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip4/185.130.47.76/tcp/4001", - "/ip4/172.18.0.3/tcp/4001", - "/ip4/185.130.47.76/udp/48208/quic", - "/ip4/185.130.47.76/udp/4142/quic", - "/ip6/64:ff9b::b982:2f4c/tcp/4001", - "/ip4/172.18.0.3/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWMcM5N5L1j43qBDAZ4Kb2QMfidjERZJWLNKerm9mWTSrq", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.13.191/udp/30005/quic", - "/ip4/172.31.13.191/tcp/30005", - "/ip4/127.0.0.1/tcp/30005", - "/ip4/127.0.0.1/udp/30005/quic", - "/ip4/3.17.183.133/udp/30005/quic", - "/ip4/3.17.183.133/tcp/30005" - ] - }, - { - "PeerID": "12D3KooWBCfKxKtVthw5svPE2DjCyzUDsCCentN1Lv49qf6R5Ppj", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.191.140.34/udp/30002/quic", - "/ip4/127.0.0.1/tcp/30002", - "/ip4/172.31.14.208/udp/30002/quic", - "/ip4/18.191.140.34/tcp/30002", - "/ip4/127.0.0.1/udp/30002/quic", - "/ip4/172.31.14.208/tcp/30002" - ] - }, - { - "PeerID": "12D3KooWPF8Z1PeHdzXJnjhturrvvFTtrFTKSHLYMKqwFnvaboqM", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "kubo/0.14.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip6/::1/tcp/4002/ws", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/34.121.54.70/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/34.121.54.70/udp/4001/quic", - "/ip6/64:ff9b::2279:3646/udp/4001/quic", - "/ip6/64:ff9b::2279:3646/tcp/4001", - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWNWAYGAuTPMao9hfw8GrehWYoUuWPHQ6LbK2mrxbbdBdE", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.189.184.249/udp/30013/quic", - "/ip4/172.31.9.156/udp/30013/quic", - "/ip4/127.0.0.1/udp/30013/quic", - "/ip4/172.31.9.156/tcp/30013", - "/ip4/127.0.0.1/tcp/30013", - "/ip4/18.189.184.249/tcp/30013" - ] - }, - { - "PeerID": "12D3KooWHQvzTwkBzHVbf51atJZNbn6uF6EB2ieLNqoNiToTMcDW", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "ioi", - "PeerMultiaddresses": [ - "/ip6/::1/udp/49250/quic", - "/ip4/222.212.36.228/tcp/50343", - "/ip4/127.0.0.1/udp/49247/quic", - "/ip4/127.0.0.1/tcp/50343", - "/ip4/222.212.36.228/udp/49247/quic", - "/ip6/::1/tcp/50344", - "/ip6/::1/tcp/50346/ws", - "/ip4/127.0.0.1/tcp/50345/ws", - "/ip4/222.212.36.228/tcp/50345/ws" - ] - }, - { - "PeerID": "12D3KooWMUjdfm6nKzsLY5wFXrAVhogRH1xVt1VqXt8Fid5QxvxP", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.7.71/udp/30004/quic", - "/ip4/3.137.171.207/udp/30004/quic", - "/ip4/3.137.171.207/tcp/30004", - "/ip4/127.0.0.1/udp/30004/quic", - "/ip4/127.0.0.1/tcp/30004", - "/ip4/172.31.7.71/tcp/30004" - ] - }, - { - "PeerID": "12D3KooWFDN3sDfvn9dPvFZG4P1hMg21PTmUt56zCtX7VWRZkLV8", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "go-ipfs/0.7.0/ea77213e3", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/23.124.76.211/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::177c:4cd3/tcp/4001", - "/ip4/23.124.76.211/tcp/4001" - ] - }, - { - "PeerID": "Qma9AJtBZtbtMHfJCd1GZRJe4R4dCyL67hyAJWQUYdfmP1", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/192.168.68.56/tcp/56225", - "/ip4/127.0.0.1/tcp/56225", - "/ip4/112.119.217.58/tcp/56225" - ] - }, - { - "PeerID": "QmUC9NZxj4Jrxr5cnc24gR8CfhCdNEeK6bAZMMRc1vKRUL", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/56510", - "/ip4/218.250.159.164/tcp/56510" - ] - }, - { - "PeerID": "QmTWW2RFwpJkrjWUzVRyexxBaoFCMczUxCZzPy9kJQT22g", - "ContentID": "QmWS6X8pLGNXsR3kxgPbX37QPQWczk5wjRYgtjVqrwhQgP", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.4852911s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/39.120.59.114/tcp/46334", - "/ip4/127.0.0.1/tcp/46334" - ] - }, - { - "PeerID": "12D3KooWB9fyYNkdyDcnnABn7EX22uKS6tMeFGdSzKMfLPZhQWNr", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "kubo/0.14.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/95.216.165.14/udp/4001/quic", - "/ip6/2a01:4f9:c011:aafc::1/tcp/4001", - "/ip6/64:ff9b::5fd8:a50e/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a01:4f9:c011:aafc::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/95.216.165.14/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWAdvTG3oxbz3AekFWsFyz6zbJNvMSYgPaktBA9CxF67gt", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.10.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/194.163.153.148/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/194.163.153.148/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWGkcereXUCLthGc8yReenh2ben4Mp42ng2RgoS7m4keHA", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/109.205.182.253/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:c206:2076:1457::1/udp/4001/quic", - "/ip6/2a02:c206:2076:1457::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/109.205.182.253/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWBmDt8644NpucAN9YDxsNVvzd1QAokgqMF1CstKENn4ZH", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.10.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2600:4040:a000:b600:6332:d488:6fb7:4f75/udp/4001/quic", - "/ip4/98.109.128.14/udp/49325/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/192.168.1.217/tcp/4001", - "/ip4/192.168.1.217/udp/4001/quic", - "/ip4/98.109.128.14/tcp/49325", - "/ip6/2600:4040:a000:b600:6332:d488:6fb7:4f75/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWPhpy2M51qMnMW4ar35DxYq8PjGtnN7CxCtj4WLZ9zBWn", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.13.1/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::c6c7:5689/udp/4001/quic", - "/ip4/198.199.86.137/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/198.199.86.137/udp/4001/quic", - "/ip6/64:ff9b::c6c7:5689/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWNSmdxhBM8mvHp5LyKFC4Gr45qDJtdcPwGnqEGEx1e3HL", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/45.32.172.149/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/45.32.172.149/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWDkvD4aNdnFoeoNbsgue1HwZoVxFhmnMUAa4gcRefYK8B", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/104.238.179.237/udp/4001/quic", - "/ip4/104.238.179.237/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::68ee:b3ed/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWR8beB9yQmLEt128LAZNujpC4nN2KoC3uy4bLA8vy7uao", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/31.10.160.81/tcp/17987", - "/ip6/2a02:aa13:6200:e880:1296:d711:8bea:cad4/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:aa13:6200:e880:1296:d711:8bea:cad4/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/31.10.160.81/udp/17813/quic" - ] - }, - { - "PeerID": "12D3KooWCtqtEEz7X8kTVe6D2tP2MthCzJD3nBzWNtW7RpQw64Yr", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.219.124.96/udp/30012/quic", - "/ip4/18.219.124.96/tcp/30012", - "/ip4/172.31.12.157/tcp/30012", - "/ip4/172.31.12.157/udp/30012/quic", - "/ip4/127.0.0.1/tcp/30012", - "/ip4/127.0.0.1/udp/30012/quic" - ] - }, - { - "PeerID": "12D3KooWF2DWzoaudM5AH5FwyakTYsCNdNanH5dJxtmPdEoWDVzo", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.12.2/", - "PeerMultiaddresses": [ - "/ip6/2001:19f0:b400:1996:5400:3ff:fefd:2a07/tcp/4001", - "/ip4/216.238.72.185/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::d8ee:48b9/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2001:19f0:b400:1996:5400:3ff:fefd:2a07/udp/4001/quic", - "/ip4/216.238.72.185/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWK7yA5SpRArsQ43eNHSywY776LEC8rAGYFq5v4cmeLYx8", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/2604:ed40:1000:1711:c08b:37ff:fe37:609f/udp/4001/quic", - "/ip4/209.151.144.212/tcp/4001", - "/ip6/2604:ed40:1000:1711:c08b:37ff:fe37:609f/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/209.151.144.212/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWCVwSk6eHQ9vyxSD7ruU8zrSdkMmSydnqtAZKNKwEWoTy", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::34dc:593e/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/52.220.89.62/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/52.220.89.62/tcp/4001", - "/ip4/10.116.0.103/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/10.116.0.103/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWQtyi63cgCdMwzX4ER1E5nsKLjoFrtbyaq6HbR69srMEi", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::70a2:f860/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/112.162.248.96/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/112.162.248.96/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWHVZ7DB82UbZfWBmCNXys2mrAMEMQk5YZs9zgyv7t7hsM", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/45.76.163.160/udp/4001/quic", - "/ip4/45.76.163.160/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "QmS17Kg47ja9G3CYsQFD7LUT4eLJPZuHez46DCwEMuTLBG", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/182.155.94.44/tcp/34387", - "/ip4/127.0.0.1/tcp/34387" - ] - }, - { - "PeerID": "QmXzYeNWu14iaZDUAUnpiZbyTubVCgdsR5rZTkYKyssevu", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/34695", - "/ip4/113.252.101.29/tcp/34695", - "/ip4/113.252.101.253/tcp/34695" - ] - }, - { - "PeerID": "QmYCQBrV5HEKP9XNZu71vPh7eEdNYrAf8qvNAj1xJ6fnbU", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "storm", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/47667", - "/ip4/1.36.220.136/tcp/47667" - ] - }, - { - "PeerID": "12D3KooWSk2Ymc6JJ1Xro9eCxapGEYNVwWGLEY24GZhJ3xs6AYGe", - "ContentID": "QmSAdPDLf4jajhUSDaiQodJjshBb18jqN9bwBxcWHGPCUZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "37.8211443s", - "UserAgent": "ioi", - "PeerMultiaddresses": [ - "/ip4/192.168.1.104/udp/54674/quic", - "/ip4/222.129.58.14/udp/1345/quic", - "/ip4/127.0.0.1/tcp/55192", - "/ip6/::1/tcp/55193", - "/ip6/::1/udp/54675/quic", - "/ip4/192.168.1.104/tcp/55192", - "/ip4/192.168.1.104/tcp/55194/ws", - "/ip4/127.0.0.1/udp/54674/quic", - "/ip4/127.0.0.1/tcp/55194/ws", - "/ip6/::1/tcp/55195/ws" - ] - }, - { - "PeerID": "12D3KooWG6YGghaG9Q2qRGKMAk1vhXBTPeHDnSyFQPv28rMx5ULK", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/217.69.11.192/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/217.69.11.192/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmbLabR3HrxrmsxWVvPLWN7a84GuroH1GUstrJAiwfgW5L", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::a747:2b25/tcp/4001", - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/10.100.248.14/tcp/1080/ws", - "/ip4/167.71.43.37/tcp/4001", - "/ip4/167.71.43.37/tcp/4002/ws", - "/ip6/2a03:b0c0:3:d0::175c:e001/tcp/4001", - "/ip6/::1/tcp/4002/ws", - "/ip6/2a03:b0c0:3:d0::175c:e001/tcp/4002/ws", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWRJB6VTdyszQfyzNhfAJXD5gJd6rnjR4sFkm6cuwCkS9e", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/64:ff9b::feb:238e/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/15.235.35.142/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/15.235.35.142/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWC8epdU21YmnEUDa18EVFwtpMFzJgtE43PaZLTpEwuokv", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/136.144.49.23/tcp/4001", - "/ip4/136.144.49.23/tcp/4002/ws", - "/ip4/136.144.49.23/udp/4001/quic", - "/ip6/2604:1380:4091:5700::1d/tcp/4001", - "/ip6/2604:1380:4091:5700::1d/tcp/4002/ws", - "/ip6/2604:1380:4091:5700::1d/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWRMcNJmsa7PtZuvZNNLNsHycbaYxg1gqQuHTNiqv1CvVs", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:c206:2076:555::1/tcp/4001", - "/ip4/194.163.137.3/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/194.163.137.3/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c206:2076:555::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWHfVr6yqNPBrp3o9LSK1ns5s1mEVrViNgVzDJysdEsRR8", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/195.90.201.7/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::c35a:c907/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/195.90.201.7/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWC45SNqHjQTE9PxmdJUZYwoB8sfJy8NLZfT9vy25C8gNp", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/62.171.188.226/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/62.171.188.226/udp/4001/quic" - ] - }, - { - "PeerID": "QmYsyRLba5jjeVvS4Sc9BTsjhi9q1Xfs4PvtNb3aSmemNc", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip6/2a02:c207:2027:2012:cdf7::4/tcp/4001", - "/ip6/2a02:c207:2027:2012:dd29::6/tcp/4001", - "/ip6/2a02:c207:2027:2012:7ccf::3/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a02:c207:2027:2012:a880::5/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/2a02:c207:2027:2012:8cd4::2/tcp/4001", - "/ip6/2a02:c207:2027:2012:778e::6/tcp/4001", - "/ip4/173.249.54.4/udp/4001/quic", - "/ip6/2a02:c207:2027:2012:dd29::6/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:c207:2027:2012:c692::4/tcp/4001", - "/ip6/2a02:c207:2027:2012:f17f::4/tcp/4001", - "/ip4/173.249.54.4/tcp/4001", - "/ip6/2a02:c207:2027:2012:adc3::4/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWPipWVG2YFexTq1rcdyTfdXnqye4M19WpQvmTm3eMpZXa", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.117.192.219/udp/30011/quic", - "/ip4/127.0.0.1/udp/30011/quic", - "/ip4/18.117.192.219/tcp/30011", - "/ip4/127.0.0.1/tcp/30011", - "/ip4/172.31.15.173/tcp/30011", - "/ip4/172.31.15.173/udp/30011/quic" - ] - }, - { - "PeerID": "12D3KooWMjmfESznEWgZVFew8CvFkGCQgL7mTCStmMRPuw3Upb1x", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/85.215.214.227/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/85.215.214.227/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWASbMkmmTHoFpZa3F6BJBfZnMzn6jFWZAQtJtg2Fd2JdW", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30003/quic", - "/ip4/3.12.165.217/tcp/30003", - "/ip4/172.31.8.152/tcp/30003", - "/ip4/3.12.165.217/udp/30003/quic", - "/ip4/127.0.0.1/tcp/30003", - "/ip4/172.31.8.152/udp/30003/quic" - ] - }, - { - "PeerID": "12D3KooWPQZBrZ5icBzpQRMu8FUZDinfAC78zsA8mcaMXdHcLkct", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/158.247.198.120/udp/4001/quic" - ] - }, - { - "PeerID": "QmSe5Prj4zF2qfd2yQUXGgRcN7LUrxfRZd7AeKJ58kZvb5", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.12.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::8e5d:79ca/tcp/4001", - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip6/2604:a880:400:d0::24c5:1001/tcp/4001", - "/ip4/142.93.121.202/tcp/4002/ws", - "/ip6/2604:a880:400:d0::24c5:1001/tcp/4002/ws", - "/ip4/10.100.248.14/tcp/1080/ws", - "/ip4/142.93.121.202/tcp/4001", - "/ip6/::1/tcp/4002/ws", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "QmeuyqGes7QDCkqatYqUUdUCdPJGWxQhaPtzpYH1J5rD2Q", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/178.139.75.99/tcp/40032", - "/ip4/127.0.0.1/tcp/40032" - ] - }, - { - "PeerID": "QmfEdRgntgQWK69BBkURQYfqEBn2Hf8hWQsyQFEhdN6yxJ", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/59.13.33.204/tcp/56879", - "/ip4/127.0.0.1/tcp/56879" - ] - }, - { - "PeerID": "QmbwLWSdqJs92ifx6eqfjoqrcD5R7Pgx1Ps6Px5m7eTusz", - "ContentID": "QmaAHJioRm64UghLmP4GbS8zFoBfDnzsYuDUVgF98az3FZ", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.7768617s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/116.86.75.241/tcp/47834", - "/ip4/127.0.0.1/tcp/47834" - ] - }, - { - "PeerID": "12D3KooWRagd9Dnwm8EuhncpWS2k9ZfdBF6AwZJBpfE13tcAfZfc", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.8.123/tcp/30001", - "/ip4/172.31.8.123/udp/30001/quic", - "/ip4/18.119.162.253/tcp/30001", - "/ip4/18.119.162.253/udp/30001/quic", - "/ip4/127.0.0.1/tcp/30001", - "/ip4/127.0.0.1/udp/30001/quic" - ] - }, - { - "PeerID": "12D3KooWGDiWfCHvoh8UZ4tGjgCYUwArLS5uDrZzf1ff6aukHYQy", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.12.0/06191df", - "PeerMultiaddresses": [ - "/ip4/163.172.211.99/udp/26182/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/163.172.211.99/tcp/4001", - "/ip4/172.17.0.2/tcp/4001", - "/ip4/163.172.211.99/udp/4001/quic", - "/ip4/172.17.0.2/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWPTtukQZ7tg9NKC1fkBY1mYphKjudxYqDWvtpxte3QT6q", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2600:3c03::f03c:92ff:fe94:3094/udp/4001/quic", - "/ip4/172.104.211.186/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/172.104.211.186/udp/4001/quic", - "/ip6/2600:3c03::f03c:92ff:fe94:3094/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmUgmRxoLtGERot7Y6G7UyF6fwvnusQZfGR15PuE6pY3aB", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.10.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4011/ws", - "/ip4/88.99.105.146/tcp/4011/ws", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a01:4f8:10a:19d1::2/tcp/4011/ws", - "/ip6/64:ff9b::5863:6992/tcp/4001", - "/ip6/2a01:4f8:10a:19d1::2/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/88.99.105.146/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4011/ws", - "/ip4/88.99.105.146/tcp/4001", - "/ip6/64:ff9b::5863:6992/udp/4001/quic", - "/ip6/2a01:4f8:10a:19d1::2/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWASG4fYZQSdrzooUXMhCNNHMNUCCFvDcccjyG6g5jXDqx", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.8.0/ce693d7", - "PeerMultiaddresses": [ - "/ip4/160.40.54.177/udp/9979/quic", - "/ip4/172.17.0.3/tcp/4001", - "/ip4/160.40.54.177/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.17.0.3/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/160.40.54.177/udp/63010/quic" - ] - }, - { - "PeerID": "12D3KooWNFr8hUBVR6SbtLNM86EVUSma7jGJCHys4rW8YaHCwJt2", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/185.78.165.202/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::b94e:a5ca/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/185.78.165.202/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWGzceqZCdhtNVoV9r5FxYsjB6uhd8xFQKtDHbjXk6bqh4", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30010", - "/ip4/172.31.3.131/tcp/30010", - "/ip4/172.31.3.131/udp/30010/quic", - "/ip4/3.137.173.8/udp/30010/quic", - "/ip4/3.137.173.8/tcp/30010", - "/ip4/127.0.0.1/udp/30010/quic" - ] - }, - { - "PeerID": "12D3KooWScxm2FUEetY4fpX2r5HNkeD843p5uCqgVCSnF8AhpbGd", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/223.206.223.75/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/223.206.223.75/udp/4001/quic" - ] - }, - { - "PeerID": "QmVH5V55UttoN4DP3iwfPFeCxA4M1kQDeha7zv91Rr6cLc", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/38625", - "/ip4/91.211.63.117/tcp/64699", - "/ip4/192.168.1.101/tcp/38625" - ] - }, - { - "PeerID": "12D3KooWJRoyL6KeW1Qdk1yD2bqXPwMZ7ipTcNgtWFfeRwri3QLu", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "ioi", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/65123/quic", - "/ip6/::1/tcp/52378/ws", - "/ip4/127.0.0.1/tcp/52375", - "/ip4/119.142.145.81/tcp/32112", - "/ip6/::1/udp/65124/quic", - "/ip4/119.142.145.81/udp/32122/quic", - "/ip6/::1/tcp/52376", - "/ip4/172.19.225.47/tcp/52377/ws", - "/ip4/172.19.225.47/tcp/52375", - "/ip6/2001:0:2851:b9f0:2cee:8374:8871:6eae/udp/65124/quic", - "/ip6/2001:0:2851:b9f0:2cee:8374:8871:6eae/tcp/52376", - "/ip6/2001:0:2851:b9f0:2cee:8374:8871:6eae/tcp/52378/ws", - "/ip4/172.19.225.47/udp/65123/quic", - "/ip4/127.0.0.1/tcp/52377/ws" - ] - }, - { - "PeerID": "12D3KooWQ12EsnoRYvLKXCbikbFBLuzyo3s5dg49FwQqkjVtrqzK", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip4/192.168.0.237/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/14.192.238.169/udp/56480/quic", - "/ip4/14.192.238.169/tcp/56480", - "/ip4/192.168.0.237/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWAPTKzjzng4mynqA8e4y2m7w5u9TfLP8Jg5raXcci3fEs", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip4/8.141.174.214/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/64:ff9b::88d:aed6/tcp/4001", - "/ip4/8.141.174.214/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.18.49.21/udp/4001/quic", - "/ip4/172.18.49.21/tcp/4001" - ] - }, - { - "PeerID": "QmUKSfnEzi7mYGFWy92wstMQxniNxNciFay1Guc6wm7CFG", - "ContentID": "QmcPeRvAk2itbBRkptrVbG2aYYiDrpP38w3SyWdPNMj8xz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.7309314s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/121.234.43.38/tcp/40179", - "/ip4/192.168.31.51/tcp/40179", - "/ip4/127.0.0.1/tcp/40179" - ] - }, - { - "PeerID": "12D3KooWAoxrqciuGhtTUjtPuRQxww7dV2iBLZTd9svkzMVwkFwt", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/5.189.128.177/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/5.189.128.177/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWMJyXYhRjDq9Vfrgs1CpTGy86awaKNdNB3kfmGag8itUC", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::33de:2fe8/udp/4001/quic", - "/ip4/51.222.47.232/udp/4001/quic", - "/ip6/64:ff9b::33de:2fe8/tcp/4001", - "/ip4/51.222.47.232/udp/55463/quic", - "/ip6/64:ff9b::33de:2fe8/udp/55463/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/51.222.47.232/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWJcKNtjb9UpF7jsKWxy46ULQjYnNUu6H9izWJiYUA4Njo", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "go-ipfs/0.12.0/", - "PeerMultiaddresses": [ - "/ip6/2605:6400:30:eeea:10:10:26:5/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2605:6400:30:eeea:10:10:26:5/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/107.189.30.119/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/107.189.30.119/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWDHFw7v4a8RZV7YYL8rFSqN8KYTP7x3KHksuVGTfE5tMk", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "go-ipfs/0.10.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::36a6:e5b3/udp/4001/quic", - "/ip6/64:ff9b::36a6:e5b3/tcp/4001", - "/ip4/172.31.85.68/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/54.166.229.179/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/172.31.85.68/tcp/4001", - "/ip4/54.166.229.179/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWKBqziH2sBGmGADvcMGcXgiG9XdMy2YmKcUtbAQUWnUry", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/95.179.242.138/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/95.179.242.138/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWCUs8DsSqyXxcqvqAFQvsTP47Jsus9WNFeAaGtmtemd9i", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/144.91.110.0/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/144.91.110.0/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWHKqSGLd6xrbfZxdMnXsbmwSoYj4LF5jA5ZajMfL9CbKQ", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.14.248/tcp/30014", - "/ip4/18.188.18.173/udp/30014/quic", - "/ip4/18.188.18.173/tcp/30014", - "/ip4/127.0.0.1/tcp/30014", - "/ip4/172.31.14.248/udp/30014/quic", - "/ip4/127.0.0.1/udp/30014/quic" - ] - }, - { - "PeerID": "QmWtrZ5eXrVkSJogjK56hGaFL2oGnbWVgXCCydVwWeajcW", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/192.168.1.66/tcp/55109", - "/ip4/127.0.0.1/tcp/55109", - "/ip4/81.225.152.199/tcp/55109" - ] - }, - { - "PeerID": "12D3KooWLpKNaZusimvqycGd56ThmkdSt14SRsnzMiJ8iPspFPxv", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/54.170.172.213/tcp/4001", - "/ip4/54.170.172.213/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/172.31.44.45/tcp/4001", - "/ip4/172.31.44.45/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "QmexxEWoedczHk7QrRs3wP42ncX2veFnWq2kjm7tGZ62B6", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "go-ipfs/0.4.23/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/115.126.61.126/tcp/4001" - ] - }, - { - "PeerID": "QmV7fKMtA2m32nS5iTtnLc582cymgmJnzgFD8xsKNuEgEB", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip6/2a02:c207:2027:3121:13f2::6/tcp/4001", - "/ip6/2a02:c207:2027:3121:7e4c::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c207:2027:3121:1200::6/tcp/4001", - "/ip6/2a02:c207:2027:3121:1200::6/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:c207:2027:3121:13f2::6/udp/4001/quic", - "/ip6/2a02:c207:2027:3121:5403::2/tcp/4001", - "/ip6/2a02:c207:2027:3121:c844::2/udp/4001/quic", - "/ip6/2a02:c207:2027:3121:7e4c::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a02:c207:2027:3121:eed1::3/tcp/4001", - "/ip6/2a02:c207:2027:3121:eed1::3/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/2a02:c207:2027:3121:84d2::6/udp/4001/quic", - "/ip4/173.249.13.18/tcp/4001", - "/ip4/173.249.13.18/udp/4001/quic", - "/ip6/2a02:c207:2027:3121:5403::2/udp/4001/quic", - "/ip6/2a02:c207:2027:3121:c844::2/tcp/4001", - "/ip6/2a02:c207:2027:3121:84d2::6/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWP5X88DMV4nqS7hCx7sCzBVv9ZkyEbsvAJEMGncbVXVLg", - "ContentID": "QmY73i7UTC7V7Sn2kidSg4SwvbyeAxdn9SrUisjfmWzKui", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "20.5315742s", - "UserAgent": "ioi", - "PeerMultiaddresses": [ - "/ip6/::1/udp/60258/quic", - "/ip4/100.78.120.206/udp/54320/quic", - "/ip6/::1/tcp/59480/ws", - "/ip6/::1/tcp/59478", - "/ip4/192.168.1.100/udp/60257/quic", - "/ip4/100.78.120.206/udp/45319/quic", - "/ip4/192.168.1.100/tcp/59477", - "/ip4/127.0.0.1/tcp/59477", - "/ip4/127.0.0.1/udp/60257/quic", - "/ip4/127.0.0.1/tcp/59479/ws", - "/ip4/100.78.120.206/tcp/44994/ws", - "/ip4/100.78.120.206/tcp/61032", - "/ip4/192.168.1.100/tcp/59479/ws", - "/ip4/100.78.120.206/tcp/23982/ws", - "/ip4/112.32.171.104/udp/49877/quic", - "/ip4/100.78.120.206/tcp/49586" - ] - }, - { - "PeerID": "12D3KooWAtEyDXky6xNUmdcPwpHo882QCR4RbopfnqdG9GHtwfL8", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.145.79.161/udp/30002/quic", - "/ip4/3.145.79.161/tcp/30002", - "/ip4/127.0.0.1/udp/30002/quic", - "/ip4/172.31.14.148/udp/30002/quic", - "/ip4/127.0.0.1/tcp/30002", - "/ip4/172.31.14.148/tcp/30002" - ] - }, - { - "PeerID": "12D3KooWC5CVs5B9xZQca3UBMmANHjmLd8f9wjtYVChgcXC3ZAC9", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/144.91.92.179/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/144.91.92.179/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWR9jLReFpjBSXgdPi3QgKNn3jkiQBZzp3Qa3LiCxhTdM7", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "kubo/0.14.0/973c031", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/192.68.216.102/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::c044:d866/udp/4001/quic", - "/ip4/192.68.216.102/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWRnCELBo7zCLDq9iiA4e4qfZPPZhEGtN9RE9QAUr2ztF2", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30012", - "/ip4/172.31.5.63/udp/30012/quic", - "/ip4/127.0.0.1/udp/30012/quic", - "/ip4/18.218.189.132/udp/30012/quic", - "/ip4/18.218.189.132/tcp/30012", - "/ip4/172.31.5.63/tcp/30012" - ] - }, - { - "PeerID": "12D3KooWSsaJQ97qFek69JarxDAjUgcKj1yu9hjuL9H4ytnexjTo", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.14.185/udp/30000/quic", - "/ip4/3.144.106.247/udp/30000/quic", - "/ip4/3.144.106.247/tcp/30000", - "/ip4/127.0.0.1/udp/30000/quic", - "/ip4/127.0.0.1/tcp/30000", - "/ip4/172.31.14.185/tcp/30000" - ] - }, - { - "PeerID": "12D3KooWMvEuUZmzW5YhPmiN7byRnqnrvLw1WqFDsgamMLDbTVrk", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "go-ipfs/0.12.0/", - "PeerMultiaddresses": [ - "/ip6/2600:3c04::f03c:93ff:fe84:3b05/tcp/4001", - "/ip6/2600:3c04::f03c:93ff:fe84:3b05/udp/4001/quic", - "/ip4/192.46.223.19/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/64:ff9b::c02e:df13/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/192.46.223.19/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::c02e:df13/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWCx5AE2cK8359my6b6bAEkYkRKU2MRjpkNq5wi1nGE1on", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/137.184.81.155/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/137.184.81.155/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWBXgxKBrF1tihhNsMXcmjiwmJLLwo2E7SZe1JN5ztuip1", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.9.152/tcp/30003", - "/ip4/127.0.0.1/udp/30003/quic", - "/ip4/3.129.69.234/udp/30003/quic", - "/ip4/172.31.9.152/udp/30003/quic", - "/ip4/3.129.69.234/tcp/30003", - "/ip4/127.0.0.1/tcp/30003" - ] - }, - { - "PeerID": "QmShTdxxd3XLkgWSEja2jJexsMschjawWE9TdUrBK3qqaY", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip6/::1/tcp/4002/ws", - "/ip4/159.223.188.89/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/10.100.248.14/tcp/1080/ws", - "/ip6/2604:a880:400:d0::2124:a001/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/159.223.188.89/tcp/4002/ws", - "/ip6/64:ff9b::9fdf:bc59/tcp/4001", - "/ip6/2604:a880:400:d0::2124:a001/tcp/4002/ws" - ] - }, - { - "PeerID": "QmciR9krxxkxBnUsQQLeJPMSHWw7cdxQAqZXPhpukcQkD2", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip4/167.86.89.3/tcp/4001", - "/ip4/167.86.89.3/udp/4001/quic", - "/ip6/2a02:c207:2026:5518:f41a::14/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a02:c207:2026:5518:f41a::14/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWSuiiP7tzRrwc6zPRC7Wpg654MDmBm5F4bsbWrV7SqsNF", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "kubo/0.16.0/38117db", - "PeerMultiaddresses": [ - "/ip4/43.139.155.139/tcp/4001", - "/ip4/43.139.155.139/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/172.17.0.2/tcp/4001", - "/ip4/43.139.155.139/tcp/55972", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.17.0.2/udp/4001/quic" - ] - }, - { - "PeerID": "QmYzyfbGBLCUKjVzLEg2CMshakquC1DzHaWrMRhuf2cZjK", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/60226", - "/ip4/182.233.206.121/tcp/60226" - ] - }, - { - "PeerID": "12D3KooWBz3LiHiaQ9jzUUCVS7gUwSqiGk718uAsMqhYyy9GM4Gy", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/10.0.0.3/udp/4001/quic", - "/ip4/10.0.0.3/tcp/4001", - "/ip4/211.58.154.16/tcp/26207", - "/ip4/211.58.154.16/udp/26207/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmQjHtpN2HmB3QVwWpeQaxMFvPce8vEaHoNLgRiyLGAQd5", - "ContentID": "QmVq8v9jhwECcpeCLz64RT3dYoTe22z5uNe6EvdmiqbjMt", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "6.6345228s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/192.168.50.183/tcp/35005", - "/ip4/127.0.0.1/tcp/35005", - "/ip4/58.152.131.61/tcp/35005" - ] - }, - { - "PeerID": "12D3KooWEz4QaRrwNEXWQQ7U1YzEMwEZLzrCvGnniT17YoyxZxXc", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/185.217.127.180/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/185.217.127.180/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWQafsCmaJ79y9Z3bTr5Vppxgbjfo1jqXMXEpwTNRXKgN5", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/66.94.100.246/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/66.94.100.246/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWKYMFdYS64c7SjX8qHFn6uunXxMYEZgMFP4oDQg7ecNPp", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.9.1/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/144.126.154.80/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/144.126.154.80/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWHr41qJABBDcd3gMbTdPM1Uv6i84yetUySe9dd6meY4Di", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/142.132.202.72/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/2a01:4f8:261:4e90::2/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/142.132.202.72/tcp/4001", - "/ip6/2a01:4f8:261:4e90::2/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWCM73fpSrPmQnUA5JFHm3R9YyY5LhdXEfqRZxTtWQ6hmv", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/38.242.212.31/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/38.242.212.31/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWRcwSQzR6F4kZ9t7z2HHrUDKr9fdMhAmiXAVN42hkmVn3", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.118.252.93/tcp/30014", - "/ip4/172.31.8.16/tcp/30014", - "/ip4/127.0.0.1/tcp/30014", - "/ip4/172.31.8.16/udp/30014/quic", - "/ip4/127.0.0.1/udp/30014/quic", - "/ip4/18.118.252.93/udp/30014/quic" - ] - }, - { - "PeerID": "QmWvi2pchXiN3fyN8JSwCmznDoJzztZMKzHxdrLu62wwif", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip6/2a02:c207:2027:2079:1c9::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/207.180.229.173/tcp/4001", - "/ip6/2a02:c207:2027:2079:3191::6/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/2a02:c207:2027:2079:bf2::6/tcp/4001", - "/ip6/2a02:c207:2027:2079:1c9::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a02:c207:2027:2079:bf2::6/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c207:2027:2079:89c5::7/tcp/4001", - "/ip4/207.180.229.173/udp/4001/quic", - "/ip6/2a02:c207:2027:2079:3191::6/udp/4001/quic", - "/ip6/2a02:c207:2027:2079:89c5::7/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWJx5jPBHuk7gELmprYsJN6cKPoSCcmMDQaDmWdqf5VHXZ", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/107.152.44.178/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/107.152.44.178/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWPi5WzzLG73HmxuzjdGTwg159tRQGAVJGUzkKV6hYTBiC", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.12.2/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/35.183.106.42/udp/4001/quic", - "/ip4/35.183.106.42/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWFYXGWFFrQAtHaPw22z6ifNT2nkesoeGKHVbN3U4T8Kd6", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/51.195.137.114/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/51.195.137.114/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWFaBtTkpuk158DU3sBLHLFHz3CjGy1kEdxP9ErsdoqkFt", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.12.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/54.195.28.196/tcp/4001", - "/ip4/54.195.28.196/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWDZL8C3vXcZEFEKLC4Dyb38NsYUEvro6rgFSjLU3Cbk7M", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::9f41:4a00/udp/4001/quic", - "/ip4/159.65.74.0/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/159.65.74.0/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWLvEmmyZUE1NoA6tiALgiDD7h2VMb5SW2ovJm38ozMPCs", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.12.2/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/152.70.247.205/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::9846:f7cd/udp/4001/quic", - "/ip4/152.70.247.205/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/2603:c022:8006:2739:41:524d:5352:5631/tcp/4001", - "/ip6/2603:c022:8006:2739:41:524d:5352:5631/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWPJwfXTK2SoEUqoAFSUn7wFZmQsDbVCoSQ3qhWf249eSg", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.9.1/", - "PeerMultiaddresses": [ - "/ip6/2602:cf:6cc5:9800:1c3e:8ca6:6faa:65c5/tcp/4001", - "/ip6/2602:cf:6cc5:9800:1138:8840:5ba3:8b17/tcp/4001", - "/ip4/192.168.206.206/udp/4001/quic", - "/ip6/2602:cf:6cc5:9800:6543:c5fb:16bd:c83b/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2602:cf:6cc5:9800:30d6:9f69:25dc:8ac5/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/207.108.197.152/tcp/4001", - "/ip6/2602:cf:6cc5:9800:1c30:2a5d:d9fe:781e/tcp/4001", - "/ip6/2602:cf:6cc5:9800:2151:b619:cbb3:ac6e/tcp/4001", - "/ip6/2602:cf:6cc5:9800:6543:c5fb:16bd:c83b/udp/4001/quic", - "/ip4/192.168.206.206/tcp/4001" - ] - }, - { - "PeerID": "Qme3M9VrZax3oNRRey8BGsMjL6ei35AQM57AffTxmLt5M5", - "ContentID": "QmdSk4QSXLpFxY8x8ok27urdghfG9ALqbocLeY7sE2yhRk", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3122022s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/121.172.76.215/tcp/39253", - "/ip4/127.0.0.1/tcp/39253" - ] - }, - { - "PeerID": "12D3KooWBJ1rRjiUfpHE6BNrAKa4TYg1KaYvza1zsY8h7c9jVBgs", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "kubo/0.16.0/38117db", - "PeerMultiaddresses": [ - "/ip4/51.159.16.54/tcp/4001", - "/ip4/51.159.16.54/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWKf6DXQM9nCdNGH8hDL5YLGyXTBA6aECp2TdVX32SwKTP", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "kubo/0.16.0/38117db6f", - "PeerMultiaddresses": [ - "/ip4/95.82.231.237/udp/53463/quic", - "/ip6/2a02:17d0:534:d300:e2d5:5eff:fec2:b8ae/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/95.82.231.237/tcp/53463", - "/ip6/::1/tcp/4001", - "/ip4/192.168.128.1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/192.168.128.1/udp/4001/quic", - "/ip6/2a02:17d0:534:d300:e2d5:5eff:fec2:b8ae/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWJ6BRCdUtdfobpFcmaH1wZtp9QWRCb5vmisGFmkcUMUqC", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30005/quic", - "/ip4/3.17.162.89/udp/30005/quic", - "/ip4/127.0.0.1/tcp/30005", - "/ip4/172.31.5.181/tcp/30005", - "/ip4/172.31.5.181/udp/30005/quic", - "/ip4/3.17.162.89/tcp/30005" - ] - }, - { - "PeerID": "12D3KooWKUmHWQ4CiT9FucfrDWsezcVH48zRd7FP98Va2gN3D2e5", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/207.246.68.168/udp/4001/quic", - "/ip4/207.246.68.168/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWDu8VV2cYj7woEiy86Ynd66Fig4QxvmSTKq95vX5W8Sgc", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "go-ipfs/0.9.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::8bb4:9b9b/udp/4001/quic", - "/ip4/139.180.155.155/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/139.180.155.155/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWKgDof8SumqhUshJm4Z5gCYcUasmuiHYDAuLpRAnZMdcj", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::4e2f:c398/udp/4001/quic", - "/ip4/78.47.195.152/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/78.47.195.152/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWPorr8edQiufcVHjQoEhMteMAWRJEy1EHKEdNi1fhW7Mj", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::6baf:5b2b/udp/4001/quic", - "/ip4/107.175.91.43/udp/4001/quic", - "/ip4/107.175.91.43/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWSgMYmHnsmw8jZYZmSFsxb82kgHG62esoLDbLftVMeGzU", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip6/2401:300:0:1:8d3:dfff:feeb:66c8/tcp/4001", - "/ip6/2401:300:0:1:8d3:dfff:feeb:66c8/udp/4001/quic", - "/ip4/202.81.252.40/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/2401:300:0:2:7c4e:a4ff:fe88:e043/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/202.81.252.40/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2401:300:0:2:7c4e:a4ff:fe88:e043/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWCYAW21Pqzjib7drTvAsRQzKq78PZ7gdPj7MAwGeEjwHW", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30005/quic", - "/ip4/52.15.151.193/udp/30005/quic", - "/ip4/52.15.151.193/tcp/30005", - "/ip4/172.31.6.244/tcp/30005", - "/ip4/127.0.0.1/tcp/30005", - "/ip4/172.31.6.244/udp/30005/quic" - ] - }, - { - "PeerID": "12D3KooWNZLMfPenoxtCcF3WtPUY6Ni3GPcFnQAKLm1wuEyNZ4WL", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "go-ipfs/0.12.2/0e8b121", - "PeerMultiaddresses": [ - "/ip4/188.134.76.139/tcp/9401", - "/ip4/127.0.0.1/tcp/9401", - "/ip4/172.16.0.8/tcp/9401" - ] - }, - { - "PeerID": "QmdTA1w6XhpMnY5Ae8yUPgNkzGYAXhRooC2hmgC6KAH4cf", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "go-ipfs/0.5.0-rc2/", - "PeerMultiaddresses": [ - "/ip6/2600:4040:778f:3500:accc:287d:21b0:f09b/tcp/4001", - "/ip4/71.175.61.50/tcp/42755", - "/ip4/172.17.0.1/tcp/4001", - "/ip4/192.168.1.48/tcp/4001" - ] - }, - { - "PeerID": "QmXLLde73kHk7dzgLjP34Y9vtbQJqA8bUKSye23L33MHnL", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "go-ipfs/0.9.1/dc2715af6", - "PeerMultiaddresses": [ - "/ip4/44.241.81.71/tcp/4001" - ] - }, - { - "PeerID": "QmZtBW8KgRAr9tnvT3rDLP4LNzWSGJYhqDz3JZ5otB4W4F", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/112.119.171.106/tcp/34428", - "/ip4/127.0.0.1/tcp/34428" - ] - }, - { - "PeerID": "12D3KooWDgtRpYRHt2VEvxvzNnfvvg1RQdL5ufe3VnyLJBqMm2hD", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.4.22/udp/30008/quic", - "/ip4/172.31.4.22/tcp/30008", - "/ip4/127.0.0.1/tcp/30008", - "/ip4/18.217.0.112/udp/30008/quic", - "/ip4/18.217.0.112/tcp/30008", - "/ip4/127.0.0.1/udp/30008/quic" - ] - }, - { - "PeerID": "12D3KooWB9QmM7o22wNCBc7F4HVMVyNkdT16e2B7JjY7HbvSUW9p", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip4/52.33.106.127/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/52.33.106.127/tcp/4001", - "/ip6/64:ff9b::3421:6a7f/tcp/4001", - "/ip4/172.31.2.203/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::3421:6a7f/udp/4001/quic", - "/ip4/172.31.2.203/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWDt6Aje8mgrZ9kKJKVXMEWbdida1euuE6fnE3wa7fw9kk", - "ContentID": "QmSAfUS8e1AorF7h6wBaY5rP3quWhiBesrf61kXmc6cpjz", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.675192s", - "UserAgent": "go-ipfs/0.8.0/cc95853", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:7c4b:a2f3:14b0:3704/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:798c:4d71:1f14:66db/tcp/4001", - "/ip6/2408:820c:d2a:7600:15f8:9c0c:a129:3cb3/tcp/4001", - "/ip6/2408:820c:d2a:7600:a2f1:7a6e:1a8e:3a87/udp/4001/quic", - "/ip4/192.168.1.4/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:2527:fb65:f326:c95b/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2408:820c:d2a:7600:5d4a:4ceb:d134:9da8/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:f22f:74ff:fede:a96c/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:832c:929:6f06:d6b3/tcp/4001", - "/ip6/2408:820c:d2a:7600:7c4b:a2f3:14b0:3704/tcp/4001", - "/ip4/223.167.142.94/udp/25415/quic", - "/ip4/223.167.142.94/tcp/23555", - "/ip6/2408:820c:d2a:7600:a2f1:7a6e:1a8e:3a87/tcp/4001", - "/ip6/2408:820c:d2a:7600:15f8:9c0c:a129:3cb3/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:5d4a:4ceb:d134:9da8/tcp/4001", - "/ip6/2408:820c:d2a:7600:2527:fb65:f326:c95b/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:f22f:74ff:fede:a96c/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/192.168.1.4/tcp/4001", - "/ip6/2408:820c:d2a:7600:832c:929:6f06:d6b3/udp/4001/quic", - "/ip6/2408:820c:d2a:7600:798c:4d71:1f14:66db/udp/4001/quic" - ] - }, - { - "PeerID": "QmRQAmLeDgGrAhzAzpmxxnkkCs3FJEdeKdjBHrx48DKhhz", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip4/173.249.29.85/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/173.249.29.85/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "QmXC7LRDNnSUYuV4rejNJoZR52FLigQi7yXky1E9FtRhxg", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.4.22/", - "PeerMultiaddresses": [ - "/ip4/62.210.136.223/tcp/4001", - "/ip4/62.210.136.223/tcp/53661", - "/ip4/62.210.136.223/tcp/53658", - "/ip6/2001:bc8:326b:101::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.17.0.1/tcp/4001", - "/ip4/10.235.146.1/tcp/4001", - "/ip4/62.210.136.223/tcp/53660", - "/ip6/::1/tcp/4001", - "/ip4/62.210.28.147/tcp/4001", - "/ip4/62.210.136.223/tcp/53659", - "/ip4/62.210.136.223/tcp/53657", - "/ip6/2001:bc8:326b:100::1263/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWGPWbqF7qGPHdVUGr9karRMMD2pXwZr2f2grXNwgGnHUQ", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/147.75.81.147/tcp/4001", - "/ip4/147.75.81.147/tcp/4002/ws", - "/ip4/147.75.81.147/udp/4001/quic", - "/ip6/2604:1380:4601:1800::d/tcp/4001", - "/ip6/2604:1380:4601:1800::d/tcp/4002/ws", - "/ip6/2604:1380:4601:1800::d/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWN2BAM6Y4dBmfRCc7a6iZnhseu5CrqKzpz8w8CCMRWMqf", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/164.92.187.122/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::a45c:bb7a/udp/4001/quic", - "/ip4/164.92.187.122/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWKGCAgknEULHuTMvVvzg8ZHvPWHgPtamTWvJkfaoL3ThP", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/207.180.237.170/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/207.180.237.170/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWCkUYDEkqVuHtLtbgW86DPm3XP453C22m7GX5BGQLJzWe", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/161.97.104.73/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/161.97.104.73/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWL4RG2fKak6HjYq9139QYu2ExfpLuqnFHmsu2zgGGebcF", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/162.212.154.112/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/162.212.154.112/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWP4SLaKm59czxbiojFUWuSi2ry8wguqmi3Vta5sGJUwsn", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/162.250.191.247/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/162.250.191.247/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWN86VzKigwWgkpdP2tv4q3fQxkwv34QxktvQxaqiuXeFK", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.139.234.239/tcp/30009", - "/ip4/127.0.0.1/tcp/30009", - "/ip4/172.31.9.74/tcp/30009", - "/ip4/3.139.234.239/udp/30009/quic", - "/ip4/127.0.0.1/udp/30009/quic", - "/ip4/172.31.9.74/udp/30009/quic" - ] - }, - { - "PeerID": "12D3KooWL3f2HqTq5XAaRyXRHZ8ZFLUnMr2qgm2wtmAZpNXuhFpM", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/144.202.57.244/udp/4001/quic", - "/ip4/144.202.57.244/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLzdC9Mi63dXaqj8c3KEtYZ3rAzzbq2gTngGXQyT3sqKB", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.9.71/tcp/30006", - "/ip4/127.0.0.1/udp/30006/quic", - "/ip4/127.0.0.1/tcp/30006", - "/ip4/18.191.208.128/tcp/30006", - "/ip4/18.191.208.128/udp/30006/quic", - "/ip4/172.31.9.71/udp/30006/quic" - ] - }, - { - "PeerID": "12D3KooWBd1RU196c8nMfhdFwg4DT5KCnwCi2WhjYYWVTerwxQ4G", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.12.157/tcp/30004", - "/ip4/172.31.12.157/udp/30004/quic", - "/ip4/18.219.124.96/tcp/30004", - "/ip4/18.219.124.96/udp/30004/quic", - "/ip4/127.0.0.1/tcp/30004", - "/ip4/127.0.0.1/udp/30004/quic" - ] - }, - { - "PeerID": "12D3KooWE9873GTNNeXhqcq12FR1njKmtT3Q1yKXrL3VS4YUW3qe", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/45.32.68.172/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "QmY2vfchMSGnjguhJ9ixpXVZT7uSKwmsGZKM27Vqnh2f4g", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/95.192.86.215/tcp/34683", - "/ip4/127.0.0.1/tcp/34683" - ] - }, - { - "PeerID": "12D3KooWGCusp3nTGDNsz2m7iQQbynH7MtaLnvffCov9ytmQt9Lh", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.0.133/udp/30014/quic", - "/ip4/127.0.0.1/udp/30014/quic", - "/ip4/172.31.0.133/tcp/30014", - "/ip4/127.0.0.1/tcp/30014", - "/ip4/3.137.176.151/udp/30014/quic", - "/ip4/3.137.176.151/tcp/30014" - ] - }, - { - "PeerID": "QmeZzpgsqTah7nZN4rD4DtqXYjKp5yqK3wBt1nX612Ai84", - "ContentID": "QmYdnx3VnME8eFyjqAY9AP15A1uJLPpWRKVsRfaxjFC4NE", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.8933847s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/161.0.158.58/tcp/8160", - "/ip4/192.168.100.156/tcp/48786", - "/ip4/127.0.0.1/tcp/48786" - ] - }, - { - "PeerID": "12D3KooWAMKWPMi62vN7QootxGRryx3gKCzPLePmj9fPEjJd9Kf4", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "go-ipfs/0.9.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/92.204.162.198/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/92.204.162.198/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWE1Pxki6BQtp9qr5yqGq3SD3CT18QTAarvN4MwPTTr8W1", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/188.34.185.25/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/188.34.185.25/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a01:4f8:c012:94eb::1/tcp/4001", - "/ip6/2a01:4f8:c012:94eb::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWAkcFaNtNKrRFjjmQKotAg1bocmVJc8SxxAAThe8AXwxp", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/165.140.242.65/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/165.140.242.65/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWHzgD9Lze7cWX6L5X7Ugea2MEN4R3UujQ1svrvGLKvVJe", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30006/quic", - "/ip4/172.31.14.228/udp/30006/quic", - "/ip4/172.31.14.228/tcp/30006", - "/ip4/3.138.34.201/tcp/30006", - "/ip4/127.0.0.1/tcp/30006", - "/ip4/3.138.34.201/udp/30006/quic" - ] - }, - { - "PeerID": "12D3KooWPKwPzK2B9NVLERsztNrsZKBtWLrmsewwDh82hsxGD6eX", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.117.183.16/tcp/30006", - "/ip4/127.0.0.1/udp/30006/quic", - "/ip4/127.0.0.1/tcp/30006", - "/ip4/172.31.6.235/udp/30006/quic", - "/ip4/172.31.6.235/tcp/30006", - "/ip4/18.117.183.16/udp/30006/quic" - ] - }, - { - "PeerID": "QmRBc1eBt4hpJQUqHqn6eA8ixQPD3LFcUDsn6coKBQtia5", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip4/146.70.124.247/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::9246:7cf7/udp/4001/quic", - "/ip4/146.70.124.247/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWMU89xKbquqRXy6MPMymsBKa1DJXQAvqr5Evzjx4X52Z6", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/2001:861:83:b330:284f:7811:be3e:2a37/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/176.172.35.138/udp/33907/quic", - "/ip4/192.168.1.11/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/192.168.1.11/udp/4001/quic", - "/ip4/176.172.35.138/tcp/33907", - "/ip6/2001:861:83:b330:284f:7811:be3e:2a37/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWG5mwZjBkmft9szbLUo4g1jBbSofLR6nQGVQo1xPzoWbQ", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.12.157/tcp/30007", - "/ip4/172.31.12.157/udp/30007/quic", - "/ip4/18.219.124.96/udp/30007/quic", - "/ip4/127.0.0.1/udp/30007/quic", - "/ip4/18.219.124.96/tcp/30007", - "/ip4/127.0.0.1/tcp/30007" - ] - }, - { - "PeerID": "12D3KooWKVChUxA4MDbNt9pyZgcm3mVaqPdeFkKqU8ArcEdgB9DA", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.15.84/tcp/30007", - "/ip4/172.31.15.84/udp/30007/quic", - "/ip4/3.17.78.57/tcp/30007", - "/ip4/3.17.78.57/udp/30007/quic", - "/ip4/127.0.0.1/tcp/30007", - "/ip4/127.0.0.1/udp/30007/quic" - ] - }, - { - "PeerID": "12D3KooWF5Qbrbvhhha1AcqRULWAfYzFEnKvWVGBUjw489hpo5La", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30014/quic", - "/ip4/3.145.1.118/udp/30014/quic", - "/ip4/3.145.1.118/tcp/30014", - "/ip4/172.31.13.24/tcp/30014", - "/ip4/127.0.0.1/tcp/30014", - "/ip4/172.31.13.24/udp/30014/quic" - ] - }, - { - "PeerID": "12D3KooWPE7jAVhAjXCVqT5PVFvPRu98UT253D9Gn26m8wG39r32", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "kubo/0.16.0/38117db", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::5420:be5e/tcp/4001", - "/ip4/84.32.190.94/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/84.32.190.94/udp/32351/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "QmNcJjUkEVumCgcug18vw3fQsNrRiZ92CYAmXWfT33CZUe", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/218.173.18.107/tcp/48035", - "/ip4/127.0.0.1/tcp/48035" - ] - }, - { - "PeerID": "12D3KooWKxLVDs3NrnQyPehc9RiQqjBaBRA65kM1TqgsE4wjnjie", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "go-ipfs/0.10.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/54.179.223.68/tcp/4001", - "/ip4/54.179.223.68/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::36b3:df44/tcp/4001", - "/ip4/10.103.3.241/udp/4001/quic", - "/ip4/10.103.3.241/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmXrVy391hLtp7LUGx8NLvne8qhyVegHuk1A61ic7ZVbXT", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/47.134.158.142/tcp/34793", - "/ip4/127.0.0.1/tcp/34793" - ] - }, - { - "PeerID": "12D3KooWDMoJdtAiZ8s4Ei6hmpfKM2CbF5zVFQ8bPe54FU8kQwcY", - "ContentID": "QmY1aeefVj7watJ2w2rYNGGJ48eGxXqqU8CTHGTSxDKrCs", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "14.0088013s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/45.32.146.216/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/45.32.146.216/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWLr3pSUJV2GNeosnB7bXQkU9nWD6FNw6y7d1Sdoxshm1o", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "kubo/0.14.0/e0fabd6db", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::3624:52d6/udp/4001/quic", - "/ip6/64:ff9b::3624:52d6/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/54.36.82.214/udp/4001/quic", - "/ip4/54.36.82.214/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWA7GLaTDmHnhvHw7zceBVWrhWrLGsDqQM4zHueFpYeqxf", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/185.202.223.141/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/185.202.223.141/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWMGDvi8w9Yw4qpnD6vBUNz4eb8od17g4Dcf15QG27SySU", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip4/139.162.216.118/tcp/4001", - "/ip6/2a01:7e00::f03c:93ff:feb3:e3eb/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a01:7e00::f03c:93ff:feb3:e3eb/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/139.162.216.118/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWEtZ7KwUjbFPdFQcBWTPk4Jiho8K2qPCdrNjWR9MCiZfH", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.105.68.107/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/172.105.68.107/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWDfPCZKCbn2V5mUXK1ViY25XVd6B5Z7KnE7KoRW5ZJ5Je", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a01:4f9:4b:5609::2/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/135.181.17.251/udp/4001/quic", - "/ip4/135.181.17.251/tcp/4001", - "/ip6/2a01:4f9:4b:5609::2/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWFGJeNYZ2EPFGk6YCTL2y8oqWXsPxqb5hB1jeMBuNP5Rg", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/157.245.93.202/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/157.245.93.202/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::9df5:5dca/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWBu1VpcFV9daZ3h9Zfezp4TWV5tdk8hP2oSb7hnf6RsxS", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.12.2/", - "PeerMultiaddresses": [ - "/ip4/109.234.36.149/udp/4001/quic", - "/ip4/109.234.36.149/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLD34NS3SbD6WzeWu2MrS6BtqtqkryhNSVBCBjNcd5EfQ", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.13.0/", - "PeerMultiaddresses": [ - "/ip4/45.15.24.95/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::2d0f:185f/udp/4001/quic", - "/ip4/45.15.24.95/udp/4001/quic", - "/ip6/2a02:4780:1:1::1:9b3b/udp/4001/quic", - "/ip6/2a02:4780:1:1::1:9b3b/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWNEjTHjJB3k1ZoioPiM9CygxVM6ho5WyNaqD3iPhevoce", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30002", - "/ip4/127.0.0.1/udp/30002/quic", - "/ip4/172.31.14.226/tcp/30002", - "/ip4/18.116.81.53/udp/30002/quic", - "/ip4/18.116.81.53/tcp/30002", - "/ip4/172.31.14.226/udp/30002/quic" - ] - }, - { - "PeerID": "12D3KooWNM6Q5Pc6WfyhiQxXyzpNAymGVvaHMZDj8YSUzvvB4G6t", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/157.230.37.209/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/157.230.37.209/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::9de6:25d1/udp/4001/quic" - ] - }, - { - "PeerID": "QmVmEL6Fshvbb5P2sT8m4NLfHsUPMQCjr4zcbqcdtmEMem", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/100.80.22.87/tcp/32882", - "/ip4/127.0.0.1/tcp/32882", - "/ip4/78.85.4.159/tcp/16506" - ] - }, - { - "PeerID": "QmZ5gLTZwvfD5DkbbaFFX4YJCi7f4C5oQAgq8qpjL8S1ur", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.4.22/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::36ec:27c1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.31.9.26/tcp/4001", - "/ip4/54.236.39.193/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWDfvxo6z8Fy6ZQM52JiusZz9Q1f32ZXD7MtkscSzNztrA", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "kubo/0.14.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/192.168.1.20/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/86.123.18.199/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/192.168.1.20/tcp/4001", - "/ip4/86.123.18.199/udp/1151/quic", - "/ip6/64:ff9b::567b:12c7/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/86.123.18.199/udp/1152/quic" - ] - }, - { - "PeerID": "Qmc7GMGf9QUQEw7KbbzjMUgWRiu24oZnXp4nVM4qa2y3h8", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "go-ipfs/0.6.0/", - "PeerMultiaddresses": [ - "/ip4/192.168.0.103/tcp/4001", - "/ip4/192.168.0.103/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/82.76.239.229/udp/42322/quic", - "/ip4/82.76.239.229/tcp/42322", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWELFj6DrvUuWgmE6n4TaCLKLG8ZuFYMRa38Uudj4wY5VL", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30003/quic", - "/ip4/3.15.141.6/tcp/30003", - "/ip4/172.31.7.144/udp/30003/quic", - "/ip4/3.15.141.6/udp/30003/quic", - "/ip4/127.0.0.1/tcp/30003", - "/ip4/172.31.7.144/tcp/30003" - ] - }, - { - "PeerID": "QmSuWRRPB6eBEefP3BD1fxsCc8LqW3AAZ3weQZf69LKnqg", - "ContentID": "QmZj6krnGkmD9HGhFw5nAX7cc9VDp2oRBZpAwrFJVnjGjK", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "32.9318489s", - "UserAgent": "storm", - "PeerMultiaddresses": [ - "/ip4/112.109.57.105/tcp/36691", - "/ip4/127.0.0.1/tcp/36691" - ] - }, - { - "PeerID": "12D3KooWPT53HoQYM6VDymwpDoqzDH79LVP5uUwe24kLvYfzUcAi", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "kubo/0.15.0-dev/9c6094e65", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/104.51.121.209/udp/4001/quic", - "/ip4/104.51.121.209/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/192.168.99.136/udp/4001/quic", - "/ip4/192.168.99.136/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWGUMiTBZM8JNnDJDwgpcyFq5S4JKtyUbUAXG4JbgobbDH", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/165.227.81.143/udp/4001/quic", - "/ip6/64:ff9b::a5e3:518f/udp/4001/quic", - "/ip4/165.227.81.143/tcp/4001", - "/ip6/64:ff9b::a5e3:518f/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWQNUGCqiAZSNU1Ed6oKcJNCdLBKG8DyoahwATSCdMHKgi", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.13.117/tcp/30003", - "/ip4/127.0.0.1/tcp/30003", - "/ip4/172.31.13.117/udp/30003/quic", - "/ip4/127.0.0.1/udp/30003/quic", - "/ip4/18.219.236.84/udp/30003/quic", - "/ip4/18.219.236.84/tcp/30003" - ] - }, - { - "PeerID": "12D3KooWFxhMGpmcACb4Lf1qKLzBGwh9q4FFPuKZun1xLqYBxtKN", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.145.199.165/tcp/30000", - "/ip4/172.31.10.100/tcp/30000", - "/ip4/3.145.199.165/udp/30000/quic", - "/ip4/127.0.0.1/udp/30000/quic", - "/ip4/127.0.0.1/tcp/30000", - "/ip4/172.31.10.100/udp/30000/quic" - ] - }, - { - "PeerID": "12D3KooWD1LAxnLRvA9hwFmiJTpyerDHW9SqYYjJ4vt6PnHfU7eK", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::3351:6b95/tcp/4001", - "/ip4/51.81.107.149/udp/49565/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/51.81.107.149/udp/4001/quic", - "/ip6/64:ff9b::3351:6b95/udp/49565/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/51.81.107.149/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWR3rcvg8LaGUH4rreApmn3dN6XYMiS36LaHozW9GemCsD", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/88.99.85.77/tcp/4001", - "/ip6/2a01:4f8:c17:5d43::1/tcp/4001", - "/ip4/88.99.85.77/udp/4001/quic", - "/ip6/2a01:4f8:c17:5d43::1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWFXfW8PxihRxZQFMN1gdskQio6cfTYzWTgrbNsNmsZK8a", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.9.0/", - "PeerMultiaddresses": [ - "/ip4/185.51.184.93/tcp/4001" - ] - }, - { - "PeerID": "12D3KooW9wKjVgTkiy1zW3jyGgPBZomRwNMYNw8ALtrQtUyHRbn6", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/149.28.250.128/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/149.28.250.128/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "QmRqxMNWmg9hw2PcfTKuYTbt6Q2AqCpDfdbm3eC3cSW4Gj", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.4.23/", - "PeerMultiaddresses": [ - "/ip4/94.250.203.169/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWGqN2YqpQ7q4rYF5CSrcLE4V789tScmej7fibyCbWFXsg", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.12.155.215/tcp/30006", - "/ip4/3.12.155.215/udp/30006/quic", - "/ip4/127.0.0.1/udp/30006/quic", - "/ip4/172.31.3.155/udp/30006/quic", - "/ip4/127.0.0.1/tcp/30006", - "/ip4/172.31.3.155/tcp/30006" - ] - }, - { - "PeerID": "12D3KooWLZGcznsE4b1U9ogW7yHcYSgXUYaeaV7Akq7c8bFYfk8S", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.13.1/8ffc7a8", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::3100:5055/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/183.88.236.47/tcp/1805", - "/ip4/49.0.80.85/udp/13655/quic", - "/ip4/192.168.100.32/tcp/4001", - "/ip4/192.168.100.32/udp/4001/quic", - "/ip4/49.0.80.85/udp/4001/quic", - "/ip4/183.88.236.47/udp/13520/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/49.0.80.85/tcp/4001" - ] - }, - { - "PeerID": "QmcSPuVUR8F86FHFEfByMeMJWwUkuSBZXdebi4kS2rZg4h", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4002/ws", - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip4/10.100.248.14/tcp/1080/ws", - "/ip6/64:ff9b::c6d3:6b89/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/2604:a880:400:d0::1cce:c001/tcp/4002/ws", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/198.211.107.137/tcp/4002/ws", - "/ip6/2604:a880:400:d0::1cce:c001/tcp/4001", - "/ip4/198.211.107.137/tcp/4001" - ] - }, - { - "PeerID": "QmNUKWQ87WYE3MTXzaK23W67Rrfi2i9VmU7KB8jw9veAVR", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip4/45.76.19.165/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/45.76.19.165/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "QmV5n4GDaQLBWGSXWeEefSwmZykuYBG649Pz5ozFNv1B1t", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.4.22/", - "PeerMultiaddresses": [ - "/ip4/34.68.67.26/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/34.68.67.26/tcp/4480" - ] - }, - { - "PeerID": "QmaaR92CRezMRu9TL7cMNcdfeFrnCHKyCXoGWZrYRUwSmM", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "storm", - "PeerMultiaddresses": [ - "/ip4/218.173.192.20/tcp/43988", - "/ip4/127.0.0.1/tcp/43988" - ] - }, - { - "PeerID": "QmU4rWDBCUWTLyQCxgBa5zNxbTEapDYonKKEAVJD2qviP8", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/51019", - "/ip4/61.85.227.247/tcp/51019" - ] - }, - { - "PeerID": "12D3KooWCSbNi8c8cGDSHN44Boq9iUhDNkPqiGrrjYx8XmXq8pbK", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/34.83.215.154/udp/4001/quic", - "/ip4/10.138.0.2/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::2253:d79a/tcp/4001", - "/ip4/10.138.0.2/udp/4001/quic", - "/ip4/34.83.215.154/tcp/4001", - "/ip6/64:ff9b::2253:d79a/udp/4001/quic", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "QmWizchV5fMEbv8dkSGBEFc57AfR4ugVzU9oEiCypmQKuQ", - "ContentID": "QmY8RWv9m8JMxeCeFgN3u5hzWBUxnRpvGmHX1cqiVg1vq5", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "15.3286717s", - "UserAgent": "go-ipfs/0.4.23/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip6/2a04:3541:1000:500:58e0:5fff:fe27:864/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/94.237.54.41/tcp/4001" - ] - }, - { - "PeerID": "QmRhtW6jWjnXDPauEpP6nFonxA2xC2CEt5knzSTeLBqPL1", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/10.0.66.253/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/64:ff9b::22e4:1d35/tcp/4001", - "/ip6/64:ff9b::22e4:1d35/udp/4001/quic", - "/ip4/34.228.29.53/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/34.228.29.53/udp/4001/quic", - "/ip4/10.0.66.253/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWNetpTQiQpF7zJUBiSH6zeHb38M7SKutQwTUxYXv2GrdN", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/194.163.146.20/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/194.163.146.20/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWHKYAsZLh9Vjxnj2qJvHGGmGRsEBLYJgXtBmDq5ELPmTN", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/207.180.253.72/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/207.180.253.72/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmUfQxnm88UGoNHhnZ6DHuqc4Gks8n7r8XW4R4bnbx9nFH", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.9.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/178.62.106.30/udp/4001/quic", - "/ip6/64:ff9b::b23e:6a1e/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/178.62.106.30/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWG2uc3CGK1pzjnFnM5Sk6rHiAV4BYXQRFYjrpk6tMyxKr", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "kubo/0.14.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::c6d3:6dcc/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/198.211.109.204/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::c6d3:6dcc/tcp/4001", - "/ip4/198.211.109.204/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWGUZGioUGs5YYLi7E7UjiZeSKDnf3BdXUSQ1FjfF9GcYJ", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/23.94.203.173/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/23.94.203.173/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWESfmf1fvYxFs4dFw6k1ENvtgdybM8fSWocVpGFPW5U2D", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.15.135/tcp/30011", - "/ip4/18.216.227.61/udp/30011/quic", - "/ip4/127.0.0.1/tcp/30011", - "/ip4/172.31.15.135/udp/30011/quic", - "/ip4/18.216.227.61/tcp/30011", - "/ip4/127.0.0.1/udp/30011/quic" - ] - }, - { - "PeerID": "12D3KooWEzzeuroCCqjfJJtAyMaYSrdZqBj31ohUEzHef76ne8YS", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.145.79.161/tcp/30007", - "/ip4/172.31.14.148/tcp/30007", - "/ip4/127.0.0.1/tcp/30007", - "/ip4/172.31.14.148/udp/30007/quic", - "/ip4/127.0.0.1/udp/30007/quic", - "/ip4/3.145.79.161/udp/30007/quic" - ] - }, - { - "PeerID": "12D3KooWKiMPWGhJdsJXFXqQLFyVgt1dhgkBhv3hDr9dr65CJVKN", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.12.2/0e8b121", - "PeerMultiaddresses": [ - "/ip4/172.17.0.5/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/66.29.156.116/udp/4001/quic", - "/ip4/66.29.156.116/tcp/4001", - "/ip4/172.17.0.5/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWJxQnnCeRT9pgcpw7aCDrTZZy2NSAshA5Koj8PWmtf1yE", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/158.247.216.69/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/158.247.216.69/udp/4001/quic" - ] - }, - { - "PeerID": "Qmdno4XXu27EziVZM4DA8Cz5wkonvhN18xDKwFpHbEaeD2", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/192.168.8.3/tcp/45563", - "/ip4/127.0.0.1/tcp/45563", - "/ip4/209.141.169.42/tcp/45563" - ] - }, - { - "PeerID": "12D3KooWQ8ZW6F1veooizJZoVwUgqhwdbhSJwww26vPgpeTMoVLV", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.13.0-dev/91c5265", - "PeerMultiaddresses": [ - "/ip4/172.17.0.2/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/172.17.0.2/udp/4001/quic", - "/ip4/129.146.162.57/tcp/4001", - "/ip4/129.146.162.57/udp/11522/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "QmcF55hZZhacN82nEgspk5CARzpxpKo6sJjcmU7oBZQEjH", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/35625", - "/ip4/1.64.250.48/tcp/35625", - "/ip4/192.168.1.32/tcp/35625" - ] - }, - { - "PeerID": "QmciY83Shhxyqw1SZhxRSqNu25kVqtQAaywbkcjztyQ8rM", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/192.168.68.104/tcp/54084", - "/ip4/127.0.0.1/tcp/54084", - "/ip4/113.252.23.21/tcp/54084" - ] - }, - { - "PeerID": "QmemoDexrDjKVcjeD7qNT24WVgjoEAQ4KJTjCL38T4mK2Q", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "storm", - "PeerMultiaddresses": [ - "/ip4/191.208.127.28/tcp/38626", - "/ip4/127.0.0.1/tcp/38626" - ] - }, - { - "PeerID": "QmUFbyXxTQuN4Jy8XWvcLHzErwitUMPGyiWFW6JyuXzqjF", - "ContentID": "Qmchqhn5fa7GrzJEQdMMbm1MCG4YoC2eD7NouYKcnHfDym", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "10.8389858s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip6/2a02:c207:2027:4886:1107::6/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:c207:2027:4886:72d5::4/tcp/4001", - "/ip6/2a02:c207:2027:4886:72d5::4/udp/4001/quic", - "/ip6/2a02:c207:2027:4886:bf4f::1/tcp/4001", - "/ip4/167.86.87.58/tcp/4001", - "/ip6/2a02:c207:2027:4886:8344::4/tcp/4001", - "/ip6/2a02:c207:2027:4886:5dd::9/tcp/4001", - "/ip6/2a02:c207:2027:4886:f98d::7/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/2a02:c207:2027:4886:871b::5/tcp/4001", - "/ip6/2a02:c207:2027:4886:38c2::2/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/167.86.87.58/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWSZRxJhuPVabGoezWrNhdPWEhBK3fX5r7RdqpFkxknbui", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/144.91.91.121/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/144.91.91.121/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWEsdnVspQ2KnqMjpsnxJPf47V4qP4KgmXSyH8uXiyT64n", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.10.0-rc1/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/51.158.153.122/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/2001:bc8:1600:3:208:a2ff:fe0c:7524/tcp/4001", - "/ip6/2001:bc8:1600:3:208:a2ff:fe0c:7524/udp/4001/quic", - "/ip6/64:ff9b::339e:997a/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/51.158.153.122/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLBC39Bjgv1vWVoqpWNHCuTLUdSbLoHnyraLtuSaYwbgY", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/161.97.112.41/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/161.97.112.41/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWPXWEVDLxRBDV7JRshu2Fg3LXV86zWi2WzeMZe59XWKKz", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "kubo/0.16.0/38117db6f", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/87.92.243.222/udp/47253/quic", - "/ip4/192.168.0.102/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/87.92.243.222/tcp/47253", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/192.168.0.102/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWQ2uHi69BWzzj2j93gYf6oHGZ7kcdgeE79zVjjk4e73Nq", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.135.218.94/udp/30003/quic", - "/ip4/127.0.0.1/tcp/30003", - "/ip4/172.31.11.153/tcp/30003", - "/ip4/172.31.11.153/udp/30003/quic", - "/ip4/3.135.218.94/tcp/30003", - "/ip4/127.0.0.1/udp/30003/quic" - ] - }, - { - "PeerID": "12D3KooWGoLBEgjrWdu8th94oePBs3P3MqJmomDyG6P3htUug1aA", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/30012/quic", - "/ip4/3.17.78.57/tcp/30012", - "/ip4/127.0.0.1/tcp/30012", - "/ip4/172.31.15.84/tcp/30012", - "/ip4/172.31.15.84/udp/30012/quic", - "/ip4/3.17.78.57/udp/30012/quic" - ] - }, - { - "PeerID": "12D3KooWP4Ad23PjCU3yFPFvSLe6UqyXqHgxWYWgmMGNNx93qiVS", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30004", - "/ip4/172.31.15.164/udp/30004/quic", - "/ip4/18.116.37.26/tcp/30004", - "/ip4/18.116.37.26/udp/30004/quic", - "/ip4/172.31.15.164/tcp/30004", - "/ip4/127.0.0.1/udp/30004/quic" - ] - }, - { - "PeerID": "12D3KooWFKcCNVp2C3RUKsaoojqr3ZUDGp6ADbHW2s1WR4QXiDJq", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/23.94.56.248/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/23.94.56.248/udp/4001/quic", - "/ip6/64:ff9b::175e:38f8/udp/4001/quic" - ] - }, - { - "PeerID": "QmQMe9ZZARFXKaWY4tZWW6AKcnMPjzwaBWQ5X5Rz1d8HqP", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip6/2a02:c207:2027:3707:6fe4::3/tcp/4001", - "/ip4/173.249.48.174/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2a02:c207:2027:3707:8537::1/tcp/4001", - "/ip6/2a02:c207:2027:3707:3459::2/tcp/4001", - "/ip6/2a02:c207:2027:3707:666e::4/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/173.249.48.174/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c207:2027:3707:666e::4/tcp/4001", - "/ip6/2a02:c207:2027:3707:21c::8/tcp/4001" - ] - }, - { - "PeerID": "QmYLfvPcz9hYjAZB9QxX2vGvzWP9b1JEAy9yMydt8fLr5M", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip6/2604:a880:400:d0::217f:7001/tcp/4002/ws", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip6/::1/tcp/4002/ws", - "/ip4/137.184.73.226/tcp/4002/ws", - "/ip6/2604:a880:400:d0::217f:7001/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/137.184.73.226/tcp/4001", - "/ip6/64:ff9b::89b8:49e2/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWEHqjgLGAeZfd5z1fvCX4viyWAfvdKcK71mt573yeUes8", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::9f59:c5ac/udp/4001/quic", - "/ip4/159.89.197.172/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/159.89.197.172/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWNtAj4sRmbfMD2WKXSt1deEMGjcRq4cdVQgG5c12dmZgn", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/101.70.136.85/udp/11264/quic", - "/ip4/101.70.136.85/tcp/11285", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWQS4zCewPxqPdSFu1ZZspzDMNbCpj7WaUFdn2P2Y3a2Dz", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.2.152/udp/30009/quic", - "/ip4/18.191.109.138/udp/30009/quic", - "/ip4/172.31.2.152/tcp/30009", - "/ip4/18.191.109.138/tcp/30009", - "/ip4/127.0.0.1/udp/30009/quic", - "/ip4/127.0.0.1/tcp/30009" - ] - }, - { - "PeerID": "QmT4gSi9deS8fTKNuzUVECngyc66BybmgXfhHpyLntprJM", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "kubo/0.16.0/38117db6f", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/65.185.32.241/tcp/24763", - "/ip4/192.168.3.38/udp/4001/quic", - "/ip4/65.185.32.241/udp/24763/quic", - "/ip6/::1/tcp/4001", - "/ip4/192.168.3.38/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "QmeTMsj653WdiNtAm4tRmCGTJEbEn1SdnPacuPVxtHcx2K", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/121.152.63.176/tcp/33257", - "/ip4/127.0.0.1/tcp/33257" - ] - }, - { - "PeerID": "QmXHrLKgDAXnp5rnRQmkpzR2hEq34rNrJ9AL7CXmzkptSm", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/36.153.37.102/tcp/53048", - "/ip4/127.0.0.1/tcp/53048" - ] - }, - { - "PeerID": "QmPR8quDhtDE3TTyhFUnfa7R8RbdTg9vtEka7chKGXhi2S", - "ContentID": "QmdTY12DgF6wc6eZpcTw2R3H48QEPq9RKZaBMLSe7LkJ56", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3165595s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/37054", - "/ip4/1.22.244.62/tcp/37054" - ] - }, - { - "PeerID": "12D3KooWEa6RBF7H7GQD9Smcj6hns2phunQ1BFLCUYfkK6dXpkrz", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/2604:1380:45f1:3f00::f/tcp/4002/ws", - "/ip6/2604:1380:45f1:3f00::f/udp/4001/quic", - "/ip4/147.28.147.197/tcp/4001", - "/ip4/147.28.147.197/tcp/4002/ws", - "/ip4/147.28.147.197/udp/4001/quic", - "/ip6/2604:1380:45f1:3f00::f/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWE3iScXkVggDXLSKYtDcP3Sn3ddgXggPSBiWJ5mT2PtfF", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/165.22.32.63/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::a516:203f/udp/4001/quic", - "/ip4/165.22.32.63/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWCD9o8Khz6CyM8jckfaYqskBMZvgbeQ2mm8eyKSjDdb98", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::5fd8:1db4/tcp/4001", - "/ip4/95.216.29.180/tcp/4001", - "/ip6/64:ff9b::5fd8:1db4/udp/27306/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/95.216.29.180/udp/4001/quic", - "/ip4/95.216.29.180/udp/27306/quic" - ] - }, - { - "PeerID": "12D3KooWGifMyEDy77T3W4y8rWs6kUten5P8yVsxSKmjSeHQgy1r", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/159.65.82.209/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/64:ff9b::9f41:52d1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/159.65.82.209/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWHGfhD5NHBWm2WeY25EgLfYKqh8wJPiuaGqBHqiFLaVWw", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.16.0/38117db6f", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/45.83.104.156/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/2a03:4000:46:26e::c17/udp/4001/quic", - "/ip6/64:ff9b::2d53:689c/udp/4001/quic", - "/ip4/45.83.104.156/tcp/4001", - "/ip6/2a03:4000:46:26e::c17/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWMYvxPHUkjGqyF2T6LzzzX8TDcH9jbTdtwNo8AzLGzpJ3", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/194.163.177.193/udp/4001/quic", - "/ip4/194.163.177.193/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWMWFRn7uHM4uiyppLBeVXKeiVXH5RPLhSKSYsx1jFcoLH", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/172.104.11.9/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2600:3c03::f03c:91ff:febd:3e70/tcp/4001", - "/ip6/2600:3c03::f03c:91ff:febd:3e70/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/172.104.11.9/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWQn1N1pWzeV3nVWGsaYe1JeXy7T1C3hbwdwwhQRjW9Zky", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/67.207.88.86/tcp/4001", - "/ip4/67.207.88.86/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWBYZEaEteZajXHuDMEBqxKpBiiADPpFiAYUF9fJkA2NHF", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.15.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::3df:8cc3/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/3.223.140.195/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/3.223.140.195/udp/4001/quic", - "/ip4/172.31.9.209/udp/4001/quic", - "/ip4/172.31.9.209/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWAHSdxLgwiWmkvA3mfZdWmpfsCkA6v1cofvSWaQdCf1mg", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/207.180.216.250/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::cfb4:d8fa/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWGwTuG7f1vjiyJxkcXMwArE6wDXFLxjxb7u3VDvKspKpM", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/154.12.227.253/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/154.12.227.253/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWRw8R6u3hH5mp73FoeHet1CCHZxwkcnsd1y4YKCHefFQN", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/209.97.164.192/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/2400:6180:0:d1::6e2:7001/tcp/4001", - "/ip6/2400:6180:0:d1::6e2:7001/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/209.97.164.192/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWEJWBga3rAbkydqkZQ84euzsEwHH8pyrAmeVJT6AZEw17", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "go-ipfs/0.8.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/39.107.157.137/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/39.107.157.137/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWE6bRJmFKbkMcoVMTckD9NftB99HbAFF68s14xiuKgs4r", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.8.68/tcp/30008", - "/ip4/127.0.0.1/udp/30008/quic", - "/ip4/3.131.37.134/tcp/30008", - "/ip4/172.31.8.68/udp/30008/quic", - "/ip4/127.0.0.1/tcp/30008", - "/ip4/3.131.37.134/udp/30008/quic" - ] - }, - { - "PeerID": "12D3KooWRxti4zG65w9PFeXGDZ8qU6ohHZFeLkj6i3pGsicMFp11", - "ContentID": "QmbYMy6zaqVyfYi3VbiKY5iuqhzxjZ3x8dqMe92EXwZ7ek", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "1.6441667s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/45.76.54.151/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/45.76.54.151/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWNMWLrcjAGUYkBgASGmtBDemuXiJd6nZjR2mUNQkvXADu", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/45.130.104.248/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2a02:c206:3008:6046::1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c206:3008:6046::1/tcp/4001", - "/ip4/45.130.104.248/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWG39cxriefxMJfUmV84WjiPUn2zQYdsK239sghBDpEAsp", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/52.166.130.52/udp/4001/quic", - "/ip4/52.166.130.52/tcp/4001", - "/ip6/64:ff9b::34a6:8234/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLzohQxXfLXDqabexQx5CKoTfe9g4hGwLAqnXc3qTpwcS", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/95.216.99.103/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/95.216.99.103/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWFwSUy8S8oqa27NmpLtJG73PnsKpYUvp5Xv4DkcXxPKNw", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "kubo/0.14.0/", - "PeerMultiaddresses": [ - "/ip4/10.68.181.99/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/173.248.29.230/udp/16890/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/173.248.29.230/tcp/16890", - "/ip4/10.68.181.99/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWGqCmXmWfQjjJmHRyYywLpmTZsUhVRCFQJet8rVmuShDu", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/207.244.239.44/udp/4001/quic", - "/ip4/207.244.239.44/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLLMmxQxGWVyv4RragpYMooqMjKPERXyztmJ63V8FUvgZ", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "go-ipfs/0.8.0/ce693d7", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/35.180.193.16/udp/4001/quic", - "/ip4/35.180.193.16/tcp/2287", - "/ip4/35.180.193.16/tcp/4001", - "/ip4/172.21.0.2/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/172.21.0.2/tcp/4001" - ] - }, - { - "PeerID": "QmQ4gad3QJkkD549dgxojyw1ZnLHvjgj7rk27SrMYhLkcB", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/93.177.245.160/tcp/48557", - "/ip4/127.0.0.1/tcp/48557" - ] - }, - { - "PeerID": "12D3KooWFVMoRovhPEMLLLhQrYCgCZYd2Wx8VjfUL2ZiWLPFa1Ua", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.15.150.32/tcp/30001", - "/ip4/127.0.0.1/udp/30001/quic", - "/ip4/172.31.2.160/tcp/30001", - "/ip4/172.31.2.160/udp/30001/quic", - "/ip4/3.15.150.32/udp/30001/quic", - "/ip4/127.0.0.1/tcp/30001" - ] - }, - { - "PeerID": "12D3KooWNLErdqAznuuucEvzmyrBFpLkNJiSSZjSgaK9QDbr97TV", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "ioi", - "PeerMultiaddresses": [ - "/ip4/171.43.182.67/tcp/46064", - "/ip6/::1/tcp/61605/ws", - "/ip6/::1/tcp/61603", - "/ip4/100.64.221.40/tcp/61602", - "/ip4/127.0.0.1/tcp/61602", - "/ip4/127.0.0.1/udp/56568/quic", - "/ip4/100.64.221.40/udp/56568/quic", - "/ip6/::1/udp/56569/quic", - "/ip4/100.64.221.40/tcp/61604/ws", - "/ip4/127.0.0.1/tcp/61604/ws", - "/ip4/171.43.182.67/udp/45940/quic" - ] - }, - { - "PeerID": "12D3KooWRfFhn69UKXhoGeKHwDdUwXDAKy8dQ4MJ2RHek1K5nsdk", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/2604:a880:400:d0::ebd:1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/198.199.79.236/tcp/4001", - "/ip4/198.199.79.236/udp/4001/quic", - "/ip6/2604:a880:400:d0::ebd:1/udp/4001/quic" - ] - }, - { - "PeerID": "QmeXn7bYoMgsFWtvLVoa8oRdafgcBHQUUL78btfSRJ7NAT", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "storm", - "PeerMultiaddresses": [ - "/ip4/192.168.0.100/tcp/34234", - "/ip4/127.0.0.1/tcp/34234", - "/ip4/106.105.204.218/tcp/34234" - ] - }, - { - "PeerID": "12D3KooWRq7VVpmtQhaiLxFu6ncFjz9zH8sw6MLJ9EbXPnsTxQMR", - "ContentID": "Qmeib5As55FHbRp7uwzthG4YbZFf8Q6YZsAZ7dsHrJAjhv", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.4686694s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/181.44.171.82/tcp/1097", - "/ip6/::1/tcp/4001", - "/ip6/2800:810:410:8cc:1061:4740:f76a:9c41/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/181.44.171.82/udp/4001/quic", - "/ip4/181.44.171.82/udp/1041/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/181.44.171.82/tcp/1096" - ] - }, - { - "PeerID": "12D3KooWSwNjgFy6AjmSwiTzqsuDpuYhArX36ZvVMNtoDYiYaakk", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/45.130.104.243/tcp/4001", - "/ip4/45.130.104.243/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/2a02:c206:3008:6041::1/udp/4001/quic", - "/ip6/2a02:c206:3008:6041::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWQDsf9LATfoXjYEK7cHzNczCLn1T1865isoEei2a7tixN", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/194.147.58.93/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/194.147.58.93/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWAP9YUDi9wgzreExo3gu8bn6FYZzMksBYfvdxiin3WKLU", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/94.76.230.229/udp/4001/quic", - "/ip4/94.76.230.229/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWM3h5o5GQbnikXn3BkvSQZwzuei1k3F6JDMdiigQeyZtt", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/164.68.120.152/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/164.68.120.152/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWPyBgeAJMEwuH7bwz4aNb2zuk691JSJKVPAxZKp4BwQqM", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/80.208.229.149/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/80.208.229.149/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLcvwC4n98FRGddq8KHWbESpUpCeqvq89hf1AFAjvG1AG", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.117.183.16/udp/30009/quic", - "/ip4/127.0.0.1/udp/30009/quic", - "/ip4/127.0.0.1/tcp/30009", - "/ip4/18.117.183.16/tcp/30009", - "/ip4/172.31.6.235/tcp/30009", - "/ip4/172.31.6.235/udp/30009/quic" - ] - }, - { - "PeerID": "12D3KooWNpBxQZwbk5iPnDPvYikrUfqn7RwxuPiH5ZfD6EzjBXMA", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.12.155.215/tcp/30012", - "/ip4/127.0.0.1/tcp/30012", - "/ip4/172.31.3.155/tcp/30012", - "/ip4/127.0.0.1/udp/30012/quic", - "/ip4/3.12.155.215/udp/30012/quic", - "/ip4/172.31.3.155/udp/30012/quic" - ] - }, - { - "PeerID": "12D3KooWRZrF17YyEgnEfmccG6agiECEWRz5UiuThTKzz8QXgtU5", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/18.118.24.61/tcp/30005", - "/ip4/172.31.9.62/tcp/30005", - "/ip4/127.0.0.1/tcp/30005", - "/ip4/172.31.9.62/udp/30005/quic", - "/ip4/127.0.0.1/udp/30005/quic", - "/ip4/18.118.24.61/udp/30005/quic" - ] - }, - { - "PeerID": "12D3KooWLf6LHMsQtqpBGBQ6TdcCU9KPNMqQYJeQfd3cgH8CCovS", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.9.0/", - "PeerMultiaddresses": [ - "/ip6/64:ff9b::90d9:dcd4/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/144.217.220.212/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/144.217.220.212/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWNehCrdAMQtmQi8ah82jty3devwWySRUb8hg1Nr2oWCTH", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.12.2/", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip4/51.81.184.118/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::3351:b876/udp/4001/quic", - "/ip4/51.81.184.118/tcp/4001", - "/ip4/127.0.0.1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWRo7h2imojR3PqpsbdZzZ2QKbvid1kD8offzU69Dm85FL", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/45.63.94.243/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/45.63.94.243/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "QmbxqocVSVzDZuaAMZN73mWZW9aE4wvuGtWqC272gGRQd9", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/218.252.202.63/tcp/57875", - "/ip4/127.0.0.1/tcp/57875" - ] - }, - { - "PeerID": "12D3KooWKiwewNdp3kPt7rK2YVjkPZaCQGn7eyYpNcLUCAcCbBM5", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip4/1.235.216.62/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "QmabecXzRXBCwawuxKnV2vA4LZX6mUFvRTTCZ8m1HtqJ2e", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/44747", - "/ip4/220.80.75.148/tcp/44747" - ] - }, - { - "PeerID": "12D3KooWD3Ko9y3FVNb7r7sG3dR4smfB2aKPzvwzuX2b79NaajUs", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/14.32.151.13/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "QmcbrMYk7ff5vqBpz8thfhskUHtuDkEmaEGemf9p3W63FY", - "ContentID": "QmNVMoU4BgX6b1vvPZuQq1K4niBsjz5Mk9jwRgvuGFmyYa", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.3880127s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/219.73.63.228/tcp/49009", - "/ip4/127.0.0.1/tcp/49009" - ] - }, - { - "PeerID": "QmUGCr3msQ5pVFKcxRvK53AChUyUYQHKDqjDKPKcS2YBNK", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.11.0/", - "PeerMultiaddresses": [ - "/ip6/2a03:b0c0:3:d0::130c:e001/tcp/4001", - "/ip6/::1/tcp/4002/ws", - "/ip4/142.93.108.62/tcp/4002/ws", - "/ip4/10.100.248.14/tcp/1080/ws", - "/ip4/127.0.0.1/tcp/4002/ws", - "/ip6/2a03:b0c0:3:d0::130c:e001/tcp/4002/ws", - "/ip6/64:ff9b::8e5d:6c3e/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/142.93.108.62/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWRRXDCFVn4eVNo62KN4a8opSbN4PAdkBJuwwVG2TUEpiS", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "kubo/0.14.0/", - "PeerMultiaddresses": [ - "/ip4/51.158.189.228/tcp/4001", - "/ip6/64:ff9b::339e:bde4/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::339e:bde4/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/51.158.189.228/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWL7yD27jVbKpcqA7oANkghxz8VK1RiJqWP8PSnpnUEzGy", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.7.71/tcp/30013", - "/ip4/3.137.171.207/tcp/30013", - "/ip4/127.0.0.1/tcp/30013", - "/ip4/127.0.0.1/udp/30013/quic", - "/ip4/172.31.7.71/udp/30013/quic", - "/ip4/3.137.171.207/udp/30013/quic" - ] - }, - { - "PeerID": "12D3KooWPdn4HcNPvJRo2ftxtHsteWSB7Gt2k1mYfBznEwixH2Xf", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/38.242.253.124/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/38.242.253.124/tcp/4001" - ] - }, - { - "PeerID": "QmTi6uTbq7mkPcHnroGeuvgL5x8Ng4vFk3R6EaLPzDLLos", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.13.0/", - "PeerMultiaddresses": [ - "/ip4/99.81.187.79/udp/4001/quic", - "/ip4/172.31.18.213/udp/4001/quic", - "/ip4/99.81.187.79/tcp/4001", - "/ip6/64:ff9b::6351:bb4f/tcp/4001", - "/ip6/64:ff9b::6351:bb4f/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/172.31.18.213/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWC6GwBqk6ghNghL4f1pEqhn85dceQ2ZtEmp9xc7AotnUk", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/30006", - "/ip4/172.31.11.60/tcp/30006", - "/ip4/3.128.198.89/udp/30006/quic", - "/ip4/127.0.0.1/udp/30006/quic", - "/ip4/172.31.11.60/udp/30006/quic", - "/ip4/3.128.198.89/tcp/30006" - ] - }, - { - "PeerID": "12D3KooWMG34SvdnHa3StsQb2t3KefRYcPzy33grj72R4KgoGrW9", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2402:1f00:8100:400::89d/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/139.99.192.132/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2402:1f00:8100:400::89d/udp/4001/quic", - "/ip6/::1/tcp/4001", - "/ip6/64:ff9b::8b63:c084/udp/4001/quic", - "/ip4/139.99.192.132/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWLqFQcMMaKDBCPeXdB2dEvzBuHAaLSSj5ejR9TxzTTWxQ", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip4/154.12.224.130/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/154.12.224.130/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWFuT9EJjo4PXtRCqVbX28HrUXPBwTz1NUWdbb9MFFGr9w", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip6/64:ff9b::6bad:905c/udp/4001/quic", - "/ip4/107.173.144.92/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/107.173.144.92/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWK8dpnQxznKSKtCAZ6q2njrGJES6mxjsge8ZzYxbFjUXd", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/203.159.93.230/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/203.159.93.230/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWPwWjSjnPDeF2mWoDmD7EuoGRhmE9YNHmJt9mA1BhSd1v", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/139.178.91.73/tcp/4001", - "/ip6/2604:1380:45e1:4a00::5/udp/4001/quic", - "/ip6/2604:1380:45e1:4a00::5/tcp/4002/ws", - "/ip4/139.178.91.73/tcp/4002/ws", - "/ip4/139.178.91.73/udp/4001/quic", - "/ip6/2604:1380:45e1:4a00::5/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWEntVos9VVFFn67BBo4tKhmB1hLNaVHcec83jxuvA3e1Z", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "kubo/0.16.0/", - "PeerMultiaddresses": [ - "/ip6/::1/udp/4001/quic", - "/ip6/2405:4802:337:d7a0:8549:7a19:a41c:6f38/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/192.168.1.25/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/192.168.1.25/tcp/4001", - "/ip6/2405:4802:337:d7a0:8549:7a19:a41c:6f38/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWE95UgjxtscZ31yBWZAB79ppVvuZv7Ut5wCh3E92b3PkE", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/158.247.211.103/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/158.247.211.103/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWLozcAic9mTyo93MpXiziv2PZyw9AzWwqcf5mhyriChTc", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.13.0/", - "PeerMultiaddresses": [ - "/ip6/2604:a880:800:10::c37:3001/udp/4001/quic", - "/ip4/143.198.25.218/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/143.198.25.218/udp/4001/quic", - "/ip6/2604:a880:800:10::c37:3001/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/64:ff9b::8fc6:19da/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWDK42YiGZVaxotkeU9e65SsEgoVdeztpF1TtGmbUjNNJ1", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "ioi", - "PeerMultiaddresses": [ - "/ip4/192.168.10.103/udp/64816/quic", - "/ip4/127.0.0.1/tcp/7260/ws", - "/ip4/192.168.10.103/tcp/7260/ws", - "/ip6/::1/udp/64817/quic", - "/ip4/117.144.103.238/tcp/36265", - "/ip4/117.144.103.238/tcp/45722/ws", - "/ip6/2001:0:2851:b9f0:1079:1149:8a6f:9811/udp/64817/quic", - "/ip4/117.144.103.238/udp/27478/quic", - "/ip6/::1/tcp/7259", - "/ip6/2001:0:2851:b9f0:1079:1149:8a6f:9811/tcp/7261/ws", - "/ip4/117.144.103.238/tcp/55864/ws", - "/ip4/117.144.103.238/tcp/33347", - "/ip4/127.0.0.1/udp/64816/quic", - "/ip4/192.168.10.103/tcp/7258", - "/ip4/127.0.0.1/tcp/7258", - "/ip4/117.144.103.238/udp/21709/quic", - "/ip6/::1/tcp/7261/ws", - "/ip6/2001:0:2851:b9f0:1079:1149:8a6f:9811/tcp/7259" - ] - }, - { - "PeerID": "12D3KooWPK33iEpags1kmt9xw9qMtViNEVBJnYbHbW2Q3WGNdyiP", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "kubo/0.14.0-rc1/", - "PeerMultiaddresses": [ - "/ip4/121.121.77.118/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/192.168.0.105/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/192.168.0.105/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "Qmf5hAQBSogm9qg631PiDZAcsreopWnuxSFFkibtT4dDeN", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/61.228.33.243/tcp/55681", - "/ip4/127.0.0.1/tcp/55681" - ] - }, - { - "PeerID": "QmTLGWJYL24ZVsc3EvjonoUPkWn7kGFpA6CsNWVfUdDjPX", - "ContentID": "QmVF9HJVQffY8hn42fuEEzFF9Ftq1fWgjQcQsbnub19Xo6", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "3.3659442s", - "UserAgent": "storm", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/33433", - "/ip4/183.63.207.51/tcp/33433" - ] - }, - { - "PeerID": "12D3KooWFmCqxM5TpGLra7L4QgDDLKqohwfdtN94mpAwBUdPZkjw", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "kubo/0.15.0/3ae52a4", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/51.195.176.65/udp/4001/quic", - "/ip4/51.195.176.65/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/51.195.176.65/udp/35569/quic", - "/ip6/64:ff9b::33c3:b041/tcp/4001" - ] - }, - { - "PeerID": "12D3KooWRLjemeKiZZPn1p9Lu5JaLLrxhVkcWqdFip8eBVSVZA6v", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip4/185.217.126.120/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip4/185.217.126.120/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWMweEAhvyW3RHXZ1gWEexsnjfcEvNFELWQBUHgWEPB2oT", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/3.128.95.39/udp/30011/quic", - "/ip4/3.128.95.39/tcp/30011", - "/ip4/127.0.0.1/udp/30011/quic", - "/ip4/127.0.0.1/tcp/30011", - "/ip4/172.31.12.143/tcp/30011", - "/ip4/172.31.12.143/udp/30011/quic" - ] - }, - { - "PeerID": "12D3KooWJVPLaepXnTZxsqGewDr12YPTMeMucNfP7agm2gaJMoVE", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "kubo/0.14.0/e0fabd6", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/193.8.130.153/tcp/4001", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", - "/ip4/193.8.130.153/udp/54061/quic", - "/ip4/193.8.130.153/udp/4001/quic" - ] - }, - { - "PeerID": "12D3KooWCYx1uJFZT9WLpBQXHLgFf6KRhs1rEt5zy7Dt8XhVXXjm", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "hydra-booster/0.7.4", - "PeerMultiaddresses": [ - "/ip4/172.31.15.84/tcp/30005", - "/ip4/3.17.78.57/udp/30005/quic", - "/ip4/172.31.15.84/udp/30005/quic", - "/ip4/127.0.0.1/udp/30005/quic", - "/ip4/3.17.78.57/tcp/30005", - "/ip4/127.0.0.1/tcp/30005" - ] - }, - { - "PeerID": "QmXMHB8Mt4wBVBX19xCNvKb5Kr2CkURatQNNNssSgpKwhv", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/81.198.154.136/tcp/38667", - "/ip4/127.0.0.1/tcp/38667" - ] - }, - { - "PeerID": "12D3KooWPVSUyev9zxHJzZpomXEbFQ6x4VWV27KBP3PR7eBKPM6q", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "kubo/0.14.0-dev/839b0848a", - "PeerMultiaddresses": [ - "/ip6/::1/tcp/4001", - "/ip6/::1/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/2400:8902::f03c:93ff:fecc:11ec/udp/4001/quic", - "/ip4/172.104.94.205/udp/4001/quic", - "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/2400:8902::f03c:93ff:fecc:11ec/tcp/4001", - "/ip4/172.104.94.205/tcp/4001" - ] - }, - { - "PeerID": "QmW186j2ZNXySbdnZ5qZJUkPpMFLBejupYAKCu7YvKbWnb", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/46.43.215.106/tcp/52247", - "/ip4/127.0.0.1/tcp/52247" - ] - }, - { - "PeerID": "QmbCHRdurAUqBH9rMZpq5zs1vACa3DEkNYGV2fMnpeibD3", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/39939", - "/ip4/177.73.170.237/tcp/39939", - "/ip4/192.168.1.2/tcp/39939" - ] - }, - { - "PeerID": "QmTaC3yjsSGqHQrkjfB6FoW2yBiGJYJWBtSTyYsxphYHk2", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/59.8.58.232/tcp/52468", - "/ip4/127.0.0.1/tcp/52468" - ] - }, - { - "PeerID": "12D3KooWPsNZUzqCcJTmjLuBriUyUUhC3Uw7cCpuPzHdnkWLifXa", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "go-ipfs/0.7.0/", - "PeerMultiaddresses": [ - "/ip6/2001:fb1:a6:137:f6be:57e8:33bf:a4f2/tcp/4001", - "/ip4/127.0.0.1/tcp/4001", - "/ip6/::1/tcp/4001", - "/ip4/124.120.26.45/tcp/4001" - ] - }, - { - "PeerID": "QmURKkorBBkENPqjrs3MtqYdDzqz9Z74PdkyxRXZGvEkGw", - "ContentID": "Qmb1VdTzEjQRfHj2saoLxFpcsQ43QHPGKSzYyyvK34qd1W", - "Creator": "QmUYZcJM9CxFWWwkjWwLGV4Qb6MbDbzsDAHwepV1GY63Hn", - "ProvideTime": "5.6153882s", - "UserAgent": "go-ipfs/0.8.0/48f94e2", - "PeerMultiaddresses": [ - "/ip4/127.0.0.1/tcp/45273", - "/ip4/179.135.89.222/tcp/45273" - ] - } - ] -} \ No newline at end of file diff --git a/go-libp2p-kad-dht b/go-libp2p-kad-dht index 6b49032..712ce90 160000 --- a/go-libp2p-kad-dht +++ b/go-libp2p-kad-dht @@ -1 +1 @@ -Subproject commit 6b490320a6c1b70eba2031260a2515c26e7519fe +Subproject commit 712ce90591db351d9149f032859f1900d8b8f239 diff --git a/go.mod b/go.mod index bc44ded..453eb7d 100644 --- a/go.mod +++ b/go.mod @@ -1,130 +1,127 @@ module github.com/cortze/ipfs-cid-hoarder -go 1.17 +go 1.19 require ( - github.com/ipfs/go-cid v0.3.0 - github.com/jackc/pgx/v4 v4.16.1 - github.com/libp2p/go-libp2p v0.22.0 - github.com/libp2p/go-libp2p-kad-dht v0.15.0 - github.com/multiformats/go-multiaddr v0.6.0 + github.com/ipfs/go-cid v0.4.1 + github.com/jackc/pgx/v5 v5.3.1 + github.com/libp2p/go-libp2p v0.27.3 + github.com/libp2p/go-libp2p-kad-dht v0.23.0 + github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multihash v0.2.1 github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.8.1 - github.com/urfave/cli/v2 v2.5.1 + github.com/sirupsen/logrus v1.9.2 + github.com/urfave/cli/v2 v2.25.3 ) require ( - github.com/benbjohnson/clock v1.3.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/cheekybits/genny v1.0.0 // indirect - github.com/containerd/cgroups v1.0.4 // indirect - github.com/coreos/go-systemd/v22 v22.3.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.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/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/base58 v1.0.4 // indirect - github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.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/fsnotify/fsnotify v1.5.4 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // 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/protobuf v1.5.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-20230510103437-eeec1cb781c3 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect - github.com/huin/goupnp v1.0.3 // indirect - github.com/ipfs/go-datastore v0.5.1 // indirect + github.com/huin/goupnp v1.2.0 // indirect + github.com/ipfs/boxo v0.8.1 // indirect + github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipns v0.2.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipld/go-ipld-prime v0.9.0 // indirect - github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.12.1 // indirect - github.com/jackc/pgio v1.0.0 // indirect + github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect - github.com/jackc/pgtype v1.11.0 // indirect - github.com/jackc/puddle v1.2.1 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/puddle/v2 v2.2.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.15.1 // indirect - github.com/klauspost/cpuid/v2 v2.1.0 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/klauspost/compress v1.16.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // 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.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-msgio v0.2.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.0 // indirect - github.com/libp2p/go-openssl v0.1.0 // indirect - github.com/libp2p/go-reuseport v0.2.0 // indirect - github.com/libp2p/go-yamux/v3 v3.1.2 // indirect - github.com/lucas-clemente/quic-go v0.28.1 // indirect - github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect - github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.1 // indirect + github.com/libp2p/go-reuseport v0.3.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.16 // indirect - github.com/mattn/go-pointer v0.0.1 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/dns v1.1.54 // 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.0.4 // indirect - github.com/multiformats/go-base36 v0.1.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.1.1 // indirect - github.com/multiformats/go-multicodec v0.5.0 // indirect - github.com/multiformats/go-multistream v0.3.3 // indirect - github.com/multiformats/go-varint v0.0.6 // indirect - github.com/nxadm/tail v1.4.8 // indirect - github.com/onsi/ginkgo v1.16.5 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multicodec v0.9.0 // 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.5 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect - github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/polydawn/refmt v0.89.0 // indirect + github.com/prometheus/client_golang v1.15.1 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.10.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.34.0 // indirect + github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - go.opencensus.io v0.23.0 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.22.0 // indirect - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.12 // indirect - google.golang.org/protobuf v1.28.1 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - lukechampine.com/blake3 v1.1.7 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/otel v1.15.1 // indirect + go.opentelemetry.io/otel/trace v1.15.1 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/dig v1.17.0 // indirect + go.uber.org/fx v1.19.3 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/exp v0.0.0-20230519143937-03e91628a987 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.9.1 // indirect + gonum.org/v1/gonum v0.13.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + lukechampine.com/blake3 v1.2.1 // indirect + nhooyr.io/websocket v1.8.7 // indirect ) -replace github.com/libp2p/go-libp2p-kad-dht v0.15.0 => ./go-libp2p-kad-dht +replace github.com/libp2p/go-libp2p-kad-dht v0.23.0 => ./go-libp2p-kad-dht diff --git a/go.sum b/go.sum index 03f8691..dc04e71 100644 --- a/go.sum +++ b/go.sum @@ -2,140 +2,50 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT 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= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 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/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 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/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/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.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 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/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +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/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +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 v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/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.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +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/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/base58 v1.0.4 h1:QJC6B0E0rXOPA8U/kw2rP+qiRJsUaE2Er+pYb3siUeA= -github.com/decred/base58 v1.0.4/go.mod h1:jJswKPEdvpFpvf7dsDvFZyLT22xZ9lWqEByX38oGd9E= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -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/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= -github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= 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= @@ -149,64 +59,56 @@ 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/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= 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-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +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/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= +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/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= -github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 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.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 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.2/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.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -214,28 +116,20 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/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.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/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.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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= @@ -243,277 +137,134 @@ github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8v 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/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 h1:2XF1Vzq06X+inNqgJ9tRnGuw+ZVCB3FazXODD6JE1R8= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/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/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= -github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= -github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= -github.com/ipfs/go-cid v0.3.0 h1:gT6Cbs6YePaBNc7l6v5EXt0xTMup1jGV5EU1N+QLVpY= -github.com/ipfs/go-cid v0.3.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= -github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.5.1 h1:WkRhLuISI+XPD0uk3OskB0fYFSyqK8Ob5ZYew9Qa1nQ= -github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= +github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= +github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= +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-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= +github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= 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-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= -github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= -github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8= -github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= -github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipns v0.2.0 h1:BgmNtQhqOw5XEZ8RAfWEpK4DhqaYiuP6h71MhIp7xXU= -github.com/ipfs/go-ipns v0.2.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= 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/ipld/go-ipld-prime v0.9.0 h1:N2OjJMb+fhyFPwPnVvJcWU/NsumP8etal+d2v3G4eww= -github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= -github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= -github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= -github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= -github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= -github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= -github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= -github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= -github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8= -github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= -github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= -github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y= -github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= -github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= -github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs= -github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= -github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= -github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= -github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y= -github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= -github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw= -github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk= +github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= 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-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= 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/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= -github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +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/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 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/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/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.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= -github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +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.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -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/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 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/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= -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/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= -github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +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.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= -github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= 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.22.0 h1:2Tce0kHOp5zASFKJbNzRElvh0iZwdtG5uZheNW8chIw= -github.com/libp2p/go-libp2p v0.22.0/go.mod h1:UDolmweypBSjQb2f7xutPnwZ/fxioLbMBxSjRksxxU4= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= -github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-core v0.19.0/go.mod h1:AkA+FUKQfYt1FLNef5fOPlo/naAWjKy/RCjkcPjqzYg= -github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= +github.com/libp2p/go-libp2p v0.27.3 h1:tkV/zm3KCZ4R5er9Xcs2pt0YNB4JH0iBfGAtHJdLHRs= +github.com/libp2p/go-libp2p v0.27.3/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-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= -github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.4.0/go.mod h1:dYEAgkVhqho3/YKxfOEGdFMIcWfAFNlZX8iAIihYA2E= -github.com/libp2p/go-libp2p-testing v0.11.0/go.mod h1:qG4sF27dfKFoK9KlVzK2y52LQKhp0VEmLjV5aDqr1Hg= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= -github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= -github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= -github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= -github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +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.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= -github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= -github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -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-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.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-yamux/v3 v3.1.2 h1:lNEy28MBk1HavUAlzKgShp+F6mn/ea1nDYWftZhFW9Q= -github.com/libp2p/go-yamux/v3 v3.1.2/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= -github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= -github.com/lucas-clemente/quic-go v0.28.1 h1:Uo0lvVxWg5la9gflIF9lwa39ONq85Xq2D91YNEIslzU= -github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= +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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= -github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR7s0bLKJeYlQ= -github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= -github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= -github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= -github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU= -github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= 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-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 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.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +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.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/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= @@ -521,142 +272,96 @@ github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKo 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.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1/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/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +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.1.3/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.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= -github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= -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.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +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.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= -github.com/multiformats/go-multiaddr v0.6.0 h1:qMnoOPj2s8xxPU5kZ57Cqdr0hHhARz7mFsPMIiYNqzg= -github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM= +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-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= -github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.5.0 h1:EgU6cBe/D7WRwQb1KmnBvU7lrcFGMggZVTPtOW9dDHs= -github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= -github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +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.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/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.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= 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.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= -github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +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.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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +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/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= +github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= 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/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= 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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 h1:CskT+S6Ay54OwxBGB0R3Rsx4Muto6UnEYTyKJbyRIAI= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= +github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.10.0 h1:UkG7GPYkO4UZyLnyXjaWYcgOSONqwdBqFUT95ugmt6I= +github.com/prometheus/procfs v0.10.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +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.34.0 h1:OvOJ9LFjTySgwOTYUZmNoq0FzVicP8YujpV0kB7m2lU= +github.com/quic-go/quic-go v0.34.0/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= +github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 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/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 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= @@ -680,232 +385,128 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. 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.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= +github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= 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/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 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 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= +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/urfave/cli/v2 v2.5.1 h1:YKwdkyA0xTBzOaP2G0DVxBnCheHGP+Y9VbKAs4K1Ess= -github.com/urfave/cli/v2 v2.5.1/go.mod h1:oDzoM7pVwz6wHn5ogWgFUU1s4VJayeQS+aEZDqXIEJs= +github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.25.3 h1:VJkt6wvEBOoSjPFQvOkv6iWIrsJyCrKGtCtxXWwmGeY= +github.com/urfave/cli/v2 v2.25.3/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= 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/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/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= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/otel v1.15.1 h1:3Iwq3lfRByPaws0f6bU3naAqOR1n5IeDWd9390kWHa8= +go.opentelemetry.io/otel v1.15.1/go.mod h1:mHHGEHVDLal6YrKMmk9LqC4a3sF5g+fHfrttQIB1NTc= +go.opentelemetry.io/otel/trace v1.15.1 h1:uXLo6iHJEzDfrNC0L0mNjItIp06SyaBQxu5t3xMlngY= +go.opentelemetry.io/otel/trace v1.15.1/go.mod h1:IWdQG/5N1x7f6YUlmdLeJvH9yxtuJAfc4VW5Agv9r/8= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 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/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= +go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA= +go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0= -go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U= +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-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/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-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/exp v0.0.0-20230519143937-03e91628a987 h1:3xJIFvzUFbu4ls0BTBYcgbCGhA63eAOEMxIHugyXJqA= +golang.org/x/exp v0.0.0-20230519143937-03e91628a987/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= 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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/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.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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-20181114220301-adae6a3d119a/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-20190227160552-c95aed5357e7/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/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.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 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/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 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= @@ -913,244 +514,91 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ 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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/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.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.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-20180905080454-ebe1bf3edb33/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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/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-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.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-20190308202827-9d24e82272b4/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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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-20181130052023-1c3d964395ce/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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= 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= +gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= +gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= 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/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 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/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 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/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1160,34 +608,21 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +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-20190902080502-41f04d3bba15/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= -gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 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= @@ -1196,16 +631,11 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd 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= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +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/pkg/cid-source/bitswap.go b/pkg/cid-source/bitswap.go deleted file mode 100644 index deba43b..0000000 --- a/pkg/cid-source/bitswap.go +++ /dev/null @@ -1,21 +0,0 @@ -package cid_source - -import "github.com/cortze/ipfs-cid-hoarder/pkg/config" - -//Not yet implemented -type BitswapCIDSource struct { -} - -//Not yet implemented -func NewBitswapCIDSource() *BitswapCIDSource { - return &BitswapCIDSource{} -} - -func (bitswap_cid_source *BitswapCIDSource) Type() string { - return config.BitswapSource -} - -func (bitswap_cid_source *BitswapCIDSource) GetNewCid() (TrackableCid, error) { - //TODO function that reads bitswap content - return TrackableCid{}, nil -} diff --git a/pkg/cid-source/http_server.go b/pkg/cid-source/http_server.go deleted file mode 100644 index 7dcef38..0000000 --- a/pkg/cid-source/http_server.go +++ /dev/null @@ -1,285 +0,0 @@ -package cid_source - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "reflect" - "sync" - "time" - - "github.com/cortze/ipfs-cid-hoarder/pkg/config" - - "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p/core/peer" - ma "github.com/multiformats/go-multiaddr" - "github.com/pkg/errors" - log "github.com/sirupsen/logrus" -) - -type HttpCidSource struct { - port int - hostname string - lock sync.Mutex - server *http.Server - providerRecords []ProviderRecords - isStarted bool -} - -func (httpCidSource *HttpCidSource) Dequeue() ProviderRecords { - if len(httpCidSource.providerRecords) == 0 { - log.Debug("Queue is empty") - return ProviderRecords{} - } - elem := httpCidSource.providerRecords[0] - httpCidSource.providerRecords = httpCidSource.providerRecords[1:] - log.Debugf("Removed element from queue, lenth is now: %d", len(httpCidSource.providerRecords)) - return elem -} - -func (httpCidSource *HttpCidSource) Enqueue(providerRecords ProviderRecords) { - httpCidSource.providerRecords = append(httpCidSource.providerRecords, providerRecords) - log.Debugf("Added new element to queue, length is now: %d", len(httpCidSource.providerRecords)) -} - -func NewHttpCidSource(port int, hostname string) *HttpCidSource { - return &HttpCidSource{ - port: port, - hostname: hostname, - server: nil, - isStarted: false, - providerRecords: []ProviderRecords{}, - } -} - -func (httpCidSource *HttpCidSource) ServeHTTP(w http.ResponseWriter, r *http.Request) { - log.Info("Received request in server HTTP") - if r.URL.Path == "/ProviderRecord" { - if r.Method == http.MethodPost { - log.Debug("The request was a post method") - // create a new TrackableCid instance - var providerRecords ProviderRecords - - // decode the request body into the TrackableCid struct - err := json.NewDecoder(r.Body).Decode(&providerRecords) - if err == nil { - log.Info("Decoded new encapsulated json received from post") - - // add the trackableCid to the list - httpCidSource.Enqueue(providerRecords) - } else { - - http.Error(w, "Error decoding request body", http.StatusBadRequest) - } - - } else if r.Method == http.MethodGet { - log.Debug("The request was a get request") - // check if there are any trackableCids to return - if len(httpCidSource.providerRecords) != 0 { - // return the last unretrieved trackableCid - providerRecords := httpCidSource.Dequeue() - log.Info("Sending new encapsulated json cid to user with get method") - // send the trackableCid back to the client as a response - json.NewEncoder(w).Encode(providerRecords) - } else { - - http.Error(w, "No record available currently", http.StatusNoContent) - } - - } else { - // return "Method Not Allowed" error - http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) - } - } - -} - -func (httpCidSource *HttpCidSource) StartServer() error { - log.Info("Starting http server") - if httpCidSource.isStarted { - return errors.New("Http server is already started") - } - httpCidSource.isStarted = true - // prepare address - addr := fmt.Sprintf(":%v", httpCidSource.port) - - httpCidSource.server = &http.Server{ - Addr: addr, - Handler: httpCidSource, - } - - /* http.HandleFunc("/ProviderRecord", func(w http.ResponseWriter, r *http.Request) { - log.Info("Set handler for requests") - if r.Method == http.MethodPost { - // create a new TrackableCid instance - var providerRecords ProviderRecords - - // decode the request body into the TrackableCid struct - err := json.NewDecoder(r.Body).Decode(&providerRecords) - if err == nil { - log.Info("Decoded new encapsulated json received from post") - - // add the trackableCid to the list - httpCidSource.Enqueue(providerRecords) - } else { - - http.Error(w, "Error decoding request body", http.StatusBadRequest) - } - - } else if r.Method == http.MethodGet { - // check if there are any trackableCids to return - if len(httpCidSource.providerRecords) != 0 { - // return the last unretrieved trackableCid - providerRecords := httpCidSource.Dequeue() - log.Info("Sending new encapsulated json cid to user with get method") - // send the trackableCid back to the client as a response - json.NewEncoder(w).Encode(providerRecords) - } else { - - http.Error(w, "No record available currently", http.StatusNoContent) - } - - } else { - // return "Method Not Allowed" error - http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) - } - }) */ - if err := httpCidSource.server.ListenAndServe(); err != nil { - if err == http.ErrServerClosed { - log.Infof("Server closed under request: %v", err) - } else { - log.Fatalf("Server closed unexpect: %v", err) - } - httpCidSource.isStarted = false - } - return nil -} - -func (httpCidSource *HttpCidSource) Shutdown(ctx context.Context) error { - httpCidSource.lock.Lock() - defer httpCidSource.lock.Unlock() - - if !httpCidSource.isStarted || httpCidSource.server == nil { - return errors.New("Server is not started") - } - - stop := make(chan bool) - go func() { - // We can use .Shutdown to gracefully shuts down the server without - // interrupting any active connection - httpCidSource.server.Shutdown(ctx) - stop <- true - }() - - select { - case <-ctx.Done(): - log.Errorf("Timeout: %v", ctx.Err()) - break - case <-stop: - log.Infof("Finished and shutting down http server") - } - - return nil -} - -func GetNewHttpCid(source interface{}) ([]TrackableCid, error) { - - httpCidSource, ok := source.(*HttpCidSource) - if !ok { - return []TrackableCid{}, fmt.Errorf("Invalid source type: %T", source) - } - - // send a GET request to the server - url := fmt.Sprintf("http://%s:%d/ProviderRecord", httpCidSource.hostname, httpCidSource.port) - resp, err := http.Get(url) - if err != nil { - return []TrackableCid{}, err - } - defer resp.Body.Close() - - // check the status code - if resp.StatusCode == http.StatusNoContent { - return []TrackableCid{}, errors.New(fmt.Sprintf("Error while retrieving new cid from stack: %s", resp.Status)) - } else if resp.StatusCode != http.StatusOK { - return []TrackableCid{}, errors.New(fmt.Sprintf("Error retrieving trackableCid: %s", resp.Status)) - } - - // decode the response into a EncapsulatedJSONProviderRecord struct - var providerRecords ProviderRecords - err = json.NewDecoder(resp.Body).Decode(&providerRecords) - if err != nil { - return []TrackableCid{}, errors.Wrap(err, " while decoding trackable cid") - } - - if reflect.DeepEqual(providerRecords, ProviderRecords{}) { - return nil, errors.New("ended providing") - } - - var trackableCidPrs []TrackableCid - - for _, providerRecord := range providerRecords.EncapsulatedJSONProviderRecords { - log.Debug("Read a new PR from the web server:") - - log.Debugf("It's cid is: %s", providerRecord.CID) - newCid, err := cid.Parse(providerRecord.CID) - if err != nil { - log.Errorf("could not convert string to cid %s", err) - } - - log.Debugf("It's peer id is: %s", providerRecord.ID) - newPid, err := peer.Decode(providerRecord.ID) - if err != nil { - log.Errorf("could not convert string to pid %s", err) - } - - log.Debugf("It's creator is: %s", providerRecord.Creator) - newCreator, err := peer.Decode(providerRecord.Creator) - if err != nil { - log.Errorf("could not convert string to creator pid %s", err) - } - - log.Debugf("It's provide time is: %s", providerRecord.ProvideTime) - newProvideTime, err := time.ParseDuration(providerRecord.ProvideTime) - - if err != nil { - log.Errorf("Error while parsing provide time: %s", err) - } - - log.Debugf("It's publication time is: %s", providerRecord.PublicationTime) - newPublicationTime, err := time.Parse(time.RFC3339, providerRecord.PublicationTime) - - if err != nil { - log.Errorf("Error while parsing publication time: %s", err) - } - - log.Debugf("It's user agent is: %s", providerRecord.UserAgent) - - multiaddresses := make([]ma.Multiaddr, 0) - for i := 0; i < len(providerRecord.Addresses); i++ { - multiaddr, err := ma.NewMultiaddr(providerRecord.Addresses[i]) - if err != nil { - //log.Errorf("could not convert string to multiaddress %s", err) - continue - } - multiaddresses = append(multiaddresses, multiaddr) - } - - log.Infof("generated new CID %s", newCid.Hash().B58String()) - - log.Infof("Read a new provider ID %s.The multiaddresses are %v. The creator is %s. The new CID is %s", string(newPid), multiaddresses, newCreator, newCid) - trackableCid := NewTrackableCid(newPid, newCid, newCreator, multiaddresses, newPublicationTime, newProvideTime, providerRecord.UserAgent) - trackableCidPrs = append(trackableCidPrs, trackableCid) - } - - return trackableCidPrs, nil - -} - -func (httpCidSource *HttpCidSource) GetNewCid() (TrackableCid, error) { - return TrackableCid{}, nil -} - -func (httpCidSource *HttpCidSource) Type() string { - return config.HttpServerSource -} diff --git a/pkg/cid-source/http_server_test.go b/pkg/cid-source/http_server_test.go deleted file mode 100644 index 3c3bb18..0000000 --- a/pkg/cid-source/http_server_test.go +++ /dev/null @@ -1,208 +0,0 @@ -package cid_source - -import ( - "bytes" - "encoding/json" - "fmt" - "net/http" - "testing" - "time" - - "github.com/cortze/ipfs-cid-hoarder/pkg/config" - "github.com/cortze/ipfs-cid-hoarder/pkg/models" - "github.com/cortze/ipfs-cid-hoarder/pkg/p2p" - - "github.com/ipfs/go-cid" - log "github.com/sirupsen/logrus" -) - -func PostRequestProviders() { - records1 := ProviderRecords{ - EncapsulatedJSONProviderRecords: []EncapsulatedJSONProviderRecord{}, - } - - records2 := ProviderRecords{ - EncapsulatedJSONProviderRecords: []EncapsulatedJSONProviderRecord{}, - } - - records1.EncapsulatedJSONProviderRecords = append(records1.EncapsulatedJSONProviderRecords, - NewEncapsulatedJSONCidProvider( - "12D3KooWMqsgdFjkn9gdnRBmHGmn8M82rc2xEg6kyVJT3MyinV2y", - "QmcAVd2AZPBvG6XKZVGsSkwdkDimME4e9cTn7QR1KN4Edv", - []string{"/ip6/2602:ff16:6:0:1:1c1:0:1/tcp/4001", "/ip6/::1/tcp/4001", "/ip4/127.0.0.1/udp/4001/quic", - "/ip6/::1/udp/4001/quic", "/ip6/2602:ff16:6:0:1:1c1:0:1/udp/4001/quic", "/ip4/89.233.108.3/udp/4001/quic", - "/ip4/127.0.0.1/tcp/4001", "/ip4/89.233.108.3/tcp/4001"}, - "QmWCmp2w4MVvuWSwfYJyzDBNJxmub5mccYsSEhmKMq1zfW", - "0s", - "0s", - "go-ipfs/0.7.0/", - ), - NewEncapsulatedJSONCidProvider( - "12D3KooWDaG92o6WsCio9KNEgtwMH5uYQ7CrjinWoTp7E7mwYSj8", - "QmcAVd2AZPBvG6XKZVGsSkwdkDimME4e9cTn7QR1KN4Edv", - []string{"/ip6/2a01:4f9:c010:d4d4::1/tcp/4001", "/ip6/64:ff9b::4115:3f3e/udp/4001/quic", - "/ip6/2a01:4f9:c010:d4d4::1/udp/4001/quic", "/ip6/::1/udp/4001/quic", "/ip4/65.21.63.62/udp/4001/quic", - "/ip4/65.21.63.62/tcp/4001", "/ip4/127.0.0.1/tcp/4001", "/ip6/::1/tcp/4001", "/ip4/127.0.0.1/udp/4001/quic"}, - "QmWCmp2w4MVvuWSwfYJyzDBNJxmub5mccYsSEhmKMq1zfW", - "0s", - "0s", - "go-ipfs/0.8.0/", - ), - ) - - records2.EncapsulatedJSONProviderRecords = append(records2.EncapsulatedJSONProviderRecords, - NewEncapsulatedJSONCidProvider( - "12D3KooWCqCptb37u82qWDtrkWQH648Hcbh7McZXwNTaT8s4oFpH", - "QmRpBb76FipRtYD9TVqJyyweURozccUpRCXSvFWfVuSu8U", - []string{"/ip4/45.63.7.28/tcp/4001", "/ip4/127.0.0.1/udp/4001/quic", - "/ip4/45.63.7.28/udp/4001/quic", "/ip6/::1/udp/4001/quic", "/ip6/::1/tcp/4001", "/ip4/127.0.0.1/tcp/4001"}, - "QmWCmp2w4MVvuWSwfYJyzDBNJxmub5mccYsSEhmKMq1zfW", - "0s", - "0s", - "kubo/0.14.0/e0fabd6", - ), - NewEncapsulatedJSONCidProvider( - "12D3KooWMwDswsL9c4Fa3c6UtgxvGxNoPBJ5dYCp8kzrXmJe59xP", - "QmRpBb76FipRtYD9TVqJyyweURozccUpRCXSvFWfVuSu8U", - []string{"/ip4/127.0.0.1/udp/4001/quic", "/ip4/165.227.164.94/tcp/4001", - "/ip6/64:ff9b::a5e3:a45e/udp/4001/quic", "/ip6/::1/udp/4001/quic", "/ip4/127.0.0.1/tcp/4001", "/ip6/::1/tcp/4001", "/ip4/165.227.164.94/udp/4001/quic"}, - "QmWCmp2w4MVvuWSwfYJyzDBNJxmub5mccYsSEhmKMq1zfW", - "0s", - "0s", - "go-ipfs/0.7.0/", - ), - ) - - // create a POST request - data, err := json.Marshal(records1) - if err != nil { - log.Errorf("Error marshalling provider records for cid: %s", err) - } - req, err := http.NewRequest("POST", "http://localhost:8080/ProviderRecord", bytes.NewReader(data)) - if err != nil { - log.Errorf("Error creating POST request: %s", err) - } - // send the post request - _, err = http.DefaultClient.Do(req) - if err != nil { - log.Errorf("Error sending POST request: %s", err) - } - - // create a POST request - data, err = json.Marshal(records2) - if err != nil { - log.Errorf("Error marshalling provider records for cid: %s", err) - } - req, err = http.NewRequest("POST", "http://localhost:8080/ProviderRecord", bytes.NewReader(data)) - if err != nil { - log.Errorf("Error creating POST request: %s", err) - } - // send the post request - _, err = http.DefaultClient.Do(req) - if err != nil { - log.Errorf("Error sending POST request: %s", err) - } - - // create a POST request - data, err = json.Marshal(ProviderRecords{}) - if err != nil { - log.Errorf("Error marshalling provider records for cid: %s", err) - } - req, err = http.NewRequest("POST", "http://localhost:8080/ProviderRecord", bytes.NewReader(data)) - if err != nil { - log.Errorf("Error creating POST request: %s", err) - } - // send the post request - _, err = http.DefaultClient.Do(req) - if err != nil { - log.Errorf("Error sending POST request: %s", err) - } - -} - -func GetRequest(httpSource *HttpCidSource) error { - trackableCids, err := GetNewHttpCid(httpSource) - - if trackableCids == nil { - - return nil - } - - if err != nil { - fmt.Errorf("Error %s while getting new cid", err) - return err - } - tr := trackableCids[0] - cidStr := tr.CID.Hash().B58String() - - log.Debugf( - "New provide and CID received from channel. Cid:%s,Pid:%s,Mutliaddresses:%v,ProvideTime:%s,UserAgent:%s", - cidStr, tr.ID.String(), - tr.Addresses, tr.ProvideTime, tr.UserAgent, - ) - - //the starting values for the discoverer - cidIn, err := cid.Parse(cidStr) - - if err != nil { - log.Errorf("couldnt parse cid") - } - - cidInfo := models.NewCidInfo(cidIn, 0, 0, config.JsonFileSource, - config.HttpServerSource, tr.Creator) - fetchRes := models.NewCidFetchResults(cidIn, 0) - - // generate a new CidFetchResults - //TODO starting data for the discoverer - fetchRes.TotalHops = 0 - fetchRes.HopsToClosest = 0 - for _, trackableCid := range trackableCids { - - cidInfo.AddProvideTime(trackableCid.ProvideTime) - - //TODO discoverer starting ping res - pingRes := models.NewPRPingResults( - cidIn, - trackableCid.ID, - //the below are starting data for the discoverer - 0, - time.Time{}, - 0, - true, - true, - p2p.NoConnError, - ) - cidInfo.AddCreator(trackableCid.Creator) - fetchRes.AddPRPingResults(pingRes) - - prHolderInfo := models.NewPeerInfo( - trackableCid.ID, - trackableCid.Addresses, - trackableCid.UserAgent, - ) - - cidInfo.AddPRHolder(prHolderInfo) - } - cidInfo.AddPRFetchResults(fetchRes) - return nil -} - -func TestGetRequest(t *testing.T) { - - httpSource := NewHttpCidSource(8080, "localhost") - go httpSource.StartServer() - - PostRequestProviders() - err := GetRequest(httpSource) - if err != nil { - t.Errorf("%s", err) - } - err = GetRequest(httpSource) - if err != nil { - t.Errorf("%s", err) - } - err = GetRequest(httpSource) - if err != nil { - t.Errorf("%s", err) - } -} diff --git a/pkg/cid-source/json_cids_file.go b/pkg/cid-source/json_cids_file.go deleted file mode 100644 index 3c27145..0000000 --- a/pkg/cid-source/json_cids_file.go +++ /dev/null @@ -1,41 +0,0 @@ -package cid_source - -//A container for the encapsulated struct. -// -//File containts a json array of provider records. -//[{ProviderRecord1},{ProviderRecord2},{ProviderRecord3}] -type ProviderRecords struct { - EncapsulatedJSONProviderRecords []EncapsulatedJSONProviderRecord `json:"ProviderRecords"` -} - -//This struct will be used to create,read and store the encapsulated data necessary for reading the -//provider records. -type EncapsulatedJSONProviderRecord struct { - ID string `json:"PeerID"` - CID string `json:"ContentID"` - Creator string `json:"Creator"` - PublicationTime string `json:"PublicationTime"` - ProvideTime string `json:"ProvideTime"` - UserAgent string `json:"UserAgent"` - Addresses []string `json:"PeerMultiaddresses"` -} - -//Creates a new: -// EncapsulatedCidProvider struct { -// ID string -// CID string -// Address ma.Multiaddr -// } -func NewEncapsulatedJSONCidProvider(id string, cid string, addresses []string, creator string, publicationTime string, providetime string, useragent string) EncapsulatedJSONProviderRecord { - return EncapsulatedJSONProviderRecord{ - ID: id, - CID: cid, - Creator: creator, - PublicationTime: publicationTime, - ProvideTime: providetime, - UserAgent: useragent, - Addresses: addresses, - } -} - -const filename = "providers.json" diff --git a/pkg/cid-source/json_file_test.go b/pkg/cid-source/json_file_test.go deleted file mode 100644 index 4e48348..0000000 --- a/pkg/cid-source/json_file_test.go +++ /dev/null @@ -1,126 +0,0 @@ -package cid_source - -import ( - "fmt" - "reflect" - "sync" - "testing" -) - -//Tests if json file opens properly and the json contents are read -func TestOpenEncodedJSONFile(t *testing.T) { - filename := "examplejsonfiles\\providersen.json" - file, err := OpenEncodedJSONFile(filename) - if err != nil { - t.Errorf("error %s while trying to open simple json file", err) - return - } - - for i := 0; i < len(file.records.EncapsulatedJSONProviderRecords); i++ { - fmt.Println(file.records.EncapsulatedJSONProviderRecords[i]) - } - -} - -func TestOpenMultipleEncodedJSONFiles(t *testing.T) { - filenames := make([]string, 0) - filenames = append(filenames, "examplejsonfiles\\encodedQma2PDpcZX6jY88fqWeFvzw5HseGvumi7RJzQ73ie9JZ7wproviders.json") - filenames = append(filenames, "examplejsonfiles\\encodedQmc5bTVHfwdTyi2anYg5XvNwiBqZpbCsmDtVau1CmBYhmLproviders.json") - filenames = append(filenames, "examplejsonfiles\\encodedQmcjTjQWn7p1r9j9JWgkevkakqEoLXLbaJj2EzeEH4dEJyproviders.json") - filenames = append(filenames, "examplejsonfiles\\encodedQmcWB1SwVDkDuLhv5UGJhhN3wQ1vaCoKWfetvoqGMQyh7Qproviders.json") - file, err := OpenMultipleEncodedJSONFiles(filenames) - if err != nil { - t.Errorf("error %s while opening json files", err) - return - } - for _, rec := range file.records.EncapsulatedJSONProviderRecords { - fmt.Println(rec) - } -} - -func TestOpenSimpleJSONFile(t *testing.T) { - filename := "examplejsonfiles\\providers.json" - file, err := OpenSimpleJSONFile(filename) - if err != nil { - t.Errorf("error %s while trying to open simple json file", err) - return - } - for _, rec := range file.records.EncapsulatedJSONProviderRecords { - fmt.Println(rec) - } -} - -func TestOpenMultipleSimpleJSONFiles(t *testing.T) { - filenames := make([]string, 0) - filenames = append(filenames, "examplejsonfiles\\Qma2PDpcZX6jY88fqWeFvzw5HseGvumi7RJzQ73ie9JZ7wproviders.json") - filenames = append(filenames, "examplejsonfiles\\Qmc5bTVHfwdTyi2anYg5XvNwiBqZpbCsmDtVau1CmBYhmLproviders.json") - filenames = append(filenames, "examplejsonfiles\\QmcjTjQWn7p1r9j9JWgkevkakqEoLXLbaJj2EzeEH4dEJyproviders.json") - filenames = append(filenames, "examplejsonfiles\\QmcWB1SwVDkDuLhv5UGJhhN3wQ1vaCoKWfetvoqGMQyh7Qproviders.json") - file, err := OpenMultipleSimpleJSONFiles(filenames) - if err != nil { - t.Errorf("error %s while opening json files", err) - return - } - for _, rec := range file.records.EncapsulatedJSONProviderRecords { - fmt.Println(rec) - } -} - -func TestGetNewCidSimpleJSON(t *testing.T) { - file, err := OpenSimpleJSONFile("examplejsonfiles\\providers.json") - if err != nil { - return - } - for true { - tp, err := file.GetNewCid() - if reflect.DeepEqual(tp, TrackableCid{}) { - break - } - if err != nil { - t.Errorf("error %s while getting new cid", err) - return - } - - } -} - -func TestGetNewCidEncodedJSON(t *testing.T) { - file, err := OpenEncodedJSONFile("examplejsonfiles\\providersen.json") - if err != nil { - t.Errorf("error %s while opening file", err) - return - } - for true { - tp, err := file.GetNewCid() - if reflect.DeepEqual(tp, TrackableCid{}) { - break - } - if err != nil { - t.Errorf("error %s while getting new cid", err) - return - } - - } -} - -func TestJsonFileCIDSource_GetNewCidWithChannel(t *testing.T) { - TrackableCidChannel := make(chan *TrackableCid, 10) - var genWG sync.WaitGroup - go routineForReceivingFromChannel(TrackableCidChannel, &genWG) - file, err := OpenSimpleJSONFile("examplejsonfiles\\providers.json") - if err != nil { - t.Errorf("error %s while opening json file", err) - } - for true { - cid, err := file.GetNewCid() - if reflect.DeepEqual(cid, TrackableCid{}) { - break - } - if err != nil { - t.Errorf("error %s while generating random cid", err) - } - TrackableCidChannel <- &cid - } - close(TrackableCidChannel) - genWG.Wait() -} diff --git a/pkg/cid-source/json_model.go b/pkg/cid-source/json_model.go deleted file mode 100644 index ddd3e38..0000000 --- a/pkg/cid-source/json_model.go +++ /dev/null @@ -1,238 +0,0 @@ -package cid_source - -import ( - "encoding/json" - "io/ioutil" - "os" - "reflect" - "time" - - "github.com/cortze/ipfs-cid-hoarder/pkg/config" - - "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p/core/peer" - ma "github.com/multiformats/go-multiaddr" - "github.com/pkg/errors" - log "github.com/sirupsen/logrus" -) - -// JsonFileCIDSource reads CIDs and their content from a json file. -//When you want to access a new CID from the file the GetNewCid() function must be called. -//The Json contents are stored inside the struct and can be accessed with the index -type JsonFileCIDSource struct { - filename string - records ProviderRecords - iter func() EncapsulatedJSONProviderRecord -} - -func OpenMultipleSimpleJSONFiles(filenames []string) (*JsonFileCIDSource, error) { - var recordsIn ProviderRecords - for i := 0; i < len(filenames); i++ { - jsonFile, err := os.Open(filenames[i]) - if err != nil { - return nil, err - } - var records ProviderRecords - - byteValue, err := ioutil.ReadAll(jsonFile) - - if err != nil { - return nil, errors.Wrap(err, "while trying to read the json file") - } - - err = json.Unmarshal(byteValue, &records) - if err != nil { - return nil, errors.Wrap(err, "while trying to unmarshal json file contents") - } - recordsIn.EncapsulatedJSONProviderRecords = append(recordsIn.EncapsulatedJSONProviderRecords, records.EncapsulatedJSONProviderRecords...) - } - - newjsonsource := &JsonFileCIDSource{ - records: recordsIn, - } - newjsonsource.initializeIter() - return newjsonsource, nil -} - -func OpenMultipleEncodedJSONFiles(filenames []string) (*JsonFileCIDSource, error) { - var recordsIn ProviderRecords - for i := 0; i < len(filenames); i++ { - jsonFile, err := os.Open(filenames[i]) - if err != nil { - return nil, err - } - var records ProviderRecords - decoder := json.NewDecoder(jsonFile) - - for decoder.More() { - err := decoder.Decode(&records) - if err != nil { - return nil, errors.Wrap(err, " while decoding encoded json") - } - recordsIn.EncapsulatedJSONProviderRecords = append(recordsIn.EncapsulatedJSONProviderRecords, records.EncapsulatedJSONProviderRecords...) - } - } - - newjsonsource := &JsonFileCIDSource{ - records: recordsIn, - } - newjsonsource.initializeIter() - return newjsonsource, nil -} - -//Opens and reads the content of a json file that has used the encode method to store the data -func OpenEncodedJSONFile(filename string) (*JsonFileCIDSource, error) { - jsonFile, err := os.Open(filename) - defer func(jsonFile *os.File) { - err := jsonFile.Close() - if err != nil { - log.Errorf("failed to close json file: %s", err) - } - }(jsonFile) - if err != nil { - return nil, err - } - - var records ProviderRecords - decoder := json.NewDecoder(jsonFile) - - var filteredRecords ProviderRecords - for decoder.More() { - - err := decoder.Decode(&records) - if err != nil { - return nil, errors.Wrap(err, " while decoding encoded json") - } - filteredRecords.EncapsulatedJSONProviderRecords = append(filteredRecords.EncapsulatedJSONProviderRecords, records.EncapsulatedJSONProviderRecords...) - - } - - newIn := &JsonFileCIDSource{ - filename: filename, - records: filteredRecords, - } - newIn.initializeIter() - return newIn, nil -} - -func OpenSimpleJSONFile(filename string) (*JsonFileCIDSource, error) { - jsonFile, err := os.Open(filename) - defer func(jsonFile *os.File) { - err := jsonFile.Close() - if err != nil { - log.Errorf("failed to close file: %s", err) - } - }(jsonFile) - if err != nil { - return nil, err - } - - var records ProviderRecords - - byteValue, err := ioutil.ReadAll(jsonFile) - - if err != nil { - return nil, errors.Wrap(err, "while trying to read the json file") - } - - err = json.Unmarshal(byteValue, &records) - if err != nil { - return nil, errors.Wrap(err, "while trying to unmarshal json file contents") - } - - newIn := &JsonFileCIDSource{ - filename: filename, - records: records, - } - newIn.initializeIter() - return newIn, nil -} - -func (fileCIDSource *JsonFileCIDSource) initializeIter() { - fileCIDSource.iter = fileCIDSource.nextEncapsulatedJSONProviderRecord() -} - -func (fileCIDSource *JsonFileCIDSource) nextEncapsulatedJSONProviderRecord() func() EncapsulatedJSONProviderRecord { - i := -1 - return func() EncapsulatedJSONProviderRecord { - i++ - if i >= len(fileCIDSource.records.EncapsulatedJSONProviderRecords) { - return EncapsulatedJSONProviderRecord{} - } - return fileCIDSource.records.EncapsulatedJSONProviderRecords[i] - } -} - -//Returns the json records read from the file when creating the file_cid_source instance. -func (fileCIDSource *JsonFileCIDSource) GetNewCid() (TrackableCid, error) { - for true { - pr := fileCIDSource.iter() - if reflect.DeepEqual(pr, EncapsulatedJSONProviderRecord{}) { - break - } - - log.Debug("Read a new PR:") - - log.Debugf("It's cid is: %s", pr.CID) - newCid, err := cid.Parse(pr.CID) - if err != nil { - log.Errorf("could not convert string to cid %s", err) - continue - } - - log.Debugf("It's peer id is: %s", pr.ID) - newPid, err := peer.Decode(pr.ID) - if err != nil { - log.Errorf("could not convert string to pid %s", err) - continue - } - - log.Debugf("It's creator is: %s", pr.Creator) - newCreator, err := peer.Decode(pr.Creator) - if err != nil { - log.Errorf("could not convert string to creator pid %s", err) - continue - } - - log.Debugf("It's provide time is: %s", pr.ProvideTime) - newProvideTime, err := time.ParseDuration(pr.ProvideTime) - - if err != nil { - log.Errorf("Error while parsing provide time: %s", err) - continue - } - - log.Debugf("It's publication time is: %s", pr.PublicationTime) - newPublicationTime, err := time.Parse(time.RFC3339, pr.PublicationTime) - - if err != nil { - log.Errorf("Error while parsing publication time: %s", err) - continue - } - - log.Debugf("It's user agent is: %s", pr.UserAgent) - - multiaddresses := make([]ma.Multiaddr, 0) - for i := 0; i < len(pr.Addresses); i++ { - multiaddr, err := ma.NewMultiaddr(pr.Addresses[i]) - if err != nil { - //log.Errorf("could not convert string to multiaddress %s", err) - continue - } - multiaddresses = append(multiaddresses, multiaddr) - } - - log.Infof("generated new CID %s", newCid.Hash().B58String()) - - log.Infof("Read a new provider ID %s.The multiaddresses are %v. The creator is %s. The new CID is %s", string(newPid), multiaddresses, newCreator, newCid) - ProviderAndCidInstance := NewTrackableCid(newPid, newCid, newCreator, multiaddresses, newPublicationTime, newProvideTime, pr.UserAgent) - - return ProviderAndCidInstance, nil - } - return TrackableCid{}, errors.New("end of provider records") -} - -//TODO type returning a string is not a good idea -func (fileCIDSource *JsonFileCIDSource) Type() string { - return config.JsonFileSource -} diff --git a/pkg/cid-source/random_generator.go b/pkg/cid-source/random_generator.go deleted file mode 100644 index 755708d..0000000 --- a/pkg/cid-source/random_generator.go +++ /dev/null @@ -1,65 +0,0 @@ -package cid_source - -import ( - "math/rand" - "time" - - "github.com/cortze/ipfs-cid-hoarder/pkg/config" - - "github.com/ipfs/go-cid" - ma "github.com/multiformats/go-multiaddr" - mh "github.com/multiformats/go-multihash" - "github.com/pkg/errors" - log "github.com/sirupsen/logrus" -) - -type RandomCidGen struct { - contentSize int - //keeps track of how many cids have been generated by the random cid gen struct - cidsGenerated int - //limit of how many cids to generate - limit int -} - -func NewRandomCidGen(contentSize int, limit int) *RandomCidGen { - return &RandomCidGen{ - contentSize: contentSize, - cidsGenerated: 0, - limit: limit, - } -} - -func (g *RandomCidGen) Type() string { - return config.RandomContent -} - -// TODO: is it worth keeping the content? -// getRandomContent returns generates an array of random bytes with the given size and the composed CID of the content -func (g *RandomCidGen) GetNewCid() (TrackableCid, error) { - if g.cidsGenerated >= g.limit { - return TrackableCid{}, errors.New("done generating cids") - } - g.cidsGenerated++ - // generate random bytes - content := make([]byte, g.contentSize) - rand.Read(content) - - //TODO do we have to have different CID types? - // configure the type of CID that we want - pref := cid.Prefix{ - Version: 1, - Codec: cid.Raw, - MhType: mh.SHA2_256, - MhLength: -1, - } - - // get the CID of the content we just generated - contID, err := pref.Sum(content) - if err != nil { - return TrackableCid{}, errors.Wrap(err, "composing CID") - } - - log.Infof("generated new CID %s", contID.Hash().B58String()) - ProvidersAndCidInstance := NewTrackableCid("", contID, "", make([]ma.Multiaddr, 0), time.Now(), 0, "") - return ProvidersAndCidInstance, nil -} diff --git a/pkg/cid-source/random_generator_test.go b/pkg/cid-source/random_generator_test.go deleted file mode 100644 index 6c8d9e5..0000000 --- a/pkg/cid-source/random_generator_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package cid_source - -import ( - "fmt" - "reflect" - "sync" - "testing" -) - -func TestRandomCidGen_GetNewCid(t *testing.T) { - randomgen := NewRandomCidGen(6, 8) - i := 0 - for { - cid, err := randomgen.GetNewCid() - if reflect.DeepEqual(cid, TrackableCid{}) { - break - } - if err != nil { - t.Errorf("error %s while generating random cid", err) - } - } - if i > randomgen.limit { - t.Errorf("i bigger than limit") - } -} - -func TestRandomCidGen_GetNewCidWithChannel(t *testing.T) { - TrackableCidChannel := make(chan *TrackableCid, 10) - var genWG sync.WaitGroup - go routineForReceivingFromChannel(TrackableCidChannel, &genWG) - randomgen := NewRandomCidGen(6, 8) - i := 0 - for { - cid, err := randomgen.GetNewCid() - if reflect.DeepEqual(cid, TrackableCid{}) { - break - } - if err != nil { - t.Errorf("error %s while generating random cid", err) - } - TrackableCidChannel <- &cid - } - close(TrackableCidChannel) - genWG.Wait() - if i > randomgen.limit { - t.Errorf("i bigger than limit") - } -} - -func routineForReceivingFromChannel(TrackableCidChannel <-chan *TrackableCid, genWG *sync.WaitGroup) { - genWG.Add(1) - defer genWG.Done() - for elem := range TrackableCidChannel { - fmt.Print("received new element: ") - fmt.Println(elem) - } -} diff --git a/pkg/cid-source/source_interface.go b/pkg/cid-source/source_interface.go deleted file mode 100644 index f27b240..0000000 --- a/pkg/cid-source/source_interface.go +++ /dev/null @@ -1,47 +0,0 @@ -package cid_source - -import ( - "time" - - cid "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p/core/peer" - ma "github.com/multiformats/go-multiaddr" -) - -var DefCIDContLen = 1024 // 1KB - -type CidSource interface { - GetNewCid() (TrackableCid, error) - Type() string -} - -const layoutPublicationTime = "Jan 2, 2006 at 3:04pm (MST)" - -//Encapsulates the return type of the GetNewCid() -type TrackableCid struct { - ID peer.ID `json:"PeerID"` - CID cid.Cid `json:"ContentID"` - Creator peer.ID `json:"Creator"` - PublicationTime time.Time `json:"PublicationTime"` - ProvideTime time.Duration `json:"ProvideTime"` - UserAgent string `json:"UserAgent"` - Content []byte `json:"Content"` - Addresses []ma.Multiaddr `json:"PeerMultiaddresses"` -} - -func NewTrackableCid(ID peer.ID, CID cid.Cid, creator peer.ID, Addresses []ma.Multiaddr, publicationTime time.Time, providetime time.Duration, useragent string) TrackableCid { - return TrackableCid{ - ID: ID, - CID: CID, - Creator: creator, - ProvideTime: providetime, - PublicationTime: publicationTime, - UserAgent: useragent, - Content: make([]byte, 0), - Addresses: Addresses, - } -} - -func (t *TrackableCid) IsEmpty() bool { - return t == (&TrackableCid{}) -} diff --git a/pkg/config/config.go b/pkg/config/config.go index b0c697a..150405e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,13 +1,6 @@ package config import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "strconv" - - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" ) @@ -16,15 +9,6 @@ var log = logrus.WithField( "module", "config", ) -const ( - RandomSource = "random-content-gen" - TextFileSource = "text-file" - JsonFileSource = "json-file" - HttpServerSource = "http-server" - BitswapSource = "bitswap" - RandomContent = "random-content-gen" -) - // Harcoded variables for the tool's profiling var PprofIp = "127.0.0.1" var PprofPort = "9020" @@ -34,192 +18,92 @@ var CliIp string = "0.0.0.0" var UserAgent string = "BSC-Cid-Hoarder" // Blacklisting UserAgents -var DefaultBlacklistUserAgent = "hydra-booster" +var DefaultBlacklistUserAgent = "" // default configuration var DefaultConfig = Config{ - Port: "9010", - LogLevel: "info", - Database: "./data/ipfs-hoarder-db.db", - ConfigJsonFile: "config.json", - CidSource: "random-content-gen", - AlreadyPublishedCIDs: false, - CidFile: "cids/cid-list.json", - //TODO introduce type of CidFile - CidContentSize: 1000, // 1MB in KBs - CidNumber: 10, - Workers: 250, - ReqInterval: "30m", - StudyDuration: "48h", - K: 20, // K-bucket parameter - HydraFilter: false, + Port: "9010", + LogLevel: "info", + Database: "postgres://user:password@ip:port/db", + CidContentSize: 1024, // 1MB in KBs + CidNumber: 10, + Workers: 250, + SinglePublisher: true, + ReqInterval: "30m", + CidPingTime: "48h", + K: 20, + BlacklistedUA: DefaultBlacklistUserAgent, } // Config compiles all the set of flags that can be read by the user while launching the cli type Config struct { - Port string `json:"port"` - LogLevel string `json:"log-level"` - Database string `json:"database-endpoint"` - CidSource string `json:"cid-source"` - CidFile string `json:"cid-file"` - ConfigJsonFile string `json:"config-json-file"` - CidContentSize int `json:"cid-content-size"` - CidNumber int `json:"cid-number"` // in KBs - Workers int `json:"workers"` - AlreadyPublishedCIDs bool `json:"already-published-cids"` //already published CIDs skips the publishing phase of the hoarder. - ReqInterval string `json:"req-interval"` - StudyDuration string `json:"study-duration"` - K int `json:"k"` - HydraFilter bool `json:"hydra-filter"` + Port string `json:"port"` + LogLevel string `json:"log-level"` + Database string `json:"database-endpoint"` + CidContentSize int `json:"cid-content-size"` + CidNumber int `json:"cid-number"` + Workers int `json:"workers"` + SinglePublisher bool `json:"single-publisher"` + ReqInterval string `json:"req-interval"` + CidPingTime string `json:"cid-ping-time"` + K int `json:"k"` + BlacklistedUA string `json:"blacklisted-ua"` } // Init takes the command line argumenst from the urfave/cli context and composes the configuration func NewConfig(ctx *cli.Context) (*Config, error) { c := &Config{} - // TODO: work on reading config file from custom path/file (reproducibility) - // export the current conf into a file? - if ctx.IsSet("name-of-config-json-file") { - c.ImportConfigFromJsonFile() - } else { - fmt.Println("applying arguments") - c.apply(ctx) - } - + c.Apply(ctx) return c, nil } -//Exports the config struct into a json file -func (c *Config) ExportConfigIntoJsonFile() error { - content, err := c.JsonConfig() - if err != nil { - return err - } - - err = ioutil.WriteFile("config.json", content, 0644) - if err != nil { - return errors.Wrap(err, " while trying to write struct to file") - } - - return nil -} - -//Imports config struct from json file -func (c *Config) ImportConfigFromJsonFile() error { - content, err := ioutil.ReadFile("config.json") - if err != nil { - return errors.Wrap(err, " while trying to import config from json file") - } - err = json.Unmarshal(content, &c) - if err != nil { - return errors.Wrap(err, " while trying to unmarshal json config") - } - return nil -} - -//Returns a json representation of the config struct -func (c *Config) JsonConfig() ([]byte, error) { - out, err := json.Marshal(c) - - if err != nil { - return nil, errors.Wrap(err, "while trying to format config struct into json") - } - - return out, nil -} - // apply parses the arguments readed from cli.Context -func (c *Config) apply(ctx *cli.Context) { +func (c *Config) Apply(ctx *cli.Context) { // Check if the flags have been set if ctx.Command.Name == "run" { if ctx.IsSet("port") { c.Port = ctx.String("port") - } else { - c.Port = DefaultConfig.Port } + if ctx.IsSet("log-level") { c.LogLevel = ctx.String("log-level") - } else { - c.LogLevel = DefaultConfig.LogLevel } - //field database endpoint is required to be set by the user + if ctx.IsSet("database-endpoint") { c.Database = ctx.String("database-endpoint") } - if ctx.IsSet("hydra-filter") { - c.HydraFilter = ctx.Bool("hydra-filter") - } else { - c.HydraFilter = DefaultConfig.HydraFilter + if ctx.IsSet("cid-content-size") { + c.CidContentSize = ctx.Int("cid-content-size") + } + + if ctx.IsSet("cid-number") { + c.CidNumber = ctx.Int("cid-number") + } + + if ctx.IsSet("workers") { + c.Workers = ctx.Int("workers") + } + + if ctx.IsSet("single-publisher") { + c.SinglePublisher = ctx.Bool("single-publisher") } - // Time delay between the each of the PRHolder pings if ctx.IsSet("req-interval") { c.ReqInterval = ctx.String("req-interval") - } else { - c.ReqInterval = DefaultConfig.ReqInterval } - if ctx.IsSet("already-published-cids") { - c.AlreadyPublishedCIDs, _ = strconv.ParseBool(ctx.String("already-published-cids")) - } else { - c.AlreadyPublishedCIDs = DefaultConfig.AlreadyPublishedCIDs - } - // Set the study duration time - if ctx.IsSet("study-duration") { - c.StudyDuration = ctx.String("study-duration") - } else { - c.StudyDuration = DefaultConfig.StudyDuration + if ctx.IsSet("cid-ping-time") { + c.CidPingTime = ctx.String("cid-ping-time") } - // check the number of random CIDs that we want to generate + if ctx.IsSet("k") { c.K = ctx.Int("k") - } else { - c.K = DefaultConfig.K - } - if ctx.IsSet("cid-source") { - c.CidSource = ctx.String("cid-source") - } else { - c.CidSource = DefaultConfig.CidSource } - // batch of CIDs for the entire study - if ctx.IsSet("workers") { - c.Workers = ctx.Int("workers") - } else { - c.Workers = DefaultConfig.Workers - } - switch c.CidSource { - case RandomSource: - // check the size of the random content to generate - fmt.Println("random source for cids found") - if ctx.IsSet("cid-content-size") { - c.CidContentSize = ctx.Int("cid-content-size") - } else { - c.CidContentSize = DefaultConfig.CidContentSize - } - // check the number of random CIDs that we want to generate - if ctx.IsSet("cid-number") { - c.CidNumber = ctx.Int("cid-number") - } else { - c.CidNumber = DefaultConfig.CidNumber - } - - //TODO support different types of cid files - case TextFileSource, JsonFileSource: - fmt.Println("text file source or json file source was found") - if ctx.IsSet("cid-file") { - c.CidFile = ctx.String("cid-file") - } else { - c.CidFile = DefaultConfig.CidFile - } - case HttpServerSource: - fmt.Println("will start http server") - case BitswapSource: - fmt.Println("bitswap content discovery not supported yet.") - os.Exit(0) - default: - log.Info("no cid source was given.") - os.Exit(0) + + if ctx.IsSet("blacklisted-ua") { + c.BlacklistedUA = ctx.String("blacklisted-ua") } } } diff --git a/pkg/crawler/crawler.go b/pkg/crawler/crawler.go index 7b615d5..1bad956 100644 --- a/pkg/crawler/crawler.go +++ b/pkg/crawler/crawler.go @@ -29,7 +29,7 @@ import ( type Crawler struct { ctx context.Context - crawler *crawler.Crawler + crawler *crawler.DefaultCrawler h host.Host results *CrawlResults blacklistUA string @@ -55,11 +55,11 @@ func New(ctx context.Context, privKey crypto.PrivKey, ip, port, blacklistUA stri } // create the official crawler - c, err := crawler.New( + c, err := crawler.NewDefaultCrawler( h, - crawler.WithParallelism(1000), - crawler.WithMsgTimeout(40*time.Second), - crawler.WithConnectTimeout(40*time.Second), + crawler.WithParallelism(800), + crawler.WithMsgTimeout(50*time.Second), + crawler.WithConnectTimeout(60*time.Second), ) if err != nil { return nil, err @@ -111,7 +111,7 @@ func (c *Crawler) run() *CrawlResults { handleSucc := func(p peer.ID, rtPeers []*peer.AddrInfo) { logEntry.Debugf("peer %s successfully connected", p.String()) - // add the peer `P` to the list of active peers + // add the peer `P` to the list of Defaultactive peers c.results.addPeer(p, active) // add each of the `rtPeers` to the discovered peers diff --git a/pkg/db/batch.go b/pkg/db/batch.go new file mode 100644 index 0000000..6de00e8 --- /dev/null +++ b/pkg/db/batch.go @@ -0,0 +1,129 @@ +package db + +import ( + "context" + "fmt" + "time" + + pgx "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" +) + +var ( + QueryTimeout = 5 * time.Minute + MaxRetries = 1 + + ErrorNoConnFree = "no connection adquirable" + noQueryError string = "no error" + noQueryResult string = "no result" +) + +type QueryBatch struct { + ctx context.Context + pgxPool *pgxpool.Pool + batch *pgx.Batch + size int + persistables []persistable +} + +func NewQueryBatch(ctx context.Context, pgxPool *pgxpool.Pool, batchSize int) *QueryBatch { + return &QueryBatch{ + ctx: ctx, + pgxPool: pgxPool, + batch: &pgx.Batch{}, + size: batchSize, + persistables: make([]persistable, 0), + } +} + +func (q *QueryBatch) IsReadyToPersist() bool { + return q.batch.Len() >= q.size +} + +func (q *QueryBatch) AddQuery(persis persistable) { + q.batch.Queue(persis.query, persis.values...) + q.persistables = append(q.persistables, persis) +} + +func (q *QueryBatch) Len() int { + return q.batch.Len() +} + +func (q *QueryBatch) PersistBatch() error { + logEntry := log.WithFields(log.Fields{ + "mod": "batch-persister", + }) + logEntry.Debugf("persisting batch of queries with len(%d)", q.Len()) + var err error +persistRetryLoop: + for i := 0; i < MaxRetries; i++ { + t := time.Now() + err = q.persistBatch() + duration := time.Since(t) + switch err { + case nil: + logEntry.Tracef("persisted %d queries in %s seconds", q.Len(), duration) + break persistRetryLoop + default: + logEntry.Tracef("attempt numb %d failed %s", i+1, err.Error()) + } + } + q.cleanBatch() + return errors.Wrap(err, "unable to persist batch query") +} + +func (q *QueryBatch) persistBatch() error { + logEntry := log.WithFields(log.Fields{ + "mod": "batch-persister", + }) + + if q.Len() == 0 { + logEntry.Trace("skipping batch-query, no queries to persist") + return nil + } + + ctx, cancel := context.WithTimeout(q.ctx, QueryTimeout) + defer cancel() + + + batchResults := q.pgxPool.SendBatch(ctx, q.batch) + defer batchResults.Close() + + var qerr error + var rows pgx.Rows + nextQuery := true + cnt := 0 + for nextQuery { + rows, qerr = batchResults.Query() + nextQuery = rows.Next() // it closes all the rows if all the rows are readed + cnt++ + } + + // check if there was any error + if qerr != nil { + /* + log.WithFields(log.Fields{ + "error": qerr.Error(), + "query": q.persistables[cnt-1].query, + "values": q.persistables[cnt-1].values, + }).Errorf("unable to persist query [cnt-1]") + log.WithFields(log.Fields{ + "error": qerr.Error(), + "query": q.persistables[cnt].query, + "values": q.persistables[cnt].values, + }).Errorf("unable to persist query [cnt]") + */ + fmt.Println("idx", cnt+1, "", qerr.Error()) + fmt.Println(q.persistables[cnt+1].query) + fmt.Println(q.persistables[cnt+1].values) + return errors.Wrap(qerr, "error persisting batch") + } + return nil +} + +func (q *QueryBatch) cleanBatch() { + q.batch = &pgx.Batch{} + q.persistables = make([]persistable, 0) +} diff --git a/pkg/db/cid.go b/pkg/db/cid.go index 346c3c1..937f354 100644 --- a/pkg/db/cid.go +++ b/pkg/db/cid.go @@ -13,16 +13,21 @@ func (db *DBClient) CreateCidInfoTable() error { _, err := db.psqlPool.Exec(db.ctx, ` CREATE TABLE IF NOT EXISTS cid_info( - id SERIAL, - cid_hash TEXT NOT NULL PRIMARY KEY, - gen_time FLOAT NOT NULL, - provide_time FLOAT NOT NULL, - req_interval INT NOT NULL, - k INT NOT NULL, - content_type TEXT NOT NULL, - source TEXT NOT NULL, - creator TEXT NOT NULL - );`) + id SERIAL, + cid_hash TEXT NOT NULL PRIMARY KEY, + pub_time TIMESTAMP NOT NULL, + provide_time_ms FLOAT NOT NULL, + req_interval_m INT NOT NULL, + k INT NOT NULL, + prov_op TEXT NOT NULL, + creator TEXT NOT NULL + ); + + CREATE INDEX IF NOT EXISTS idx_cid_info_cid_hash ON cid_info (cid_hash); + CREATE INDEX IF NOT EXISTS idx_cid_info_pub_time ON cid_info (pub_time); + CREATE INDEX IF NOT EXISTS idx_cid_info_provide_time_ms ON cid_info (provide_time_ms); + CREATE INDEX IF NOT EXISTS idx_cid_info_prov_op ON cid_info (prov_op); + `) if err != nil { return errors.Wrap(err, "error preparing statement for CidInfo table generation") } @@ -30,53 +35,30 @@ func (db *DBClient) CreateCidInfoTable() error { return nil } -func (db *DBClient) addCidInfo(cidInfo *models.CidInfo) (err error) { - - log.WithFields(log.Fields{ - "cid": cidInfo.CID.Hash().B58String(), - }).Trace("adding new cid info to DB") - - // insert the cidInfo - _, err = db.psqlPool.Exec(db.ctx, `INSERT INTO cid_info ( +func (db *DBClient) addCidInfo(cidInfo *models.CidInfo) persistable { + persis := newPersistable() + persis.query = `INSERT INTO cid_info( cid_hash, - gen_time, - provide_time, - req_interval, + pub_time, + provide_time_ms, + req_interval_m, k, - content_type, - source, + prov_op, creator) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, - cidInfo.CID.Hash().B58String(), - cidInfo.GenTime.Unix(), - cidInfo.ProvideTime.Milliseconds(), - int(cidInfo.ReqInterval.Minutes()), - cidInfo.K, - cidInfo.ContentType, - cidInfo.Source, - cidInfo.Creator.String(), - ) - if err != nil { - return err - } + VALUES($1, $2, $3, $4, $5, $6, $7)` - // add the peer info of the PR holders - err = db.addNewPeerInfoSet(cidInfo.PRHolders) - if err != nil { - return errors.Wrap(err, "insering peer info") - } + persis.values = append(persis.values, cidInfo.CID.Hash().B58String()) + persis.values = append(persis.values, cidInfo.PublishTime) + persis.values = append(persis.values, cidInfo.ProvideTime.Milliseconds()) + persis.values = append(persis.values, int(cidInfo.ReqInterval.Minutes())) + persis.values = append(persis.values, cidInfo.K) + persis.values = append(persis.values, cidInfo.ProvideOp) + persis.values = append(persis.values, cidInfo.Creator.String()) - // add the PR holders to the table - err = db.addPRHoldersSet(cidInfo.CID, cidInfo.PRHolders) - if err != nil { - return errors.Wrap(err, "inserting pr_holders") - } - - return nil + return persis } func (db *DBClient) GetIdOfCid(cidStr string) (id int, err error) { - row := db.psqlPool.QueryRow(db.ctx, `SELECT id FROM cid_info WHERE cid_hash=$1;`, cidStr) err = row.Scan(&id) if err != nil { diff --git a/pkg/db/client.go b/pkg/db/client.go index bb4556c..9304cb6 100644 --- a/pkg/db/client.go +++ b/pkg/db/client.go @@ -2,50 +2,55 @@ package db import ( "context" - "os" "sync" + "time" "github.com/cortze/ipfs-cid-hoarder/pkg/models" - "github.com/jackc/pgx/v4/pgxpool" + "github.com/jackc/pgx/v5/pgxpool" "github.com/pkg/errors" log "github.com/sirupsen/logrus" ) -const bufferSize = 20000 -const maxPersisters = 1 +const ( + batchSize = 1024 + batchFlushTime = 1 * time.Second + maxPersisters = 1 +) type DBClient struct { ctx context.Context m sync.RWMutex - connectionUrl string // the url might not be necessary (better to remove it?¿) psqlPool *pgxpool.Pool + persistC chan persistable + closeCs []chan struct{} +} - // Req Channels - cidInfoC chan *models.CidInfo - peerInfoC chan *models.PeerInfo - fetchResultC chan *models.CidFetchResults - pingResultsC chan []*models.PRPingResults - - persistC chan interface{} +// persistable is the common structure that will be held to the db workers over the +// persistC channel and added to a batch later on +type persistable struct { + query string + values []interface{} +} - doneC chan struct{} +func newPersistable () persistable { + return persistable{ + query: "", + values: make([]interface{}, 0), + } } -func RemoveOldDBIfExists(oldDBPath string) { - os.Remove(oldDBPath) +func (persis *persistable) isZero() bool { + return persis.query == "" } // NewDBClient creates and returns a db.cli to persist data into a PostgreSQL database func NewDBClient(ctx context.Context, url string) (*DBClient, error) { - logEntry := log.WithFields(log.Fields{ - "db": url, - }, - ) - logEntry.Debug("initialising the db") + logEntry := log.WithFields(log.Fields{"db": url}) + logEntry.Trace("initialising the db") - psqlPool, err := pgxpool.Connect(ctx, url) + psqlPool, err := pgxpool.New(ctx, url) if err != nil { return nil, errors.Wrap(err, "unable to initialise Posgres DB at "+url) } @@ -57,21 +62,16 @@ func NewDBClient(ctx context.Context, url string) (*DBClient, error) { dbCli := &DBClient{ ctx: ctx, - connectionUrl: url, psqlPool: psqlPool, - cidInfoC: make(chan *models.CidInfo, bufferSize), - peerInfoC: make(chan *models.PeerInfo, bufferSize), - fetchResultC: make(chan *models.CidFetchResults, bufferSize), - pingResultsC: make(chan []*models.PRPingResults, bufferSize), - persistC: make(chan interface{}, bufferSize), - doneC: make(chan struct{}), + persistC: make(chan persistable, maxPersisters), + closeCs: make([]chan struct{}, 0, maxPersisters), } err = dbCli.initTables() if err != nil { return nil, errors.Wrap(err, "initialising the tables") } - + go dbCli.runPersisters() logEntry.Infof("DB initialised") @@ -81,128 +81,152 @@ func NewDBClient(ctx context.Context, url string) (*DBClient, error) { // runPersisters creates a pool of DB persistors // TODO: originally created for cuncurrency issues with SQLite3, might not be needed now with PostgreSQL func (db *DBClient) runPersisters() { - log.Info("Initializing DB persisters") - + log.Debug("Initializing DB persisters") + var persisterWG sync.WaitGroup - for persister := 1; persister <= maxPersisters; persister++ { - persisterWG.Add(4) - go func(wg *sync.WaitGroup, persisterID int) { - defer wg.Done() - logEntry := log.WithField("persister", persisterID) - for { - // give priority to the dbDone channel if it closed - select { - case <-db.doneC: - logEntry.Info("finish detected, closing persister") - return - default: - } - - select { - case p := <-db.persistC: - switch p.(type) { - case (*models.CidInfo): - cidInfo := p.(*models.CidInfo) - logEntry.Debugf("persisting CID %s into DB", cidInfo.CID.Hash().B58String()) - err := db.addCidInfo(cidInfo) - if err != nil { - logEntry.Error("error persisting CidInfo - " + err.Error()) - } - case (*models.PeerInfo): - dbPeer := p.(*models.PeerInfo) - logEntry.Debugf("persisting peer %s into DB", dbPeer.ID.String()) - err := db.addPeerInfo(dbPeer) - if err != nil { - logEntry.Error("error persisting PeerInfo - " + err.Error()) - } - case (*models.CidFetchResults): - fetchRes := p.(*models.CidFetchResults) - logEntry.Debugf("persisting fetch info into DB") - err := db.addFetchResults(fetchRes) - if err != nil { - logEntry.Error("error persisting FetchResults - " + err.Error()) - } - } - case <-db.ctx.Done(): - logEntry.Info("shutdown detected, closing persister") - return - } - } - }(&persisterWG, persister) - + for persisterID := 1; persisterID <= maxPersisters; persisterID++ { + // create a new closeC channel + closeC := make(chan struct{}, 1) + db.closeCs = append(db.closeCs, closeC) + // launch one persiter more + persisterWG.Add(1) + go db.persisterWorker(closeC, &persisterWG, persisterID) } persisterWG.Wait() - log.Info("Done persisting study") - - close(db.cidInfoC) - close(db.peerInfoC) - close(db.fetchResultC) - close(db.pingResultsC) close(db.persistC) - close(db.doneC) + for _, closeC := range db.closeCs { + close(closeC) + } + db.psqlPool.Close() + log.Info("DB client successfully finished") } func (db *DBClient) AddCidInfo(c *models.CidInfo) { - db.persistC <- c + log.WithFields(log.Fields{ + "event_type": "cid_info", + "cid": c.CID.String(), + }).Trace("new event to perstist") + + db.persistC <- db.addCidInfo(c) + db.persistC <- db.addNewPeerInfoSet(c.PRHolders) + db.persistC <- db.addPRHoldersSet(c.CID, c.PRHolders) } func (db *DBClient) AddPeerInfo(p *models.PeerInfo) { - db.persistC <- p + log.WithFields(log.Fields{ + "event_type": "peer_info", + "peerID": p.ID.String(), + }).Trace("new event to perstist") + + db.persistC <- db.addPeerInfo(p) } func (db *DBClient) AddFetchResult(f *models.CidFetchResults) { - db.persistC <- f + log.WithFields(log.Fields{ + "event_type": "fetch_results", + "cid": f.Cid.Hash().B58String(), + }).Trace("new event to perstist") + + db.persistC <- db.addFetchResults(f) + db.persistC <- db.addPingResultsSet(f.PRPingResults) + db.persistC <- db.addClosestPeerSet(&models.ClosestPeers{ + Cid: f.Cid, + PingRound: f.Round, + Peers: f.ClosestPeers, + }) } -// Close closes all the connections opened with the DB -// TODO: still not completed -func (db *DBClient) Close() { - log.Info("closing DB for the CID Hoarder") - // send message on doneC - db.doneC <- struct{}{} - // db.psqlPool.Close() +// persisterWorker is the main logic of each of the main DB client persisters +// it batches a range of queries untill the flush time is achieved or the number of queries +// is reached +func (db *DBClient) persisterWorker (closeC chan struct {}, wg *sync.WaitGroup, persisterID int) { + defer wg.Done() + logEntry := log.WithField("persister", persisterID) + + // control variables for the persister + shutdown := false + batcher := NewQueryBatch(db.ctx, db.psqlPool, batchSize) + flushTicker := time.NewTicker(batchFlushTime) + + for { + // check if the routine needs to end + if shutdown && len(db.persistC) == 0 { + logEntry.Info("persister finished, C ya!") + return + } + // select over the different events/interruptions that might occur + select { + case persis := <-db.persistC: + if persis.isZero() { + continue + } + batcher.AddQuery(persis) + if batcher.IsReadyToPersist() { + logEntry.Trace("batcher full, flishing it") + batcher.PersistBatch() + } + + case <- flushTicker.C: + logEntry.Trace("flush interval reached, persisting batch") + batcher.PersistBatch() + + case <-closeC: + logEntry.Info("controled closure detected, closing persister") + shutdown = true + continue + + case <-db.ctx.Done(): + logEntry.Info("sudden shutdown detected, closing persister") + return + } + } } + // initTables creates all the necesary tables in the given DB func (db *DBClient) initTables() error { var err error - // cid_info table err = db.CreateCidInfoTable() if err != nil { return err } - // peer_info table err = db.CreatePeerInfoTable() if err != nil { return err } - // pr_holders err = db.CreatePRHoldersTable() if err != nil { return err } - // fetch_results table err = db.CreateFetchResultsTable() if err != nil { return err } - // ping_results table err = db.CreatePingResultsTable() if err != nil { return err } - // k_closest_peers err = db.CreateClosestPeersTable() if err != nil { return err } - return err } + + +// Close makes sure that all the persisters are notified of the closure +func (db *DBClient) Close() { + log.Info("orchestrating peacefull DB closing") + for _, closeC := range db.closeCs { + closeC <- struct{}{} + } +} + + diff --git a/pkg/db/closest_peers.go b/pkg/db/closest_peers.go index 2c535d9..6cdedba 100644 --- a/pkg/db/closest_peers.go +++ b/pkg/db/closest_peers.go @@ -19,7 +19,12 @@ func (db *DBClient) CreateClosestPeersTable() error { peer_id TEXT NOT NULL, FOREIGN KEY(cid_hash) REFERENCES cid_info(cid_hash) - );`) + ); + + CREATE INDEX IF NOT EXISTS idx_k_closest_peers_cid_hash ON k_closest_peers (cid_hash); + CREATE INDEX IF NOT EXISTS idx_k_closest_peers_ping_round ON k_closest_peers (ping_round); + CREATE INDEX IF NOT EXISTS idx_k_closest_peers_peer_id ON k_closest_peers (peer_id); + `) if err != nil { return errors.Wrap(err, "error preparing statement for k_closest_peers table generation") } @@ -27,42 +32,29 @@ func (db *DBClient) CreateClosestPeersTable() error { return nil } -func (db *DBClient) addClosestPeerSet(closestPeers *models.ClosestPeers) (err error) { - // first round has not closest peers - if closestPeers.PingRound == 0 { - return nil - } +func (db *DBClient) addClosestPeerSet(closestPeers *models.ClosestPeers) persistable { + persis := newPersistable() - if len(closestPeers.Peers) <= 0 { - return errors.New("unable to insert closest peers - no closest peers set given") + if closestPeers.PingRound == 0 || len(closestPeers.Peers) <= 0 { + return persis } - cStr := closestPeers.Cid.Hash().B58String() - log.WithFields(log.Fields{ - "cid": cStr, - }).Debug("adding set of cid closest_peers to DB") - - // insert each of the Peers holding the PR - for _, p := range closestPeers.Peers { - _, err = db.psqlPool.Exec(db.ctx, ` + // compose the multiquery + persis.query = multiValueComposer(` INSERT INTO k_closest_peers ( cid_hash, ping_round, - peer_id) - VALUES ($1, $2, $3)`, - cStr, - closestPeers.PingRound, - p.String(), - ) - if err != nil { - return errors.Wrap(err, "unable to insert closest_peers at DB ") - } + peer_id)`, + "", + len(closestPeers.Peers), // number of values + 3) // number of items on value - log.WithFields(log.Fields{ - "cid": cStr, - "round": closestPeers.PingRound, - "closePeers": len(closestPeers.Peers), - }).Trace("tx successfully saved closest_peers into DB") + // insert each of the Peers as values + for _, p := range closestPeers.Peers { + persis.values = append(persis.values, closestPeers.Cid.Hash().B58String()) + persis.values = append(persis.values, closestPeers.PingRound) + persis.values = append(persis.values, p.String()) } - return err + + return persis } diff --git a/pkg/db/fetch_results.go b/pkg/db/fetch_results.go index 6184847..e9acbba 100644 --- a/pkg/db/fetch_results.go +++ b/pkg/db/fetch_results.go @@ -16,10 +16,12 @@ func (db *DBClient) CreateFetchResultsTable() error { id SERIAL PRIMARY KEY, cid_hash TEXT NOT NULL, ping_round INT NOT NULL, - fetch_time FLOAT NOT NULL, - fetch_duration FLOAT NOT NULL, + fetch_time TIMESTAMP NOT NULL, + fetch_time_since_publication_m FLOAT NOT NULL, + fetch_duration_ms FLOAT NOT NULL, total_hops INT NOT NULL, - hops_for_closest INT NOT NULL, + hops_tree_depth INT NOT NULL, + min_hops_for_closest INT NOT NULL, holders_ping_duration FLOAT NOT NULL, find_prov_duration FLOAT NOT NULL, get_closest_peer_duration FLOAT NOT NULL, @@ -27,68 +29,65 @@ func (db *DBClient) CreateFetchResultsTable() error { success_att INT NOT NULL, fail_att INT NOT NULL, is_retrievable BOOL NOT NULL, + pr_with_maddrs BOOL NOT NULL, UNIQUE(cid_hash, ping_round), FOREIGN KEY(cid_hash) REFERENCES cid_info(cid_hash) - );`) + ); + + CREATE INDEX IF NOT EXISTS idx_fetch_results_cid_hash ON fetch_results (cid_hash); + CREATE INDEX IF NOT EXISTS idx_fetch_results_ping_round ON fetch_results (ping_round); + CREATE INDEX IF NOT EXISTS idx_fetch_results_fetch_time ON fetch_results (fetch_time); + CREATE INDEX IF NOT EXISTS idx_fetch_results_fetch_time_since_publication_m ON fetch_results (fetch_time_since_publication_m); + `) if err != nil { return errors.Wrap(err, "error preparing statement for fetch_results table generation") } return nil } -func (db *DBClient) addFetchResults(fetchRes *models.CidFetchResults) (err error) { - - log.WithFields(log.Fields{ - "cid": fetchRes.Cid.Hash().B58String(), - }).Trace("adding fetch_results to DB") - - tot, suc, fail := fetchRes.GetSummary() +func (db *DBClient) addFetchResults(fetchRes *models.CidFetchResults) persistable { + persis := newPersistable() - _, err = db.psqlPool.Exec(db.ctx, ` + persis.query = ` INSERT INTO fetch_results ( cid_hash, ping_round, fetch_time, - fetch_duration, - total_hops, - hops_for_closest, + fetch_time_since_publication_m, + fetch_duration_ms, + total_hops, + hops_tree_depth, + min_hops_for_closest, holders_ping_duration, find_prov_duration, get_closest_peer_duration, k, success_att, fail_att, - is_retrievable) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, + is_retrievable, + pr_with_maddrs) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)` + + tot, suc, fail := fetchRes.GetSummary() + + persis.values = append(persis.values, fetchRes.Cid.Hash().B58String(), - fetchRes.Round, - fetchRes.StartTime.Unix(), - fetchRes.FinishTime.Sub(fetchRes.StartTime).Milliseconds(), + fetchRes.Round, + fetchRes.StartTime, + fetchRes.GetFetchTimeSincePublication().Minutes(), + fetchRes.FinishTime.Sub(fetchRes.StartTime).Milliseconds(), fetchRes.TotalHops, - fetchRes.HopsToClosest, - fetchRes.PRHoldPingDuration.Milliseconds(), - fetchRes.FindProvDuration.Milliseconds(), - fetchRes.GetClosePeersDuration.Milliseconds(), - tot, - suc, + fetchRes.HopsTreeDepth, + fetchRes.MinHopsToClosest, + fetchRes.PRHoldPingDuration.Milliseconds(), + fetchRes.FindProvDuration.Milliseconds(), + fetchRes.GetClosePeersDuration.Milliseconds(), + tot, + suc, fail, fetchRes.IsRetrievable, - ) - if err != nil { - return errors.Wrap(err, "unable to insert fetch_results at DB ") - } - - err = db.addPingResultsSet(fetchRes.PRPingResults) - if err != nil { - return errors.Wrap(err, "persisting PingResults") - } - - err = db.addClosestPeerSet(&models.ClosestPeers{ - Cid: fetchRes.Cid, - PingRound: fetchRes.Round, - Peers: fetchRes.ClosestPeers, - }) + fetchRes.PRWithMAddr) - return err + return persis } diff --git a/pkg/db/peer_info.go b/pkg/db/peer_info.go index d059a97..6247085 100644 --- a/pkg/db/peer_info.go +++ b/pkg/db/peer_info.go @@ -19,7 +19,11 @@ func (db *DBClient) CreatePeerInfoTable() error { user_agent TEXT NOT NULL, client TEXT NOT NULL, version TEXT NOT NULL - );`) + ); + + CREATE INDEX IF NOT EXISTS idx_peer_info_peer_id ON peer_info (peer_id); + CREATE INDEX IF NOT EXISTS idx_peer_info_client ON peer_info (client); + `) if err != nil { return errors.Wrap(err, "creating table peer_info ") } @@ -27,53 +31,62 @@ func (db *DBClient) CreatePeerInfoTable() error { return nil } -func (db *DBClient) addNewPeerInfoSet(pInfos []*models.PeerInfo) (err error) { +func (db *DBClient) addNewPeerInfoSet(pInfos []*models.PeerInfo) persistable { + persis := newPersistable() if len(pInfos) <= 0 { - return errors.New("unable to insert peer_info set - no peer_info set given") + return persis } - log.WithFields(log.Fields{ - "peerIDs": len(pInfos), - }).Trace("adding set of peer infos to DB") - // insert each of the Peers holding the PR - for _, p := range pInfos { - err = db.addPeerInfo(p) - if err != nil { - return errors.Wrap(err, "unable to insert peer info at DB ") - } + // compose the query + persis.query = multiValueComposer(` + INSERT INTO peer_info ( + peer_id, + multi_addrs, + user_agent, + client, + version)`, + "ON CONFLICT DO NOTHING", + len(pInfos), + 5) + + // add the values + for _, pInfo := range pInfos { + persis.values = append(persis.values, + pInfo.ID.String(), + pInfo.MultiAddr, + pInfo.UserAgent, + pInfo.Client, + pInfo.Version) } - return err + return persis } -func (db *DBClient) addPeerInfo(pInfo *models.PeerInfo) (err error) { +func (db *DBClient) addPeerInfo(pInfo *models.PeerInfo) persistable { + persis := newPersistable() - log.Tracef("adding new peer %s info to DB", pInfo.ID.String()) - - // insert the cidInfo - _, err = db.psqlPool.Exec(db.ctx, `INSERT INTO peer_info ( + // compose the query + persis.query = ` + INSERT INTO peer_info ( peer_id, multi_addrs, user_agent, client, version) VALUES ($1, $2, $3, $4, $5) - ON CONFLICT DO NOTHING`, - pInfo.ID.String(), - pInfo.MultiAddr, - pInfo.UserAgent, - pInfo.Client, - pInfo.Version, - ) - if err != nil { - return err - } + ON CONFLICT DO NOTHING` - return err + // add the values + persis.values = append(persis.values, pInfo.ID.String()) + persis.values = append(persis.values, pInfo.MultiAddr) + persis.values = append(persis.values, pInfo.UserAgent) + persis.values = append(persis.values, pInfo.Client) + persis.values = append(persis.values, pInfo.Version) + + return persis } func (db *DBClient) GetIdOfPeer(pIdStr string) (id int, err error) { - err = db.psqlPool.QueryRow(db.ctx, `SELECT id FROM peer_info WHERE peer_id=$1`, pIdStr).Scan(&id) if err != nil { return -1, errors.Wrap(err, "got empty row quering id of cid "+pIdStr) diff --git a/pkg/db/ping_results.go b/pkg/db/ping_results.go index a1fb937..9ada12e 100644 --- a/pkg/db/ping_results.go +++ b/pkg/db/ping_results.go @@ -8,19 +8,19 @@ import ( ) func (db *DBClient) CreatePingResultsTable() error { - log.Debugf("creating table 'ping_results' for DB") - _, err := db.psqlPool.Exec(db.ctx, ` CREATE TABLE IF NOT EXISTS ping_results( id SERIAL PRIMARY KEY, cid_hash TEXT NOT NULL, ping_round INT NOT NULL, peer_id TEXT NOT NULL, - ping_time FLOAT NOT NULL, - ping_duration FLOAT NOT NULL, + ping_time TIMESTAMP NOT NULL, + ping_time_since_publication_m FLOAT NOT NULL, + ping_duration_ms FLOAT NOT NULL, is_active BOOL NOT NULL, has_records BOOL NOT NULL, + records_with_maddrs BOOL NOT NULL, conn_error TEXT NOT NULL, UNIQUE(cid_hash, ping_round, peer_id), @@ -30,53 +30,44 @@ func (db *DBClient) CreatePingResultsTable() error { if err != nil { return errors.Wrap(err, "ping_results table") } - return nil } -func (db *DBClient) addPingResultsSet(pingRes []*models.PRPingResults) (err error) { +func (db *DBClient) addPingResultsSet(pingRes []*models.PRPingResults) persistable { + persis := newPersistable() if len(pingRes) <= 0 { - return errors.New("insert ping result set - no ping_results set given") + return persis } - cStr := pingRes[0].Cid.Hash().B58String() - pingRound := pingRes[0].Round - - log.WithFields(log.Fields{ - "cid": cStr, - }).Debug("adding set of cid ping_results to DB") - - // insert each of the Peers holding the PR - for _, ping := range pingRes { - _, err = db.psqlPool.Exec(db.ctx, ` + persis.query = multiValueComposer(` INSERT INTO ping_results ( cid_hash, ping_round, peer_id, ping_time, - ping_duration, + ping_time_since_publication_m, + ping_duration_ms, is_active, has_records, - conn_error) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, - cStr, - ping.Round, - ping.PeerID.String(), - ping.FetchTime.Unix(), - ping.FetchDuration.Milliseconds(), - ping.Active, - ping.HasRecords, - ping.ConError, - ) - if err != nil { - return errors.Wrap(err, "insert ping_results ") - } + records_with_maddrs, + conn_error)`, + "", + len(pingRes), // number of values + 10) // number of items per value - log.WithFields(log.Fields{ - "cid": cStr, - "round": pingRound, - "pings": len(pingRes), - }).Trace("tx successfully saved ping_results into DB") + // insert each of the Peers holding the PR + for _, ping := range pingRes { + persis.values = append(persis.values, ping.Cid.Hash().B58String()) + persis.values = append(persis.values, ping.Round) + persis.values = append(persis.values, ping.PeerID.String()) + persis.values = append(persis.values, ping.PingTime) + persis.values = append(persis.values, ping.GetPingTimeSincePublication().Minutes()) + persis.values = append(persis.values, ping.PingDuration.Milliseconds()) + persis.values = append(persis.values, ping.Active) + persis.values = append(persis.values, ping.HasRecords) + persis.values = append(persis.values, ping.RecordsWithMAddrs) + persis.values = append(persis.values, ping.ConError) } - return err + + return persis } diff --git a/pkg/db/pr_holders.go b/pkg/db/pr_holders.go index 49b3fd4..1020748 100644 --- a/pkg/db/pr_holders.go +++ b/pkg/db/pr_holders.go @@ -9,9 +9,7 @@ import ( ) func (db *DBClient) CreatePRHoldersTable() error { - log.Debugf("creating table 'pr_holders' for DB") - _, err := db.psqlPool.Exec(db.ctx, ` CREATE TABLE IF NOT EXISTS pr_holders( id SERIAL PRIMARY KEY, @@ -24,36 +22,27 @@ func (db *DBClient) CreatePRHoldersTable() error { if err != nil { return errors.Wrap(err, "error preparing statement for pr_holders table generation") } - return nil } -func (db *DBClient) addPRHoldersSet(c cid.Cid, prHolders []*models.PeerInfo) (err error) { +func (db *DBClient) addPRHoldersSet(c cid.Cid, prHolders []*models.PeerInfo) persistable { + persis := newPersistable() if len(prHolders) <= 0 { - return errors.New("unable to insert pr_holders - no pr_holders set given") + return persis } - log.WithFields(log.Fields{ - "cid": c.Hash().B58String(), - }).Debug("adding set of cid pr_holders to DB") - - // insert each of the Peers holding the PR - for _, p := range prHolders { - _, err = db.psqlPool.Exec(db.ctx, ` + persis.query = multiValueComposer(` INSERT INTO pr_holders ( cid_hash, - peer_id) - VALUES ($1, $2)`, - c.Hash().B58String(), - p.ID.String(), - ) - if err != nil { - return errors.Wrap(err, "unable to insert pr_holders at DB ") - } + peer_id)`, + "", // no appendix to the query + len(prHolders), // number of Values to insert + 2) // number of items per value (cid_hash, peer_id) - log.WithFields(log.Fields{ - "cid": c.Hash().B58String(), - "pr_holders": len(prHolders), - }).Trace("tx successfully saved pr_holders into DB") + // add each of the items of the PR holders to the values + for _, p := range prHolders { + persis.values = append(persis.values, c.Hash().B58String()) + persis.values = append(persis.values, p.ID.String()) } - return err + + return persis } diff --git a/pkg/db/utils.go b/pkg/db/utils.go new file mode 100644 index 0000000..f2172c2 --- /dev/null +++ b/pkg/db/utils.go @@ -0,0 +1,34 @@ +package db + +import ( + "fmt" + "strings" +) + +// multiValueComposer includes the VALUES ($1, $2) ($3, $4) for the given query on the given +// valueLen and itemsPerValue and returns the new query +func multiValueComposer (mainQuery string, appendable string, valueLen, itemsPerValue int) string { + var s strings.Builder + s.WriteString(mainQuery) + baseIdx := 1 + for valueItem := 0; valueItem < valueLen; valueItem++ { + if valueItem == 0 { + s.WriteString("\nVALUES (") + } else { + s.WriteString(",(") + } + for item := baseIdx; item < (baseIdx + itemsPerValue); item++ { + if item != baseIdx { + s.WriteString(",") + } + s.WriteString(fmt.Sprintf("$%d", item)) + } + s.WriteString(")") + baseIdx += itemsPerValue + } + if appendable != "" { + s.WriteString("\n") + s.WriteString(appendable) + } + return s.String() +} diff --git a/pkg/db/utils_test.go b/pkg/db/utils_test.go new file mode 100644 index 0000000..523bcdd --- /dev/null +++ b/pkg/db/utils_test.go @@ -0,0 +1,21 @@ +package db + +import ( + "fmt" + "testing" +) + +func TestUtils (t *testing.T) { + query := ` + INSERT INTO peer_info( + peer_id, + cid_hash)` + + newQuery := multiValueComposer( + query, + "ON CONFLICT DO NOTHING", + 4, + 2) + fmt.Println(query) + fmt.Println(newQuery) +} diff --git a/pkg/hoarder/cid_generator.go b/pkg/hoarder/cid_generator.go new file mode 100644 index 0000000..0bccca0 --- /dev/null +++ b/pkg/hoarder/cid_generator.go @@ -0,0 +1,135 @@ +package hoarder + +import ( + "context" + "math/rand" + "sync" + + "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" +) + +var ( + CidLimitError error = errors.New("limit of cids reached") +) + +// CidGenerator composes the basic object that generates set of CIDs defined in the configuration +type CidGenerator struct { + ctx context.Context + hoarderWG *sync.WaitGroup + generatorWG *sync.WaitGroup + + contentSize int + cidNumber int + + generator *randomCidGen + newCidC chan *cid.Cid + doneC chan struct{} + doneNotC chan struct{} +} + +// NewCidTracker generates a new instance of the CIDTracker +func NewCidGenerator( + ctx context.Context, + hoarderWG *sync.WaitGroup, + cSize, cNumber int) *CidGenerator { + + return &CidGenerator{ + ctx: ctx, + hoarderWG: hoarderWG, + generatorWG: new(sync.WaitGroup), + contentSize: cSize, + cidNumber: cNumber, + generator: newRandomCidGen(cSize, cNumber), + newCidC: make(chan *cid.Cid, 1), + doneC: make(chan struct{}, 1), + doneNotC: make(chan struct{}, 1), + } +} + +// Generates cids depending on the cid source +func (g *CidGenerator) Run() (chan *cid.Cid, chan struct{}) { + g.generatorWG.Add(1) + go func() { + defer g.generatorWG.Done() + for { + select { + case <-g.ctx.Done(): + log.Info("context shutdown detected on CidGenerator") + return + case <-g.doneC: + log.Info("controled shutdown detected on CidGenerator") + return + default: + contId, err := g.generator.getNewCid() + switch err { + case CidLimitError: + log.Infof("Cid generation marked reached: %d, clossing generator", g.cidNumber) + return + case nil: + log.Infof("generated new CID %s", contId.Hash().B58String()) + g.newCidC <- &contId + default: + log.Error("Error generating new CID: %s", err.Error()) + } + } + } + }() + return g.newCidC, g.doneNotC +} + +func (g *CidGenerator) Close() { + g.doneC <- struct{}{} + g.generatorWG.Wait() + g.hoarderWG.Done() + log.Info("cid generator successfully closed") + g.doneNotC <- struct{}{} + close(g.doneC) + close(g.doneNotC) +} + +type randomCidGen struct { + contentSize int + //keeps track of how many cids have been generated by the random cid gen struct + cidsGenerated int + //limit of how many cids to generate (-1 to run it contineously) + limit int +} + +func newRandomCidGen(contentSize int, limit int) *randomCidGen { + return &randomCidGen{ + contentSize: contentSize, + cidsGenerated: 0, + limit: limit, + } +} + +// getRandomContent returns generates an array of random bytes with the given size and the composed CID of the content +func (g *randomCidGen) getNewCid() (cid.Cid, error) { + if g.cidsGenerated >= g.limit { + return cid.Cid{}, CidLimitError + } + + g.cidsGenerated++ + // generate random bytes + content := make([]byte, g.contentSize) + rand.Read(content) + + //TODO do we have to have different CID types? + // configure the type of CID that we want + pref := cid.Prefix{ + Version: 1, + Codec: cid.Raw, + MhType: mh.SHA2_256, + MhLength: -1, + } + + // get the CID of the content we just generated + contID, err := pref.Sum(content) + if err != nil { + return cid.Cid{}, errors.Wrap(err, "composing CID") + } + return contID, nil +} diff --git a/pkg/hoarder/cid_set.go b/pkg/hoarder/cid_set.go new file mode 100644 index 0000000..900fe1d --- /dev/null +++ b/pkg/hoarder/cid_set.go @@ -0,0 +1,110 @@ +package hoarder + +import ( + "sort" + "sync" + + "github.com/cortze/ipfs-cid-hoarder/pkg/models" +) + +// cidSet is a simple s.eue of CIDs that allows rapid access to content through maps, +// while being abel to sort the array by closer next ping time to determine which is +// the next soonest peer to ping +type cidSet struct { + sync.RWMutex + + cidMap map[string]*models.CidInfo + cidArray []*models.CidInfo + + init bool +} + +// newCidQueue creates a new CidSet +func newCidSet() *cidSet { + return &cidSet{ + cidMap: make(map[string]*models.CidInfo), + cidArray: make([]*models.CidInfo, 0), + init: false, + } +} + +func (s *cidSet) isInit() bool { + return s.init +} + +func (s *cidSet) isCidAlready(c string) bool { + s.RLock() + defer s.RUnlock() + + _, ok := s.cidMap[c] + return ok +} + +func (s *cidSet) addCid(c *models.CidInfo) { + s.Lock() + defer s.Unlock() + + s.cidMap[c.CID.Hash().B58String()] = c + s.cidArray = append(s.cidArray, c) + + if !s.init { + s.init = true + } +} + +func (s *cidSet) removeCid(cStr string) { + delete(s.cidMap, cStr) + // check if len of the s.eue is only one + if s.Len() == 1 { + s.cidArray = make([]*models.CidInfo, 0) + return + } + item := -1 + for idx, c := range s.cidArray { + if c.CID.Hash().B58String() == cStr { + item = idx + break + } + } + // check if the item was found + if item >= 0 { + s.cidArray = append(s.cidArray[:item], s.cidArray[(item+1):]...) + } +} + +func (s *cidSet) getCid(cStr string) (*models.CidInfo, bool) { + s.RLock() + defer s.RUnlock() + + c, ok := s.cidMap[cStr] + return c, ok +} + +func (s *cidSet) sortCidList() { + sort.Sort(s) + return +} + +// Swap is part of sort.Interface. +func (s *cidSet) Swap(i, j int) { + s.Lock() + defer s.Unlock() + + s.cidArray[i], s.cidArray[j] = s.cidArray[j], s.cidArray[i] +} + +// Less is part of sort.Interface. We use c.PeerList.NextConnection as the value to sort by. +func (s *cidSet) Less(i, j int) bool { + s.RLock() + defer s.RUnlock() + + return s.cidArray[i].NextPing.Before(s.cidArray[j].NextPing) +} + +// Len is part of sort.Interface. We use the peer list to get the length of the array. +func (s *cidSet) Len() int { + s.RLock() + defer s.RUnlock() + + return len(s.cidArray) +} diff --git a/pkg/hoarder/discoverer.go b/pkg/hoarder/discoverer.go deleted file mode 100644 index 71f114c..0000000 --- a/pkg/hoarder/discoverer.go +++ /dev/null @@ -1,330 +0,0 @@ -package hoarder - -import ( - "context" - "sync" - "time" - - "github.com/ipfs/go-cid" - "github.com/pkg/errors" - - src "github.com/cortze/ipfs-cid-hoarder/pkg/cid-source" - "github.com/cortze/ipfs-cid-hoarder/pkg/config" - "github.com/cortze/ipfs-cid-hoarder/pkg/models" - "github.com/cortze/ipfs-cid-hoarder/pkg/p2p" - - "github.com/libp2p/go-libp2p/core/peer" - ma "github.com/multiformats/go-multiaddr" - log "github.com/sirupsen/logrus" -) - -type CidDiscoverer struct { - *CidTracker - m sync.Mutex - CidMap map[string][]*src.TrackableCid -} - -func NewCidDiscoverer(tracker *CidTracker) (*CidDiscoverer, error) { - log.Info("Creating a new CID discoverer") - - return &CidDiscoverer{ - CidTracker: tracker, - CidMap: make(map[string][]*src.TrackableCid), - }, nil -} - -func (discoverer *CidDiscoverer) httpRun() { - trackableCidsChannel := make(chan []src.TrackableCid, discoverer.Workers) - // CID generator - var genWG sync.WaitGroup - genWG.Add(1) - go discoverer.generateCidsHttp(&genWG, trackableCidsChannel) - var addProviderWG sync.WaitGroup - go discoverer.addProviderRecordsHttp(&addProviderWG, trackableCidsChannel) - genWG.Wait() - addProviderWG.Wait() - err := discoverer.host.Close() - if err != nil { - log.Errorf("failed to close host: %s", err) - return - } - log.Debug("Closed the discoverer host") -} - -func (discoverer *CidDiscoverer) run() { - defer discoverer.wg.Done() - // launch the PRholder reading routine - //msgNotChannel := discoverer.MsgNot.GetNotifierChan() - - if discoverer.CidSource.Type() == config.HttpServerSource { - discoverer.httpRun() - return - } - trackableCidC := make(chan *src.TrackableCid, discoverer.Workers) - // CID generator - var genWG sync.WaitGroup - genWG.Add(1) - go discoverer.generateCids(&genWG, trackableCidC) - - var addProviderWG sync.WaitGroup - go discoverer.addProvider(&addProviderWG, trackableCidC) - genWG.Wait() - addProviderWG.Wait() - - log.Debugf("Number of cids read was: %d", len(discoverer.CidMap)) - var discovererWG sync.WaitGroup - - for cidstr, getNewCidReturnTypeArray := range discoverer.CidMap { - discovererWG.Add(1) - go discoverer.discoveryProcess(&discovererWG, cidstr, getNewCidReturnTypeArray) - } - - discovererWG.Wait() - //close(msgNotChannel) - //log.Debug("CLOSED NOT CHANNEL") - err := discoverer.host.Close() - if err != nil { - log.Errorf("failed to close host: %s", err) - return - } - log.Debug("Closed the discoverer host") -} - -func (discoverer *CidDiscoverer) addToMap(trackableCid *src.TrackableCid) { - cidStr := trackableCid.CID.Hash().B58String() - if typeInstance, ok := discoverer.CidMap[cidStr]; ok { - discoverer.CidMap[cidStr] = append(typeInstance, trackableCid) - } else { - arr := make([]*src.TrackableCid, 0) - arr = append(arr, trackableCid) - discoverer.CidMap[cidStr] = arr - } -} - -func (discoverer *CidDiscoverer) addProvider(addProviderWG *sync.WaitGroup, trackableCidC <-chan *src.TrackableCid) { - defer addProviderWG.Done() - ctx := discoverer.ctx - for { - select { - case trackableCid, ok := <-trackableCidC: - if !ok { - break - } - if trackableCid.IsEmpty() { - break - } - - cidStr := trackableCid.CID.Hash().B58String() - - log.Debugf( - "New provide and CID received from channel. Cid:%s,Pid:%s,Mutliaddresses:%v,ProvideTime:%s,UserAgent:%s", - cidStr, trackableCid.ID.String(), - trackableCid.Addresses, trackableCid.ProvideTime, trackableCid.UserAgent, - ) - discoverer.m.Lock() - discoverer.addToMap(trackableCid) - - err := addPeerToProviderStore(ctx, discoverer.host, trackableCid.ID, trackableCid.CID, trackableCid.Addresses) - if err != nil { - log.Errorf("error %s calling addpeertoproviderstore method", err) - } else { - log.Debug("Added providers to provider store") - } - - err = addAgentVersionToProvideStore(discoverer.host, trackableCid.ID, trackableCid.UserAgent) - - if err != nil { - log.Errorf("error %s calling addAgentVersionToProvideStore", err) - } else { - log.Debug("Added agent version to provider store") - } - - discoverer.m.Unlock() - - case <-ctx.Done(): - log.Debugf("shutdown detected, closing discoverer through add provider") - return - default: - //log.Debug("haven't received anything yet") - } - } -} - -func (discoverer *CidDiscoverer) addProviderRecordsHttp(addProviderWG *sync.WaitGroup, trackableCidsChannel <-chan []src.TrackableCid) { - defer addProviderWG.Done() - ctx := discoverer.ctx - for { - select { - case trackableCids, ok := <-trackableCidsChannel: - if !ok { - break - } - if trackableCids == nil { - break - } - - tr := trackableCids[0] - cidStr := tr.CID.Hash().B58String() - - log.Debugf( - "New provide and CID received from channel. Cid:%s,Pid:%s,Mutliaddresses:%v,ProvideTime:%s,UserAgent:%s", - cidStr, tr.ID.String(), - tr.Addresses, tr.ProvideTime, tr.UserAgent, - ) - - //the starting values for the discoverer - cidIn, err := cid.Parse(cidStr) - - if err != nil { - log.Errorf("couldnt parse cid") - } - - cidInfo := models.NewCidInfo(cidIn, discoverer.ReqInterval, discoverer.StudyDuration, config.JsonFileSource, - discoverer.CidSource.Type(), "") - fetchRes := models.NewCidFetchResults(cidIn, 0) - - // generate a new CidFetchResults - //TODO starting data for the discoverer - fetchRes.TotalHops = 0 - fetchRes.HopsToClosest = 0 - for _, trackableCid := range trackableCids { - - err := addPeerToProviderStore(ctx, discoverer.host, trackableCid.ID, trackableCid.CID, trackableCid.Addresses) - if err != nil { - log.Errorf("error %s calling addpeertoproviderstore method", err) - } else { - log.Debug("Added providers to provider store") - } - - err = addAgentVersionToProvideStore(discoverer.host, trackableCid.ID, trackableCid.UserAgent) - - if err != nil { - log.Errorf("error %s calling addAgentVersionToProvideStore", err) - } else { - log.Debug("Added agent version to provider store") - } - cidInfo.AddPublicationTime(trackableCid.PublicationTime) - cidInfo.AddProvideTime(trackableCid.ProvideTime) - - //TODO discoverer starting ping res - pingRes := models.NewPRPingResults( - cidIn, - trackableCid.ID, - //the below are starting data for the discoverer - 0, - time.Time{}, - 0, - true, - true, - p2p.NoConnError, - ) - cidInfo.AddCreator(trackableCid.Creator) - fetchRes.AddPRPingResults(pingRes) - - log.Debugf("User agent received from provider store: %s", discoverer.host.GetUserAgentOfPeer(trackableCid.ID)) - - prHolderInfo := models.NewPeerInfo( - trackableCid.ID, - discoverer.host.Peerstore().Addrs(trackableCid.ID), - discoverer.host.GetUserAgentOfPeer(trackableCid.ID), - ) - - cidInfo.AddPRHolder(prHolderInfo) - } - cidInfo.AddPRFetchResults(fetchRes) - - discoverer.DBCli.AddCidInfo(cidInfo) - discoverer.DBCli.AddFetchResult(fetchRes) - - discoverer.CidPinger.AddCidInfo(cidInfo) - - case <-ctx.Done(): - log.Debugf("shutdown detected, closing discoverer through add provider") - return - default: - //log.Debug("haven't received anything yet") - } - } -} - -// This method essentially initializes the data for the pinger to be able to get information about the PR holders later. -func (discoverer *CidDiscoverer) discoveryProcess(discovererWG *sync.WaitGroup, cidstr string, trackableCidArr []*src.TrackableCid) { - defer discovererWG.Done() - //the starting values for the discoverer - cidIn, err := cid.Parse(cidstr) - - if err != nil { - log.Errorf("couldnt parse cid") - } - - cidInfo := models.NewCidInfo(cidIn, discoverer.ReqInterval, discoverer.StudyDuration, config.JsonFileSource, discoverer.CidSource.Type(), "") - fetchRes := models.NewCidFetchResults(cidIn, 0) - - // generate a new CidFetchResults - //TODO starting data for the discoverer - fetchRes.TotalHops = 0 - fetchRes.HopsToClosest = 0 - for _, val := range trackableCidArr { - cidInfo.AddPublicationTime(val.PublicationTime) - cidInfo.AddProvideTime(val.ProvideTime) - //TODO discoverer starting ping res - pingRes := models.NewPRPingResults( - cidIn, - val.ID, - //the below are starting data for the discoverer - 0, - time.Time{}, - 0, - true, - true, - p2p.NoConnError, - ) - cidInfo.AddCreator(val.Creator) - fetchRes.AddPRPingResults(pingRes) - - log.Debugf("User agent received from provider store: %s", discoverer.host.GetUserAgentOfPeer(val.ID)) - - prHolderInfo := models.NewPeerInfo( - val.ID, - discoverer.host.Peerstore().Addrs(val.ID), - discoverer.host.GetUserAgentOfPeer(val.ID), - ) - - cidInfo.AddPRHolder(prHolderInfo) - } - - cidInfo.AddPRFetchResults(fetchRes) - - tot, success, failed := cidInfo.GetFetchResultSummaryOfRound(0) - if tot < 0 { - log.Warnf("no ping results for the PR provide round of Cid %s", cidInfo.CID.Hash().B58String()) - } else { - log.Infof("Cid %s - %d total PRHolders | %d successfull PRHolders | %d failed PRHolders", - cidIn, tot, success, failed) - } - - discoverer.DBCli.AddCidInfo(cidInfo) - discoverer.DBCli.AddFetchResult(fetchRes) - - discoverer.CidPinger.AddCidInfo(cidInfo) -} - -/* -func addAddrtoPeerstore(h host.Host, pid peer.ID, multiaddr []ma.Multiaddr) { - h.Peerstore().AddAddrs(pid, multiaddr, peerstore.PermanentAddrTTL) -} -*/ - -// Instead of adding directly to peerstore the API is the following -func addPeerToProviderStore(ctx context.Context, h *p2p.Host, pid peer.ID, cid cid.Cid, multiaddr []ma.Multiaddr) error { - keyMH := cid.Hash() - err := h.DHT.ProviderStore().AddProvider(ctx, keyMH, peer.AddrInfo{ID: pid, Addrs: multiaddr}) - if err != nil { - return errors.Wrap(err, " while trying to add provider to peerstore") - } - return nil -} - -func addAgentVersionToProvideStore(h *p2p.Host, pid peer.ID, useragent string) error { - return h.Peerstore().Put(pid, "AgentVersion", useragent) -} diff --git a/pkg/hoarder/hoarder.go b/pkg/hoarder/hoarder.go index 549d1ca..9868429 100644 --- a/pkg/hoarder/hoarder.go +++ b/pkg/hoarder/hoarder.go @@ -5,29 +5,27 @@ import ( "sync" "time" - src "github.com/cortze/ipfs-cid-hoarder/pkg/cid-source" - "github.com/cortze/ipfs-cid-hoarder/pkg/config" "github.com/cortze/ipfs-cid-hoarder/pkg/db" + "github.com/cortze/ipfs-cid-hoarder/pkg/p2p" "github.com/pkg/errors" log "github.com/sirupsen/logrus" - "github.com/cortze/ipfs-cid-hoarder/pkg/p2p" - - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/libp2p/go-libp2p/core/network" + "github.com/cortze/ipfs-cid-hoarder/pkg/crawler" ) type CidHoarder struct { ctx context.Context wg *sync.WaitGroup - Host *p2p.Host - PingerHost *p2p.Host - DBCli *db.DBClient - CidTracker Tracker - CidPinger *CidPinger + dbCli *db.DBClient + + cidSet *cidSet + cidPublisher *CidPublisher + cidPinger *CidPinger + + FinishedC chan struct{} } func NewCidHoarder(ctx context.Context, conf *config.Config) (*CidHoarder, error) { @@ -39,173 +37,112 @@ func NewCidHoarder(ctx context.Context, conf *config.Config) (*CidHoarder, error return nil, errors.Wrap(err, "initialise the DB") } - // generate private key for the publisher Libp2p host - pubprivk, _, err := crypto.GenerateKeyPair(crypto.Secp256k1, 256) - if err != nil { - return nil, errors.Wrap(err, "unable to generate priv key for client's host") - } - log.Debugf("Generated Priv Key for the host %s", p2p.PrivKeyToString(pubprivk)) - - // generate new priv key for pinger host - pingprivk, _, err := crypto.GenerateKeyPair(crypto.Secp256k1, 256) - if err != nil { - return nil, errors.Wrap(err, "unable to generate priv key for pinger's host") + // ------ Configure the settings for the Libp2p hosts ------ + hostOpts := p2p.HostOptions { + IP: "0.0.0.0", + Port: conf.Port, + K: conf.K, + BlacklistingUA: conf.BlacklistedUA, } - - // prevent dial backoffs - ctx = network.WithForceDirectDial(ctx, "prevent backoff") - - // ----- Compose the Publisher or discoverer Libp2p host ----- - pubordishost, err := p2p.NewHost(ctx, pubprivk, config.CliIp, conf.Port, conf.K, conf.HydraFilter) - if err != nil { - return nil, errors.Wrap(err, "error generating publisher or discoverer libp2p host for the tool") - } - - // ----- Compose Pinger Libp2p Host ----- - pingerHost, err := p2p.NewHost(ctx, pingprivk, config.CliIp, conf.Port, conf.K, conf.HydraFilter) - if err != nil { - return nil, errors.Wrap(err, "error generating pinger libp2p host for the tool") + if conf.BlacklistedUA != "" { + log.Infof("UA blacklisting activated -> crawling network to identify %s (might take 5-7mins)\n", + hostOpts.BlacklistingUA, + ) + // launch light crawler identifying balcklistable peers + crawlResutls, err := crawler.RunLightCrawler(ctx, conf.BlacklistedUA) + if err != nil { + return nil, err + } + hostOpts.BlacklistedPeers = crawlResutls.GetBlacklistedPeers() } // ------ Study Parameters --------- var studyWG sync.WaitGroup - reqInterval, err := time.ParseDuration(conf.ReqInterval) if err != nil { return nil, errors.Wrap(err, "error parsing ReqInterval "+conf.ReqInterval) } - studyDuration, err := time.ParseDuration(conf.StudyDuration) + + cidPingTime, err := time.ParseDuration(conf.CidPingTime) if err != nil { - return nil, errors.Wrap(err, "error parsing StudyDuration"+conf.StudyDuration) + return nil, errors.Wrap(err, "error parsing StudyDuration "+conf.CidPingTime) } - - log.Info("configured Hoarder to request at an interval of ", reqInterval, " and during ", studyDuration) - - // TODO: understimate the number of workers that will be needed might add certain delay between rounds - // Better to swap it to check the final time for finishing the run than counting rounds - rounds := int(studyDuration/reqInterval) + 1 + log.Info("configured Hoarder to request at an interval of ", reqInterval, " and during ", cidPingTime) // ----- Generate the CidPinger ----- + cidSet := newCidSet() studyWG.Add(1) - cidPinger := NewCidPinger(ctx, &studyWG, pingerHost, dbInstance, reqInterval, rounds, conf.Workers) - - //TODO this needs to be changed meaning the generation - // ----- Generate the CidTracker(either a discoverer or a publisher) ----- - cidSource, err := findCidSource(conf) + cidPinger, err := NewCidPinger( + ctx, + &studyWG, + hostOpts, + dbInstance, + reqInterval, + conf.Workers, + cidSet, + ) if err != nil { - return nil, errors.Wrap(err, " error generating the CID Tracker") + return nil, err } + // ---- Generate the CidPublisher ----- + // select the provide operation that we want to perform: + provOp := StandardDHTProvide + pubWorkers := 1 + if !conf.SinglePublisher { + pubWorkers = conf.Workers + } studyWG.Add(1) - if conf.AlreadyPublishedCIDs { - cidTracker, err := NewCidTracker(ctx, &studyWG, pubordishost, dbInstance, cidSource, cidPinger, conf.K, conf.Workers, reqInterval, studyDuration) - if err != nil { - return nil, errors.Wrap(err, "error generating the CidTracker") - } - cidDiscoverer, err := NewCidDiscoverer(cidTracker) - // if the type is http source you need to assign the type to the tracker - if cidSource.Type() == config.HttpServerSource { - httpCidSource, ok := cidSource.(*src.HttpCidSource) - if !ok { - return nil, errors.New("Couldn't deduce type") - } - go httpCidSource.StartServer() - if err != nil { - return nil, errors.New("Couldn't start server") - } - //assign to user later for graceful shutdown - cidTracker.httpSource = httpCidSource - } - log.Debug("CidHoarder Initialized with cid discoverer") - - return &CidHoarder{ - ctx: ctx, - wg: &studyWG, - Host: pubordishost, - PingerHost: pingerHost, - DBCli: dbInstance, - CidTracker: cidDiscoverer, - CidPinger: cidPinger, - }, nil - } else { - cidTracker, err := NewCidTracker(ctx, &studyWG, pubordishost, dbInstance, cidSource, cidPinger, conf.K, conf.Workers, reqInterval, studyDuration) - if err != nil { - return nil, errors.Wrap(err, "error generating the CidTracker") - } - cidPublisher, err := NewCidPublisher(cidTracker, pubordishost, conf.CidNumber) - log.Debug("CidHoarder Initialized with cid publisher") - return &CidHoarder{ - ctx: ctx, - wg: &studyWG, - Host: pubordishost, - PingerHost: pingerHost, - DBCli: dbInstance, - CidTracker: cidPublisher, - CidPinger: cidPinger, - }, nil + cidPublisher, err := NewCidPublisher( + ctx, + &studyWG, + hostOpts, + provOp, + dbInstance, + NewCidGenerator( + ctx, + &studyWG, + conf.CidContentSize, + conf.CidNumber, + ), + cidSet, + conf.K, + pubWorkers, + reqInterval, + cidPingTime, + ) + if err != nil { + return nil, err } + return &CidHoarder{ + ctx: ctx, + wg: &studyWG, + dbCli: dbInstance, + cidPublisher: cidPublisher, + cidPinger: cidPinger, + FinishedC: make(chan struct{}, 1), + }, nil } func (c *CidHoarder) Run() error { - // Boostrap the kdht host - err := c.Host.Boostrap(c.ctx) - if err != nil { - return errors.Wrap(err, "unable to boostrap the publisher or discoverer host with the kdht routing table.") - } - - err = c.PingerHost.Boostrap(c.ctx) - if err != nil { - return errors.Wrap(err, "unable to boostrap the pinger host with the kdht routing table.") - } - - // Launch the Cid Tracker - go c.CidTracker.run() - go c.CidPinger.Run() - - c.wg.Wait() - - log.Info("study finished! closing everything") - - // after the CidTracker has already finished, close the DB - c.DBCli.Close() - + // Launch the publisher and the pinger + go c.cidPublisher.Run() + go c.cidPinger.Run() + // wait until the app has been closed / finished to notify + go func (){ + c.wg.Wait() + c.dbCli.Close() + log.Info("hoarder run finished, organically closed") + c.FinishedC <- struct{}{} + }() return nil } -// Generates the cid source given a specific config struct. E.g. a randomly generated cid source uses the Random_Cid_Gen struct, this function must return that. -// The options for the cid source are defined in this enum like const value. -// -// const ( -// RandomSource = "random-content-gen" -// TextFileSource = "text-file" -// JsonFileSource = "json-file" -// BitswapSource = "bitswap" -// HttpSource = "HttpServerSource" -// RandomContent = "random" -// ) -// -// const ( -// RandomSource = "random-content-gen" -// TextFileSource = "text-file" -// JsonFileSource = "json-file" -// BitswapSource = "bitswap" -// RandomContent = "random" -// ) -func findCidSource(conf *config.Config) (src.CidSource, error) { - switch conf.CidSource { - case config.TextFileSource: - return nil, errors.New("text file source not yet implemented") - case config.HttpServerSource: - server := src.NewHttpCidSource(8080, "localhost") - return server, nil - case config.JsonFileSource: - return src.OpenEncodedJSONFile(conf.CidFile) - case config.RandomSource: - return src.NewRandomCidGen(conf.CidContentSize, conf.CidNumber), nil - case config.BitswapSource: - return nil, errors.New("bitswap source not yet implemented") - - default: - return nil, errors.New("Could not figure out cid source") - } +func (c *CidHoarder) Close() { + c.cidPublisher.Close() + c.cidPinger.Close() + c.wg.Wait() + // after the CidTracker has already finished, close the DB + c.dbCli.Close() + log.Info("hoarder interruption successfully closed! C ya") } diff --git a/pkg/hoarder/pinger.go b/pkg/hoarder/pinger.go index 6e9398c..13701f7 100644 --- a/pkg/hoarder/pinger.go +++ b/pkg/hoarder/pinger.go @@ -2,14 +2,15 @@ package hoarder import ( "context" - "fmt" "sync" "time" "github.com/cortze/ipfs-cid-hoarder/pkg/db" "github.com/cortze/ipfs-cid-hoarder/pkg/models" "github.com/cortze/ipfs-cid-hoarder/pkg/p2p" + "github.com/pkg/errors" + "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" log "github.com/sirupsen/logrus" ) @@ -17,347 +18,222 @@ import ( const ( LookupTimeout = 60 * time.Second minIterTime = 500 * time.Millisecond - maxDialAttempts = 1 // Are two attempts enough? - dialGraceTime = 15 * time.Second + maxDialAttempts = 2 // Are two attempts enough? + dialGraceTime = 5 * time.Second ) // CidPinger is the main object to schedule and monitor all the CID related metrics type CidPinger struct { ctx context.Context - wg *sync.WaitGroup + appWG *sync.WaitGroup + + orchersterWG *sync.WaitGroup + pingersWG *sync.WaitGroup + orchersterCloseC chan struct{} + pingersCloseC chan struct{} host *p2p.Host dbCli *db.DBClient pingInterval time.Duration - rounds int workers int init bool - pingOrcDoneFlag bool - initC chan struct{} - cidQ *cidQueue + cidS *cidSet pingTaskC chan *models.CidInfo + } -// NewCidPinger return a CidPinger with the given configuration,creates a new: -// -// CidPinger struct { -// ctx context.Context -// sync.Mutex -// wg *sync.WaitGroup -// -// host *p2p.Host -// dbCli *db.DBClient -// pingInterval time.Duration -// rounds int -// workers int -// -// init bool -// initC chan struct{} -// -// cidQ *cidQueue -// pingTaskC chan *models.CidInfo -// } +// NewCidPinger return a CidPinger with the given configuration func NewCidPinger( ctx context.Context, - wg *sync.WaitGroup, - host *p2p.Host, + appWG *sync.WaitGroup, + hostOpts p2p.HostOptions, dbCli *db.DBClient, pingInterval time.Duration, - rounds int, - workers int) *CidPinger { - + workers int, + cidSet *cidSet) (*CidPinger, error) { + + log.WithField("mod", "pinger").Info("initializing the pinger") + h, err := p2p.NewHost( + ctx, + hostOpts.IP, + hostOpts.Port, + hostOpts.K, + hostOpts.BlacklistingUA, + hostOpts.BlacklistedPeers, + ) + if err != nil { + return nil, errors.Wrap(err, "pinger:") + } return &CidPinger{ ctx: ctx, - wg: wg, - host: host, + appWG: appWG, + orchersterWG: new(sync.WaitGroup), + pingersWG: new(sync.WaitGroup), + orchersterCloseC: make(chan struct{}, 1), + pingersCloseC: make(chan struct{}, 1), + host: h, dbCli: dbCli, pingInterval: pingInterval, - rounds: rounds, - cidQ: newCidQueue(), - initC: make(chan struct{}), pingTaskC: make(chan *models.CidInfo, workers), // TODO: hardcoded workers: workers, - } + cidS: cidSet, + }, nil } // Run executes the main logic of the CID Pinger. // 1. runs the queue logic that schedules the pings // 2. launchs the pinger pool that will perform all the CID monitoring calls func (pinger *CidPinger) Run() { - defer pinger.wg.Done() - - var pingOrchWG sync.WaitGroup - var pingerWG sync.WaitGroup + pinger.appWG.Add(1) + defer pinger.appWG.Done() + + logEntry := log.WithField("pinger", "setup") + // initialize the host + // TODO: consider having multiple pinger hosts to have concurrency calls: + // https://github.com/libp2p/go-libp2p-kad-dht/issues/805 + logEntry.Debug("bootstraping host") + err := pinger.host.Boostrap(pinger.ctx) + if err != nil { + logEntry.Panic(errors.Wrap(err, "pinger:")) + } - pingOrchWG.Add(1) + pinger.orchersterWG.Add(1) // Generate the Ping Orchester - go pinger.runPingOrchester(&pingOrchWG) + go pinger.runPingOrchester() // Launch CID pingers (workers) for pingerCounter := 0; pingerCounter < pinger.workers; pingerCounter++ { - pingerWG.Add(1) - go pinger.runPinger(&pingerWG, pingerCounter) + pinger.pingersWG.Add(1) + go pinger.runPinger(pingerCounter) } // wait until the ping orchester has finished - pingOrchWG.Wait() - log.Infof("finished pinging the CIDs on %d rounds", pinger.rounds) - pinger.pingOrcDoneFlag = true + pinger.orchersterWG.Wait() + logEntry.Infof("finished pinging the CIDs") + pinger.pingersCloseC <- struct{}{} // wait until the ping workers finish - pingerWG.Wait() - log.Debug("done from the CID Pinger") + pinger.pingersWG.Wait() + logEntry.Info("done from the CID Pinger") // close all the pending channels close(pinger.pingTaskC) //close the publisher host - err := pinger.host.Close() + err = pinger.host.Close() if err != nil { - log.Errorf("failed to close pinger host: %s", err) + logEntry.Errorf("failed to close pinger host: %s", err) return } } -// AddCidInfo adds a new CID to the pinging queue -func (p *CidPinger) AddCidInfo(c *models.CidInfo) { - if !p.init { - p.init = true - p.initC <- struct{}{} - } - p.cidQ.addCid(c) -} - -// PingPRHolder dials a given PR Holder to check whether it's active or not, and whether it has the PRs or not -func (pinger *CidPinger) PingPRHolder(c *models.CidInfo, round int, pAddr peer.AddrInfo) *models.PRPingResults { - logEntry := log.WithFields(log.Fields{ - "cid": c.CID.Hash().B58String(), - }) - - var active, hasRecords bool - var connError string - - // track time of the process - tstart := time.Now() - - // fulfill the control fields from a successful connection - succesfulConnection := func() { - active = true - connError = p2p.NoConnError - - // if the connection was successful, request whether it has the records or not - provs, _, err := pinger.host.DHT.GetProvidersFromPeer(pinger.ctx, pAddr.ID, c.CID.Hash()) - if err != nil { - log.Warnf("unable to retrieve providers from peer %s - error: %s", pAddr.ID, err.Error()) - } else { - logEntry.Debugf("providers for Cid %s from peer %s - %v\n", c.CID.Hash().B58String(), pAddr.ID.String(), provs) - } - // iter through the providers to see if it matches with the host's peerID - for _, paddrs := range provs { - if paddrs.ID == c.Creator { - hasRecords = true - fmt.Println(time.Now(), "Peer", pAddr.ID.String(), "reporting on", c.CID.Hash().B58String(), " -> ", paddrs) - } - } - } - - // check if we already have a connection open to the peer - peerList := pinger.host.Network().Peers() - connected := false - for _, p := range peerList { - if p.String() == pAddr.ID.String() { - connected = true - break - } - } - - if connected { - logEntry.Debugf("peer %s was alread connected, success connection for Cid %s", pAddr.ID.String(), c.CID.Hash().B58String()) - succesfulConnection() - } else { - // loop over max tries if the connection is connection refused/ connection reset by peer - for att := 0; att < maxDialAttempts; att++ { - // attempt to connect the peer - err := pinger.host.Connect(pinger.ctx, pAddr) - if err != nil { - logEntry.Debugf("unable to connect peer %s for Cid %s - error %s", pAddr.ID.String(), c.CID.Hash().B58String(), err.Error()) - connError = p2p.ParseConError(err) - // If the error is not linked to an connection refused or reset by peer, just break the look - if connError != p2p.DialErrorConnectionRefused && connError != p2p.DialErrorStreamReset { - break - } else { - // add random delay between trials - ticker := time.NewTicker(dialGraceTime) - select { - case <-ticker.C: - continue - case <-pinger.ctx.Done(): - break - } - } - } else { - logEntry.Debugf("succesful connection to peer %s for Cid %s", pAddr.ID.String(), c.CID.Hash().B58String()) - succesfulConnection() - break - } - } - } - - fetchTime := time.Since(tstart) - - return models.NewPRPingResults( - c.CID, - pAddr.ID, - round, - tstart, - fetchTime, - active, - hasRecords, - connError) -} -// runPingOrchester handles the way pings are going to happen: -// -// 1.) The ping orchester waits for a cid to be generated by: -// -// func generateCids(...) -// -// and the cid to be sent to the: -// -// initC chan struct{} -// -// inside the cid tracker generation by the: -// -// func AddCidInfo(...) -// -// 2.) Loops over the queue of CidInfos and determines whether a cid needs to be pinged. If the cid needs to be pinged: -// -// pinger.pingTaskC <- cidInfo -// -// # TODO connection between this and the next go routine -// -// 3.) This is a ongoing step. Keeps a timer using: -// -// minTimeT := time.NewTicker(minIterTime) -// -// and waits until a new iteration occurs to restart looping over the cids: -// -// <-minTimeT.C -func (pinger *CidPinger) runPingOrchester(pingOrchWG *sync.WaitGroup) { - defer pingOrchWG.Done() - - logEntry := log.WithField("mod", "cid-orchester") - // we need to wait until the first CID is added, wait otherwise - // this cid is added inside the AddCidInfo method called from Cid tracker - <-pinger.initC +// runPingOrchester orchestrates all the pings based on the next ping time of the cids +func (pinger *CidPinger) runPingOrchester() { + defer pinger.orchersterWG.Done() + logEntry := log.WithField("pinger", "orchester") + // generate a timer to determine minTimeT := time.NewTicker(minIterTime) + // ensure that the cidSet is not freshly created + initLoop: + for !pinger.cidS.isInit() { + select { + case<- minTimeT.C: + minTimeT.Reset(minIterTime) + logEntry.Trace("cid set still not initialized") + case <- pinger.orchersterCloseC: + break initLoop + } + } + orchersterLoop: for { select { case <-pinger.ctx.Done(): - log.Info("shutdown was detected, closing Cid Ping Orchester") - return + logEntry.Info("shutdown was detected, closing Cid Ping Orchester") + break orchersterLoop + + case <- pinger.orchersterCloseC: + logEntry.Info("shutdown was detected, closing Cid Ping Orchester") + break orchersterLoop default: // loop over the list of CIDs, and check whether they need to be pinged or not - for _, cidInfo := range pinger.cidQ.cidArray { - // check if ctx was was closed - if pinger.ctx.Err() != nil { - log.Info("shutdown was detected, closing Cid Ping Orchester") - return - } - + orchersterRound: + for _, cidInfo := range pinger.cidS.cidArray { cidStr := cidInfo.CID.Hash().B58String() // check if the time for next ping has arrived if !cidInfo.IsReadyForNextPing() { - logEntry.Debugf("not in time to ping %s", cidStr) - break // we assume that the Array is sorted with the lower NextPingTime at the begining, therefore, we break the loop + logEntry.Tracef("not in time to ping %s", cidStr) + break orchersterRound } - // increment Ping Counter cidInfo.IncreasePingCounter() - // Add the CID to the pingTaskC pinger.pingTaskC <- cidInfo - // check if they have finished the duration of the study - // if yes, remove them from the cidQ.cidArray + // if yes, remove them from the cidS.cidArray if cidInfo.IsFinished() { // delete the CID from the list - pinger.cidQ.removeCid(cidStr) - logEntry.Infof("finished pinging CID %s - max pings reached %d", cidStr, pinger.rounds) + pinger.cidS.removeCid(cidStr) + logEntry.Infof("finished pinging CID %s - pingend over %s", + cidStr, cidInfo.StudyDuration) } - } - // if CID pinger was initialized and there are no more CIDs to track, we are done with the study - if pinger.cidQ.Len() == 0 { - return + if pinger.cidS.Len() == 0 { + logEntry.Info("no more cids to ping, closing orcherster") + break orchersterLoop } - // reorganize the array of CIDs from lowest next ping time to biggest one - pinger.cidQ.sortCidList() - + pinger.cidS.sortCidList() // check if ticker for next iteration was raised <-minTimeT.C + minTimeT.Reset(minIterTime) } } } // runPinger creates the necessary pinger to retrieve the content from the network and ping the PR holders of the content. -// 1.) Receives a cidInfo struct from the channel: -// -// pinger.pingTaskC chan *models.CidInfo -// -// inside the generatePingOrchester goroutine. -// -// 2.) Requests the status of the PR holders(substeps): -// -// 1.) Finds the provider of the CIDs -// -// 2.) Recalculates the k closest peers -// -// The above requests are done to populate the CidFetchRes struct{...} and then -// -// 3.) Pings the PR holders in parallel calling the: -// -// func PingPRholder(...) -// -// which adds the: -// -// PRPingResults to the CidFetchRes field []*PRPingResults -func (pinger *CidPinger) runPinger(wg *sync.WaitGroup, pingerID int) { - defer wg.Done() +func (pinger *CidPinger) runPinger(pingerID int) { + defer pinger.pingersWG.Done() + minTimeT := time.NewTicker(minIterTime) logEntry := log.WithField("pinger", pingerID) - logEntry.Debug("Initialized") + logEntry.Debug("ready") + + closePingerF := false for { // check if the ping orcherster has finished - if pinger.pingOrcDoneFlag && len(pinger.pingTaskC) == 0 { + if closePingerF && len(pinger.pingTaskC) == 0 { logEntry.Info("no more pingTasks to perform orcherster has finished, finishing worker") return } select { case cidInfo := <-pinger.pingTaskC: - logEntry.Debug("new ping task received from channel") + var wg sync.WaitGroup cidStr := cidInfo.CID.Hash().B58String() pingCounter := cidInfo.GetPingCounter() logEntry.Infof("pinging CID %s for round %d", cidStr, pingCounter) // request the status of PR Holders - cidFetchRes := models.NewCidFetchResults(cidInfo.CID, pingCounter) - - var wg sync.WaitGroup - - wg.Add(1) + cidFetchRes := models.NewCidFetchResults( + cidInfo.CID, + cidInfo.PublishTime, + pingCounter, + cidInfo.K, + ) + // DHT FindProviders call to see if the content is actually retrievable from the network + wg.Add(1) go func(p *CidPinger, c *models.CidInfo, fetchRes *models.CidFetchResults) { defer wg.Done() var isRetrievable bool = false + var prWithMAddrs bool = false t := time.Now() ctxT, cancel := context.WithTimeout(p.ctx, LookupTimeout) @@ -366,28 +242,25 @@ func (pinger *CidPinger) runPinger(wg *sync.WaitGroup, pingerID int) { pingTime := time.Since(t) fetchRes.FindProvDuration = pingTime if err != nil { - logEntry.Warnf("unable to get the closest peers to cid %s - %s", cidStr, err.Error()) + logEntry.Warnf("unable to lookup for provider of cid %s - %s", + cidStr, err.Error(), + ) } // iter through the providers to see if it matches with the host's peerID for _, paddrs := range providers { if paddrs.ID == c.Creator { isRetrievable = true + if len(paddrs.Addrs) > 0 { + prWithMAddrs = true + } } } - // Removable - Just double checking - if len(providers) == 0 && isRetrievable { - log.Errorf("missmatch - content retrievable but no providers (%d)", len(providers)) - } - if len(providers) > 0 && !isRetrievable { - log.Error("missmatch - content not retrievable but found providers (%d)", len(providers)) - } - fetchRes.IsRetrievable = isRetrievable - fmt.Println(time.Now(), "Providers for", c.CID.Hash().B58String(), "->", providers) + fetchRes.PRWithMAddr = prWithMAddrs }(pinger, cidInfo, cidFetchRes) + // recalculate the closest k peers to the content. wg.Add(1) - // recalculate the closest k peers to the content. This needs to be done due to node churn.(?) go func(p *CidPinger, c *models.CidInfo, fetchRes *models.CidFetchResults) { defer wg.Done() t := time.Now() @@ -396,12 +269,18 @@ func (pinger *CidPinger) runPinger(wg *sync.WaitGroup, pingerID int) { defer cancel() closestPeers, lookupMetrics, err := p.host.DHT.GetClosestPeers(ctxT, string(c.CID.Hash())) pingTime := time.Since(t) - fetchRes.TotalHops = lookupMetrics.GetHops() - fetchRes.HopsToClosest = lookupMetrics.GetHopsForPeerSet(closestPeers) - fetchRes.GetClosePeersDuration = pingTime if err != nil { logEntry.Warnf("unable to get the closest peers to cid %s - %s", cidStr, err.Error()) + fetchRes.TotalHops = -1 + fetchRes.HopsTreeDepth = -1 + fetchRes.MinHopsToClosest = -1 + } else { + fetchRes.TotalHops = lookupMetrics.GetTotalHops() + fetchRes.HopsTreeDepth = lookupMetrics.GetTreeDepth() + fetchRes.MinHopsToClosest = lookupMetrics.GetMinHopsForPeerSet(lookupMetrics.GetClosestPeers()) } + fetchRes.GetClosePeersDuration = pingTime + for _, peer := range closestPeers { cidFetchRes.AddClosestPeer(peer) } @@ -427,8 +306,135 @@ func (pinger *CidPinger) runPinger(wg *sync.WaitGroup, pingerID int) { case <-pinger.ctx.Done(): logEntry.Info("shutdown detected, closing pinger") return + + case <- pinger.pingersCloseC: + logEntry.Info("gracefull shutdown detected") + closePingerF = true + return + case <-minTimeT.C: // and min iter time has passed - // not ping task to read from the channel, checking again + // not ping task to read from the channel, checking again in case we have to close the routine } } } + +// PingPRHolder dials a given PR Holder to check whether it's active or not, and whether it has the PRs or not +func (pinger *CidPinger) PingPRHolder(c *models.CidInfo, round int, pAddr peer.AddrInfo) *models.PRPingResults { + logEntry := log.WithFields(log.Fields{ + "ping-to-cid": c.CID.Hash().B58String(), + }) + + var active, hasRecords, recordsWithMAddrs bool + var connError string + + // track time of the process + tstart := time.Now() + + // fulfill the control fields from a successful connection + succesfulConnection := func() { + active = true + connError = p2p.NoConnError + + // if the connection was successful, request whether it has the records or not + provs, _, err := pinger.host.DHT.GetProvidersFromPeer(pinger.ctx, pAddr.ID, c.CID.Hash()) + if err != nil { + logEntry.Debugf("unable to retrieve providers from peer %s - error: %s", pAddr.ID, err.Error()) + } else { + logEntry.Debugf("providers for Cid %s from peer %s - %v", c.CID.Hash().B58String(), pAddr.ID.String(), provs) + } + // iter through the providers to see if it matches with the host's peerID + for _, paddrs := range provs { + if paddrs.ID == c.Creator { + hasRecords = true + if len(paddrs.Addrs) > 0 { + recordsWithMAddrs = true + } + } + } + } + + // check if the peer is among the already connected ones + if isPeerConnected(pAddr.ID, pinger.host) { + logEntry.Debugf("peer %s was alread connected, success connection for Cid %s", + pAddr.ID.String(), c.CID.Hash().B58String(), + ) + succesfulConnection() + } else { + // loop over max tries if the connection is connection refused/ connection reset by peer + connetionRetry: + for att := 0; att < maxDialAttempts; att++ { + // attempt to connect the peer + err := pinger.host.Connect(pinger.ctx, pAddr) + connError := p2p.ParseConError(err) + switch connError { + case p2p.NoConnError: // no error at all + logEntry.Debugf("succesful connection to peer %s for Cid %s", + pAddr.ID.String(), c.CID.Hash().B58String(), + ) + succesfulConnection() + break connetionRetry + + case p2p.DialErrorConnectionRefused, p2p.DialErrorStreamReset: + // the error is due to a connection rejected, try again + logEntry.Debugf("unable to connect peer %s for Cid %s - error %s, retrying", + pAddr.ID.String(), c.CID.Hash().B58String(), err.Error(), + ) + if (att + 1) < maxDialAttempts { + // add random delay between trials + ticker := time.NewTicker(dialGraceTime) + select { + case <-ticker.C: + continue + case <-pinger.ctx.Done(): + break connetionRetry + } + } else { + logEntry.Debugf("%d retries done without succesful connection %s", + att+1, connError, + ) + break connetionRetry + } + + default: + // the + logEntry.Debugf("unable to connect peer %s for Cid %s - error %s", + pAddr.ID.String(), c.CID.Hash().B58String(), err.Error(), + ) + break connetionRetry + } + } + } + + return models.NewPRPingResults( + c.CID, + pAddr.ID, + round, + c.PublishTime, + tstart, + time.Since(tstart), + active, + hasRecords, + recordsWithMAddrs, + connError, + ) +} + + +func (pinger *CidPinger) Close() { + log.WithField("mod", "pinger").Info("shutdown detected from the CidPinger") + pinger.orchersterCloseC <- struct{}{} +} + +// conside moving this to the Host +func isPeerConnected(pId peer.ID, h host.Host) bool { + // check if we already have a connection open to the peer + peerList := h.Network().Peers() + for _, p := range peerList { + if p.String() == pId.String() { + return true + } + } + return false +} + + diff --git a/pkg/hoarder/publisher.go b/pkg/hoarder/publisher.go index 9aea284..269ad46 100644 --- a/pkg/hoarder/publisher.go +++ b/pkg/hoarder/publisher.go @@ -5,203 +5,232 @@ import ( "sync" "time" - src "github.com/cortze/ipfs-cid-hoarder/pkg/cid-source" - - "github.com/cortze/ipfs-cid-hoarder/pkg/config" + "github.com/cortze/ipfs-cid-hoarder/pkg/db" "github.com/cortze/ipfs-cid-hoarder/pkg/models" "github.com/cortze/ipfs-cid-hoarder/pkg/p2p" "github.com/ipfs/go-cid" dht "github.com/libp2p/go-libp2p-kad-dht" pb "github.com/libp2p/go-libp2p-kad-dht/pb" + "github.com/pkg/errors" log "github.com/sirupsen/logrus" ) +type ProvideOption string + +var ( + StandardDHTProvide ProvideOption = "std-dht-provide" +) + type CidPublisher struct { - //entries of this map are added inside the publishingProccess and received from addProviderMessageListener - CidMap sync.Map - //number of cids to publish - CidNumber int - *CidTracker + ctx context.Context + wg *sync.WaitGroup + + host *p2p.Host + dhtProvide ProvideOption + DBCli *db.DBClient + cidGenerator *CidGenerator + + //receive message from listen for add provider message function + MsgNot *p2p.Notifier + K int + Workers int + ReqInterval time.Duration + CidPingTime time.Duration + + // main set of Cids that will keep track of them over the run + cidSet *cidSet } -func NewCidPublisher(tracker *CidTracker, h *p2p.Host, cidNum int) (*CidPublisher, error) { +func NewCidPublisher( + ctx context.Context, + wg *sync.WaitGroup, + hostOpts p2p.HostOptions, + dhtProvide ProvideOption, + db *db.DBClient, + generator *CidGenerator, + cidSet *cidSet, + k, workers int, + reqInterval, + cidPingTime time.Duration, +) (*CidPublisher, error) { + log.Debug("Creating a new CID publisher") + h, err := p2p.NewHost( + ctx, + hostOpts.IP, + hostOpts.Port, + hostOpts.K, + hostOpts.BlacklistingUA, + hostOpts.BlacklistedPeers, + ) + if err != nil { + return nil, errors.Wrap(err, "publisher:") + } + return &CidPublisher{ - CidNumber: cidNum, - CidTracker: tracker, + ctx: ctx, + wg: wg, + host: h, + dhtProvide: dhtProvide, + DBCli: db, + MsgNot: h.GetMsgNotifier(), + cidGenerator: generator, + K: k, + ReqInterval: reqInterval, + CidPingTime: cidPingTime, + Workers: workers, + cidSet: cidSet, }, nil } -func (publisher *CidPublisher) run() { +func (publisher *CidPublisher) Run() { defer publisher.wg.Done() // launch the PRholder reading routine msgNotChannel := publisher.MsgNot.GetNotifierChan() // control variables - var firstCidFetchRes sync.Map - - var genWG sync.WaitGroup var publisherWG sync.WaitGroup var msgNotWG sync.WaitGroup - var generationDone bool = false - var publicationDone bool = false - - // generate a channel with the same size as the Workers one - trackableCidC := make(chan *src.TrackableCid, publisher.Workers) + var firstCidFetchRes sync.Map + generationDoneC := make(chan struct {}, 1) + publicationDoneC := make(chan struct {}, 1) // IPFS DHT Message Notification Listener msgNotWG.Add(1) - go publisher.addProviderMsgListener(&msgNotWG, &publicationDone, &firstCidFetchRes, msgNotChannel) + go publisher.addProviderMsgListener( + &msgNotWG, + publicationDoneC, + &firstCidFetchRes, + msgNotChannel, + ) + + // bootstrap the Libp2p node + err := publisher.host.Boostrap(publisher.ctx) + if err != nil { + log.Panic(errors.Wrap(err, "publisher")) + } // CID generator - genWG.Add(1) - go publisher.generateCids(&genWG, trackableCidC) + cidPubC, genDoneC := publisher.cidGenerator.Run() // CID PR Publishers which are essentially the workers of tracker. for publisherCounter := 0; publisherCounter < publisher.Workers; publisherCounter++ { publisherWG.Add(1) // start the providing process - go publisher.publishingProcess(&publisherWG, &generationDone, publisherCounter, trackableCidC, &firstCidFetchRes) + go publisher.publishingProcess( + &publisherWG, + generationDoneC, + publisherCounter, + cidPubC, + &firstCidFetchRes, + ) } // wait until the generation of the CIDs is done - genWG.Wait() - generationDone = true + <- genDoneC log.Info("generation process finished successfully") + generationDoneC <- struct{}{} // wait until the publication of the CIDs is done publisherWG.Wait() - publicationDone = true log.Info("publication process finished successfully") + publicationDoneC <- struct{}{} // wait until the msg not reader has ended msgNotWG.Wait() log.Info("msg notification channel finished successfully") //close the publisher host - err := publisher.host.Close() + err = publisher.host.Close() if err != nil { log.Errorf("failed to close publisher host: %s", err) return } } -// addProviderMsgListener listens to a: -// -// msgNotchannel chan *p2p.MsgNotification -// -// for a: -// -// MsgNotification.Msg.Type of Message_ADD_PROVIDER -// -// when this message is received it adds the provider onto the database for later pings: -// -// 1.)Creates a new: -// -// PRPingResults struct{...} -// -// the result of a ping of an individual PR_HOLDER -// -// 2.) Adds the PRPingResults struct{...} into the: -// -// var cidFetRes *CidFetchResults -// -// using: -// -// citFetRes.AddPRPingResults(pingRes) -// -// which is set inside the providing_process routine: -// -// fetchRes := models.NewCidFetchResults(*received_cid, 0) // First round = Publish PR -// cidFetchRes.Store(received_cidStr, fetchRes) -// -// 3.)Creates a new: -// -// PeerInfo struct{...} -// -// which is stored inside a cidInfo struct{...}: -// -// cidInfo.AddPRHolder(prHolderInfo) -// -// this is taken by the providing_process routine: -// -// cidInfo := models.NewCidInfo(*received_cid, publisher.ReqInterval, config.RandomContent, publisher.CidSource.Type(), publisher.host.ID()) -// // generate the cidFetcher -// publisher.CidMap.Store(received_cidStr, cidInfo) -func (publisher *CidPublisher) addProviderMsgListener(msgNotWg *sync.WaitGroup, publicationDone *bool, firstCidFetchRes *sync.Map, msgNotChannel <-chan *p2p.MsgNotification) { +// addProviderMsgListener listens the Notchannel for ADD_PROVIDER messages for the provided CIDs +// from each of the messages received, it composes/adds a new PR holder to the CID +// finally, it aggregates all the PingRound info of the publication as the first PingRound (0) +func (publisher *CidPublisher) addProviderMsgListener( + msgNotWg *sync.WaitGroup, + publicationDoneC chan struct{}, + firstCidFetchRes *sync.Map, + msgNotChannel chan *p2p.MsgNotification) { defer func() { // notify that the msg listener has been closed msgNotWg.Done() }() for { - // check if we are done with the publication (with priority) - if *publicationDone && (len(msgNotChannel) == 0) { - log.Info("publication done and not missing sent msgs to check, closing msgNotChannel") - return - } - select { - case msgNot := <-msgNotChannel: //this receives a message from SendMessage in messages.go after the DHT.Provide operation is called from the PUT_PROVIDER method. + // this receives a message from SendMessage in messages.go after the DHT.Provide operation + // is called from the PUT_PROVIDER method. + case msgNot := <-msgNotChannel: // check the msg type - casted_cid, err := cid.Cast(msgNot.Msg.GetKey()) + castedCid, err := cid.Cast(msgNot.Msg.GetKey()) if err != nil { log.Errorf("unable to cast msg key into cid. %s", err.Error()) } switch msgNot.Msg.Type { case pb.Message_ADD_PROVIDER: - var active, hasRecords bool + var active bool var connError string if msgNot.Error != nil { - connError = p2p.ParseConError(msgNot.Error) //TODO: parse the errors in a better way - log.Debugf("Failed putting PR for CID %s of PRHolder %s - error %s", casted_cid.String(), msgNot.RemotePeer.String(), msgNot.Error.Error()) + //TODO: parse the errors in a better way + connError = p2p.ParseConError(msgNot.Error) + log.Debugf("Failed putting PR for CID %s of PRHolder %s - error %s", + castedCid.Hash().B58String(), msgNot.RemotePeer.String(), msgNot.Error.Error(), + ) } else { + // assume that if the peer replies successfully to the ADD_PROVIDER messages, + // the remote peer keeps the info (We are assuming also this for the Hydras) active = true - hasRecords = true connError = p2p.NoConnError - log.Debugf("Successfull PRHolder for CID %s of PRHolder %s", casted_cid.String(), msgNot.RemotePeer.String()) + log.Debugf("Successfull PRHolder for CID %s of PRHolder %s", castedCid.Hash().B58String(), msgNot.RemotePeer.String()) } - //if no error occurred in p2p.MsgNotification the ping result will contain active = true and hasRecords = true, - //else it will have these fields as false. - pingRes := models.NewPRPingResults( - casted_cid, - msgNot.RemotePeer, - 0, // round is 0 since is the ADD_PROVIDE result - msgNot.QueryTime, - msgNot.QueryDuration, - active, - hasRecords, - connError) + // Read the CidInfo from the local Sync.Map struct + cidInfo, ok := publisher.cidSet.getCid(castedCid.Hash().B58String()) + if !ok { + log.Panic("unable to find CidInfo on CidSet for Cid ", castedCid.Hash().B58String()) + } // add the ping result - val, ok := firstCidFetchRes.Load(casted_cid.Hash().B58String()) + val, ok := firstCidFetchRes.Load(castedCid.Hash().B58String()) cidFetRes := val.(*models.CidFetchResults) if !ok { - log.Errorf("CidFetcher not ready for cid %s", casted_cid.Hash().B58String()) - } else { - // TODO: move into a seaparate method to make the DB interaction easier? - cidFetRes.AddPRPingResults(pingRes) + log.Panicf("CidFetcher not found for cid %s", castedCid.Hash().B58String()) } - useragent := publisher.host.GetUserAgentOfPeer(msgNot.RemotePeer) - log.Debugf("User agent is: %s", useragent) + // save the ping result into the FetchRes + cidFetRes.AddPRPingResults(models.NewPRPingResults( + castedCid, + msgNot.RemotePeer, + 0, // round is 0 since is the ADD_PROVIDE result + cidFetRes.GetPublicationTime(), + msgNot.QueryTime, + msgNot.QueryDuration, + active, + false, + false, + connError), + ) // Generate the new PeerInfo struct for the new PRHolder prHolderInfo := models.NewPeerInfo( msgNot.RemotePeer, publisher.host.Peerstore().Addrs(msgNot.RemotePeer), - useragent, + publisher.host.GetUserAgentOfPeer(msgNot.RemotePeer), ) - // add PRHolder to the CidInfo - val, ok = publisher.CidMap.Load(casted_cid.Hash().B58String()) - cidInfo := val.(*models.CidInfo) - if !ok { - log.Warnf("unable to find CidInfo on CidMap for Cid %s", casted_cid.Hash().B58String()) - } else { - cidInfo.AddPRHolder(prHolderInfo) + // add all the PRHolder info to the CidInfo + cidInfo.AddPRHolder(prHolderInfo) + + // are we done with this CID? + if cidFetRes.IsDone() { + // notify the publisher that the CID is ready + cidFetRes.DoneC <- struct{}{} } default: @@ -209,145 +238,126 @@ func (publisher *CidPublisher) addProviderMsgListener(msgNotWg *sync.WaitGroup, } case <-publisher.ctx.Done(): - log.Info("context has been closed, finishing Cid Tracker") + log.Info("context has been closed, finishing Cid Publisher") + return + + case <- publicationDoneC: + // if the publication has finished, we don't expect more messages to arrive, the host + // has been shut down + log.Info("publication done and not missing sent msgs to check, closing msgNotChannel") return - default: - // if there is no msg to check and ctx is still active, check if we have finished } } } -// The providing process doesn't only publish the CIDs to the network but it's important for setting up the pinging process used later -// by the tool. -// Things that it does: -// -// 1.)Receives the cids from the generateCids(...) method -// -// 2.)After receiving a cid it creates a: -// -// CIdInfo struct {...} instance -// -// which documents basic info about a specific CID -// -// 3.) Create a: -// -// CidFetchResults struct {...} -// -// which contains basic info about the fetching process (pinging) -// -// 4.) Calls the: -// -// func provide(...) inside this package cid-tracker.go -// -// providing the CID to the network -// -// 5.) adds the metrics received from func provide(...) and the fetch result struct to the newly created: -// -// var cidInfo *CidInfo -// -// 6.) Access the tracker's field: -// -// DBCli *db.DBClient -// -// and adds the cidInfo and the fetchRes -// -// 7.) Adds the cid info to the tracker's: -// -// CidPinger *CidPinger -// -// to be later pinged by the pinger. +// publisherService is a service that generates random CID from the generator +// and publishes them to the IPFS network based on the specified configuration +// the publisher also tracks the provide operation instrumenting it, persisting the metadata +// into the DB, and adding the CID to the pingerService func (publisher *CidPublisher) publishingProcess( publisherWG *sync.WaitGroup, - generationDone *bool, + generationDoneC chan struct{}, publisherID int, - cidChannel <-chan *src.TrackableCid, + cidChannel chan *cid.Cid, cidFetchRes *sync.Map) { - defer func() { - publisherWG.Done() - }() + + defer publisherWG.Done() + + // if there is no msg to check and ctx is still active, check if we have finished logEntry := log.WithField("publisherID", publisherID) logEntry.Debugf("publisher ready") + generationDone := false + minIterTicker := time.NewTicker(minIterTime) for { // check if the generation is done to finish the publisher (with priority) - if *generationDone && len(cidChannel) == 0 { - log.Info("generation process has finished and no cid is waiting to be published, closing publishingProcess") + if generationDone && len(cidChannel) == 0 { + log.Info("gen process finished and no cid is waiting to be published, closing publishingProcess") return } select { - case receivedType := <-cidChannel: //this channel receives the CID from the CID generator go routine - receivedCid := &receivedType.CID - logEntry.Debugf("new cid to publish %s", receivedCid.Hash().B58String()) - receivedCidStr := receivedCid.Hash().B58String() - // generate the new CidInfo cause a new CID was just received - //TODO the content type is not necessarily random content - cidInfo := models.NewCidInfo(*receivedCid, publisher.ReqInterval, publisher.StudyDuration, config.RandomContent, publisher.CidSource.Type(), publisher.host.ID()) + case nextCid := <-cidChannel: //this channel receives the CID from the CID generator go routine + cidStr := nextCid.Hash().B58String() + logEntry.Debugf("new cid to publish %s", cidStr) - // generate the cidFetcher - publisher.CidMap.Store(receivedCidStr, cidInfo) + // generate the new CidInfo cause a new CID was just received + cidInfo := models.NewCidInfo( + *nextCid, + publisher.K, + publisher.ReqInterval, + publisher.CidPingTime, + string(publisher.dhtProvide), + publisher.host.ID(), + ) + + // track the new Cid into the cidSet + publisher.cidSet.addCid(cidInfo) + + // save the cid into the CidSet + pubTime := time.Now() - // generate a new CidFetchResults - fetchRes := models.NewCidFetchResults(*receivedCid, 0) // First round = Publish PR - cidFetchRes.Store(receivedCidStr, fetchRes) + // compose the fetchRes of the publication phase + fetchRes := models.NewCidFetchResults(*nextCid, pubTime, 0, publisher.K) + cidFetchRes.Store(cidStr, fetchRes) // necessary stuff to get the different hop measurements lookupMetrics := dht.NewLookupMetrics() // currently linking a ContextKey variable througth the context that we generate ctx := context.WithValue(publisher.ctx, dht.ContextKey("lookupMetrics"), lookupMetrics) - - pubTime := time.Now() - reqTime, err := provide(ctx, publisher, receivedCid) + reqTime, err := publisher.provide(ctx, nextCid) if err != nil { logEntry.Errorf("unable to Provide content. %s", err.Error()) } + // add the number of hops to the fetch results - fetchRes.TotalHops = lookupMetrics.GetHops() - fetchRes.HopsToClosest = lookupMetrics.GetHopsForPeerSet(lookupMetrics.GetClosestPeers()) + fetchRes.TotalHops = lookupMetrics.GetTotalHops() + fetchRes.HopsTreeDepth = lookupMetrics.GetTreeDepth() + fetchRes.MinHopsToClosest = lookupMetrics.GetMinHopsForPeerSet(lookupMetrics.GetClosestPeers()) - // TODO: fix this little wait to comput last PR Holder status - // little not inside the CID to notify when k peers where recorded? - time.Sleep(500 * time.Millisecond) + // Make sure we don't + <- fetchRes.DoneC - // add the request time to the CidInfo + // update the info of the Cid After its publication cidInfo.AddPublicationTime(pubTime) cidInfo.AddProvideTime(reqTime) cidInfo.AddPRFetchResults(fetchRes) - // the Cid has already being published to the network, we can already save it into the DB - // ----- Persist inot DB ------- - // Add the cidInfo to the DB + // the Cid has already being published, save it into the DB publisher.DBCli.AddCidInfo(cidInfo) - - // Add the fetchResults to the DB publisher.DBCli.AddFetchResult(fetchRes) - // ----- End of the persist into DB ------- - - // Calculate success ratio on adding PR into PRHolders - tot, success, failed := cidInfo.GetFetchResultSummaryOfRound(0) - if tot < 0 { - logEntry.Warnf("no ping results for the PR provide round of Cid %s", cidInfo.CID.Hash().B58String()) - } else { - logEntry.Infof("Cid %s - %d total PRHolders | %d successfull PRHolders | %d failed PRHolders", - receivedCid, tot, success, failed) - } - // send the cid_info to the cid_pinger adn start pinging PR Holders - publisher.CidPinger.AddCidInfo(cidInfo) + // print summary of the publication (round 0) + publisher.printSummary(logEntry, cidInfo, 0) case <-publisher.ctx.Done(): logEntry.WithField("publisherID", publisherID).Debugf("shutdown detected, closing publisher") return - default: + + case <- generationDoneC: + generationDone = true + + case <- minIterTicker.C: // keep checking if the generation has ended to close the routine } + minIterTicker.Reset(minIterTime) + } +} + +// printSummary shows in the stdout the publication summary of a given CID +func (publisher *CidPublisher) printSummary(logE *log.Entry, cInfo *models.CidInfo, round int) { + // Calculate success ratio on adding PR into PRHolders + tot, success, failed := cInfo.GetFetchResultSummaryOfRound(round) + if tot < 0 { + logE.Warnf("no ping results for the PR provide round of Cid %s", + cInfo.CID.Hash().B58String()) + } else { + logE.Infof("Cid %s - %d total PRHolders | %d successfull PRHolders | %d failed PRHolders", + cInfo.CID.Hash().B58String(), tot, success, failed) } } -// provide calls: -// -// DHT.Provide(...) method to provide the cid to the network -// -// and documents the time it took to publish a CID -func provide(ctx context.Context, publisher *CidPublisher, receivedCid *cid.Cid) (time.Duration, error) { +// provide performs the DHT.Provide(...) method and publishes the CID to the network +// documenting the time it took to publish a CID +func (publisher *CidPublisher) provide(ctx context.Context, receivedCid *cid.Cid) (time.Duration, error) { log.Debug("calling provide method") tstart := time.Now() err := publisher.host.DHT.Provide(ctx, *receivedCid, true) @@ -357,3 +367,9 @@ func provide(ctx context.Context, publisher *CidPublisher, receivedCid *cid.Cid) reqTime := time.Since(tstart) return reqTime, nil } + +func (publisher *CidPublisher) Close() { + // close the generator and everything else will be closed in cascade + publisher.cidGenerator.Close() + +} diff --git a/pkg/hoarder/queue.go b/pkg/hoarder/queue.go deleted file mode 100644 index 3109441..0000000 --- a/pkg/hoarder/queue.go +++ /dev/null @@ -1,106 +0,0 @@ -package hoarder - -import ( - "sort" - "sync" - - "github.com/cortze/ipfs-cid-hoarder/pkg/models" -) - -// cidQueue is a simple queue of CIDs that allows rapid access to content through maps, -// while being abel to sort the array by closer next ping time to determine which is -// the next soonest peer to ping -type cidQueue struct { - sync.RWMutex - - cidMap map[string]*models.CidInfo - cidArray []*models.CidInfo -} - -//Creates a new: -// cidQueue struct { -// sync.RWMutex -// -// cidMap map[string]*models.CidInfo -// cidArray []*models.CidInfo -// } -func newCidQueue() *cidQueue { - return &cidQueue{ - cidMap: make(map[string]*models.CidInfo), - cidArray: make([]*models.CidInfo, 0), - } -} - -func (q *cidQueue) isCidAlready(c string) bool { - q.RLock() - defer q.RUnlock() - - _, ok := q.cidMap[c] - return ok -} - -func (q *cidQueue) addCid(c *models.CidInfo) { - q.Lock() - defer q.Unlock() - - q.cidMap[c.CID.Hash().B58String()] = c - q.cidArray = append(q.cidArray, c) - -} - -func (q *cidQueue) removeCid(cStr string) { - delete(q.cidMap, cStr) - // check if len of the queue is only one - if q.Len() == 1 { - q.cidArray = make([]*models.CidInfo, 0) - return - } - item := -1 - for idx, c := range q.cidArray { - if c.CID.Hash().B58String() == cStr { - item = idx - break - } - } - // check if the item was found - if item >= 0 { - q.cidArray = append(q.cidArray[:item], q.cidArray[(item+1):]...) - } -} - -func (q *cidQueue) getCid(cStr string) (*models.CidInfo, bool) { - q.RLock() - defer q.RUnlock() - - c, ok := q.cidMap[cStr] - return c, ok -} - -func (q *cidQueue) sortCidList() { - sort.Sort(q) - return -} - -// Swap is part of sort.Interface. -func (q *cidQueue) Swap(i, j int) { - q.Lock() - defer q.Unlock() - - q.cidArray[i], q.cidArray[j] = q.cidArray[j], q.cidArray[i] -} - -// Less is part of sort.Interface. We use c.PeerList.NextConnection as the value to sort by. -func (q *cidQueue) Less(i, j int) bool { - q.RLock() - defer q.RUnlock() - - return q.cidArray[i].NextPing.Before(q.cidArray[j].NextPing) -} - -// Len is part of sort.Interface. We use the peer list to get the length of the array. -func (q *cidQueue) Len() int { - q.RLock() - defer q.RUnlock() - - return len(q.cidArray) -} diff --git a/pkg/hoarder/tracker.go b/pkg/hoarder/tracker.go deleted file mode 100644 index bfdd5ea..0000000 --- a/pkg/hoarder/tracker.go +++ /dev/null @@ -1,141 +0,0 @@ -package hoarder - -import ( - "context" - "sync" - "time" - - log "github.com/sirupsen/logrus" - - src "github.com/cortze/ipfs-cid-hoarder/pkg/cid-source" - "github.com/cortze/ipfs-cid-hoarder/pkg/config" - "github.com/cortze/ipfs-cid-hoarder/pkg/db" - "github.com/cortze/ipfs-cid-hoarder/pkg/p2p" -) - -type Tracker interface { - run() - //this should be run as a go routine - generateCids(genWG *sync.WaitGroup, trackableCidC chan<- *src.TrackableCid) -} - -// CidTracker composes the basic object that generates and publishes the set of CIDs defined in the configuration -type CidTracker struct { - ctx context.Context - wg *sync.WaitGroup - - m sync.Mutex - - host *p2p.Host - DBCli *db.DBClient - CidSource src.CidSource - httpSource *src.HttpCidSource // leave this nil - CidPinger *CidPinger - //receive message from listen for add provider message function - MsgNot *p2p.Notifier - K int - Workers int - ReqInterval time.Duration - StudyDuration time.Duration -} - -//Creates a new: -// CidTracker struct{ -// ctx context.Context -// wg *sync.WaitGroup -// -// m sync.Mutex -// -// host *p2p.Host -// DBCli *db.DBClient -// MsgNot *p2p.Notifier -// CidSource CidSource -// CidPinger *CidPinger -// -// K int -// CidNumber int -// Workers int -// ReqInterval time.Duration -// StudyDuration time.Duration -// CidMap sync.Map -// } -func NewCidTracker( - ctx context.Context, - wg *sync.WaitGroup, - h *p2p.Host, - db *db.DBClient, - cidSource src.CidSource, - cidPinger *CidPinger, - k, Workers int, - reqInterval, studyDuration time.Duration) (*CidTracker, error) { - - return &CidTracker{ - ctx: ctx, - host: h, - wg: wg, - DBCli: db, - MsgNot: h.GetMsgNotifier(), - CidSource: cidSource, - CidPinger: cidPinger, - K: k, - ReqInterval: reqInterval, - StudyDuration: studyDuration, - Workers: Workers, - }, nil -} - -// Receives provider records from http server -// they are received in form trackableCids{ pr1, pr2, pr3, pr4} for the same cid -func (tracker *CidTracker) generateCidsHttp(genWG *sync.WaitGroup, trackableCidArrayC chan<- []src.TrackableCid) { - defer genWG.Done() - // generate a timer to determine - minTimeT := time.NewTicker(10 * time.Second) - log.Debugf("Source is: %s and config source is: ", tracker.CidSource.Type(), config.HttpServerSource) - - for true { - trackableCids, err := src.GetNewHttpCid(tracker.CidSource) - - if trackableCids == nil { - log.Debug("Received empty provider records") - trackableCidArrayC <- nil - close(trackableCidArrayC) - //gracefully shutdown server - go tracker.httpSource.Shutdown(tracker.ctx) - break - } - - if err != nil { - log.Errorf("error while getting new cid: %s", err) - // check if ticker for next iteration was raised - <-minTimeT.C - continue - } - - trackableCidArrayC <- trackableCids - // check if ticker for next iteration was raised - <-minTimeT.C - - } -} - -//Generates cids depending on the cid source -func (tracker *CidTracker) generateCids(genWG *sync.WaitGroup, trackableCidC chan<- *src.TrackableCid) { - defer genWG.Done() - // generate a timer to determine - for true { - cid, err := tracker.CidSource.GetNewCid() - if cid.IsEmpty() { - log.Debugf("Received empty cid: %s with peer id: %s", cid.CID.String(), cid.ID.String()) - trackableCidC <- &cid - close(trackableCidC) - break - } - - if err != nil { - log.Errorf("error while getting new cid: %s", err) - return - } - - trackableCidC <- &cid - } -} diff --git a/pkg/models/cid_info.go b/pkg/models/cid_info.go index 0f2b8c6..c20052a 100644 --- a/pkg/models/cid_info.go +++ b/pkg/models/cid_info.go @@ -11,7 +11,7 @@ import ( // CidInfo contains the basic information of the CID to track. // It also includes the information about the PRHolders and the fetch results of all the fetch attempts. type CidInfo struct { - m sync.Mutex + m sync.RWMutex CID cid.Cid @@ -22,64 +22,48 @@ type CidInfo struct { K int // Number of K peers that should get the initial PR PRHolders []*PeerInfo // Peers that took the responsability to keep the PR PRPingResults []*CidFetchResults - ContentType string // Type of the content that is under the CID (Random, Video, Image...) - Source string // Track where is the content coming from (Random, Cid-File, Bitswap) - //TODO change source to CidSource + + ProvideOp string // Track where is the content coming from (Random, Cid-File, Bitswap) Creator peer.ID // Peer hosting the content, so far only one (us) ReqInterval time.Duration StudyDuration time.Duration NextPing time.Time - PingCounter int -} - -// Creates a new: -// -// CidInfo struct { -// m sync.Mutex -// -// CID cid.Cid -// -// GenTime time.Time -// PublishTime time.Time -// ReqInterval time.Duration -// -// K int // Number of K peers that should get the initial PR -// PRHolders []*PeerInfo // Peers that took the responsability to keep the PR -// PRPingResults []*CidFetchResults -// ContentType string // Type of the content that is under the CID (Random, Video, Image...) -// Source string // Track where is the content coming from (Random, Cid-File, Bitswap) -// Creator peer.ID // Peer hosting the content, so far only one (us) -// -// ProvideTime time.Duration // time that took to publish the provider records -// NextPing time.Time -// PingCounter int -// } + pingCounter int +} + +// NewCidInfo creates the basic CID info struct that covers all the metadata and details of the +// provided CIDs func NewCidInfo( id cid.Cid, + k int, reqInt time.Duration, studyDurt time.Duration, - contentType, source string, + provOp string, creator peer.ID) *CidInfo { return &CidInfo{ - m: sync.Mutex{}, CID: id, GenTime: time.Now(), // fill the CID with the current time - ReqInterval: reqInt, - StudyDuration: studyDurt, + K: 0, + PRPingResults: make([]*CidFetchResults, 0, k), PRHolders: make([]*PeerInfo, 0), - ContentType: contentType, - Source: source, + ProvideOp: provOp, Creator: creator, + ReqInterval: reqInt, + StudyDuration: studyDurt, } } +// IsInit return a boolean depending on whether the +func (c *CidInfo) IsInit() bool { + return len(c.PRPingResults) > 0 +} + // AddPublicationTime adds the time at which the CID was published to the network func (c *CidInfo) AddPublicationTime(pubTime time.Time) { c.m.Lock() defer c.m.Unlock() - c.PublishTime = pubTime } @@ -87,38 +71,32 @@ func (c *CidInfo) AddPublicationTime(pubTime time.Time) { func (c *CidInfo) AddProvideTime(reqTime time.Duration) { c.m.Lock() defer c.m.Unlock() - c.ProvideTime = reqTime } +// AddCreator aggregates the Peer.ID of the host/client that created the CID func (c *CidInfo) AddCreator(creator peer.ID) { c.m.Lock() defer c.m.Unlock() - c.Creator = creator } -// AddPRHolder inserts a given Peer selected/attempted to keep the PRs for a CID,this is the CidInfo struct's field: -// -// PRHolders []*PeerInfo // Peers that took the responsability to keep the PR +// AddPRHolder inserts a given Peer selected/attempted to keep the PRs for a CID func (c *CidInfo) AddPRHolder(prHolder *PeerInfo) { c.m.Lock() defer c.m.Unlock() - c.PRHolders = append(c.PRHolders, prHolder) c.K++ } -// AddPRFetchResults inserts the results of a given CidFetch round into the CID object: -// -// CidInfo struct {...} contains PRPingResults []*CidFetchResults +// AddPRFetchResults inserts the results of a given CidFetch round into the CID struct func (c *CidInfo) AddPRFetchResults(results *CidFetchResults) { c.m.Lock() defer c.m.Unlock() c.PRPingResults = append(c.PRPingResults, results) // check if the CID is initialized or not - if c.NextPing == (time.Time{}) { + if c.NextPing.IsZero() { // Update the next ping time to PublicationTime + req interval // take also into account the publication time offset := c.ProvideTime / 2 @@ -129,12 +107,16 @@ func (c *CidInfo) AddPRFetchResults(results *CidFetchResults) { // IsReadyForNextPing returns true if it's time to ping the CID // (taking into account the nextPing time previously calculated) func (c *CidInfo) IsReadyForNextPing() bool { - return time.Now().After(c.NextPing) + c.m.RLock() + defer c.m.RUnlock() + return !c.NextPing.IsZero() && time.Now().After(c.NextPing) } // IsFinished returns true if the study for the given CID has already finished (enough ping rounds to cover the study time) // (taking into account the publicationTime previously calculated) func (c *CidInfo) IsFinished() bool { + c.m.RLock() + defer c.m.RUnlock() return time.Now().After(c.PublishTime.Add(c.StudyDuration)) } @@ -143,22 +125,21 @@ func (c *CidInfo) IsFinished() bool { func (c *CidInfo) IncreasePingCounter() { c.m.Lock() defer c.m.Unlock() - - // TODO: since is internal and we have GetPingCounter, PingCounter local - c.PingCounter++ + c.pingCounter++ c.NextPing = c.NextPing.Add(c.ReqInterval) } // GetPingCounter returns the state of the internal pingCounter func (c *CidInfo) GetPingCounter() int { - c.m.Lock() - defer c.m.Unlock() - - return c.PingCounter + c.m.RLock() + defer c.m.RUnlock() + return c.pingCounter } // GetFetchResultsLen returns the number of FetchResults that are stored in the CID func (c *CidInfo) GetFetchResultsLen() int { + c.m.RLock() + defer c.m.RUnlock() return len(c.PRPingResults) } @@ -169,6 +150,20 @@ func (c *CidInfo) GetFetchResultSummaryOfRound(round int) (tot, success, failed return -1, -1, -1 } // calculate the summary of the PingRound + c.m.Lock() cidFetchRes := c.PRPingResults[round] + c.m.Unlock() return cidFetchRes.GetSummary() } + +func (c *CidInfo) NumberOfPRHolders() int { + c.m.RLock() + defer c.m.RUnlock() + return len(c.PRHolders) +} + +func (c *CidInfo) PublicationFinished() bool { + c.m.RLock() + defer c.m.RUnlock() + return len(c.PRHolders) == c.K +} diff --git a/pkg/models/cid_ping_results.go b/pkg/models/cid_ping_results.go index 6d7a25c..76d7bff 100644 --- a/pkg/models/cid_ping_results.go +++ b/pkg/models/cid_ping_results.go @@ -10,123 +10,126 @@ import ( // PRPingResults is the basic struct containing the result of the individual ping of a PR Holder. type PRPingResults struct { - Cid cid.Cid - PeerID peer.ID - Round int - FetchTime time.Time - FetchDuration time.Duration - Active bool - HasRecords bool - ConError string + Cid cid.Cid + PeerID peer.ID + Round int + cidPubTime time.Time + PingTime time.Time + PingDuration time.Duration + Active bool + HasRecords bool + RecordsWithMAddrs bool + ConError string } -// Creates a new: -// -// PRPingResults struct { -// Cid cid.Cid -// PeerID peer.ID -// Round int -// FetchTime time.Time -// FetchDuration time.Duration -// Active bool -// HasRecords bool -// ConError string -// } +// NewPRPingResults creates a new struct with the basic status/performance info for each individual pings to PR Holders func NewPRPingResults( cid cid.Cid, p peer.ID, round int, - fetchT time.Time, - fetchD time.Duration, + cidPubTime time.Time, + pingTime time.Time, + pingDuration time.Duration, active bool, hasRecords bool, + recordsWithMAddrs bool, connError string) *PRPingResults { return &PRPingResults{ cid, p, round, - fetchT, - fetchD, + cidPubTime, + pingTime, + pingDuration, active, hasRecords, + recordsWithMAddrs, connError, } } +// GetPingTimeSincePublication return the time range since the publication of the CID when we pinged the CID +func (ping *PRPingResults) GetPingTimeSincePublication() time.Duration { + return ping.PingTime.Add(ping.PingDuration).Sub(ping.cidPubTime) +} + // CidFetchResults is the basic struct containing the summary of all the requests done for a given CID on a fetch round. type CidFetchResults struct { - m sync.Mutex - Cid cid.Cid - + m sync.RWMutex + Cid cid.Cid + cidPubTime time.Time // time when the CID was published Round int StartTime time.Time FinishTime time.Time TotalHops int - HopsToClosest int + HopsTreeDepth int + MinHopsToClosest int PRHoldPingDuration time.Duration FindProvDuration time.Duration GetClosePeersDuration time.Duration PRPingResults []*PRPingResults IsRetrievable bool + PRWithMAddr bool ClosestPeers []peer.ID + Target int + DoneC chan struct{} } -// Creates a new: -// -// CidFetchResults struct { -// m sync.Mutex -// Cid cid.Cid -// -// Round int -// StartTime time.Time -// FinishTime time.Time -// TotalHops int -// HopsToClosest int -// PRHoldPingDuration time.Duration -// FindProvDuration time.Duration -// GetClosePeersDuration time.Duration -// PRPingResults []*PRPingResults -// IsRetrievable bool -// ClosestPeers []peer.ID -// } -func NewCidFetchResults(contentID cid.Cid, round int) *CidFetchResults { +// NewCidFetchResults return the FetchResults struct that contains the basic information for the entire fetch round of a particular CID. +func NewCidFetchResults(contentID cid.Cid, pubTime time.Time, round int, target int) *CidFetchResults { return &CidFetchResults{ - m: sync.Mutex{}, Cid: contentID, Round: round, + cidPubTime: pubTime, StartTime: time.Now(), FinishTime: time.Now(), PRPingResults: make([]*PRPingResults, 0), ClosestPeers: make([]peer.ID, 0), + Target: target, // K + DoneC: make(chan struct{}, 1), } } -// AddPRPingResults inserts a new ping result of type: -// -// type PRPingResults struct{...}, -// into the: -// type CidFetchResult struct{...} which contains []*PRPingResults, -// +// IsDone reports whether the entire Fetch Result has been completed +func (c *CidFetchResults) IsDone() bool { + return len(c.PRPingResults) >= c.Target +} + +// AddPRPingResults inserts a new ping result // updating at the same time the final duration of the PR Holder ping process. func (c *CidFetchResults) AddPRPingResults(pingRes *PRPingResults) { c.m.Lock() defer c.m.Unlock() c.PRPingResults = append(c.PRPingResults, pingRes) - if pingRes.FetchDuration > c.PRHoldPingDuration { - c.PRHoldPingDuration = pingRes.FetchDuration + if pingRes.PingDuration > c.PRHoldPingDuration { + c.PRHoldPingDuration = pingRes.PingDuration } } +func (c *CidFetchResults) GetPublicationTime() time.Time { + c.m.RLock() + defer c.m.RUnlock() + return c.cidPubTime +} + +// GetPingTimeSincePublication return the time range since the publication of the CID when we pinged the CID +func (c *CidFetchResults) GetFetchTimeSincePublication() time.Duration { + c.m.RLock() + defer c.m.RUnlock() + return c.FinishTime.Sub(c.cidPubTime) +} + // GetSummary returns the summary of the PR Holder pings for the fetch round func (c *CidFetchResults) GetSummary() (tot, success, failed int) { + c.m.RLock() + defer c.m.RUnlock() // calculate the summary of the PingRound for _, pingRes := range c.PRPingResults { tot++ if pingRes.Active { success++ - // add IsRetrievable to true } else { failed++ } @@ -135,9 +138,6 @@ func (c *CidFetchResults) GetSummary() (tot, success, failed int) { } // AddClosestPeer inserts into the CidFetchResults a peer that is inside the K closest peers in the IPFS DHT in that fetch round. -// Adds to the: -// -// CidFetchResults struct{...} for the field ClosestPeers []peer.ID func (c *CidFetchResults) AddClosestPeer(pInfo peer.ID) { c.m.Lock() defer c.m.Unlock() diff --git a/pkg/p2p/error_parser.go b/pkg/p2p/error_parser.go index 102ce72..bc1469d 100644 --- a/pkg/p2p/error_parser.go +++ b/pkg/p2p/error_parser.go @@ -1,7 +1,6 @@ package p2p import ( - "fmt" "strings" net "github.com/libp2p/go-libp2p-kad-dht/net" @@ -71,6 +70,9 @@ var KnownErrors = map[string]string{ } func ParseConError(err error) string { + if err == nil { + return NoConnError + } // nested error casting to the swarm.DialError to process all the errors that might come connErr, ok := err.(*swarm.DialError) if !ok && connErr != nil { @@ -85,7 +87,5 @@ func ParseConError(err error) string { return key } } - - fmt.Println(err) return DialErrorUnknown } diff --git a/pkg/p2p/host.go b/pkg/p2p/host.go index b47b908..9e01ed8 100644 --- a/pkg/p2p/host.go +++ b/pkg/p2p/host.go @@ -8,21 +8,19 @@ import ( "time" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" "github.com/cortze/ipfs-cid-hoarder/pkg/config" - "github.com/cortze/ipfs-cid-hoarder/pkg/crawler" - - log "github.com/sirupsen/logrus" libp2p "github.com/libp2p/go-libp2p" + kaddht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/host" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" - kaddht "github.com/libp2p/go-libp2p-kad-dht" - ma "github.com/multiformats/go-multiaddr" ) @@ -30,6 +28,14 @@ const ( DialTimeout = 60 * time.Second ) +type HostOptions struct { + IP string + Port string + K int + BlacklistingUA string + BlacklistedPeers map[peer.ID]struct{} +} + type Host struct { ctx context.Context @@ -40,9 +46,24 @@ type Host struct { StartTime time.Time } -func NewHost(ctx context.Context, privKey crypto.PrivKey, ip, port string, bucketSize int, hydraFilter bool) (*Host, error) { +func NewHost( + ctx context.Context, + ip, port string, + bucketSize int, + blacklistingUA string, + blacklistedPeers map[peer.ID]struct{}) (*Host, error) { log.Debug("Creating host") + // prevent dial backoffs + ctx = network.WithForceDirectDial(ctx, "prevent backoff") + + // generate private key for the publisher Libp2p host + privKey, _, err := crypto.GenerateKeyPair(crypto.Secp256k1, 256) + if err != nil { + return nil, errors.Wrap(err, "unable to generate priv key for client's host") + } + log.Debugf("Generated Priv Key for the host %s", PrivKeyToString(privKey)) + // compose the multiaddress mAddr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%s", ip, port)) if err != nil { @@ -50,38 +71,23 @@ func NewHost(ctx context.Context, privKey crypto.PrivKey, ip, port string, bucke } var dht *kaddht.IpfsDHT + // generate a new custom message sender + msgSender := NewCustomMessageSender(blacklistingUA) - // check if hydra filter has been tuned - var blacklistedUA string - var blacklistPeers map[peer.ID]struct{} - if hydraFilter { - log.Info("hydra-filter: ON -> crawling network to identify hydra-boosters (might take 5-7mins)") - blacklistedUA = config.DefaultBlacklistUserAgent - // launch light crawler identifying balcklistable peers - crawlResutls, err := crawler.RunLightCrawler(ctx, blacklistedUA) - if err != nil { - return nil, err - } - blacklistPeers = crawlResutls.GetBlacklistedPeers() + // unlimit the resources for the host + limiter := rcmgr.NewFixedLimiter(rcmgr.InfiniteLimits) + rm, err := rcmgr.NewResourceManager(limiter) + if err != nil { + return nil, fmt.Errorf("new resource manager: %w", err) } - // // Configure the resource manager to not yell at us - // limiter := rcmgr.NewFixedLimiter(rcmgr.InfiniteLimits) - // rm, err := rcmgr.NewResourceManager(limiter) - // if err != nil { - // panic(err) - // } - - // generate a new custom message sender - msgSender := NewCustomMessageSender(blacklistedUA) - // generate the libp2p host h, err := libp2p.New( libp2p.WithDialTimeout(DialTimeout), libp2p.ListenAddrs(mAddr), libp2p.Identity(privKey), libp2p.UserAgent(config.UserAgent), - libp2p.ResourceManager(network.NullResourceManager), + libp2p.ResourceManager(rm), libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { var err error dht, err = kaddht.New(ctx, h, @@ -89,7 +95,7 @@ func NewHost(ctx context.Context, privKey crypto.PrivKey, ip, port string, bucke // Consider a Wrapper around MessageSender to get more details of underneath processes kaddht.WithCustomMessageSender(msgSender.Init), kaddht.BucketSize(bucketSize), - kaddht.WithPeerBlacklist(blacklistPeers), // always blacklist (can be an empty map or a full one) + kaddht.WithPeerBlacklist(blacklistedPeers), // always blacklist (can be an empty map or a full one) ) return dht, err }), @@ -97,7 +103,6 @@ func NewHost(ctx context.Context, privKey crypto.PrivKey, ip, port string, bucke if err != nil { return nil, err } - // check if the DHT is empty or not if dht == nil { return nil, errors.New("error - no IpfsDHT server has been initialized") @@ -140,7 +145,7 @@ func (h *Host) Boostrap(ctx context.Context) error { } else { atomic.AddInt64(&succCon, 1) } - }(bnode) + }(*bnode) } wg.Wait() diff --git a/pkg/p2p/notifier.go b/pkg/p2p/notifier.go index a2d882c..fcffeee 100644 --- a/pkg/p2p/notifier.go +++ b/pkg/p2p/notifier.go @@ -7,7 +7,7 @@ import ( "github.com/libp2p/go-libp2p/core/peer" ) -//This is the struct type received and send by the notifier's channel. +// This is the struct type received and send by the notifier's channel. type MsgNotification struct { RemotePeer peer.ID QueryTime time.Time @@ -29,10 +29,12 @@ func NewMsgNotifier() *Notifier { } } -//This returns the channel of the notifier struct: +// This returns the channel of the notifier struct: +// +// msgChan chan *MsgNotification +// +// The notifier channel receives and sends: // -// msgChan chan *MsgNotification -//The notifier channel receives and sends: // MsgNotification struct{ // RemotePeer peer.ID // QueryTime time.Time @@ -45,17 +47,21 @@ func (notifier_instance *Notifier) GetNotifierChan() chan *MsgNotification { return notifier_instance.msgChan } -//Sends a new: +// Sends a new: +// // MsgNotification struct{ // ... // } +// // To the underlying channel: +// // msgChan chan *MsgNotification func (notifier_instance *Notifier) Notify(msgStatus *MsgNotification) { notifier_instance.msgChan <- msgStatus } // Closes the underlying: +// // msgChan chan *MsgNotification func (notifier_instance *Notifier) Close() { close(notifier_instance.msgChan)