diff --git a/benchmarks/benchmark_test.go b/benchmarks/benchmark_test.go index 11bd970d..9648945e 100644 --- a/benchmarks/benchmark_test.go +++ b/benchmarks/benchmark_test.go @@ -29,13 +29,17 @@ import ( "github.com/ipld/go-ipld-prime/node/basicnode" ipldselector "github.com/ipld/go-ipld-prime/traversal/selector" "github.com/ipld/go-ipld-prime/traversal/selector/builder" + protocol "github.com/libp2p/go-libp2p/core/protocol" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "github.com/ipfs/go-graphsync/benchmarks/testinstance" - tn "github.com/ipfs/go-graphsync/benchmarks/testnet" graphsync "github.com/ipfs/go-graphsync/impl" + gsmsg "github.com/ipfs/go-graphsync/message" + gsmsgv2 "github.com/ipfs/go-graphsync/message/v2" + gsnet "github.com/ipfs/go-graphsync/network" + tn "github.com/ipfs/go-protocolnetwork/pkg/testnet" ) type runStats struct { @@ -78,7 +82,8 @@ func BenchmarkRoundtripSuccess(b *testing.B) { func benchmarkRepeatedDisconnects(ctx context.Context, b *testing.B, numnodes int, df distFunc, tdm *tempDirMaker) { ctx, cancel := context.WithCancel(ctx) mn := mocknet.New() - net := tn.StreamNet(ctx, mn) + net, err := tn.StreamNet[gsmsg.GraphSyncMessage](ctx, "graphsync", []protocol.ID{gsnet.ProtocolGraphsync_2_0_0}, gsnet.NewMessageHandlerSelector(), mn) + require.NoError(b, err) ig := testinstance.NewTestInstanceGenerator(ctx, net, nil, tdm, false) instances, err := ig.Instances(numnodes + 1) require.NoError(b, err) @@ -147,7 +152,8 @@ func p2pStrestTest(ctx context.Context, b *testing.B, numfiles int, df distFunc, defer cancel() mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{Latency: 100 * time.Millisecond, Bandwidth: 3000000}) - net := tn.StreamNet(ctx, mn) + net, err := tn.StreamNet[gsmsg.GraphSyncMessage](ctx, "graphsync", []protocol.ID{gsnet.ProtocolGraphsync_2_0_0}, gsnet.NewMessageHandlerSelector(), mn) + require.NoError(b, err) ig := testinstance.NewTestInstanceGenerator(ctx, net, options, tdm, diskBasedDatastore) instances, err := ig.Instances(1 + b.N) require.NoError(b, err) @@ -198,7 +204,7 @@ func p2pStrestTest(ctx context.Context, b *testing.B, numfiles int, df distFunc, func subtestDistributeAndFetch(ctx context.Context, b *testing.B, numnodes int, d delay.D, bstoreLatency time.Duration, df distFunc, tdm *tempDirMaker) { ctx, cancel := context.WithCancel(ctx) defer cancel() - net := tn.VirtualNetwork(d) + net := tn.VirtualNetwork[gsmsg.GraphSyncMessage](d, []protocol.ID{gsnet.ProtocolGraphsync_2_0_0}, gsmsgv2.NewMessageHandler()) ig := testinstance.NewTestInstanceGenerator(ctx, net, nil, tdm, false) instances, err := ig.Instances(numnodes + b.N) require.NoError(b, err) diff --git a/benchmarks/testinstance/testinstance.go b/benchmarks/testinstance/testinstance.go index d69ae7fb..7cddad70 100644 --- a/benchmarks/testinstance/testinstance.go +++ b/benchmarks/testinstance/testinstance.go @@ -10,14 +10,15 @@ import ( badgerds "github.com/ipfs/go-ds-badger" blockstore "github.com/ipfs/go-ipfs-blockstore" delay "github.com/ipfs/go-ipfs-delay" + tn "github.com/ipfs/go-protocolnetwork/pkg/testnet" "github.com/ipld/go-ipld-prime" tnet "github.com/libp2p/go-libp2p-testing/net" p2ptestutil "github.com/libp2p/go-libp2p-testing/netutil" peer "github.com/libp2p/go-libp2p/core/peer" graphsync "github.com/ipfs/go-graphsync" - tn "github.com/ipfs/go-graphsync/benchmarks/testnet" gsimpl "github.com/ipfs/go-graphsync/impl" + gsmsg "github.com/ipfs/go-graphsync/message" gsnet "github.com/ipfs/go-graphsync/network" "github.com/ipfs/go-graphsync/storeutil" ) @@ -29,7 +30,7 @@ type TempDirGenerator interface { // NewTestInstanceGenerator generates a new InstanceGenerator for the given // testnet -func NewTestInstanceGenerator(ctx context.Context, net tn.Network, gsOptions []gsimpl.Option, tempDirGenerator TempDirGenerator, diskBasedDatastore bool) InstanceGenerator { +func NewTestInstanceGenerator(ctx context.Context, net tn.Network[gsmsg.GraphSyncMessage], gsOptions []gsimpl.Option, tempDirGenerator TempDirGenerator, diskBasedDatastore bool) InstanceGenerator { ctx, cancel := context.WithCancel(ctx) return InstanceGenerator{ net: net, @@ -45,7 +46,7 @@ func NewTestInstanceGenerator(ctx context.Context, net tn.Network, gsOptions []g // InstanceGenerator generates new test instances of bitswap+dependencies type InstanceGenerator struct { seq int - net tn.Network + net tn.Network[gsmsg.GraphSyncMessage] ctx context.Context cancel context.CancelFunc gsOptions []gsimpl.Option @@ -139,7 +140,7 @@ func (i *Instance) SetBlockstoreLatency(t time.Duration) time.Duration { // NB: It's easy make mistakes by providing the same peer ID to two different // instances. To safeguard, use the InstanceGenerator to generate instances. It's // just a much better idea. -func NewInstance(ctx context.Context, net tn.Network, p tnet.Identity, gsOptions []gsimpl.Option, tempDir string, diskBasedDatastore bool) (Instance, error) { +func NewInstance(ctx context.Context, net tn.Network[gsmsg.GraphSyncMessage], p tnet.Identity, gsOptions []gsimpl.Option, tempDir string, diskBasedDatastore bool) (Instance, error) { bsdelay := delay.Fixed(0) adapter := net.Adapter(p) diff --git a/benchmarks/testnet/interface.go b/benchmarks/testnet/interface.go deleted file mode 100644 index 5a947aef..00000000 --- a/benchmarks/testnet/interface.go +++ /dev/null @@ -1,15 +0,0 @@ -package testnet - -import ( - tnet "github.com/libp2p/go-libp2p-testing/net" - "github.com/libp2p/go-libp2p/core/peer" - - gsnet "github.com/ipfs/go-graphsync/network" -) - -// Network is an interface for generating graphsync network interfaces -// based on a test network. -type Network interface { - Adapter(tnet.Identity) gsnet.GraphSyncNetwork - HasPeer(peer.ID) bool -} diff --git a/benchmarks/testnet/internet_latency_delay_generator.go b/benchmarks/testnet/internet_latency_delay_generator.go deleted file mode 100644 index eca20941..00000000 --- a/benchmarks/testnet/internet_latency_delay_generator.go +++ /dev/null @@ -1,63 +0,0 @@ -package testnet - -import ( - "math/rand" - "time" - - delay "github.com/ipfs/go-ipfs-delay" -) - -var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano())) - -// InternetLatencyDelayGenerator generates three clusters of delays, -// typical of the type of peers you would encounter on the interenet. -// Given a base delay time T, the wait time generated will be either: -// 1. A normalized distribution around the base time -// 2. A normalized distribution around the base time plus a "medium" delay -// 3. A normalized distribution around the base time plus a "large" delay -// The size of the medium & large delays are determined when the generator -// is constructed, as well as the relative percentages with which delays fall -// into each of the three different clusters, and the standard deviation for -// the normalized distribution. -// This can be used to generate a number of scenarios typical of latency -// distribution among peers on the internet. -func InternetLatencyDelayGenerator( - mediumDelay time.Duration, - largeDelay time.Duration, - percentMedium float64, - percentLarge float64, - std time.Duration, - rng *rand.Rand) delay.Generator { - if rng == nil { - rng = sharedRNG - } - - return &internetLatencyDelayGenerator{ - mediumDelay: mediumDelay, - largeDelay: largeDelay, - percentLarge: percentLarge, - percentMedium: percentMedium, - std: std, - rng: rng, - } -} - -type internetLatencyDelayGenerator struct { - mediumDelay time.Duration - largeDelay time.Duration - percentLarge float64 - percentMedium float64 - std time.Duration - rng *rand.Rand -} - -func (d *internetLatencyDelayGenerator) NextWaitTime(t time.Duration) time.Duration { - clusterDistribution := d.rng.Float64() - baseDelay := time.Duration(d.rng.NormFloat64()*float64(d.std)) + t - if clusterDistribution < d.percentLarge { - return baseDelay + d.largeDelay - } else if clusterDistribution < d.percentMedium+d.percentLarge { - return baseDelay + d.mediumDelay - } - return baseDelay -} diff --git a/benchmarks/testnet/internet_latency_delay_generator_test.go b/benchmarks/testnet/internet_latency_delay_generator_test.go deleted file mode 100644 index 4680420c..00000000 --- a/benchmarks/testnet/internet_latency_delay_generator_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package testnet_test - -import ( - "math" - "math/rand" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/ipfs/go-graphsync/benchmarks/testnet" -) - -const testSeed = 99 - -func TestInternetLatencyDelayNextWaitTimeDistribution(t *testing.T) { - initialValue := 1000 * time.Millisecond - deviation := 100 * time.Millisecond - mediumDelay := 1000 * time.Millisecond - largeDelay := 3000 * time.Millisecond - percentMedium := 0.2 - percentLarge := 0.4 - buckets := make(map[string]int) - internetLatencyDistributionDelay := testnet.InternetLatencyDelayGenerator( - mediumDelay, - largeDelay, - percentMedium, - percentLarge, - deviation, - rand.New(rand.NewSource(testSeed))) - - buckets["fast"] = 0 - buckets["medium"] = 0 - buckets["slow"] = 0 - buckets["outside_1_deviation"] = 0 - - // strategy here is rather than mock randomness, just use enough samples to - // get approximately the distribution you'd expect - for i := 0; i < 10000; i++ { - next := internetLatencyDistributionDelay.NextWaitTime(initialValue) - if math.Abs((next - initialValue).Seconds()) <= deviation.Seconds() { - buckets["fast"]++ - } else if math.Abs((next - initialValue - mediumDelay).Seconds()) <= deviation.Seconds() { - buckets["medium"]++ - } else if math.Abs((next - initialValue - largeDelay).Seconds()) <= deviation.Seconds() { - buckets["slow"]++ - } else { - buckets["outside_1_deviation"]++ - } - } - totalInOneDeviation := float64(10000 - buckets["outside_1_deviation"]) - oneDeviationPercentage := totalInOneDeviation / 10000 - fastPercentageResult := float64(buckets["fast"]) / totalInOneDeviation - mediumPercentageResult := float64(buckets["medium"]) / totalInOneDeviation - slowPercentageResult := float64(buckets["slow"]) / totalInOneDeviation - - // see 68-95-99 rule for normal distributions - require.LessOrEqual(t, math.Abs(oneDeviationPercentage-0.6827), 0.1, "should distribute values normally based on standard deviation") - - require.LessOrEqual(t, math.Abs(fastPercentageResult+percentMedium+percentLarge-1), 0.1, "should have correct percentage of values distributed around fast delay time") - require.LessOrEqual(t, math.Abs(mediumPercentageResult-percentMedium), 0.1, "should have correct percentage of values distributed around medium delay time") - require.LessOrEqual(t, math.Abs(slowPercentageResult-percentLarge), 0.1, "should have correct percentage of values distributed around slow delay time") -} diff --git a/benchmarks/testnet/network_test.go b/benchmarks/testnet/network_test.go deleted file mode 100644 index 69966173..00000000 --- a/benchmarks/testnet/network_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package testnet_test - -import ( - "context" - "sync" - "testing" - - blocks "github.com/ipfs/go-block-format" - delay "github.com/ipfs/go-ipfs-delay" - tnet "github.com/libp2p/go-libp2p-testing/net" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/stretchr/testify/require" - - "github.com/ipfs/go-graphsync/benchmarks/testnet" - gsmsg "github.com/ipfs/go-graphsync/message" - gsnet "github.com/ipfs/go-graphsync/network" -) - -func TestSendMessageAsyncButWaitForResponse(t *testing.T) { - net := testnet.VirtualNetwork(delay.Fixed(0)) - responderPeer := tnet.RandIdentityOrFatal(t) - waiter := net.Adapter(tnet.RandIdentityOrFatal(t)) - responder := net.Adapter(responderPeer) - - var wg sync.WaitGroup - - wg.Add(1) - - expectedStr := "received async" - - responder.SetDelegate(lambda(func( - ctx context.Context, - fromWaiter peer.ID, - msgFromWaiter gsmsg.GraphSyncMessage) { - - builder := gsmsg.NewBuilder() - builder.AddBlock(blocks.NewBlock([]byte(expectedStr))) - msgToWaiter, err := builder.Build() - require.NoError(t, err) - err = waiter.SendMessage(ctx, fromWaiter, msgToWaiter) - if err != nil { - t.Error(err) - } - })) - - waiter.SetDelegate(lambda(func( - ctx context.Context, - fromResponder peer.ID, - msgFromResponder gsmsg.GraphSyncMessage) { - - // TODO assert that this came from the correct peer and that the message contents are as expected - ok := false - for _, b := range msgFromResponder.Blocks() { - if string(b.RawData()) == expectedStr { - wg.Done() - ok = true - } - } - - if !ok { - t.Fatal("Message not received from the responder") - } - })) - - builder := gsmsg.NewBuilder() - builder.AddBlock(blocks.NewBlock([]byte("data"))) - messageSentAsync, err := builder.Build() - require.NoError(t, err) - errSending := waiter.SendMessage( - context.Background(), responderPeer.ID(), messageSentAsync) - if errSending != nil { - t.Fatal(errSending) - } - - wg.Wait() // until waiter delegate function is executed -} - -type receiverFunc func(ctx context.Context, p peer.ID, - incoming gsmsg.GraphSyncMessage) - -// lambda returns a Receiver instance given a receiver function -func lambda(f receiverFunc) gsnet.Receiver { - return &lambdaImpl{ - f: f, - } -} - -type lambdaImpl struct { - f func(ctx context.Context, p peer.ID, incoming gsmsg.GraphSyncMessage) -} - -func (lam *lambdaImpl) ReceiveMessage(ctx context.Context, - p peer.ID, incoming gsmsg.GraphSyncMessage) { - lam.f(ctx, p, incoming) -} - -func (lam *lambdaImpl) ReceiveError(_ peer.ID, _ error) { - // TODO log error -} - -func (lam *lambdaImpl) Connected(p peer.ID) { - // TODO -} -func (lam *lambdaImpl) Disconnected(peer.ID) { - // TODO -} diff --git a/benchmarks/testnet/peernet.go b/benchmarks/testnet/peernet.go deleted file mode 100644 index 9c918323..00000000 --- a/benchmarks/testnet/peernet.go +++ /dev/null @@ -1,43 +0,0 @@ -package testnet - -import ( - "context" - - tnet "github.com/libp2p/go-libp2p-testing/net" - "github.com/libp2p/go-libp2p/core/peer" - mockpeernet "github.com/libp2p/go-libp2p/p2p/net/mock" - - gsnet "github.com/ipfs/go-graphsync/network" -) - -type peernet struct { - mockpeernet.Mocknet -} - -// StreamNet is a testnet that uses libp2p's MockNet -func StreamNet(ctx context.Context, net mockpeernet.Mocknet) Network { - return &peernet{net} -} - -func (pn *peernet) Adapter(p tnet.Identity) gsnet.GraphSyncNetwork { - client, err := pn.Mocknet.AddPeer(p.PrivateKey(), p.Address()) - if err != nil { - panic(err.Error()) - } - err = pn.Mocknet.LinkAll() - if err != nil { - panic(err.Error()) - } - return gsnet.NewFromLibp2pHost(client) -} - -func (pn *peernet) HasPeer(p peer.ID) bool { - for _, member := range pn.Mocknet.Peers() { - if p == member { - return true - } - } - return false -} - -var _ Network = (*peernet)(nil) diff --git a/benchmarks/testnet/rate_limit_generators.go b/benchmarks/testnet/rate_limit_generators.go deleted file mode 100644 index 1fe3fcc6..00000000 --- a/benchmarks/testnet/rate_limit_generators.go +++ /dev/null @@ -1,42 +0,0 @@ -package testnet - -import ( - "math/rand" -) - -type fixedRateLimitGenerator struct { - rateLimit float64 -} - -// FixedRateLimitGenerator returns a rate limit generatoe that always generates -// the specified rate limit in bytes/sec. -func FixedRateLimitGenerator(rateLimit float64) RateLimitGenerator { - return &fixedRateLimitGenerator{rateLimit} -} - -func (rateLimitGenerator *fixedRateLimitGenerator) NextRateLimit() float64 { - return rateLimitGenerator.rateLimit -} - -type variableRateLimitGenerator struct { - rateLimit float64 - std float64 - rng *rand.Rand -} - -// VariableRateLimitGenerator makes rate limites that following a normal distribution. -func VariableRateLimitGenerator(rateLimit float64, std float64, rng *rand.Rand) RateLimitGenerator { - if rng == nil { - rng = sharedRNG - } - - return &variableRateLimitGenerator{ - std: std, - rng: rng, - rateLimit: rateLimit, - } -} - -func (rateLimitGenerator *variableRateLimitGenerator) NextRateLimit() float64 { - return rateLimitGenerator.rng.NormFloat64()*rateLimitGenerator.std + rateLimitGenerator.rateLimit -} diff --git a/benchmarks/testnet/virtual.go b/benchmarks/testnet/virtual.go deleted file mode 100644 index d78225c3..00000000 --- a/benchmarks/testnet/virtual.go +++ /dev/null @@ -1,314 +0,0 @@ -package testnet - -import ( - "bytes" - "context" - "errors" - "sort" - "sync" - "time" - - delay "github.com/ipfs/go-ipfs-delay" - mockrouting "github.com/ipfs/go-ipfs-routing/mock" - tnet "github.com/libp2p/go-libp2p-testing/net" - "github.com/libp2p/go-libp2p/core/connmgr" - "github.com/libp2p/go-libp2p/core/peer" - mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" - - gsmsg "github.com/ipfs/go-graphsync/message" - gsmsgv2 "github.com/ipfs/go-graphsync/message/v2" - gsnet "github.com/ipfs/go-graphsync/network" -) - -// VirtualNetwork generates a new testnet instance - a fake network that -// is used to simulate sending messages. -func VirtualNetwork(d delay.D) Network { - return &network{ - latencies: make(map[peer.ID]map[peer.ID]time.Duration), - clients: make(map[peer.ID]*receiverQueue), - delay: d, - isRateLimited: false, - rateLimitGenerator: nil, - conns: make(map[string]struct{}), - } -} - -// RateLimitGenerator is an interface for generating rate limits across peers -type RateLimitGenerator interface { - NextRateLimit() float64 -} - -// RateLimitedVirtualNetwork generates a testnet instance where nodes are rate -// limited in the upload/download speed. -func RateLimitedVirtualNetwork(rs mockrouting.Server, d delay.D, rateLimitGenerator RateLimitGenerator) Network { - return &network{ - latencies: make(map[peer.ID]map[peer.ID]time.Duration), - rateLimiters: make(map[peer.ID]map[peer.ID]*mocknet.RateLimiter), - clients: make(map[peer.ID]*receiverQueue), - delay: d, - isRateLimited: true, - rateLimitGenerator: rateLimitGenerator, - conns: make(map[string]struct{}), - } -} - -type network struct { - mu sync.Mutex - latencies map[peer.ID]map[peer.ID]time.Duration - rateLimiters map[peer.ID]map[peer.ID]*mocknet.RateLimiter - clients map[peer.ID]*receiverQueue - delay delay.D - isRateLimited bool - rateLimitGenerator RateLimitGenerator - conns map[string]struct{} -} - -type message struct { - from peer.ID - msg gsmsg.GraphSyncMessage - shouldSend time.Time -} - -// receiverQueue queues up a set of messages to be sent, and sends them *in -// order* with their delays respected as much as sending them in order allows -// for -type receiverQueue struct { - receiver *networkClient - queue []*message - active bool - lk sync.Mutex -} - -func (n *network) Adapter(p tnet.Identity) gsnet.GraphSyncNetwork { - n.mu.Lock() - defer n.mu.Unlock() - - client := &networkClient{ - local: p.ID(), - network: n, - } - n.clients[p.ID()] = &receiverQueue{receiver: client} - return client -} - -func (n *network) HasPeer(p peer.ID) bool { - n.mu.Lock() - defer n.mu.Unlock() - - _, found := n.clients[p] - return found -} - -// TODO should this be completely asynchronous? -// TODO what does the network layer do with errors received from services? -func (n *network) SendMessage( - ctx context.Context, - from peer.ID, - to peer.ID, - mes gsmsg.GraphSyncMessage) error { - - mes = mes.Clone() - - n.mu.Lock() - defer n.mu.Unlock() - - latencies, ok := n.latencies[from] - if !ok { - latencies = make(map[peer.ID]time.Duration) - n.latencies[from] = latencies - } - - latency, ok := latencies[to] - if !ok { - latency = n.delay.NextWaitTime() - latencies[to] = latency - } - - var bandwidthDelay time.Duration - if n.isRateLimited { - rateLimiters, ok := n.rateLimiters[from] - if !ok { - rateLimiters = make(map[peer.ID]*mocknet.RateLimiter) - n.rateLimiters[from] = rateLimiters - } - - rateLimiter, ok := rateLimiters[to] - if !ok { - rateLimiter = mocknet.NewRateLimiter(n.rateLimitGenerator.NextRateLimit()) - rateLimiters[to] = rateLimiter - } - - buf := new(bytes.Buffer) - err := gsmsgv2.NewMessageHandler().ToNet(peer.ID("foo"), mes, buf) - if err != nil { - return err - } - size := buf.Len() - bandwidthDelay = rateLimiter.Limit(size) - } else { - bandwidthDelay = 0 - } - - receiver, ok := n.clients[to] - if !ok { - return errors.New("cannot locate peer on network") - } - - // nb: terminate the context since the context wouldn't actually be passed - // over the network in a real scenario - - msg := &message{ - from: from, - msg: mes, - shouldSend: time.Now().Add(latency).Add(bandwidthDelay), - } - receiver.enqueue(msg) - - return nil -} - -type networkClient struct { - local peer.ID - gsnet.Receiver - network *network -} - -func (nc *networkClient) SendMessage( - ctx context.Context, - to peer.ID, - message gsmsg.GraphSyncMessage) error { - if err := nc.network.SendMessage(ctx, nc.local, to, message); err != nil { - return err - } - return nil -} - -type messagePasser struct { - net *networkClient - target peer.ID - local peer.ID - ctx context.Context -} - -func (mp *messagePasser) SendMsg(ctx context.Context, m gsmsg.GraphSyncMessage) error { - return mp.net.SendMessage(ctx, mp.target, m) -} - -func (mp *messagePasser) Close() error { - return nil -} - -func (mp *messagePasser) Reset() error { - return nil -} - -func (nc *networkClient) NewMessageSender(ctx context.Context, p peer.ID, _ gsnet.MessageSenderOpts) (gsnet.MessageSender, error) { - return &messagePasser{ - net: nc, - target: p, - local: nc.local, - ctx: ctx, - }, nil -} - -func (nc *networkClient) SetDelegate(r gsnet.Receiver) { - nc.Receiver = r -} - -func (nc *networkClient) ConnectTo(_ context.Context, p peer.ID) error { - nc.network.mu.Lock() - otherClient, ok := nc.network.clients[p] - if !ok { - nc.network.mu.Unlock() - return errors.New("no such peer in network") - } - - tag := tagForPeers(nc.local, p) - if _, ok := nc.network.conns[tag]; ok { - nc.network.mu.Unlock() - // log.Warning("ALREADY CONNECTED TO PEER (is this a reconnect? test lib needs fixing)") - return nil - } - nc.network.conns[tag] = struct{}{} - nc.network.mu.Unlock() - - otherClient.receiver.Connected(nc.local) - nc.Receiver.Connected(p) - return nil -} - -func (nc *networkClient) DisconnectFrom(_ context.Context, p peer.ID) error { - nc.network.mu.Lock() - defer nc.network.mu.Unlock() - - otherClient, ok := nc.network.clients[p] - if !ok { - return errors.New("no such peer in network") - } - - tag := tagForPeers(nc.local, p) - if _, ok := nc.network.conns[tag]; !ok { - // Already disconnected - return nil - } - delete(nc.network.conns, tag) - - otherClient.receiver.Disconnected(nc.local) - nc.Receiver.Disconnected(p) - return nil -} - -func (nc *networkClient) ConnectionManager() gsnet.ConnManager { - return &connmgr.NullConnMgr{} -} - -func (rq *receiverQueue) enqueue(m *message) { - rq.lk.Lock() - defer rq.lk.Unlock() - rq.queue = append(rq.queue, m) - if !rq.active { - rq.active = true - go rq.process() - } -} - -func (rq *receiverQueue) Swap(i, j int) { - rq.queue[i], rq.queue[j] = rq.queue[j], rq.queue[i] -} - -func (rq *receiverQueue) Len() int { - return len(rq.queue) -} - -func (rq *receiverQueue) Less(i, j int) bool { - return rq.queue[i].shouldSend.UnixNano() < rq.queue[j].shouldSend.UnixNano() -} - -func (rq *receiverQueue) process() { - for { - rq.lk.Lock() - sort.Sort(rq) - if len(rq.queue) == 0 { - rq.active = false - rq.lk.Unlock() - return - } - m := rq.queue[0] - if time.Until(m.shouldSend).Seconds() < 0.1 { - rq.queue = rq.queue[1:] - rq.lk.Unlock() - time.Sleep(time.Until(m.shouldSend)) - rq.receiver.ReceiveMessage(context.TODO(), m.from, m.msg) - } else { - rq.lk.Unlock() - time.Sleep(100 * time.Millisecond) - } - } -} - -func tagForPeers(a, b peer.ID) string { - if a < b { - return string(a + b) - } - return string(b + a) -} diff --git a/go.mod b/go.mod index 2a6bdef5..27024168 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e github.com/ipfs/go-block-format v0.0.3 github.com/ipfs/go-blockservice v0.3.0 - github.com/ipfs/go-cid v0.3.2 + github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ds-badger v0.3.0 github.com/ipfs/go-ipfs-blockstore v1.2.0 @@ -18,24 +18,23 @@ require ( github.com/ipfs/go-ipfs-delay v0.0.1 github.com/ipfs/go-ipfs-exchange-offline v0.2.0 github.com/ipfs/go-ipfs-pq v0.0.2 - github.com/ipfs/go-ipfs-routing v0.3.0 github.com/ipfs/go-ipfs-util v0.0.2 github.com/ipfs/go-ipld-format v0.3.0 github.com/ipfs/go-libipfs v0.1.0 github.com/ipfs/go-log/v2 v2.5.1 github.com/ipfs/go-merkledag v0.8.1 github.com/ipfs/go-peertaskqueue v0.8.0 + github.com/ipfs/go-protocolnetwork v0.0.3 github.com/ipfs/go-unixfs v0.4.3 github.com/ipfs/go-unixfsnode v1.5.2 github.com/ipld/go-codec-dagpb v1.5.0 github.com/ipld/go-ipld-prime v0.20.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c - github.com/libp2p/go-libp2p v0.25.0 + github.com/libp2p/go-libp2p v0.27.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-msgio v0.3.0 - github.com/multiformats/go-multiaddr v0.8.0 github.com/multiformats/go-multihash v0.2.1 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.3 go.opentelemetry.io/otel v1.2.0 go.opentelemetry.io/otel/sdk v1.2.0 go.opentelemetry.io/otel/trace v1.2.0 @@ -44,7 +43,7 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -52,56 +51,71 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/ristretto v0.0.2 // indirect github.com/dustin/go-humanize v1.0.0 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/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-20230405160723-4a4c7d95572b // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/huin/goupnp v1.0.3 // indirect + github.com/huin/goupnp v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect github.com/ipfs/go-ipfs-exchange-interface v0.1.0 // indirect github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect + github.com/ipfs/go-ipfs-routing v0.3.0 // indirect github.com/ipfs/go-ipld-cbor v0.0.5 // indirect github.com/ipfs/go-ipld-legacy v0.1.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-verifcid v0.0.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/cpuid/v2 v2.2.1 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect - github.com/libp2p/go-libp2p-record v0.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.53 // indirect github.com/minio/sha256-simd v1.0.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multiaddr v0.9.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.8.0 // indirect - github.com/multiformats/go-multistream v0.4.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multicodec v0.8.1 // indirect + github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/onsi/ginkgo/v2 v2.9.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect + github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-19 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -109,15 +123,17 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.4.0 // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.4.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/tools v0.3.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/go.sum b/go.sum index 08625861..bb449bde 100644 --- a/go.sum +++ b/go.sum @@ -2,38 +2,7 @@ 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= @@ -43,7 +12,6 @@ github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOv github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= 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/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -58,8 +26,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy 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/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -104,19 +72,15 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA 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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/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/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= 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/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= 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= @@ -188,21 +152,18 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME 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/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -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.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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-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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -216,23 +177,19 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= 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= @@ -243,8 +200,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD 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/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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= @@ -252,9 +209,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a 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.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= @@ -268,15 +223,9 @@ 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-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -286,10 +235,8 @@ 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/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -333,10 +280,9 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= 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.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= +github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/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/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= @@ -357,8 +303,8 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= -github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +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.0.1/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.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= @@ -436,6 +382,8 @@ github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= +github.com/ipfs/go-protocolnetwork v0.0.3 h1:775hug7o1FDDCkVJ8SM44Gxh7jo6p8m1FLsjodqxGj0= +github.com/ipfs/go-protocolnetwork v0.0.3/go.mod h1:5XPmTWg4+rTHetA1Hy/rdQ7b0FtsZ/EByrif8VkaWcI= github.com/ipfs/go-unixfs v0.4.3 h1:EdDc1sNZNFDUlo4UrVAvvAofVI5EwTnKu8Nv8mgXkWQ= github.com/ipfs/go-unixfs v0.4.3/go.mod h1:TSG7G1UuT+l4pNj91raXAPkX0BhJi3jST1FDTfQ5QyM= github.com/ipfs/go-unixfsnode v1.5.2 h1:CvsiTt58W2uR5dD8bqQv+aAY0c1qolmXmSyNbPHYiew= @@ -474,10 +422,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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/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.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 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= @@ -489,16 +434,17 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= +github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= -github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +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/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.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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/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/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -529,10 +475,10 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= -github.com/libp2p/go-libp2p v0.25.0 h1:ND6Hc6ZYCzC8S++C4mOD7LdPnLXRkNbr12/8FXgUfIo= -github.com/libp2p/go-libp2p v0.25.0/go.mod h1:vXHmFpcfl+xIGN4qW58Bw3a0/SKGAesr5/T4IuJHE3o= -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 v0.27.0 h1:QbhrTuB0ln9j9op6yAOR0o+cx/qa9NyNZ5ov0Tql8ZU= +github.com/libp2p/go-libp2p v0.27.0/go.mod h1:FAvvfQa/YOShUYdiSS03IR9OXzkcJXwcNA2FUCh9ImE= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= @@ -595,7 +541,6 @@ github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYc github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= 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-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= @@ -708,8 +653,8 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.13/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-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -721,8 +666,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -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.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= +github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= @@ -748,7 +693,6 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ 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/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -772,8 +716,8 @@ github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +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.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= @@ -792,10 +736,10 @@ github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysj github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= 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.8.0 h1:evBmgkbSQux+Ds2IgfhkO38Dl2GDtRW8/Rp6YiSHX/Q= -github.com/multiformats/go-multicodec v0.8.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= +github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -809,8 +753,8 @@ github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= -github.com/multiformats/go-multistream v0.4.0 h1:5i4JbawClkbuaX+mIVXiHQYVPxUW+zjv6w7jtSRukxc= -github.com/multiformats/go-multistream v0.4.0/go.mod h1:BS6ZSYcA4NwYEaIMeCtpJydp2Dc+fNRA6uJMSu/m8+4= +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.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -838,14 +782,15 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= 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.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= +github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.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.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -877,8 +822,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 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= @@ -887,8 +832,6 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -905,10 +848,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -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.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -916,15 +857,18 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= 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.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= -github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= -github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= -github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= -github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -964,11 +908,13 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 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/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/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 v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= -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/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= @@ -994,32 +940,30 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= 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.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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.0.0 h1:+HU9SCbu8GnEUFtIBfuUNXN39ofWViIEJIp6SURMpCg= github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= 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/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -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/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d h1:wSxKhvbN7kUoP0sfRS+w2tWr45qlU8409i94hHLOT8w= @@ -1035,9 +979,7 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go. github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 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/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= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1046,7 +988,6 @@ go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 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= @@ -1065,8 +1006,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/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= +go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= +go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= @@ -1074,8 +1015,8 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ 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.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= @@ -1099,7 +1040,6 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/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-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1112,43 +1052,25 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-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/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= -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-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-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.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +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-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= @@ -1167,30 +1089,15 @@ golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73r 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-20190923162816-aa69164e4478/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= @@ -1198,21 +1105,12 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= 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-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-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/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= @@ -1221,7 +1119,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ 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= @@ -1241,47 +1138,30 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h 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-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-20190526052359-791d8a0f4d09/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-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/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-20191220142924-d4481acd189f/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-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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1294,29 +1174,23 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-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= @@ -1327,54 +1201,25 @@ golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGm 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-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-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-20191108193012-7d206e10da11/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-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 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-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.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1385,64 +1230,20 @@ google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+ 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.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -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-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -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= @@ -1450,19 +1251,13 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/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.28.1/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.31.1/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= @@ -1473,12 +1268,11 @@ 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= +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/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= @@ -1503,7 +1297,6 @@ 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= @@ -1512,15 +1305,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.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -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= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/impl/graphsync.go b/impl/graphsync.go index 0b1e036d..9d597878 100644 --- a/impl/graphsync.go +++ b/impl/graphsync.go @@ -20,7 +20,6 @@ import ( "github.com/ipfs/go-graphsync/messagequeue" gsnet "github.com/ipfs/go-graphsync/network" "github.com/ipfs/go-graphsync/panics" - "github.com/ipfs/go-graphsync/peermanager" "github.com/ipfs/go-graphsync/peerstate" "github.com/ipfs/go-graphsync/persistenceoptions" "github.com/ipfs/go-graphsync/requestmanager" @@ -32,6 +31,7 @@ import ( "github.com/ipfs/go-graphsync/responsemanager/responseassembler" "github.com/ipfs/go-graphsync/selectorvalidator" "github.com/ipfs/go-graphsync/taskqueue" + "github.com/ipfs/go-protocolnetwork/pkg/messagequeuemanager" ) var log = logging.Logger("graphsync") @@ -42,6 +42,7 @@ const defaultMaxMemoryPerPeer = uint64(16 << 20) const defaultMaxInProgressRequests = uint64(6) const defaultMessageSendRetries = 10 const defaultSendMessageTimeout = 10 * time.Minute +const defaultSendErrorBackoff = 100 * time.Millisecond // GraphSync is an instance of a GraphSync exchange that implements // the graphsync protocol. @@ -55,7 +56,7 @@ type GraphSync struct { requestQueue taskqueue.TaskQueue requestExecutor *executor.Executor responseAssembler *responseassembler.ResponseAssembler - peerManager *peermanager.PeerMessageManager + peerManager *messagequeuemanager.MessageQueueManager[messagequeue.MessageParams] incomingRequestHooks *responderhooks.IncomingRequestHooks outgoingBlockHooks *responderhooks.OutgoingBlockHooks requestUpdatedHooks *responderhooks.RequestUpdatedHooks @@ -86,6 +87,7 @@ type graphsyncConfigOptions struct { maxLinksPerIncomingRequest uint64 messageSendRetries int sendMessageTimeout time.Duration + sendErrorBackoff time.Duration panicCallback panics.CallBackFn } @@ -214,6 +216,7 @@ func New(parent context.Context, network gsnet.GraphSyncNetwork, registerDefaultValidator: true, messageSendRetries: defaultMessageSendRetries, sendMessageTimeout: defaultSendMessageTimeout, + sendErrorBackoff: defaultSendErrorBackoff, panicCallback: nil, } for _, option := range options { @@ -237,10 +240,10 @@ func New(parent context.Context, network gsnet.GraphSyncNetwork, incomingRequestHooks.Register(selectorvalidator.SelectorValidator(maxRecursionDepth)) } responseAllocator := allocator.NewAllocator(gsConfig.totalMaxMemoryResponder, gsConfig.maxMemoryPerPeerResponder) - createMessageQueue := func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) peermanager.PeerQueue { - return messagequeue.New(ctx, p, network, responseAllocator, gsConfig.messageSendRetries, gsConfig.sendMessageTimeout, onShutdown) + createMessageQueue := func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) messagequeuemanager.MessageQueue[messagequeue.MessageParams] { + return messagequeue.New(ctx, p, network, responseAllocator, gsConfig.messageSendRetries, gsConfig.sendMessageTimeout, gsConfig.sendErrorBackoff, onShutdown) } - peerManager := peermanager.NewMessageManager(ctx, createMessageQueue) + peerManager := messagequeuemanager.NewMessageQueueManager(ctx, createMessageQueue) requestQueue := taskqueue.NewTaskQueue(ctx) requestManager := requestmanager.New(ctx, persistenceOptions, linkSystem, outgoingRequestHooks, incomingResponseHooks, networkErrorListeners, outgoingRequestProcessingListeners, requestQueue, network.ConnectionManager(), gsConfig.maxLinksPerOutgoingRequest, gsConfig.panicCallback) @@ -307,7 +310,7 @@ func New(parent context.Context, network gsnet.GraphSyncNetwork, requestQueue.Startup(gsConfig.maxInProgressOutgoingRequests, requestExecutor) responseManager.Startup() responseQueue.Startup(gsConfig.maxInProgressIncomingRequests, queryExecutor) - network.SetDelegate((*graphSyncReceiver)(graphSync)) + network.Start((*graphSyncReceiver)(graphSync)) return graphSync } @@ -506,12 +509,12 @@ func (gsr *graphSyncReceiver) ReceiveError(p peer.ID, err error) { // Connected is part of the networks 's Receiver interface and handles peers connecting // on the network -func (gsr *graphSyncReceiver) Connected(p peer.ID) { +func (gsr *graphSyncReceiver) PeerConnected(p peer.ID) { gsr.graphSync().peerManager.Connected(p) } // Connected is part of the networks 's Receiver interface and handles peers connecting // on the network -func (gsr *graphSyncReceiver) Disconnected(p peer.ID) { +func (gsr *graphSyncReceiver) PeerDisconnected(p peer.ID) { gsr.graphSync().peerManager.Disconnected(p) } diff --git a/message/builder_test.go b/message/builder_test.go index 25e22c04..bbb39cb7 100644 --- a/message/builder_test.go +++ b/message/builder_test.go @@ -1,4 +1,4 @@ -package message +package message_test import ( "io" @@ -9,7 +9,9 @@ import ( "github.com/ipld/go-ipld-prime/node/basicnode" "github.com/stretchr/testify/require" + "github.com/ipfs/go-cid" "github.com/ipfs/go-graphsync" + gsmsg "github.com/ipfs/go-graphsync/message" "github.com/ipfs/go-graphsync/testutil" ) @@ -39,13 +41,13 @@ func TestMessageBuilding(t *testing.T) { requestID4 := graphsync.NewRequestID() closer := io.NopCloser(nil) testCases := map[string]struct { - build func(*Builder) + build func(*gsmsg.Builder) expectedSize uint64 expectedStreams map[graphsync.RequestID]io.Closer - checkMsg func(t *testing.T, message GraphSyncMessage) + checkMsg func(t *testing.T, message gsmsg.GraphSyncMessage) }{ "normal building": { - build: func(rb *Builder) { + build: func(rb *gsmsg.Builder) { rb.AddLink(requestID1, links[0], graphsync.LinkActionPresent) rb.AddLink(requestID1, links[1], graphsync.LinkActionMissing) @@ -74,7 +76,7 @@ func TestMessageBuilding(t *testing.T) { requestID1: closer, requestID2: closer, }, - checkMsg: func(t *testing.T, message GraphSyncMessage) { + checkMsg: func(t *testing.T, message gsmsg.GraphSyncMessage) { responses := message.Responses() sentBlocks := message.Blocks() @@ -82,7 +84,7 @@ func TestMessageBuilding(t *testing.T) { response1 := findResponseForRequestID(t, responses, requestID1) require.Equal(t, graphsync.RequestCompletedPartial, response1.Status(), "did not generate completed partial response") - assertMetadata(t, response1, []GraphSyncLinkMetadatum{ + assertMetadata(t, response1, []gsmsg.GraphSyncLinkMetadatum{ {Link: links[0].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionMissing}, {Link: links[2].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, @@ -91,7 +93,7 @@ func TestMessageBuilding(t *testing.T) { response2 := findResponseForRequestID(t, responses, requestID2) require.Equal(t, graphsync.RequestCompletedFull, response2.Status(), "did not generate completed full response") - assertMetadata(t, response2, []GraphSyncLinkMetadatum{ + assertMetadata(t, response2, []gsmsg.GraphSyncLinkMetadatum{ {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, {Link: links[2].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, @@ -99,7 +101,7 @@ func TestMessageBuilding(t *testing.T) { response3 := findResponseForRequestID(t, responses, requestID3) require.Equal(t, graphsync.PartialResponse, response3.Status(), "did not generate partial response") - assertMetadata(t, response3, []GraphSyncLinkMetadatum{ + assertMetadata(t, response3, []gsmsg.GraphSyncLinkMetadatum{ {Link: links[0].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionDuplicateNotSent}, }) @@ -116,12 +118,12 @@ func TestMessageBuilding(t *testing.T) { }, }, "message with only extensions": { - build: func(rb *Builder) { + build: func(rb *gsmsg.Builder) { rb.AddExtensionData(requestID1, extension1) rb.AddExtensionData(requestID2, extension2) }, expectedSize: 0, - checkMsg: func(t *testing.T, message GraphSyncMessage) { + checkMsg: func(t *testing.T, message gsmsg.GraphSyncMessage) { responses := message.Responses() response1 := findResponseForRequestID(t, responses, requestID1) @@ -136,7 +138,7 @@ func TestMessageBuilding(t *testing.T) { }, }, "scrub response": { - build: func(rb *Builder) { + build: func(rb *gsmsg.Builder) { rb.AddLink(requestID1, links[0], graphsync.LinkActionPresent) rb.AddLink(requestID1, links[1], graphsync.LinkActionMissing) @@ -161,7 +163,7 @@ func TestMessageBuilding(t *testing.T) { rb.ScrubResponses([]graphsync.RequestID{requestID1}) }, expectedSize: 200, - checkMsg: func(t *testing.T, message GraphSyncMessage) { + checkMsg: func(t *testing.T, message gsmsg.GraphSyncMessage) { responses := message.Responses() sentBlocks := message.Blocks() @@ -169,7 +171,7 @@ func TestMessageBuilding(t *testing.T) { response2 := findResponseForRequestID(t, responses, requestID2) require.Equal(t, graphsync.RequestCompletedFull, response2.Status(), "did not generate completed full response") - assertMetadata(t, response2, []GraphSyncLinkMetadatum{ + assertMetadata(t, response2, []gsmsg.GraphSyncLinkMetadatum{ {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, {Link: links[2].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, @@ -177,7 +179,7 @@ func TestMessageBuilding(t *testing.T) { response3 := findResponseForRequestID(t, responses, requestID3) require.Equal(t, graphsync.PartialResponse, response3.Status(), "did not generate partial response") - assertMetadata(t, response3, []GraphSyncLinkMetadatum{ + assertMetadata(t, response3, []gsmsg.GraphSyncLinkMetadatum{ {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, }) assertExtension(t, response3, extension2) @@ -194,7 +196,7 @@ func TestMessageBuilding(t *testing.T) { }, }, "scrub multiple responses": { - build: func(rb *Builder) { + build: func(rb *gsmsg.Builder) { rb.AddLink(requestID1, links[0], graphsync.LinkActionPresent) rb.AddLink(requestID1, links[1], graphsync.LinkActionMissing) @@ -219,7 +221,7 @@ func TestMessageBuilding(t *testing.T) { rb.ScrubResponses([]graphsync.RequestID{requestID1, requestID2, requestID4}) }, expectedSize: 100, - checkMsg: func(t *testing.T, message GraphSyncMessage) { + checkMsg: func(t *testing.T, message gsmsg.GraphSyncMessage) { responses := message.Responses() sentBlocks := message.Blocks() @@ -227,7 +229,7 @@ func TestMessageBuilding(t *testing.T) { response3 := findResponseForRequestID(t, responses, requestID3) require.Equal(t, graphsync.PartialResponse, response3.Status(), "did not generate partial response") - assertMetadata(t, response3, []GraphSyncLinkMetadatum{ + assertMetadata(t, response3, []gsmsg.GraphSyncLinkMetadatum{ {Link: links[1].(cidlink.Link).Cid, Action: graphsync.LinkActionPresent}, }) assertExtension(t, response3, extension2) @@ -240,7 +242,7 @@ func TestMessageBuilding(t *testing.T) { } for testCase, data := range testCases { t.Run(testCase, func(t *testing.T) { - b := NewBuilder() + b := gsmsg.NewBuilder() data.build(b) require.Equal(t, data.expectedSize, b.BlockSize(), "did not calculate block size correctly") message, err := b.Build() @@ -250,22 +252,30 @@ func TestMessageBuilding(t *testing.T) { } } -func findResponseForRequestID(t *testing.T, responses []GraphSyncResponse, requestID graphsync.RequestID) GraphSyncResponse { +func findResponseForRequestID(t *testing.T, responses []gsmsg.GraphSyncResponse, requestID graphsync.RequestID) gsmsg.GraphSyncResponse { for _, response := range responses { if response.RequestID() == requestID { return response } } require.FailNow(t, "Could not find request") - return GraphSyncResponse{} + return gsmsg.GraphSyncResponse{} } -func assertExtension(t *testing.T, response GraphSyncResponse, extension graphsync.ExtensionData) { +func assertExtension(t *testing.T, response gsmsg.GraphSyncResponse, extension graphsync.ExtensionData) { returnedExtensionData, found := response.Extension(extension.Name) require.True(t, found) require.Equal(t, extension.Data, returnedExtensionData, "did not encode extension") } -func assertMetadata(t *testing.T, response GraphSyncResponse, expectedMetadata []GraphSyncLinkMetadatum) { - require.Equal(t, expectedMetadata, response.metadata, "incorrect metadata included in response") +func assertMetadata(t *testing.T, response gsmsg.GraphSyncResponse, expectedMetadata []gsmsg.GraphSyncLinkMetadatum) { + md := response.Metadata() + require.Equal(t, len(expectedMetadata), int(md.Length())) + idx := 0 + md.Iterate(func(c cid.Cid, la graphsync.LinkAction) { + require.Equal(t, expectedMetadata[idx].Link, c, "incorrect metadata included in response") + require.Equal(t, expectedMetadata[idx].Action, la, "incorrect metadata included in response") + idx++ + }) + require.Equal(t, idx, len(expectedMetadata)) } diff --git a/message/message.go b/message/message.go index b26e7e2a..6d3e89aa 100644 --- a/message/message.go +++ b/message/message.go @@ -4,9 +4,11 @@ import ( "fmt" "io" "strings" + "time" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log/v2" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/codec/dagjson" "github.com/ipld/go-ipld-prime/datamodel" @@ -401,3 +403,14 @@ func (gsr GraphSyncRequest) MergeExtensions(extensions []graphsync.ExtensionData } return newRequest(gsr.id, gsr.root, gsr.selector, gsr.priority, gsr.requestType, combinedExtensions), nil } + +func (gsm GraphSyncMessage) SendTimeout() time.Duration { + return time.Minute * 10 +} + +func (gsm GraphSyncMessage) Log(log *logging.ZapEventLogger, eventName string) { + if eventName == "outgoing" { + log.Debugf("Outgoing message with %d requests, %d responses, and %d blocks", + len(gsm.Requests()), len(gsm.Responses()), len(gsm.Blocks())) + } +} diff --git a/messagequeue/builder.go b/messagequeue/builder.go index 073f8e87..9a4178ab 100644 --- a/messagequeue/builder.go +++ b/messagequeue/builder.go @@ -6,7 +6,7 @@ import ( "github.com/ipfs/go-graphsync" gsmsg "github.com/ipfs/go-graphsync/message" - "github.com/ipfs/go-graphsync/notifications" + "github.com/ipfs/go-protocolnetwork/pkg/notifications" ) // Builder wraps a message builder with additional functions related to metadata @@ -16,7 +16,7 @@ type Builder struct { *gsmsg.Builder topic Topic responseStreams map[graphsync.RequestID]io.Closer - subscribers map[graphsync.RequestID]notifications.Subscriber + subscribers map[graphsync.RequestID]notifications.Subscriber[Topic, Event] blockData map[graphsync.RequestID][]graphsync.BlockData } @@ -27,7 +27,7 @@ func NewBuilder(ctx context.Context, topic Topic) *Builder { Builder: gsmsg.NewBuilder(), topic: topic, responseStreams: make(map[graphsync.RequestID]io.Closer), - subscribers: make(map[graphsync.RequestID]notifications.Subscriber), + subscribers: make(map[graphsync.RequestID]notifications.Subscriber[Topic, Event]), blockData: make(map[graphsync.RequestID][]graphsync.BlockData), } } @@ -42,7 +42,7 @@ func (b *Builder) SetResponseStream(requestID graphsync.RequestID, stream io.Clo } // SetSubscriber sets the given subscriber to get notified as events occur for this message -func (b *Builder) SetSubscriber(requestID graphsync.RequestID, subscriber notifications.Subscriber) { +func (b *Builder) SetSubscriber(requestID graphsync.RequestID, subscriber notifications.Subscriber[Topic, Event]) { b.subscribers[requestID] = subscriber } @@ -67,7 +67,7 @@ func (b *Builder) ResponseStreams() map[graphsync.RequestID]io.Closer { } // Subscribers inspect current subscribers -func (b *Builder) Subscribers() map[graphsync.RequestID]notifications.Subscriber { +func (b *Builder) Subscribers() map[graphsync.RequestID]notifications.Subscriber[Topic, Event] { return b.subscribers } @@ -75,23 +75,3 @@ func (b *Builder) Subscribers() map[graphsync.RequestID]notifications.Subscriber func (b *Builder) BlockData() map[graphsync.RequestID][]graphsync.BlockData { return b.blockData } - -func (b *Builder) build(publisher notifications.Publisher) (gsmsg.GraphSyncMessage, internalMetadata, error) { - message, err := b.Build() - if err != nil { - return gsmsg.GraphSyncMessage{}, internalMetadata{}, err - } - for _, subscriber := range b.subscribers { - publisher.Subscribe(b.topic, subscriber) - } - return message, internalMetadata{ - public: Metadata{ - BlockData: b.blockData, - ResponseCodes: message.ResponseCodes(), - }, - ctx: b.ctx, - topic: b.topic, - msgSize: b.BlockSize(), - responseStreams: b.responseStreams, - }, nil -} diff --git a/messagequeue/messagequeue.go b/messagequeue/messagequeue.go index 29f3a7a0..2045fe76 100644 --- a/messagequeue/messagequeue.go +++ b/messagequeue/messagequeue.go @@ -3,12 +3,13 @@ package messagequeue import ( "context" "errors" - "fmt" "io" "sync" "time" logging "github.com/ipfs/go-log/v2" + "github.com/ipfs/go-protocolnetwork/pkg/messagequeue" + "github.com/ipfs/go-protocolnetwork/pkg/network" "github.com/libp2p/go-libp2p/core/peer" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -17,8 +18,7 @@ import ( "github.com/ipfs/go-graphsync" gsmsg "github.com/ipfs/go-graphsync/message" - gsnet "github.com/ipfs/go-graphsync/network" - "github.com/ipfs/go-graphsync/notifications" + "github.com/ipfs/go-protocolnetwork/pkg/notifications" ) var log = logging.Logger("graphsync") @@ -47,84 +47,76 @@ type Event struct { Metadata Metadata } -// MessageNetwork is any network that can connect peers and generate a message -// sender. -type MessageNetwork interface { - NewMessageSender(context.Context, peer.ID, gsnet.MessageSenderOpts) (gsnet.MessageSender, error) - ConnectTo(context.Context, peer.ID) error -} - type Allocator interface { AllocateBlockMemory(p peer.ID, amount uint64) <-chan error ReleasePeerMemory(p peer.ID) error ReleaseBlockMemory(p peer.ID, amount uint64) error } -// MessageQueue implements queue of want messages to send to peers. -type MessageQueue struct { - p peer.ID - network MessageNetwork - ctx context.Context - - outgoingWork chan struct{} - done chan struct{} - doneOnce sync.Once +// MessageParams are parameters sent to build messages +type MessageParams struct { + Size uint64 + BuildMessageFn func(*Builder) +} +// messageBuilder implements queue of want messages to send to peers. +type messageBuilder struct { + ctx context.Context + p peer.ID // internal do not touch outside go routines - sender gsnet.MessageSender - eventPublisher notifications.Publisher - buildersLk sync.RWMutex - builders []*Builder - nextBuilderTopic Topic - allocator Allocator - maxRetries int - sendMessageTimeout time.Duration - onShutdown func(peer.ID) + eventPublisher notifications.Publisher[Topic, Event] + buildersLk sync.RWMutex + builders []*Builder + nextBuilderTopic Topic + allocator Allocator } // New creats a new MessageQueue. -func New(ctx context.Context, p peer.ID, network MessageNetwork, allocator Allocator, maxRetries int, sendMessageTimeout time.Duration, onShutdown func(peer.ID)) *MessageQueue { - return &MessageQueue{ - ctx: ctx, - network: network, - p: p, - outgoingWork: make(chan struct{}, 1), - done: make(chan struct{}), - eventPublisher: notifications.NewPublisher(), - allocator: allocator, - maxRetries: maxRetries, - sendMessageTimeout: sendMessageTimeout, - onShutdown: onShutdown, - } +func New(ctx context.Context, p peer.ID, messageNetwork messagequeue.MessageNetwork[gsmsg.GraphSyncMessage], allocator Allocator, maxRetries int, sendMessageTimeout time.Duration, sendErrorBackoff time.Duration, onShutdown func(peer.ID)) *messagequeue.MessageQueue[gsmsg.GraphSyncMessage, MessageParams] { + eventPublisher := notifications.NewPublisher[Topic, Event]() + messageBuilder := &messageBuilder{ + ctx: ctx, + p: p, + eventPublisher: eventPublisher, + allocator: allocator, + } + return messagequeue.New[gsmsg.GraphSyncMessage, MessageParams](ctx, p, messageNetwork, messageBuilder, &network.MessageSenderOpts{ + MaxRetries: maxRetries, + SendTimeout: sendMessageTimeout, + SendErrorBackoff: sendErrorBackoff, + }, eventPublisher.Startup, func() { + allocator.ReleasePeerMemory(p) + eventPublisher.Shutdown() + onShutdown(p) + }) + } // AllocateAndBuildMessage allows you to work modify the next message that is sent in the queue. // If blkSize > 0, message building may block until enough memory has been freed from the queues to allocate the message. -func (mq *MessageQueue) AllocateAndBuildMessage(size uint64, buildMessageFn func(*Builder)) { - if size > 0 { +func (mb *messageBuilder) BuildMessage(params MessageParams) bool { + if params.Size > 0 { select { - case <-mq.allocator.AllocateBlockMemory(mq.p, size): - case <-mq.ctx.Done(): - return + case <-mb.allocator.AllocateBlockMemory(mb.p, params.Size): + case <-mb.ctx.Done(): + return false } } - if mq.buildMessage(size, buildMessageFn) { - mq.signalWork() - } + return mb.buildMessage(params.Size, params.BuildMessageFn) } -func (mq *MessageQueue) buildMessage(size uint64, buildMessageFn func(*Builder)) bool { - mq.buildersLk.Lock() - defer mq.buildersLk.Unlock() - if shouldBeginNewResponse(mq.builders, size) { - topic := mq.nextBuilderTopic - mq.nextBuilderTopic++ - ctx, _ := otel.Tracer("graphsync").Start(mq.ctx, "message", trace.WithAttributes( +func (mb *messageBuilder) buildMessage(size uint64, buildMessageFn func(*Builder)) bool { + mb.buildersLk.Lock() + defer mb.buildersLk.Unlock() + if shouldBeginNewResponse(mb.builders, size) { + topic := mb.nextBuilderTopic + mb.nextBuilderTopic++ + ctx, _ := otel.Tracer("graphsync").Start(mb.ctx, "message", trace.WithAttributes( attribute.Int64("topic", int64(topic)), )) - mq.builders = append(mq.builders, NewBuilder(ctx, topic)) + mb.builders = append(mb.builders, NewBuilder(ctx, topic)) } - builder := mq.builders[len(mq.builders)-1] + builder := mb.builders[len(mb.builders)-1] buildMessageFn(builder) return !builder.Empty() } @@ -139,143 +131,52 @@ func shouldBeginNewResponse(builders []*Builder, blkSize uint64) bool { return builders[len(builders)-1].BlockSize()+blkSize > maxBlockSize } -// Startup starts the processing of messages, and creates an initial message -// based on the given initial wantlist. -func (mq *MessageQueue) Startup() { - go mq.runQueue() -} - -// Shutdown stops the processing of messages for a message queue. -func (mq *MessageQueue) Shutdown() { - mq.doneOnce.Do(func() { - close(mq.done) - }) -} - -func (mq *MessageQueue) runQueue() { - defer func() { - _ = mq.allocator.ReleasePeerMemory(mq.p) - mq.eventPublisher.Shutdown() - mq.onShutdown(mq.p) - }() - mq.eventPublisher.Startup() - for { - select { - case <-mq.outgoingWork: - mq.sendMessage() - case <-mq.done: - select { - case <-mq.outgoingWork: - for { - _, metadata, err := mq.extractOutgoingMessage() - if err == nil { - span := trace.SpanFromContext(metadata.ctx) - err := fmt.Errorf("message queue shutdown") - span.RecordError(err) - span.SetStatus(codes.Error, err.Error()) - span.End() - mq.publishError(metadata, err) - mq.eventPublisher.Close(metadata.topic) - } else { - break - } - } - default: - } - if mq.sender != nil { - mq.sender.Close() - } - return - case <-mq.ctx.Done(): - if mq.sender != nil { - _ = mq.sender.Reset() - } - return - } - } -} - -func (mq *MessageQueue) signalWork() { - select { - case mq.outgoingWork <- struct{}{}: - default: - } -} - var errEmptyMessage = errors.New("empty Message") -func (mq *MessageQueue) extractOutgoingMessage() (gsmsg.GraphSyncMessage, internalMetadata, error) { +func (mb *messageBuilder) NextMessage() (messagequeue.MessageSpec[gsmsg.GraphSyncMessage], bool, error) { // grab outgoing message - mq.buildersLk.Lock() - if len(mq.builders) == 0 { - mq.buildersLk.Unlock() - return gsmsg.GraphSyncMessage{}, internalMetadata{}, errEmptyMessage - } - builder := mq.builders[0] - mq.builders = mq.builders[1:] - // if there are more queued messages, signal we still have more work - if len(mq.builders) > 0 { - select { - case mq.outgoingWork <- struct{}{}: - default: - } - } - mq.buildersLk.Unlock() - if builder.Empty() { - return gsmsg.GraphSyncMessage{}, internalMetadata{}, errEmptyMessage - } - return builder.build(mq.eventPublisher) -} - -func (mq *MessageQueue) sendMessage() { - message, metadata, err := mq.extractOutgoingMessage() - - if err != nil { - if err != errEmptyMessage { - log.Errorf("Unable to assemble GraphSync message: %s", err.Error()) - } - return - } - span := trace.SpanFromContext(metadata.ctx) - defer span.End() - _, sendSpan := otel.Tracer("graphsync").Start(metadata.ctx, "sendMessage", trace.WithAttributes( - attribute.Int64("topic", int64(metadata.topic)), - attribute.Int64("size", int64(metadata.msgSize)), - )) - defer sendSpan.End() - mq.publishQueued(metadata) - defer mq.eventPublisher.Close(metadata.topic) - - err = mq.initializeSender() - if err != nil { - log.Infof("cant open message sender to peer %s: %s", mq.p, err) - // TODO: cant connect, what now? - mq.publishError(metadata, fmt.Errorf("cant open message sender to peer %s: %w", mq.p, err)) - select { - case <-mq.done: - default: - mq.Shutdown() + mb.buildersLk.Lock() + defer mb.buildersLk.Unlock() + if len(mb.builders) == 0 { + return nil, false, errEmptyMessage + } + b := mb.builders[0] + mb.builders = mb.builders[1:] + if b.Empty() { + return nil, len(mb.builders) > 0, errEmptyMessage + } + return func() (gsmsg.GraphSyncMessage, messagequeue.Notifier, error) { + message, err := b.Build() + if err != nil { + return gsmsg.GraphSyncMessage{}, &internalMetadata{}, err } - return - } - - for i := 0; i < mq.maxRetries; i++ { // try to send this message until we fail. - if mq.attemptSendAndRecovery(message, metadata) { - return + for _, subscriber := range b.subscribers { + mb.eventPublisher.Subscribe(b.topic, subscriber) } - } - mq.publishError(metadata, fmt.Errorf("expended retries on SendMsg(%s)", mq.p)) -} - -func (mq *MessageQueue) scrubResponseStreams(responseStreams map[graphsync.RequestID]io.Closer) { + return message, &internalMetadata{ + builder: mb, + span: trace.SpanFromContext(b.ctx), + public: Metadata{ + BlockData: b.blockData, + ResponseCodes: message.ResponseCodes(), + }, + ctx: b.ctx, + topic: b.topic, + msgSize: b.BlockSize(), + responseStreams: b.responseStreams, + }, nil + }, len(mb.builders) > 0, nil +} + +func (mb *messageBuilder) scrubResponseStreams(responseStreams map[graphsync.RequestID]io.Closer) { requestIDs := make([]graphsync.RequestID, 0, len(responseStreams)) for requestID, responseStream := range responseStreams { _ = responseStream.Close() requestIDs = append(requestIDs, requestID) } - totalFreed := mq.scrubResponses(requestIDs) + totalFreed := mb.scrubResponses(requestIDs) if totalFreed > 0 { - err := mq.allocator.ReleaseBlockMemory(mq.p, totalFreed) + err := mb.allocator.ReleaseBlockMemory(mb.p, totalFreed) if err != nil { log.Error(err) } @@ -284,90 +185,25 @@ func (mq *MessageQueue) scrubResponseStreams(responseStreams map[graphsync.Reque // ScrubResponses removes the given response and associated blocks // from all pending messages in the queue -func (mq *MessageQueue) scrubResponses(requestIDs []graphsync.RequestID) uint64 { - mq.buildersLk.Lock() - newBuilders := make([]*Builder, 0, len(mq.builders)) +func (mb *messageBuilder) scrubResponses(requestIDs []graphsync.RequestID) uint64 { + mb.buildersLk.Lock() + newBuilders := make([]*Builder, 0, len(mb.builders)) totalFreed := uint64(0) - for _, builder := range mq.builders { + for _, builder := range mb.builders { totalFreed = builder.ScrubResponses(requestIDs) if !builder.Empty() { newBuilders = append(newBuilders, builder) } } - mq.builders = newBuilders - mq.buildersLk.Unlock() + mb.builders = newBuilders + mb.buildersLk.Unlock() return totalFreed } -func (mq *MessageQueue) initializeSender() error { - if mq.sender != nil { - return nil - } - nsender, err := openSender(mq.ctx, mq.network, mq.p, mq.sendMessageTimeout) - if err != nil { - return err - } - mq.sender = nsender - return nil -} - -func (mq *MessageQueue) attemptSendAndRecovery(message gsmsg.GraphSyncMessage, metadata internalMetadata) bool { - err := mq.sender.SendMsg(mq.ctx, message) - if err == nil { - mq.publishSent(metadata) - return true - } - - log.Infof("graphsync send error: %s", err) - _ = mq.sender.Reset() - mq.sender = nil - - select { - case <-mq.done: - mq.publishError(metadata, errors.New("queue shutdown")) - return true - case <-mq.ctx.Done(): - mq.publishError(metadata, errors.New("context cancelled")) - return true - case <-time.After(time.Millisecond * 100): - // wait 100ms in case disconnect notifications are still propogating - log.Warn("SendMsg errored but neither 'done' nor context.Done() were set") - } - - err = mq.initializeSender() - if err != nil { - log.Infof("couldnt open sender again after SendMsg(%s) failed: %s", mq.p, err) - // TODO(why): what do we do now? - // I think the *right* answer is to probably put the message we're - // trying to send back, and then return to waiting for new work or - // a disconnect. - mq.publishError(metadata, fmt.Errorf("couldnt open sender again after SendMsg(%s) failed: %w", mq.p, err)) - return true - } - - return false -} - -func openSender(ctx context.Context, network MessageNetwork, p peer.ID, sendTimeout time.Duration) (gsnet.MessageSender, error) { - // allow ten minutes for connections this includes looking them up in the - // dht dialing them, and handshaking - conctx, cancel := context.WithTimeout(ctx, time.Minute*10) - defer cancel() - - err := network.ConnectTo(conctx, p) - if err != nil { - return nil, err - } - - nsender, err := network.NewMessageSender(ctx, p, gsnet.MessageSenderOpts{SendTimeout: sendTimeout}) - if err != nil { - return nil, err - } - - return nsender, nil -} - type internalMetadata struct { + builder *messageBuilder + span trace.Span + sendSpan trace.Span ctx context.Context public Metadata topic Topic @@ -375,17 +211,31 @@ type internalMetadata struct { responseStreams map[graphsync.RequestID]io.Closer } -func (mq *MessageQueue) publishQueued(metadata internalMetadata) { - mq.eventPublisher.Publish(metadata.topic, Event{Name: Queued, Metadata: metadata.public}) +func (metadata *internalMetadata) HandleQueued() { + _, metadata.sendSpan = otel.Tracer("graphsync").Start(metadata.ctx, "sendMessage", trace.WithAttributes( + attribute.Int64("topic", int64(metadata.topic)), + attribute.Int64("size", int64(metadata.msgSize)), + )) + metadata.builder.eventPublisher.Publish(metadata.topic, Event{Name: Queued, Metadata: metadata.public}) +} + +func (metadata *internalMetadata) HandleSent() { + metadata.builder.eventPublisher.Publish(metadata.topic, Event{Name: Sent, Metadata: metadata.public}) + _ = metadata.builder.allocator.ReleaseBlockMemory(metadata.builder.p, metadata.msgSize) } -func (mq *MessageQueue) publishSent(metadata internalMetadata) { - mq.eventPublisher.Publish(metadata.topic, Event{Name: Sent, Metadata: metadata.public}) - _ = mq.allocator.ReleaseBlockMemory(mq.p, metadata.msgSize) +func (metadata *internalMetadata) HandleError(err error) { + metadata.builder.scrubResponseStreams(metadata.responseStreams) + metadata.builder.eventPublisher.Publish(metadata.topic, Event{Name: Error, Err: err, Metadata: metadata.public}) + _ = metadata.builder.allocator.ReleaseBlockMemory(metadata.builder.p, metadata.msgSize) + metadata.span.RecordError(err) + metadata.span.SetStatus(codes.Error, err.Error()) } -func (mq *MessageQueue) publishError(metadata internalMetadata, err error) { - mq.scrubResponseStreams(metadata.responseStreams) - mq.eventPublisher.Publish(metadata.topic, Event{Name: Error, Err: err, Metadata: metadata.public}) - _ = mq.allocator.ReleaseBlockMemory(mq.p, metadata.msgSize) +func (metadata *internalMetadata) HandleFinished() { + metadata.builder.eventPublisher.Close(metadata.topic) + if metadata.sendSpan != nil { + metadata.sendSpan.End() + } + metadata.span.End() } diff --git a/messagequeue/messagequeue_test.go b/messagequeue/messagequeue_test.go index ad6c337f..e65b0264 100644 --- a/messagequeue/messagequeue_test.go +++ b/messagequeue/messagequeue_test.go @@ -1,4 +1,4 @@ -package messagequeue +package messagequeue_test import ( "context" @@ -13,13 +13,14 @@ import ( "github.com/ipld/go-ipld-prime/node/basicnode" "github.com/ipld/go-ipld-prime/traversal/selector/builder" "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/stretchr/testify/require" "github.com/ipfs/go-graphsync" allocator2 "github.com/ipfs/go-graphsync/allocator" gsmsg "github.com/ipfs/go-graphsync/message" + "github.com/ipfs/go-graphsync/messagequeue" gsnet "github.com/ipfs/go-graphsync/network" - "github.com/ipfs/go-graphsync/notifications" "github.com/ipfs/go-graphsync/testutil" ) @@ -37,7 +38,7 @@ func TestStartupAndShutdown(t *testing.T) { messageNetwork := &fakeMessageNetwork{nil, nil, messageSender, &waitGroup} allocator := allocator2.NewAllocator(1<<30, 1<<30) - messageQueue := New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, func(peer.ID) {}) + messageQueue := messagequeue.New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, sendErrorBackoff, func(peer.ID) {}) messageQueue.Startup() id := graphsync.NewRequestID() priority := graphsync.Priority(rand.Int31()) @@ -46,15 +47,17 @@ func TestStartupAndShutdown(t *testing.T) { root := testutil.GenerateCids(1)[0] waitGroup.Add(1) - messageQueue.AllocateAndBuildMessage(0, func(b *Builder) { - b.AddRequest(gsmsg.NewRequest(id, root, selector, priority)) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: 0, + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddRequest(gsmsg.NewRequest(id, root, selector, priority)) + }}) testutil.AssertDoesReceive(ctx, t, messagesSent, "message was not sent") messageQueue.Shutdown() - testutil.AssertDoesReceiveFirst(t, fullClosedChan, "message sender should be closed", resetChan, ctx.Done()) + testutil.AssertDoesReceiveFirst(t, resetChan, "message sender should be closed", fullClosedChan, ctx.Done()) } func TestShutdownDuringMessageSend(t *testing.T) { @@ -75,7 +78,7 @@ func TestShutdownDuringMessageSend(t *testing.T) { messageNetwork := &fakeMessageNetwork{nil, nil, messageSender, &waitGroup} allocator := allocator2.NewAllocator(1<<30, 1<<30) - messageQueue := New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, func(peer.ID) {}) + messageQueue := messagequeue.New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, sendErrorBackoff, func(peer.ID) {}) messageQueue.Startup() id := graphsync.NewRequestID() priority := graphsync.Priority(rand.Int31()) @@ -85,9 +88,11 @@ func TestShutdownDuringMessageSend(t *testing.T) { // setup a message and advance as far as beginning to send it waitGroup.Add(1) - messageQueue.AllocateAndBuildMessage(0, func(b *Builder) { - b.AddRequest(gsmsg.NewRequest(id, root, selector, priority)) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: 0, + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddRequest(gsmsg.NewRequest(id, root, selector, priority)) + }}) waitGroup.Wait() // now shut down @@ -123,7 +128,7 @@ func TestProcessingNotification(t *testing.T) { messageNetwork := &fakeMessageNetwork{nil, nil, messageSender, &waitGroup} allocator := allocator2.NewAllocator(1<<30, 1<<30) - messageQueue := New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, func(peer.ID) {}) + messageQueue := messagequeue.New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, sendErrorBackoff, func(peer.ID) {}) messageQueue.Startup() waitGroup.Add(1) blks := testutil.GenerateBlocksOfSize(3, 128) @@ -137,12 +142,14 @@ func TestProcessingNotification(t *testing.T) { status := graphsync.RequestCompletedFull blkData := testutil.NewFakeBlockData() subscriber := testutil.NewTestSubscriber(5) - messageQueue.AllocateAndBuildMessage(0, func(b *Builder) { - b.AddResponseCode(responseID, status) - b.AddExtensionData(responseID, extension) - b.AddBlockData(responseID, blkData) - b.SetSubscriber(responseID, subscriber) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: 0, + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddResponseCode(responseID, status) + b.AddExtensionData(responseID, extension) + b.AddBlockData(responseID, blkData) + b.SetSubscriber(responseID, subscriber) + }}) // wait for send attempt waitGroup.Wait() @@ -160,7 +167,7 @@ func TestProcessingNotification(t *testing.T) { require.True(t, found) require.Equal(t, extension.Data, extensionData) - expectedMetadata := Metadata{ + expectedMetadata := messagequeue.Metadata{ ResponseCodes: map[graphsync.RequestID]graphsync.ResponseStatusCode{ responseID: status, }, @@ -168,13 +175,13 @@ func TestProcessingNotification(t *testing.T) { responseID: {blkData}, }, } - subscriber.ExpectEventsAllTopics(ctx, t, []notifications.Event{ - Event{ - Name: Queued, + subscriber.ExpectEventsAllTopics(ctx, t, []messagequeue.Event{ + { + Name: messagequeue.Queued, Metadata: expectedMetadata, }, - Event{ - Name: Sent, + { + Name: messagequeue.Sent, Metadata: expectedMetadata, }, }) @@ -196,7 +203,7 @@ func TestDedupingMessages(t *testing.T) { messageNetwork := &fakeMessageNetwork{nil, nil, messageSender, &waitGroup} allocator := allocator2.NewAllocator(1<<30, 1<<30) - messageQueue := New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, func(peer.ID) {}) + messageQueue := messagequeue.New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, sendErrorBackoff, func(peer.ID) {}) messageQueue.Startup() waitGroup.Add(1) id := graphsync.NewRequestID() @@ -205,9 +212,11 @@ func TestDedupingMessages(t *testing.T) { selector := ssb.Matcher().Node() root := testutil.GenerateCids(1)[0] - messageQueue.AllocateAndBuildMessage(0, func(b *Builder) { - b.AddRequest(gsmsg.NewRequest(id, root, selector, priority)) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: 0, + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddRequest(gsmsg.NewRequest(id, root, selector, priority)) + }}) // wait for send attempt waitGroup.Wait() id2 := graphsync.NewRequestID() @@ -219,10 +228,12 @@ func TestDedupingMessages(t *testing.T) { selector3 := ssb.ExploreIndex(0, ssb.Matcher()).Node() root3 := testutil.GenerateCids(1)[0] - messageQueue.AllocateAndBuildMessage(0, func(b *Builder) { - b.AddRequest(gsmsg.NewRequest(id2, root2, selector2, priority2)) - b.AddRequest(gsmsg.NewRequest(id3, root3, selector3, priority3)) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: 0, + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddRequest(gsmsg.NewRequest(id2, root2, selector2, priority2)) + b.AddRequest(gsmsg.NewRequest(id3, root3, selector3, priority3)) + }}) var message gsmsg.GraphSyncMessage testutil.AssertReceive(ctx, t, messagesSent, &message, "message did not send") @@ -274,15 +285,17 @@ func TestSendsVeryLargeBlocksResponses(t *testing.T) { messageNetwork := &fakeMessageNetwork{nil, nil, messageSender, &waitGroup} allocator := allocator2.NewAllocator(1<<30, 1<<30) - messageQueue := New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, func(peer.ID) {}) + messageQueue := messagequeue.New(ctx, targetPeer, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, sendErrorBackoff, func(peer.ID) {}) messageQueue.Startup() waitGroup.Add(1) // generate large blocks before proceeding blks := testutil.GenerateBlocksOfSize(5, 1000000) - messageQueue.AllocateAndBuildMessage(uint64(len(blks[0].RawData())), func(b *Builder) { - b.AddBlock(blks[0]) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[0].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[0]) + }}) waitGroup.Wait() var message gsmsg.GraphSyncMessage testutil.AssertReceive(ctx, t, messagesSent, &message, "message did not send") @@ -292,15 +305,21 @@ func TestSendsVeryLargeBlocksResponses(t *testing.T) { require.True(t, blks[0].Cid().Equals(msgBlks[0].Cid())) // Send 3 very large blocks - messageQueue.AllocateAndBuildMessage(uint64(len(blks[1].RawData())), func(b *Builder) { - b.AddBlock(blks[1]) - }) - messageQueue.AllocateAndBuildMessage(uint64(len(blks[2].RawData())), func(b *Builder) { - b.AddBlock(blks[2]) - }) - messageQueue.AllocateAndBuildMessage(uint64(len(blks[3].RawData())), func(b *Builder) { - b.AddBlock(blks[3]) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[1].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[1]) + }}) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[2].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[2]) + }}) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[3].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[3]) + }}) testutil.AssertReceive(ctx, t, messagesSent, &message, "message did not send") msgBlks = message.Blocks() @@ -334,22 +353,26 @@ func TestSendsResponsesMemoryPressure(t *testing.T) { // use allocator with very small limit allocator := allocator2.NewAllocator(1000, 1000) - messageQueue := New(ctx, p, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, func(peer.ID) {}) + messageQueue := messagequeue.New(ctx, p, messageNetwork, allocator, messageSendRetries, sendMessageTimeout, sendErrorBackoff, func(peer.ID) {}) messageQueue.Startup() waitGroup.Add(1) // start sending block that exceeds memory limit blks := testutil.GenerateBlocksOfSize(2, 999) - messageQueue.AllocateAndBuildMessage(uint64(len(blks[0].RawData())), func(b *Builder) { - b.AddBlock(blks[0]) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[0].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[0]) + }}) finishes := make(chan string, 2) go func() { // attempt to send second block. Should block until memory is released - messageQueue.AllocateAndBuildMessage(uint64(len(blks[1].RawData())), func(b *Builder) { - b.AddBlock(blks[1]) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[1].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[1]) + }}) finishes <- "sent message" }() @@ -393,7 +416,7 @@ func TestNetworkErrorClearResponses(t *testing.T) { allocator := allocator2.NewAllocator(1<<30, 1<<30) // we use only a retry count of 1 to avoid multiple send attempts for each message - messageQueue := New(ctx, targetPeer, messageNetwork, allocator, 1, sendMessageTimeout, func(peer.ID) {}) + messageQueue := messagequeue.New(ctx, targetPeer, messageNetwork, allocator, 1, sendMessageTimeout, sendErrorBackoff, func(peer.ID) {}) messageQueue.Startup() waitGroup.Add(1) @@ -401,11 +424,13 @@ func TestNetworkErrorClearResponses(t *testing.T) { blks := testutil.GenerateBlocksOfSize(5, 1000000) subscriber := testutil.NewTestSubscriber(5) - messageQueue.AllocateAndBuildMessage(uint64(len(blks[0].RawData())), func(b *Builder) { - b.AddBlock(blks[0]) - b.AddLink(requestID1, cidlink.Link{Cid: blks[0].Cid()}, graphsync.LinkActionPresent) - b.SetSubscriber(requestID1, subscriber) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[0].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[0]) + b.AddLink(requestID1, cidlink.Link{Cid: blks[0].Cid()}, graphsync.LinkActionPresent) + b.SetSubscriber(requestID1, subscriber) + }}) waitGroup.Wait() var message gsmsg.GraphSyncMessage testutil.AssertReceive(ctx, t, messagesSent, &message, "message did not send") @@ -414,39 +439,43 @@ func TestNetworkErrorClearResponses(t *testing.T) { require.Len(t, msgBlks, 1, "number of blks in first message was not 1") require.True(t, blks[0].Cid().Equals(msgBlks[0].Cid())) - expectedMetadata := Metadata{ + expectedMetadata := messagequeue.Metadata{ ResponseCodes: map[graphsync.RequestID]graphsync.ResponseStatusCode{ requestID1: graphsync.PartialResponse, }, BlockData: map[graphsync.RequestID][]graphsync.BlockData{}, } - subscriber.ExpectEventsAllTopics(ctx, t, []notifications.Event{ - Event{Name: Queued, Metadata: expectedMetadata}, - Event{Name: Sent, Metadata: expectedMetadata}, + subscriber.ExpectEventsAllTopics(ctx, t, []messagequeue.Event{ + {Name: messagequeue.Queued, Metadata: expectedMetadata}, + {Name: messagequeue.Sent, Metadata: expectedMetadata}, }) subscriber.ExpectNCloses(ctx, t, 1) fc1 := &fakeCloser{fms: messageSender} - fc2 := &fakeCloser{fms: messageSender} // Send 3 very large blocks - messageQueue.AllocateAndBuildMessage(uint64(len(blks[1].RawData())), func(b *Builder) { - b.AddBlock(blks[1]) - b.SetResponseStream(requestID1, fc1) - b.AddLink(requestID1, cidlink.Link{Cid: blks[1].Cid()}, graphsync.LinkActionPresent) - }) - messageQueue.AllocateAndBuildMessage(uint64(len(blks[2].RawData())), func(b *Builder) { - b.AddBlock(blks[2]) - b.SetResponseStream(requestID1, fc1) - b.AddLink(requestID1, cidlink.Link{Cid: blks[2].Cid()}, graphsync.LinkActionPresent) - }) - messageQueue.AllocateAndBuildMessage(uint64(len(blks[3].RawData())), func(b *Builder) { - b.SetResponseStream(requestID2, fc2) - b.AddLink(requestID2, cidlink.Link{Cid: blks[3].Cid()}, graphsync.LinkActionPresent) - b.AddBlock(blks[3]) - }) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[1].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[1]) + b.SetResponseStream(requestID1, fc1) + b.AddLink(requestID1, cidlink.Link{Cid: blks[1].Cid()}, graphsync.LinkActionPresent) + }}) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[2].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddBlock(blks[2]) + b.SetResponseStream(requestID1, fc1) + b.AddLink(requestID1, cidlink.Link{Cid: blks[2].Cid()}, graphsync.LinkActionPresent) + }}) + messageQueue.BuildMessage(messagequeue.MessageParams{ + Size: uint64(len(blks[3].RawData())), + BuildMessageFn: func(b *messagequeue.Builder) { + b.AddLink(requestID2, cidlink.Link{Cid: blks[3].Cid()}, graphsync.LinkActionPresent) + b.AddBlock(blks[3]) + }}) messageSender.sendError = errors.New("something went wrong") - // add one since the stream will get reopened + // add one since the stream may get reopened waitGroup.Add(1) testutil.AssertReceive(ctx, t, messagesSent, &message, "message did not send") @@ -454,17 +483,11 @@ func TestNetworkErrorClearResponses(t *testing.T) { require.Len(t, msgBlks, 1, "number of blks in first message was not 1") require.True(t, blks[1].Cid().Equals(msgBlks[0].Cid())) - // should skip block2 as it's linked to errored request - testutil.AssertReceive(ctx, t, messagesSent, &message, "message did not send") - msgBlks = message.Blocks() - require.Len(t, msgBlks, 1, "number of blks in first message was not 1") - require.True(t, blks[3].Cid().Equals(msgBlks[0].Cid())) - require.True(t, fc1.closed) - require.False(t, fc2.closed) } const sendMessageTimeout = 10 * time.Minute +const sendErrorBackoff = 100 * time.Millisecond const messageSendRetries = 10 type fakeMessageNetwork struct { @@ -478,7 +501,7 @@ func (fmn *fakeMessageNetwork) ConnectTo(context.Context, peer.ID) error { return fmn.connectError } -func (fmn *fakeMessageNetwork) NewMessageSender(context.Context, peer.ID, gsnet.MessageSenderOpts) (gsnet.MessageSender, error) { +func (fmn *fakeMessageNetwork) NewMessageSender(context.Context, peer.ID, *gsnet.MessageSenderOpts) (gsnet.MessageSender, error) { fmn.wait.Done() if fmn.messageSenderError == nil { return fmn.messageSender, nil @@ -486,6 +509,8 @@ func (fmn *fakeMessageNetwork) NewMessageSender(context.Context, peer.ID, gsnet. return nil, fmn.messageSenderError } +var _ gsnet.MessageSender = (*fakeMessageSender)(nil) + type fakeMessageSender struct { sendError error fullClosed chan<- struct{} @@ -499,6 +524,9 @@ func (fms *fakeMessageSender) SendMsg(ctx context.Context, msg gsmsg.GraphSyncMe } func (fms *fakeMessageSender) Close() error { fms.fullClosed <- struct{}{}; return nil } func (fms *fakeMessageSender) Reset() error { fms.reset <- struct{}{}; return nil } +func (fms *fakeMessageSender) Protocol() protocol.ID { + return gsnet.ProtocolGraphsync_2_0_0 +} type fakeCloser struct { fms *fakeMessageSender diff --git a/network/interface.go b/network/interface.go index f3f4af45..12e9b53c 100644 --- a/network/interface.go +++ b/network/interface.go @@ -1,13 +1,10 @@ package network import ( - "context" - "time" - - "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" gsmsg "github.com/ipfs/go-graphsync/message" + "github.com/ipfs/go-protocolnetwork/pkg/network" ) var ( @@ -16,53 +13,9 @@ var ( ) // GraphSyncNetwork provides network connectivity for GraphSync. -type GraphSyncNetwork interface { - - // SendMessage sends a GraphSync message to a peer. - SendMessage( - context.Context, - peer.ID, - gsmsg.GraphSyncMessage) error - - // SetDelegate registers the Receiver to handle messages received from the - // network. - SetDelegate(Receiver) - - // ConnectTo establishes a connection to the given peer - ConnectTo(context.Context, peer.ID) error - - NewMessageSender(context.Context, peer.ID, MessageSenderOpts) (MessageSender, error) - - ConnectionManager() ConnManager -} - -// MessageSenderOpts sets parameters for a message sender -type MessageSenderOpts struct { - SendTimeout time.Duration -} - -// ConnManager provides the methods needed to protect and unprotect connections -type ConnManager interface { - Protect(peer.ID, string) - Unprotect(peer.ID, string) bool -} - -// MessageSender is an interface to send messages to a peer -type MessageSender interface { - SendMsg(context.Context, gsmsg.GraphSyncMessage) error - Close() error - Reset() error -} - -// Receiver is an interface for receiving messages from the GraphSyncNetwork. -type Receiver interface { - ReceiveMessage( - ctx context.Context, - sender peer.ID, - incoming gsmsg.GraphSyncMessage) +type GraphSyncNetwork network.ProtocolNetwork[gsmsg.GraphSyncMessage] - ReceiveError(p peer.ID, err error) +type MessageSender = network.MessageSender[gsmsg.GraphSyncMessage] +type MessageSenderOpts = network.MessageSenderOpts - Connected(p peer.ID) - Disconnected(p peer.ID) -} +type Receiver = network.Receiver[gsmsg.GraphSyncMessage] diff --git a/network/libp2p_impl.go b/network/libp2p_impl.go index 5de12945..635e2455 100644 --- a/network/libp2p_impl.go +++ b/network/libp2p_impl.go @@ -1,68 +1,50 @@ package network import ( - "context" "fmt" "io" - "time" logging "github.com/ipfs/go-log/v2" + "github.com/ipfs/go-protocolnetwork/pkg/network" "github.com/libp2p/go-libp2p/core/host" - "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-msgio" - ma "github.com/multiformats/go-multiaddr" gsmsg "github.com/ipfs/go-graphsync/message" gsmsgv2 "github.com/ipfs/go-graphsync/message/v2" - "github.com/ipfs/go-graphsync/panics" ) var log = logging.Logger("graphsync_network") -var sendMessageTimeout = time.Minute * 10 - // Option is an option for configuring the libp2p storage market network -type Option func(*libp2pGraphSyncNetwork) +type Option func() network.NetOpt -// DataTransferProtocols OVERWRITES the default libp2p protocols we use for +// GraphsyncProtocols OVERWRITES the default libp2p protocols we use for // graphsync with the specified protocols func GraphsyncProtocols(protocols []protocol.ID) Option { - return func(gsnet *libp2pGraphSyncNetwork) { - gsnet.setProtocols(protocols) - } -} - -// PanicCallback allows calling code to receive information about panics that -// Graphsync recovers from. Graphsync recovers panics that occur during -// message handling in order to keep the over all system running, although -// they are still treated as standard errors in normal execution flow. -func PanicCallback(callbackFn panics.CallBackFn) Option { - return func(gsnet *libp2pGraphSyncNetwork) { - gsnet.panicCallback = callbackFn + return func() network.NetOpt { + return network.SupportedProtocols(supportedProtocols(protocols)) } } // NewFromLibp2pHost returns a GraphSyncNetwork supported by underlying Libp2p host. func NewFromLibp2pHost(host host.Host, options ...Option) GraphSyncNetwork { - graphSyncNetwork := libp2pGraphSyncNetwork{ - host: host, - protocols: []protocol.ID{ProtocolGraphsync_2_0_0}, - } + netOpts := []network.NetOpt{network.SupportedProtocols([]protocol.ID{ProtocolGraphsync_2_0_0})} for _, option := range options { - option(&graphSyncNetwork) + netOpts = append(netOpts, option()) } - graphSyncNetwork.panicHandler = panics.MakeHandler(graphSyncNetwork.panicCallback) + messageHandlerSelector := NewMessageHandlerSelector() - graphSyncNetwork.messageHandlerSelector = &messageHandlerSelector{ + return network.NewFromLibp2pHost[gsmsg.GraphSyncMessage]("graphsync", host, messageHandlerSelector, netOpts...) +} + +func NewMessageHandlerSelector() *MessageHandlerSelector { + return &MessageHandlerSelector{ v2MessageHandler: gsmsgv2.NewMessageHandler(), - panicHandler: graphSyncNetwork.panicHandler, } - - return &graphSyncNetwork } // a message.MessageHandler that simply returns an error for any of the calls, allows @@ -82,13 +64,11 @@ func (mhe messageHandlerErrorer) ToNet(peer.ID, gsmsg.GraphSyncMessage, io.Write return mhe.err } -type messageHandlerSelector struct { +type MessageHandlerSelector struct { v2MessageHandler gsmsg.MessageHandler - - panicHandler panics.PanicHandler } -func (smh messageHandlerSelector) Select(protocol protocol.ID) gsmsg.MessageHandler { +func (smh MessageHandlerSelector) Select(protocol protocol.ID) network.MessageHandler[gsmsg.GraphSyncMessage] { switch protocol { case ProtocolGraphsync_2_0_0: return smh.v2MessageHandler @@ -97,190 +77,13 @@ func (smh messageHandlerSelector) Select(protocol protocol.ID) gsmsg.MessageHand } } -// libp2pGraphSyncNetwork transforms the libp2p host interface, which sends and receives -// NetMessage objects, into the graphsync network interface. -type libp2pGraphSyncNetwork struct { - host host.Host - // inbound messages from the network are forwarded to the receiver - receiver Receiver - protocols []protocol.ID - messageHandlerSelector *messageHandlerSelector - panicCallback panics.CallBackFn - panicHandler panics.PanicHandler -} - -type streamMessageSender struct { - s network.Stream - opts MessageSenderOpts - messageHandlerSelector *messageHandlerSelector -} - -func (s *streamMessageSender) Close() error { - return s.s.Close() -} - -func (s *streamMessageSender) Reset() error { - return s.s.Reset() -} - -func (s *streamMessageSender) SendMsg(ctx context.Context, msg gsmsg.GraphSyncMessage) error { - return msgToStream(ctx, s.s, s.messageHandlerSelector, msg, s.opts.SendTimeout) -} - -func msgToStream(ctx context.Context, s network.Stream, mh *messageHandlerSelector, msg gsmsg.GraphSyncMessage, timeout time.Duration) (err error) { - defer func() { - if rerr := mh.panicHandler(recover()); rerr != nil { - log.Warnf("recovered panic handling message: %s", err) - err = rerr - } - }() - - log.Debugf("Outgoing message with %d requests, %d responses, and %d blocks", - len(msg.Requests()), len(msg.Responses()), len(msg.Blocks())) - - deadline := time.Now().Add(timeout) - if dl, ok := ctx.Deadline(); ok { - deadline = dl - } - if err := s.SetWriteDeadline(deadline); err != nil { - log.Warnf("error setting deadline: %s", err) - } - - if err := mh.Select(s.Protocol()).ToNet(s.Conn().RemotePeer(), msg, s); err != nil { - log.Debugf("error: %s", err) - return err - } - - if err := s.SetWriteDeadline(time.Time{}); err != nil { - log.Warnf("error resetting deadline: %s", err) - } - - return err -} - -func (gsnet *libp2pGraphSyncNetwork) NewMessageSender(ctx context.Context, p peer.ID, opts MessageSenderOpts) (MessageSender, error) { - s, err := gsnet.newStreamToPeer(ctx, p) - if err != nil { - return nil, err - } - - return &streamMessageSender{ - s: s, - opts: setDefaults(opts), - messageHandlerSelector: gsnet.messageHandlerSelector, - }, nil -} - -func (gsnet *libp2pGraphSyncNetwork) newStreamToPeer(ctx context.Context, p peer.ID) (network.Stream, error) { - return gsnet.host.NewStream(ctx, p, gsnet.protocols...) -} - -func (gsnet *libp2pGraphSyncNetwork) SendMessage( - ctx context.Context, - p peer.ID, - outgoing gsmsg.GraphSyncMessage) error { - - s, err := gsnet.newStreamToPeer(ctx, p) - if err != nil { - return err - } - - if err = msgToStream(ctx, s, gsnet.messageHandlerSelector, outgoing, sendMessageTimeout); err != nil { - _ = s.Reset() - return err - } - - return s.Close() -} - -func (gsnet *libp2pGraphSyncNetwork) SetDelegate(r Receiver) { - gsnet.receiver = r - for _, p := range gsnet.protocols { - gsnet.host.SetStreamHandler(p, gsnet.handleNewStream) - } - gsnet.host.Network().Notify((*libp2pGraphSyncNotifee)(gsnet)) -} - -func (gsnet *libp2pGraphSyncNetwork) ConnectTo(ctx context.Context, p peer.ID) error { - return gsnet.host.Connect(ctx, peer.AddrInfo{ID: p}) -} - -// handleNewStream receives a new stream from the network. -func (gsnet *libp2pGraphSyncNetwork) handleNewStream(s network.Stream) { - var p peer.ID - - defer s.Close() - defer func() { - if rerr := gsnet.panicHandler(recover()); rerr != nil { - log.Debugf("graphsync net handleNewStream recovered error from %s error: %s", s.Conn().RemotePeer(), rerr) - _ = s.Reset() - go gsnet.receiver.ReceiveError(p, rerr) - } - }() - - if gsnet.receiver == nil { - _ = s.Reset() - return - } - - reader := msgio.NewVarintReaderSize(s, network.MessageSizeMax) - for { - p = s.Conn().RemotePeer() - received, err := gsnet.messageHandlerSelector.Select(s.Protocol()).FromMsgReader(s.Conn().RemotePeer(), reader) - - if err != nil { - if err != io.EOF { - _ = s.Reset() - go gsnet.receiver.ReceiveError(p, err) - log.Debugf("graphsync net handleNewStream from %s error: %s", s.Conn().RemotePeer(), err) - } - return - } - - ctx := context.Background() - log.Debugf("graphsync net handleNewStream from %s", s.Conn().RemotePeer()) - - gsnet.receiver.ReceiveMessage(ctx, p, received) - } -} - -func (gsnet *libp2pGraphSyncNetwork) ConnectionManager() ConnManager { - return gsnet.host.ConnManager() -} - -func (gsnet *libp2pGraphSyncNetwork) setProtocols(protocols []protocol.ID) { - gsnet.protocols = make([]protocol.ID, 0) +func supportedProtocols(protocols []protocol.ID) []protocol.ID { + protocols = make([]protocol.ID, 0) for _, proto := range protocols { switch proto { case ProtocolGraphsync_2_0_0: - gsnet.protocols = append([]protocol.ID{}, proto) + protocols = append([]protocol.ID{}, proto) } } -} - -type libp2pGraphSyncNotifee libp2pGraphSyncNetwork - -func (nn *libp2pGraphSyncNotifee) libp2pGraphSyncNetwork() *libp2pGraphSyncNetwork { - return (*libp2pGraphSyncNetwork)(nn) -} - -func (nn *libp2pGraphSyncNotifee) Connected(n network.Network, v network.Conn) { - nn.libp2pGraphSyncNetwork().receiver.Connected(v.RemotePeer()) -} - -func (nn *libp2pGraphSyncNotifee) Disconnected(n network.Network, v network.Conn) { - nn.libp2pGraphSyncNetwork().receiver.Disconnected(v.RemotePeer()) -} - -func (nn *libp2pGraphSyncNotifee) OpenedStream(n network.Network, v network.Stream) {} -func (nn *libp2pGraphSyncNotifee) ClosedStream(n network.Network, v network.Stream) {} -func (nn *libp2pGraphSyncNotifee) Listen(n network.Network, a ma.Multiaddr) {} -func (nn *libp2pGraphSyncNotifee) ListenClose(n network.Network, a ma.Multiaddr) {} - -func setDefaults(opts MessageSenderOpts) MessageSenderOpts { - copy := opts - if opts.SendTimeout == 0 { - copy.SendTimeout = sendMessageTimeout - } - return copy + return protocols } diff --git a/network/libp2p_impl_test.go b/network/libp2p_impl_test.go index e71e217f..4aecc206 100644 --- a/network/libp2p_impl_test.go +++ b/network/libp2p_impl_test.go @@ -40,11 +40,11 @@ func (r *receiver) ReceiveMessage( func (r *receiver) ReceiveError(_ peer.ID, _ error) { } -func (r *receiver) Connected(p peer.ID) { +func (r *receiver) PeerConnected(p peer.ID) { r.connectedPeers <- p } -func (r *receiver) Disconnected(p peer.ID) { +func (r *receiver) PeerDisconnected(p peer.ID) { } func TestMessageSendAndReceive(t *testing.T) { @@ -66,8 +66,8 @@ func TestMessageSendAndReceive(t *testing.T) { messageReceived: make(chan struct{}), connectedPeers: make(chan peer.ID, 2), } - gsnet1.SetDelegate(r) - gsnet2.SetDelegate(r) + gsnet1.Start(r) + gsnet2.Start(r) root := testutil.GenerateCids(1)[0] ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any) diff --git a/notifications/notifications_test.go b/notifications/notifications_test.go deleted file mode 100644 index 73af3099..00000000 --- a/notifications/notifications_test.go +++ /dev/null @@ -1,143 +0,0 @@ -package notifications_test - -import ( - "context" - "testing" - "time" - - "github.com/ipfs/go-graphsync/notifications" - "github.com/ipfs/go-graphsync/testutil" -) - -func TestSubscribeWithData(t *testing.T) { - ctx := context.Background() - testCases := map[string]func(ctx context.Context, t *testing.T, ps notifications.Publisher){ - "Add subscriptions": func(ctx context.Context, t *testing.T, ps notifications.Publisher) { - sub1 := testutil.NewTestSubscriber(3) - sub2 := testutil.NewTestSubscriber(3) - ps.Subscribe("t1", sub1) - ps.Subscribe("t2", sub2) - - ps.Publish("t1", "hi1") - ps.Publish("t2", "hi2") - - ps.Subscribe("t2", sub1) - ps.Subscribe("t3", sub1) - - ps.Publish("t2", "hi3") - ps.Publish("t3", "hi4") - - ps.Shutdown() - sub1.ExpectEvents(ctx, t, []testutil.DispatchedEvent{ - { - Topic: "t1", - Event: "hi1", - }, - { - Topic: "t2", - Event: "hi3", - }, - { - Topic: "t3", - Event: "hi4", - }, - }) - sub1.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t1", "t2", "t3"}) - sub2.ExpectEvents(ctx, t, []testutil.DispatchedEvent{ - {Topic: "t2", Event: "hi2"}, {Topic: "t2", Event: "hi3"}, - }) - sub2.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t2"}) - }, - "Unsubscribe": func(ctx context.Context, t *testing.T, ps notifications.Publisher) { - sub1 := testutil.NewTestSubscriber(3) - sub2 := testutil.NewTestSubscriber(3) - ps.Subscribe("t1", sub1) - ps.Subscribe("t2", sub1) - ps.Subscribe("t3", sub1) - ps.Subscribe("t1", sub2) - ps.Subscribe("t3", sub2) - ps.Unsubscribe(sub1) - ps.Publish("t1", "hi") - ps.Shutdown() - - sub2.ExpectEvents(ctx, t, []testutil.DispatchedEvent{ - {Topic: "t1", Event: "hi"}, - }) - sub2.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t1", "t3"}) - sub1.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t1", "t2", "t3"}) - sub1.NoEventsReceived(t) - }, - "Close": func(ctx context.Context, t *testing.T, ps notifications.Publisher) { - sub1 := testutil.NewTestSubscriber(3) - sub2 := testutil.NewTestSubscriber(3) - sub3 := testutil.NewTestSubscriber(3) - sub4 := testutil.NewTestSubscriber(3) - ps.Subscribe("t1", sub1) - ps.Subscribe("t1", sub2) - ps.Subscribe("t2", sub3) - ps.Subscribe("t3", sub4) - - ps.Publish("t1", "hi") - ps.Publish("t2", "hello") - ps.Close("t1") - ps.Close("t2") - - sub1.ExpectEvents(ctx, t, []testutil.DispatchedEvent{ - {Topic: "t1", Event: "hi"}, - }) - sub1.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t1"}) - sub2.ExpectEvents(ctx, t, []testutil.DispatchedEvent{ - {Topic: "t1", Event: "hi"}, - }) - sub2.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t1"}) - sub3.ExpectEvents(ctx, t, []testutil.DispatchedEvent{ - {Topic: "t2", Event: "hello"}, - }) - sub3.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t2"}) - - // publishing on a topic after close should be like starting from scratch - // -- no one listening before should receive events - ps.Publish("t1", "hi") - ps.Publish("t2", "hi") - - ps.Publish("t3", "welcome") - ps.Shutdown() - - sub4.ExpectEvents(ctx, t, []testutil.DispatchedEvent{ - {Topic: "t3", Event: "welcome"}, - }) - sub4.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t3"}) - sub1.NoEventsReceived(t) - sub2.NoEventsReceived(t) - sub3.NoEventsReceived(t) - }, - "Shutdown": func(ctx context.Context, t *testing.T, ps notifications.Publisher) { - sub1 := testutil.NewTestSubscriber(3) - sub2 := testutil.NewTestSubscriber(3) - ps.Subscribe("t1", sub1) - ps.Subscribe("t2", sub2) - - ps.Shutdown() - - // operations after shutdown have no effect - ps.Publish("t1", "hi") - ps.Publish("t2", "hello") - sub1.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t1"}) - sub2.ExpectClosesAnyOrder(ctx, t, []notifications.Topic{"t2"}) - time.Sleep(100 * time.Millisecond) - sub1.NoEventsReceived(t) - sub2.NoEventsReceived(t) - }, - } - for testCase, testPublisher := range testCases { - t.Run(testCase, func(t *testing.T) { - ctx, cancel := context.WithTimeout(ctx, 1*time.Second) - defer cancel() - ps := notifications.NewPublisher() - ps.Startup() - testPublisher(ctx, t, ps) - ps.Shutdown() - }) - } - -} diff --git a/notifications/publisher.go b/notifications/publisher.go deleted file mode 100644 index 1c43cd56..00000000 --- a/notifications/publisher.go +++ /dev/null @@ -1,235 +0,0 @@ -package notifications - -import ( - "sync" - - logging "github.com/ipfs/go-log/v2" -) - -var log = logging.Logger("gs-notifications") - -type operation int - -const ( - subscribe operation = iota - pub - unsubAll - closeTopic - shutdown -) - -type cmd struct { - op operation - topics []Topic - sub Subscriber - msg Event -} - -// publisher is a publisher of events for -type publisher struct { - lk sync.RWMutex - closed chan struct{} - cmds []cmd - cmdsLk *sync.Cond -} - -// NewPublisher returns a new message event publisher -func NewPublisher() Publisher { - ps := &publisher{ - cmdsLk: sync.NewCond(&sync.Mutex{}), - closed: make(chan struct{}), - } - return ps -} - -func (ps *publisher) Startup() { - go ps.start() -} - -// Publish publishes an event for the given message id -func (ps *publisher) Publish(topic Topic, event Event) { - ps.lk.RLock() - defer ps.lk.RUnlock() - select { - case <-ps.closed: - return - default: - } - - ps.queue(cmd{op: pub, topics: []Topic{topic}, msg: event}) -} - -// Shutdown shuts down all events and subscriptions -func (ps *publisher) Shutdown() { - ps.lk.Lock() - defer ps.lk.Unlock() - select { - case <-ps.closed: - return - default: - } - close(ps.closed) - ps.queue(cmd{op: shutdown}) -} - -func (ps *publisher) Close(id Topic) { - ps.lk.RLock() - defer ps.lk.RUnlock() - select { - case <-ps.closed: - return - default: - } - ps.queue(cmd{op: closeTopic, topics: []Topic{id}}) -} - -func (ps *publisher) Subscribe(topic Topic, sub Subscriber) bool { - ps.lk.RLock() - defer ps.lk.RUnlock() - - select { - case <-ps.closed: - return false - default: - } - - ps.queue(cmd{op: subscribe, topics: []Topic{topic}, sub: sub}) - return true -} - -func (ps *publisher) Unsubscribe(sub Subscriber) bool { - ps.lk.RLock() - defer ps.lk.RUnlock() - - select { - case <-ps.closed: - return false - default: - } - - ps.queue(cmd{op: unsubAll, sub: sub}) - return true -} - -func (ps *publisher) start() { - reg := subscriberRegistry{ - topics: make(map[Topic]map[Subscriber]struct{}), - revTopics: make(map[Subscriber]map[Topic]struct{}), - } - -loop: - for { - cmd := ps.dequeue() - if cmd.topics == nil { - switch cmd.op { - case unsubAll: - reg.removeSubscriber(cmd.sub) - - case shutdown: - break loop - } - - continue loop - } - - for _, topic := range cmd.topics { - switch cmd.op { - case subscribe: - reg.add(topic, cmd.sub) - - case pub: - reg.send(topic, cmd.msg) - - case closeTopic: - reg.removeTopic(topic) - } - } - } - - for topic, subs := range reg.topics { - for sub := range subs { - reg.remove(topic, sub) - } - } -} - -type subscriberRegistry struct { - topics map[Topic]map[Subscriber]struct{} - revTopics map[Subscriber]map[Topic]struct{} -} - -func (reg *subscriberRegistry) add(topic Topic, sub Subscriber) { - if reg.topics[topic] == nil { - reg.topics[topic] = make(map[Subscriber]struct{}) - } - reg.topics[topic][sub] = struct{}{} - - if reg.revTopics[sub] == nil { - reg.revTopics[sub] = make(map[Topic]struct{}) - } - reg.revTopics[sub][topic] = struct{}{} -} - -func (reg *subscriberRegistry) send(topic Topic, msg Event) { - for sub := range reg.topics[topic] { - sub.OnNext(topic, msg) - } -} - -func (reg *subscriberRegistry) removeTopic(topic Topic) { - for sub := range reg.topics[topic] { - reg.remove(topic, sub) - } -} - -func (reg *subscriberRegistry) removeSubscriber(sub Subscriber) { - for topic := range reg.revTopics[sub] { - reg.remove(topic, sub) - } -} - -func (reg *subscriberRegistry) remove(topic Topic, sub Subscriber) { - if _, ok := reg.topics[topic]; !ok { - return - } - - if _, ok := reg.topics[topic][sub]; !ok { - return - } - - delete(reg.topics[topic], sub) - delete(reg.revTopics[sub], topic) - - if len(reg.topics[topic]) == 0 { - delete(reg.topics, topic) - } - - if len(reg.revTopics[sub]) == 0 { - delete(reg.revTopics, sub) - } - - sub.OnClose(topic) -} - -func (ps *publisher) queue(cmd cmd) { - ps.cmdsLk.L.Lock() - ps.cmds = append(ps.cmds, cmd) - cmdsLen := len(ps.cmds) - ps.cmdsLk.L.Unlock() - log.Debugw("added notification command", "cmd", cmd, "queue len", cmdsLen) - ps.cmdsLk.Signal() -} - -func (ps *publisher) dequeue() cmd { - ps.cmdsLk.L.Lock() - for len(ps.cmds) == 0 { - ps.cmdsLk.Wait() - } - - cmd := ps.cmds[0] - ps.cmds = ps.cmds[1:] - cmdsLen := len(ps.cmds) - ps.cmdsLk.L.Unlock() - log.Debugw("processing notification command", "cmd", cmd, "remaining in queue", cmdsLen) - return cmd -} diff --git a/notifications/types.go b/notifications/types.go deleted file mode 100644 index 716500fe..00000000 --- a/notifications/types.go +++ /dev/null @@ -1,31 +0,0 @@ -package notifications - -// Topic is a topic that events appear on -type Topic interface{} - -// Event is a publishable event -type Event interface{} - -// TopicData is data added to every message broadcast on a topic -type TopicData interface{} - -// Subscriber is a subscriber that can receive events -type Subscriber interface { - OnNext(Topic, Event) - OnClose(Topic) -} - -// Subscribable is a stream that can be subscribed to -type Subscribable interface { - Subscribe(topic Topic, sub Subscriber) bool - Unsubscribe(sub Subscriber) bool -} - -// Publisher is an publisher of events that can be subscribed to -type Publisher interface { - Close(Topic) - Publish(Topic, Event) - Shutdown() - Startup() - Subscribable -} diff --git a/peermanager/peermanager.go b/peermanager/peermanager.go deleted file mode 100644 index e2ea0ea2..00000000 --- a/peermanager/peermanager.go +++ /dev/null @@ -1,122 +0,0 @@ -package peermanager - -import ( - "context" - "sync" - - "github.com/libp2p/go-libp2p/core/peer" -) - -// PeerProcess is any process that provides services for a peer -type PeerProcess interface { - Startup() - Shutdown() -} - -type PeerHandler interface{} - -// PeerProcessFactory provides a function that will create a PeerQueue. -type PeerProcessFactory func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) PeerHandler - -type peerProcessInstance struct { - refcnt int - process PeerHandler -} - -// PeerManager manages a pool of peers and sends messages to peers in the pool. -type PeerManager struct { - peerProcesses map[peer.ID]*peerProcessInstance - peerProcessesLk sync.RWMutex - - createPeerProcess PeerProcessFactory - ctx context.Context -} - -// New creates a new PeerManager, given a context and a peerQueueFactory. -func New(ctx context.Context, createPeerQueue PeerProcessFactory) *PeerManager { - return &PeerManager{ - peerProcesses: make(map[peer.ID]*peerProcessInstance), - createPeerProcess: createPeerQueue, - ctx: ctx, - } -} - -// ConnectedPeers returns a list of peers this PeerManager is managing. -func (pm *PeerManager) ConnectedPeers() []peer.ID { - pm.peerProcessesLk.RLock() - defer pm.peerProcessesLk.RUnlock() - peers := make([]peer.ID, 0, len(pm.peerProcesses)) - for p := range pm.peerProcesses { - peers = append(peers, p) - } - return peers -} - -// Connected is called to add a new peer to the pool -func (pm *PeerManager) Connected(p peer.ID) { - pm.peerProcessesLk.Lock() - pq := pm.getOrCreate(p) - pq.refcnt++ - pm.peerProcessesLk.Unlock() -} - -// Disconnected is called to remove a peer from the pool. -func (pm *PeerManager) Disconnected(p peer.ID) { - pm.peerProcessesLk.Lock() - pq, ok := pm.peerProcesses[p] - if !ok { - pm.peerProcessesLk.Unlock() - return - } - - pq.refcnt-- - if pq.refcnt > 0 { - pm.peerProcessesLk.Unlock() - return - } - - delete(pm.peerProcesses, p) - pm.peerProcessesLk.Unlock() - - if pprocess, ok := pq.process.(PeerProcess); ok { - pprocess.Shutdown() - } -} - -// GetProcess returns the process for the given peer -func (pm *PeerManager) GetProcess( - p peer.ID) PeerHandler { - // Usually this this is just a read - pm.peerProcessesLk.RLock() - pqi, ok := pm.peerProcesses[p] - if ok { - pm.peerProcessesLk.RUnlock() - return pqi.process - } - pm.peerProcessesLk.RUnlock() - // but sometimes it involves a create (we still need to do get or create cause it's possible - // another writer grabbed the Lock first and made the process) - pm.peerProcessesLk.Lock() - pqi = pm.getOrCreate(p) - pm.peerProcessesLk.Unlock() - return pqi.process -} - -func (pm *PeerManager) getOrCreate(p peer.ID) *peerProcessInstance { - pqi, ok := pm.peerProcesses[p] - if !ok { - pq := pm.createPeerProcess(pm.ctx, p, pm.onQueueShutdown) - if pprocess, ok := pq.(PeerProcess); ok { - pprocess.Startup() - } - pqi = &peerProcessInstance{0, pq} - pm.peerProcesses[p] = pqi - } - return pqi -} - -func (pm *PeerManager) onQueueShutdown(p peer.ID) { - pm.peerProcessesLk.Lock() - defer pm.peerProcessesLk.Unlock() - delete(pm.peerProcesses, p) -} diff --git a/peermanager/peermanager_test.go b/peermanager/peermanager_test.go deleted file mode 100644 index 8f09e750..00000000 --- a/peermanager/peermanager_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package peermanager - -import ( - "context" - "testing" - - "github.com/libp2p/go-libp2p/core/peer" - - "github.com/ipfs/go-graphsync/testutil" -) - -type fakePeerProcess struct { -} - -func (fp *fakePeerProcess) Startup() {} -func (fp *fakePeerProcess) Shutdown() {} - -func TestAddingAndRemovingPeers(t *testing.T) { - ctx := context.Background() - peerProcessFatory := func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) PeerHandler { - return &fakePeerProcess{} - } - - tp := testutil.GeneratePeers(5) - peer1, peer2, peer3, peer4, peer5 := tp[0], tp[1], tp[2], tp[3], tp[4] - peerManager := New(ctx, peerProcessFatory) - - peerManager.Connected(peer1) - peerManager.Connected(peer2) - peerManager.Connected(peer3) - - connectedPeers := peerManager.ConnectedPeers() - - testutil.AssertContainsPeer(t, connectedPeers, peer1) - testutil.AssertContainsPeer(t, connectedPeers, peer2) - testutil.AssertContainsPeer(t, connectedPeers, peer3) - - testutil.RefuteContainsPeer(t, connectedPeers, peer4) - testutil.RefuteContainsPeer(t, connectedPeers, peer5) - - // removing a peer with only one reference - peerManager.Disconnected(peer1) - connectedPeers = peerManager.ConnectedPeers() - - testutil.RefuteContainsPeer(t, connectedPeers, peer1) - - // connecting a peer twice, then disconnecting once, should stay in queue - peerManager.Connected(peer2) - peerManager.Disconnected(peer2) - connectedPeers = peerManager.ConnectedPeers() - - testutil.AssertContainsPeer(t, connectedPeers, peer2) -} diff --git a/peermanager/peermessagemanager.go b/peermanager/peermessagemanager.go deleted file mode 100644 index dc3f2000..00000000 --- a/peermanager/peermessagemanager.go +++ /dev/null @@ -1,39 +0,0 @@ -package peermanager - -import ( - "context" - - "github.com/libp2p/go-libp2p/core/peer" - - "github.com/ipfs/go-graphsync/messagequeue" -) - -// PeerQueue is a process that sends messages to a peer -type PeerQueue interface { - PeerProcess - AllocateAndBuildMessage(blkSize uint64, buildMessageFn func(*messagequeue.Builder)) -} - -// PeerQueueFactory provides a function that will create a PeerQueue. -type PeerQueueFactory func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) PeerQueue - -// PeerMessageManager manages message queues for peers -type PeerMessageManager struct { - *PeerManager -} - -// NewMessageManager generates a new manger for sending messages -func NewMessageManager(ctx context.Context, createPeerQueue PeerQueueFactory) *PeerMessageManager { - return &PeerMessageManager{ - PeerManager: New(ctx, func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) PeerHandler { - return createPeerQueue(ctx, p, onShutdown) - }), - } -} - -// BuildMessage allows you to modify the next message that is sent for the given peer -// If blkSize > 0, message building may block until enough memory has been freed from the queues to allocate the message. -func (pmm *PeerMessageManager) AllocateAndBuildMessage(p peer.ID, blkSize uint64, buildMessageFn func(*messagequeue.Builder)) { - pq := pmm.GetProcess(p).(PeerQueue) - pq.AllocateAndBuildMessage(blkSize, buildMessageFn) -} diff --git a/peermanager/peermessagemanager_test.go b/peermanager/peermessagemanager_test.go deleted file mode 100644 index aa9c4b0b..00000000 --- a/peermanager/peermessagemanager_test.go +++ /dev/null @@ -1,123 +0,0 @@ -package peermanager - -import ( - "context" - "math/rand" - "testing" - "time" - - "github.com/ipld/go-ipld-prime/node/basicnode" - "github.com/ipld/go-ipld-prime/traversal/selector/builder" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/stretchr/testify/require" - - "github.com/ipfs/go-graphsync" - gsmsg "github.com/ipfs/go-graphsync/message" - "github.com/ipfs/go-graphsync/messagequeue" - "github.com/ipfs/go-graphsync/testutil" -) - -type messageSent struct { - p peer.ID - message gsmsg.GraphSyncMessage -} - -var _ PeerQueue = (*fakePeer)(nil) - -type fakePeer struct { - p peer.ID - messagesSent chan messageSent - onShutdown func(peer.ID) -} - -func (fp *fakePeer) AllocateAndBuildMessage(blkSize uint64, buildMessage func(b *messagequeue.Builder)) { - builder := messagequeue.NewBuilder(context.TODO(), messagequeue.Topic(0)) - buildMessage(builder) - message, err := builder.Build() - if err != nil { - panic(err) - } - - fp.messagesSent <- messageSent{fp.p, message} -} - -func (fp *fakePeer) Startup() {} -func (fp *fakePeer) Shutdown() {} - -//func (fp *fakePeer) AddRequest(graphSyncRequest gsmsg.GraphSyncRequest, notifees ...notifications.Notifee) { -// message := gsmsg.New() -// message.AddRequest(graphSyncRequest) -// fp.messagesSent <- messageSent{fp.p, message} -//} - -func makePeerQueueFactory(messagesSent chan messageSent) PeerQueueFactory { - return func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) PeerQueue { - return &fakePeer{ - p: p, - messagesSent: messagesSent, - onShutdown: onShutdown, - } - } -} - -func TestSendingMessagesToPeers(t *testing.T) { - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, 1*time.Second) - defer cancel() - messagesSent := make(chan messageSent, 5) - peerQueueFactory := makePeerQueueFactory(messagesSent) - - tp := testutil.GeneratePeers(5) - - id := graphsync.NewRequestID() - priority := graphsync.Priority(rand.Int31()) - root := testutil.GenerateCids(1)[0] - ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any) - selector := ssb.Matcher().Node() - - peerManager := NewMessageManager(ctx, peerQueueFactory) - - request := gsmsg.NewRequest(id, root, selector, priority) - peerManager.AllocateAndBuildMessage(tp[0], 0, func(b *messagequeue.Builder) { - b.AddRequest(request) - }) - peerManager.AllocateAndBuildMessage(tp[1], 0, func(b *messagequeue.Builder) { - b.AddRequest(request) - }) - cancelRequest := gsmsg.NewCancelRequest(id) - peerManager.AllocateAndBuildMessage(tp[0], 0, func(b *messagequeue.Builder) { - b.AddRequest(cancelRequest) - }) - - var firstMessage messageSent - testutil.AssertReceive(ctx, t, messagesSent, &firstMessage, "first message did not send") - require.Equal(t, tp[0], firstMessage.p, "first message sent to incorrect peer") - request = firstMessage.message.Requests()[0] - require.Equal(t, id, request.ID()) - require.Equal(t, request.Type(), graphsync.RequestTypeNew) - require.Equal(t, priority, request.Priority()) - require.Equal(t, selector, request.Selector()) - - var secondMessage messageSent - testutil.AssertReceive(ctx, t, messagesSent, &secondMessage, "second message did not send") - require.Equal(t, tp[1], secondMessage.p, "second message sent to incorrect peer") - request = secondMessage.message.Requests()[0] - require.Equal(t, id, request.ID()) - require.Equal(t, request.Type(), graphsync.RequestTypeNew) - require.Equal(t, priority, request.Priority()) - require.Equal(t, selector, request.Selector()) - - var thirdMessage messageSent - testutil.AssertReceive(ctx, t, messagesSent, &thirdMessage, "third message did not send") - - require.Equal(t, tp[0], thirdMessage.p, "third message sent to incorrect peer") - request = thirdMessage.message.Requests()[0] - require.Equal(t, id, request.ID()) - require.Equal(t, request.Type(), graphsync.RequestTypeCancel) - - connectedPeers := peerManager.ConnectedPeers() - require.Len(t, connectedPeers, 2) - - testutil.AssertContainsPeer(t, connectedPeers, tp[0]) - testutil.AssertContainsPeer(t, connectedPeers, tp[1]) -} diff --git a/requestmanager/client.go b/requestmanager/client.go index 5faa58df..07b31f93 100644 --- a/requestmanager/client.go +++ b/requestmanager/client.go @@ -11,6 +11,7 @@ import ( blocks "github.com/ipfs/go-block-format" logging "github.com/ipfs/go-log/v2" "github.com/ipfs/go-peertaskqueue/peertask" + "github.com/ipfs/go-protocolnetwork/pkg/network" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/traversal" "github.com/ipld/go-ipld-prime/traversal/selector" @@ -23,8 +24,6 @@ import ( "github.com/ipfs/go-graphsync/listeners" gsmsg "github.com/ipfs/go-graphsync/message" "github.com/ipfs/go-graphsync/messagequeue" - "github.com/ipfs/go-graphsync/network" - "github.com/ipfs/go-graphsync/notifications" "github.com/ipfs/go-graphsync/panics" "github.com/ipfs/go-graphsync/peerstate" "github.com/ipfs/go-graphsync/requestmanager/executor" @@ -69,7 +68,7 @@ type inProgressRequestStatus struct { // PeerHandler is an interface that can send requests to peers type PeerHandler interface { - AllocateAndBuildMessage(p peer.ID, blkSize uint64, buildMessageFn func(*messagequeue.Builder)) + BuildMessage(p peer.ID, params messagequeue.MessageParams) } // PersistenceOptions is an interface for getting loaders by name @@ -376,10 +375,12 @@ func (rm *RequestManager) PeerState(p peer.ID) peerstate.PeerState { // SendRequest sends a request to the message queue func (rm *RequestManager) SendRequest(p peer.ID, request gsmsg.GraphSyncRequest) { sub := &reqSubscriber{p, request, rm.networkErrorListeners} - rm.peerHandler.AllocateAndBuildMessage(p, 0, func(builder *messagequeue.Builder) { - builder.AddRequest(request) - builder.SetSubscriber(request.ID(), sub) - }) + rm.peerHandler.BuildMessage(p, messagequeue.MessageParams{ + Size: 0, + BuildMessageFn: func(builder *messagequeue.Builder) { + builder.AddRequest(request) + builder.SetSubscriber(request.ID(), sub) + }}) } // Startup starts processing for the WantManager. @@ -406,13 +407,9 @@ type reqSubscriber struct { networkErrorListeners *listeners.NetworkErrorListeners } -func (r *reqSubscriber) OnNext(_ notifications.Topic, event notifications.Event) { - mqEvt, isMQEvt := event.(messagequeue.Event) - if !isMQEvt || mqEvt.Name != messagequeue.Error { - return - } - r.networkErrorListeners.NotifyNetworkErrorListeners(r.p, r.request, mqEvt.Err) +func (r *reqSubscriber) OnNext(_ messagequeue.Topic, event messagequeue.Event) { + r.networkErrorListeners.NotifyNetworkErrorListeners(r.p, r.request, event.Err) } -func (r reqSubscriber) OnClose(_ notifications.Topic) { +func (r reqSubscriber) OnClose(_ messagequeue.Topic) { } diff --git a/requestmanager/requestmanager_test.go b/requestmanager/requestmanager_test.go index 0ce65207..47a46368 100644 --- a/requestmanager/requestmanager_test.go +++ b/requestmanager/requestmanager_test.go @@ -1029,10 +1029,9 @@ type fakePeerHandler struct { requestRecordChan chan requestRecord } -func (fph *fakePeerHandler) AllocateAndBuildMessage(p peer.ID, blkSize uint64, - requestBuilder func(b *messagequeue.Builder)) { +func (fph *fakePeerHandler) BuildMessage(p peer.ID, params messagequeue.MessageParams) { builder := messagequeue.NewBuilder(context.TODO(), messagequeue.Topic(0)) - requestBuilder(builder) + params.BuildMessageFn(builder) message, err := builder.Build() if err != nil { panic(err) diff --git a/responsemanager/client.go b/responsemanager/client.go index 486fd7d9..0322cd25 100644 --- a/responsemanager/client.go +++ b/responsemanager/client.go @@ -7,6 +7,7 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/ipfs/go-peertaskqueue/peertask" + "github.com/ipfs/go-protocolnetwork/pkg/network" ipld "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/traversal" "github.com/libp2p/go-libp2p/core/peer" @@ -15,14 +16,14 @@ import ( "github.com/ipfs/go-graphsync" "github.com/ipfs/go-graphsync/ipldutil" gsmsg "github.com/ipfs/go-graphsync/message" - "github.com/ipfs/go-graphsync/network" - "github.com/ipfs/go-graphsync/notifications" + "github.com/ipfs/go-graphsync/messagequeue" "github.com/ipfs/go-graphsync/panics" "github.com/ipfs/go-graphsync/peerstate" "github.com/ipfs/go-graphsync/responsemanager/hooks" "github.com/ipfs/go-graphsync/responsemanager/queryexecutor" "github.com/ipfs/go-graphsync/responsemanager/responseassembler" "github.com/ipfs/go-graphsync/taskqueue" + "github.com/ipfs/go-protocolnetwork/pkg/notifications" ) // The code in this file implements the public interface of the response manager. @@ -85,7 +86,7 @@ type NetworkErrorListeners interface { // ResponseAssembler is an interface that returns sender interfaces for peer responses. type ResponseAssembler interface { - NewStream(ctx context.Context, p peer.ID, requestID graphsync.RequestID, subscriber notifications.Subscriber) responseassembler.ResponseStream + NewStream(ctx context.Context, p peer.ID, requestID graphsync.RequestID, subscriber notifications.Subscriber[messagequeue.Topic, messagequeue.Event]) responseassembler.ResponseStream } type responseManagerMessage interface { diff --git a/responsemanager/responseassembler/responseassembler.go b/responsemanager/responseassembler/responseassembler.go index 5236174f..4f6cbebd 100644 --- a/responsemanager/responseassembler/responseassembler.go +++ b/responsemanager/responseassembler/responseassembler.go @@ -18,8 +18,8 @@ import ( "github.com/ipfs/go-graphsync" "github.com/ipfs/go-graphsync/messagequeue" - "github.com/ipfs/go-graphsync/notifications" - "github.com/ipfs/go-graphsync/peermanager" + "github.com/ipfs/go-protocolnetwork/pkg/notifications" + "github.com/ipfs/go-protocolnetwork/pkg/peermanager" ) // Transaction is a series of operations that should be send together in a single response @@ -56,27 +56,27 @@ type ResponseBuilder interface { // PeerMessageHandler is an interface that can queue a response for a given peer to go out over the network // If blkSize > 0, message building may block until enough memory has been freed from the queues to allocate the message. type PeerMessageHandler interface { - AllocateAndBuildMessage(p peer.ID, blkSize uint64, buildResponseFn func(*messagequeue.Builder)) + BuildMessage(p peer.ID, params messagequeue.MessageParams) } // ResponseAssembler manages assembling responses to go out over the network // in libp2p messages type ResponseAssembler struct { - *peermanager.PeerManager + *peermanager.PeerManager[*peerLinkTracker] peerHandler PeerMessageHandler } // New generates a new ResponseAssembler for sending responses func New(ctx context.Context, peerHandler PeerMessageHandler) *ResponseAssembler { return &ResponseAssembler{ - PeerManager: peermanager.New(ctx, func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) peermanager.PeerHandler { + PeerManager: peermanager.New(ctx, func(ctx context.Context, p peer.ID, onShutdown func(peer.ID)) *peerLinkTracker { return newTracker() }), peerHandler: peerHandler, } } -func (ra *ResponseAssembler) NewStream(ctx context.Context, p peer.ID, requestID graphsync.RequestID, subscriber notifications.Subscriber) ResponseStream { +func (ra *ResponseAssembler) NewStream(ctx context.Context, p peer.ID, requestID graphsync.RequestID, subscriber notifications.Subscriber[messagequeue.Topic, messagequeue.Event]) ResponseStream { return &responseStream{ ctx: ctx, requestID: requestID, @@ -94,8 +94,8 @@ type responseStream struct { closed bool closedLk sync.RWMutex messageSenders PeerMessageHandler - linkTrackers *peermanager.PeerManager - subscriber notifications.Subscriber + linkTrackers *peermanager.PeerManager[*peerLinkTracker] + subscriber notifications.Subscriber[messagequeue.Topic, messagequeue.Event] } func (r *responseStream) Close() error { @@ -123,22 +123,22 @@ type ResponseStream interface { // DedupKey indicates that outgoing blocks should be deduplicated in a seperate bucket (only with requests that share // supplied key string) func (rs *responseStream) DedupKey(key string) { - rs.linkTrackers.GetProcess(rs.p).(*peerLinkTracker).DedupKey(rs.requestID, key) + rs.linkTrackers.GetHandler(rs.p).DedupKey(rs.requestID, key) } // IgnoreBlocks indicates that a list of keys should be ignored when sending blocks func (rs *responseStream) IgnoreBlocks(links []ipld.Link) { - rs.linkTrackers.GetProcess(rs.p).(*peerLinkTracker).IgnoreBlocks(rs.requestID, links) + rs.linkTrackers.GetHandler(rs.p).IgnoreBlocks(rs.requestID, links) } // SkipFirstBlocks tells the assembler for the given request to not send the first N blocks func (rs *responseStream) SkipFirstBlocks(skipFirstBlocks int64) { - rs.linkTrackers.GetProcess(rs.p).(*peerLinkTracker).SkipFirstBlocks(rs.requestID, skipFirstBlocks) + rs.linkTrackers.GetHandler(rs.p).SkipFirstBlocks(rs.requestID, skipFirstBlocks) } // ClearRequest removes all tracking for this request. func (rs *responseStream) ClearRequest() { - _ = rs.linkTrackers.GetProcess(rs.p).(*peerLinkTracker).FinishTracking(rs.requestID) + _ = rs.linkTrackers.GetHandler(rs.p).FinishTracking(rs.requestID) } func (rs *responseStream) Transaction(transaction Transaction) error { @@ -147,7 +147,7 @@ func (rs *responseStream) Transaction(transaction Transaction) error { rb := &responseBuilder{ ctx: ctx, requestID: rs.requestID, - linkTracker: rs.linkTrackers.GetProcess(rs.p).(*peerLinkTracker), + linkTracker: rs.linkTrackers.GetHandler(rs.p), } err := transaction(rb) rs.execute(ctx, rb.operations) @@ -165,17 +165,19 @@ func (rs *responseStream) execute(ctx context.Context, operations []responseOper for _, op := range operations { size += op.size() } - rs.messageSenders.AllocateAndBuildMessage(rs.p, size, func(builder *messagequeue.Builder) { - _, span = otel.Tracer("graphsync").Start(ctx, "buildMessage", trace.WithLinks(trace.LinkFromContext(builder.Context()))) - defer span.End() - - if rs.isClosed() { - return - } - for _, op := range operations { - op.build(builder) - } - builder.SetResponseStream(rs.requestID, rs) - builder.SetSubscriber(rs.requestID, rs.subscriber) - }) + rs.messageSenders.BuildMessage(rs.p, messagequeue.MessageParams{ + Size: size, + BuildMessageFn: func(builder *messagequeue.Builder) { + _, span = otel.Tracer("graphsync").Start(ctx, "buildMessage", trace.WithLinks(trace.LinkFromContext(builder.Context()))) + defer span.End() + + if rs.isClosed() { + return + } + for _, op := range operations { + op.build(builder) + } + builder.SetResponseStream(rs.requestID, rs) + builder.SetSubscriber(rs.requestID, rs.subscriber) + }}) } diff --git a/responsemanager/responseassembler/responseassembler_test.go b/responsemanager/responseassembler/responseassembler_test.go index 314cd5a7..c3a882d1 100644 --- a/responsemanager/responseassembler/responseassembler_test.go +++ b/responsemanager/responseassembler/responseassembler_test.go @@ -17,8 +17,8 @@ import ( "github.com/ipfs/go-graphsync" gsmsg "github.com/ipfs/go-graphsync/message" "github.com/ipfs/go-graphsync/messagequeue" - "github.com/ipfs/go-graphsync/notifications" "github.com/ipfs/go-graphsync/testutil" + "github.com/ipfs/go-protocolnetwork/pkg/notifications" ) func TestResponseAssemblerSendsResponses(t *testing.T) { @@ -546,7 +546,7 @@ type fakePeerHandler struct { lastResponseStreams map[graphsync.RequestID]io.Closer lastBlocks []blocks.Block lastResponses []gsmsg.GraphSyncResponse - lastSubscribers map[graphsync.RequestID]notifications.Subscriber + lastSubscribers map[graphsync.RequestID]notifications.Subscriber[messagequeue.Topic, messagequeue.Event] lastBlockData map[graphsync.RequestID][]graphsync.BlockData sent chan struct{} } @@ -555,7 +555,7 @@ func newFakePeerHandler(ctx context.Context, t *testing.T) *fakePeerHandler { t.Helper() return &fakePeerHandler{ lastResponseStreams: map[graphsync.RequestID]io.Closer{}, - lastSubscribers: map[graphsync.RequestID]notifications.Subscriber{}, + lastSubscribers: map[graphsync.RequestID]notifications.Subscriber[messagequeue.Topic, messagequeue.Event]{}, lastBlockData: map[graphsync.RequestID][]graphsync.BlockData{}, ctx: ctx, t: t, @@ -613,7 +613,7 @@ func (fph *fakePeerHandler) AssertExtensions(extensionSets [][]graphsync.Extensi } } -func (fph *fakePeerHandler) AssertSubscriber(requestID graphsync.RequestID, expected notifications.Subscriber) { +func (fph *fakePeerHandler) AssertSubscriber(requestID graphsync.RequestID, expected notifications.Subscriber[messagequeue.Topic, messagequeue.Event]) { actual, ok := fph.lastSubscribers[requestID] require.True(fph.t, ok) require.Equal(fph.t, expected, actual) @@ -629,9 +629,9 @@ func (fph *fakePeerHandler) RefuteResponses() { require.Empty(fph.t, fph.lastResponses) } -func (fph *fakePeerHandler) AllocateAndBuildMessage(p peer.ID, blkSize uint64, buildMessageFn func(*messagequeue.Builder)) { +func (fph *fakePeerHandler) BuildMessage(p peer.ID, params messagequeue.MessageParams) { builder := messagequeue.NewBuilder(context.TODO(), messagequeue.Topic(0)) - buildMessageFn(builder) + params.BuildMessageFn(builder) msg, err := builder.Build() require.NoError(fph.t, err) @@ -643,7 +643,7 @@ func (fph *fakePeerHandler) sendResponse(p peer.ID, responses []gsmsg.GraphSyncResponse, blks []blocks.Block, responseStreams map[graphsync.RequestID]io.Closer, - subscribers map[graphsync.RequestID]notifications.Subscriber, + subscribers map[graphsync.RequestID]notifications.Subscriber[messagequeue.Topic, messagequeue.Event], blockData map[graphsync.RequestID][]graphsync.BlockData) { fph.lastResponses = responses fph.lastBlocks = blks @@ -654,7 +654,7 @@ func (fph *fakePeerHandler) sendResponse(p peer.ID, func (fph *fakePeerHandler) Clear() { fph.lastResponses = nil - fph.lastSubscribers = map[graphsync.RequestID]notifications.Subscriber{} + fph.lastSubscribers = map[graphsync.RequestID]notifications.Subscriber[messagequeue.Topic, messagequeue.Event]{} fph.lastBlockData = map[graphsync.RequestID][]graphsync.BlockData{} fph.lastResponseStreams = map[graphsync.RequestID]io.Closer{} fph.lastBlocks = nil diff --git a/responsemanager/responsemanager_test.go b/responsemanager/responsemanager_test.go index 9deb4345..9c1fe514 100644 --- a/responsemanager/responsemanager_test.go +++ b/responsemanager/responsemanager_test.go @@ -28,7 +28,6 @@ import ( "github.com/ipfs/go-graphsync/listeners" gsmsg "github.com/ipfs/go-graphsync/message" "github.com/ipfs/go-graphsync/messagequeue" - "github.com/ipfs/go-graphsync/notifications" "github.com/ipfs/go-graphsync/persistenceoptions" "github.com/ipfs/go-graphsync/responsemanager/hooks" "github.com/ipfs/go-graphsync/responsemanager/queryexecutor" @@ -36,6 +35,7 @@ import ( "github.com/ipfs/go-graphsync/selectorvalidator" "github.com/ipfs/go-graphsync/taskqueue" "github.com/ipfs/go-graphsync/testutil" + "github.com/ipfs/go-protocolnetwork/pkg/notifications" ) func TestIncomingQuery(t *testing.T) { @@ -978,7 +978,7 @@ type fakeResponseAssembler struct { missingBlock bool } -func (fra *fakeResponseAssembler) NewStream(ctx context.Context, p peer.ID, requestID graphsync.RequestID, subscriber notifications.Subscriber) responseassembler.ResponseStream { +func (fra *fakeResponseAssembler) NewStream(ctx context.Context, p peer.ID, requestID graphsync.RequestID, subscriber notifications.Subscriber[messagequeue.Topic, messagequeue.Event]) responseassembler.ResponseStream { fra.notifeePublisher.AddSubscriber(subscriber) return &fakeResponseStream{fra, requestID} } @@ -1416,8 +1416,8 @@ func (td *testData) assertSkippedFirstBlocks(expectedSkipCount int64) { func (td *testData) notifyStatusMessagesSent() { td.transactionLk.Lock() - td.notifeePublisher.PublishEvents(notifications.Topic(rand.Int31), []notifications.Event{ - messagequeue.Event{Name: messagequeue.Sent, Metadata: messagequeue.Metadata{ResponseCodes: td.completedNotifications}}, + td.notifeePublisher.PublishEvents(messagequeue.Topic(rand.Int63()), []messagequeue.Event{ + {Name: messagequeue.Sent, Metadata: messagequeue.Metadata{ResponseCodes: td.completedNotifications}}, }) td.completedNotifications = make(map[graphsync.RequestID]graphsync.ResponseStatusCode) td.responseAssembler.completedNotifications = td.completedNotifications @@ -1426,8 +1426,8 @@ func (td *testData) notifyStatusMessagesSent() { func (td *testData) notifyBlockSendsSent() { td.transactionLk.Lock() - td.notifeePublisher.PublishEvents(notifications.Topic(graphsync.NewRequestID), []notifications.Event{ - messagequeue.Event{Name: messagequeue.Sent, Metadata: messagequeue.Metadata{BlockData: td.blkNotifications}}, + td.notifeePublisher.PublishEvents(messagequeue.Topic(rand.Int63()), []messagequeue.Event{ + {Name: messagequeue.Sent, Metadata: messagequeue.Metadata{BlockData: td.blkNotifications}}, }) td.blkNotifications = make(map[graphsync.RequestID][]graphsync.BlockData) td.responseAssembler.blkNotifications = td.blkNotifications @@ -1436,8 +1436,8 @@ func (td *testData) notifyBlockSendsSent() { func (td *testData) notifyStatusMessagesNetworkError(err error) { td.transactionLk.Lock() - td.notifeePublisher.PublishEvents(notifications.Topic(rand.Int31), []notifications.Event{ - messagequeue.Event{Name: messagequeue.Error, Err: err, Metadata: messagequeue.Metadata{ResponseCodes: td.completedNotifications}}, + td.notifeePublisher.PublishEvents(messagequeue.Topic(rand.Int63()), []messagequeue.Event{ + {Name: messagequeue.Error, Err: err, Metadata: messagequeue.Metadata{ResponseCodes: td.completedNotifications}}, }) td.completedNotifications = make(map[graphsync.RequestID]graphsync.ResponseStatusCode) td.responseAssembler.completedNotifications = td.completedNotifications @@ -1446,8 +1446,8 @@ func (td *testData) notifyStatusMessagesNetworkError(err error) { func (td *testData) notifyBlockSendsNetworkError(err error) { td.transactionLk.Lock() - td.notifeePublisher.PublishEvents(notifications.Topic(rand.Int31), []notifications.Event{ - messagequeue.Event{Name: messagequeue.Error, Err: err, Metadata: messagequeue.Metadata{BlockData: td.blkNotifications}}, + td.notifeePublisher.PublishEvents(messagequeue.Topic(rand.Int63()), []messagequeue.Event{ + {Name: messagequeue.Error, Err: err, Metadata: messagequeue.Metadata{BlockData: td.blkNotifications}}, }) td.blkNotifications = make(map[graphsync.RequestID][]graphsync.BlockData) td.responseAssembler.blkNotifications = td.blkNotifications diff --git a/responsemanager/subscriber.go b/responsemanager/subscriber.go index 0fd0f728..ca395b87 100644 --- a/responsemanager/subscriber.go +++ b/responsemanager/subscriber.go @@ -6,8 +6,7 @@ import ( "github.com/ipfs/go-graphsync" gsmsg "github.com/ipfs/go-graphsync/message" "github.com/ipfs/go-graphsync/messagequeue" - "github.com/ipfs/go-graphsync/network" - "github.com/ipfs/go-graphsync/notifications" + "github.com/ipfs/go-protocolnetwork/pkg/network" ) // RequestCloser can cancel request on a network error @@ -26,11 +25,7 @@ type subscriber struct { connManager network.ConnManager } -func (s *subscriber) OnNext(_ notifications.Topic, event notifications.Event) { - responseEvent, ok := event.(messagequeue.Event) - if !ok { - return - } +func (s *subscriber) OnNext(_ messagequeue.Topic, responseEvent messagequeue.Event) { switch responseEvent.Name { case messagequeue.Error: s.requestCloser.CloseWithNetworkError(s.request.ID()) @@ -52,6 +47,5 @@ func (s *subscriber) OnNext(_ notifications.Topic, event notifications.Event) { } } -func (s *subscriber) OnClose(_ notifications.Topic) { - +func (s *subscriber) OnClose(_ messagequeue.Topic) { } diff --git a/testutil/testconnmanager.go b/testutil/testconnmanager.go index 5932a295..a12559e7 100644 --- a/testutil/testconnmanager.go +++ b/testutil/testconnmanager.go @@ -82,3 +82,9 @@ func (tcm *TestConnManager) RefuteProtectedWithTags(t testing.TB, p peer.ID, tag require.NotContains(t, tcm.protectedConns[p], tag) } } + +func (tcm *TestConnManager) TagPeer(p peer.ID, tag string, priority int) { +} + +func (tcm *TestConnManager) UntagPeer(p peer.ID, tag string) { +} diff --git a/testutil/testnotifications.go b/testutil/testnotifications.go index 4fdab9e2..13095b08 100644 --- a/testutil/testnotifications.go +++ b/testutil/testnotifications.go @@ -7,31 +7,32 @@ import ( "github.com/stretchr/testify/require" - "github.com/ipfs/go-graphsync/notifications" + "github.com/ipfs/go-graphsync/messagequeue" + "github.com/ipfs/go-protocolnetwork/pkg/notifications" ) type TestSubscriber struct { receivedEvents chan DispatchedEvent - closed chan notifications.Topic + closed chan messagequeue.Topic } type DispatchedEvent struct { - Topic notifications.Topic - Event notifications.Event + Topic messagequeue.Topic + Event messagequeue.Event } func NewTestSubscriber(bufferSize int) *TestSubscriber { return &TestSubscriber{ receivedEvents: make(chan DispatchedEvent, bufferSize), - closed: make(chan notifications.Topic, bufferSize), + closed: make(chan messagequeue.Topic, bufferSize), } } -func (ts *TestSubscriber) OnNext(topic notifications.Topic, ev notifications.Event) { +func (ts *TestSubscriber) OnNext(topic messagequeue.Topic, ev messagequeue.Event) { ts.receivedEvents <- DispatchedEvent{topic, ev} } -func (ts *TestSubscriber) OnClose(topic notifications.Topic) { +func (ts *TestSubscriber) OnClose(topic messagequeue.Topic) { ts.closed <- topic } @@ -43,7 +44,7 @@ func (ts *TestSubscriber) ExpectEvents(ctx context.Context, t *testing.T, events require.Equal(t, expectedEvent, event) } } -func (ts *TestSubscriber) ExpectEventsAllTopics(ctx context.Context, t *testing.T, events []notifications.Event) { +func (ts *TestSubscriber) ExpectEventsAllTopics(ctx context.Context, t *testing.T, events []messagequeue.Event) { t.Helper() for _, expectedEvent := range events { var event DispatchedEvent @@ -57,13 +58,13 @@ func (ts *TestSubscriber) NoEventsReceived(t *testing.T) { AssertChannelEmpty(t, ts.receivedEvents, "should have received no events") } -func (ts *TestSubscriber) ExpectClosesAnyOrder(ctx context.Context, t *testing.T, topics []notifications.Topic) { +func (ts *TestSubscriber) ExpectClosesAnyOrder(ctx context.Context, t *testing.T, topics []messagequeue.Topic) { t.Helper() - expectedTopics := make(map[notifications.Topic]struct{}) - receivedTopics := make(map[notifications.Topic]struct{}) + expectedTopics := make(map[messagequeue.Topic]struct{}) + receivedTopics := make(map[messagequeue.Topic]struct{}) for _, expectedTopic := range topics { expectedTopics[expectedTopic] = struct{}{} - var topic notifications.Topic + var topic messagequeue.Topic AssertReceive(ctx, t, ts.closed, &topic, "should receive another event") receivedTopics[topic] = struct{}{} } @@ -77,10 +78,10 @@ func (ts *TestSubscriber) ExpectNCloses(ctx context.Context, t *testing.T, n int } } -func (ts *TestSubscriber) ExpectCloses(ctx context.Context, t *testing.T, topics []notifications.Topic) { +func (ts *TestSubscriber) ExpectCloses(ctx context.Context, t *testing.T, topics []messagequeue.Topic) { t.Helper() for _, expectedTopic := range topics { - var topic notifications.Topic + var topic messagequeue.Topic AssertReceive(ctx, t, ts.closed, &topic, "should receive another event") require.Equal(t, expectedTopic, topic) } @@ -88,16 +89,16 @@ func (ts *TestSubscriber) ExpectCloses(ctx context.Context, t *testing.T, topics type MockPublisher struct { subscribersLk sync.Mutex - subscribers []notifications.Subscriber + subscribers []notifications.Subscriber[messagequeue.Topic, messagequeue.Event] } -func (mp *MockPublisher) AddSubscriber(subscriber notifications.Subscriber) { +func (mp *MockPublisher) AddSubscriber(subscriber notifications.Subscriber[messagequeue.Topic, messagequeue.Event]) { mp.subscribersLk.Lock() mp.subscribers = append(mp.subscribers, subscriber) mp.subscribersLk.Unlock() } -func (mp *MockPublisher) PublishEvents(topic notifications.Topic, events []notifications.Event) { +func (mp *MockPublisher) PublishEvents(topic messagequeue.Topic, events []messagequeue.Event) { mp.subscribersLk.Lock() for _, subscriber := range mp.subscribers {