diff --git a/Makefile b/Makefile
index fe5a9852..01272fbf 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
.PHONY: build build-release build-sncli build-sn-manager
-.PHONY: install-lumera setup-supernodes system-test-setup
+.PHONY: install-lumera setup-supernodes system-test-setup install-deps
.PHONY: gen-cascade gen-supernode
.PHONY: test-e2e test-unit test-integration test-system
@@ -140,9 +140,9 @@ test-e2e:
# Run cascade e2e tests only
test-cascade:
@echo "Running cascade e2e tests..."
- @cd tests/system && go test -tags=system_test -v -run TestCascadeE2E .
+ @cd tests/system && go mod tidy && go test -tags=system_test -v -run TestCascadeE2E .
# Run sn-manager e2e tests only
test-sn-manager:
@echo "Running sn-manager e2e tests..."
- @cd tests/system && go test -tags=system_test -v -run '^TestSNManager' .
\ No newline at end of file
+ @cd tests/system && go test -tags=system_test -v -run '^TestSNManager' .
diff --git a/go.mod b/go.mod
index b7f53ec1..46091df2 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,6 @@ module github.com/LumeraProtocol/supernode/v2
go 1.24.1
replace (
- github.com/LumeraProtocol/supernode/v2/supernode => ./supernode
github.com/bytedance/sonic => github.com/bytedance/sonic v1.14.0
github.com/bytedance/sonic/loader => github.com/bytedance/sonic/loader v0.3.0
)
diff --git a/p2p/kademlia/network.go b/p2p/kademlia/network.go
index a2322ff7..935d1583 100644
--- a/p2p/kademlia/network.go
+++ b/p2p/kademlia/network.go
@@ -2,7 +2,6 @@ package kademlia
import (
"context"
- "encoding/hex"
"fmt"
"io"
"net"
@@ -951,7 +950,7 @@ func (s *Network) handleGetValuesRequest(ctx context.Context, message *Message,
i++
}
- values, count, err := s.dht.store.RetrieveBatchValues(ctx, keys, true)
+ values, count, err := s.dht.store.RetrieveBatchValues(ctx, keys, false)
if err != nil {
err = errors.Errorf("batch find values: %w", err)
s.appendRetrieveEntry(message.Sender.IP, RecentBatchRetrieveEntry{
@@ -976,17 +975,8 @@ func (s *Network) handleGetValuesRequest(ctx context.Context, message *Message,
for i, key := range keys {
val := KeyValWithClosest{
- Value: values[i],
- }
- if len(val.Value) == 0 {
- decodedKey, err := hex.DecodeString(keys[i])
- if err != nil {
- err = errors.Errorf("batch find vals: decode key: %w - key %s", err, keys[i])
- return s.generateResponseMessage(BatchGetValues, message.Sender, ResultFailed, err.Error())
- }
-
- nodes, _ := s.dht.ht.closestContacts(Alpha, decodedKey, []*Node{message.Sender})
- val.Closest = nodes.Nodes
+ Value: values[i],
+ Closest: make([]*Node, 0), // for compatibility, not used - each node now has full view of the whole network
}
request.Data[key] = val
diff --git a/pkg/codec/codec_mock.go b/pkg/codec/codec_mock.go
index 9c3cf864..09484cee 100644
--- a/pkg/codec/codec_mock.go
+++ b/pkg/codec/codec_mock.go
@@ -1,10 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: codec.go
-//
-// Generated by this command:
-//
-// mockgen -destination=codec_mock.go -package=codec -source=codec.go
-//
// Package codec is a generated GoMock package.
package codec
@@ -13,14 +8,13 @@ import (
context "context"
reflect "reflect"
- gomock "go.uber.org/mock/gomock"
+ gomock "github.com/golang/mock/gomock"
)
// MockCodec is a mock of Codec interface.
type MockCodec struct {
ctrl *gomock.Controller
recorder *MockCodecMockRecorder
- isgomock struct{}
}
// MockCodecMockRecorder is the mock recorder for MockCodec.
@@ -50,7 +44,7 @@ func (m *MockCodec) Decode(ctx context.Context, req DecodeRequest) (DecodeRespon
}
// Decode indicates an expected call of Decode.
-func (mr *MockCodecMockRecorder) Decode(ctx, req any) *gomock.Call {
+func (mr *MockCodecMockRecorder) Decode(ctx, req interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decode", reflect.TypeOf((*MockCodec)(nil).Decode), ctx, req)
}
@@ -65,7 +59,7 @@ func (m *MockCodec) Encode(ctx context.Context, req EncodeRequest) (EncodeRespon
}
// Encode indicates an expected call of Encode.
-func (mr *MockCodecMockRecorder) Encode(ctx, req any) *gomock.Call {
+func (mr *MockCodecMockRecorder) Encode(ctx, req interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Encode", reflect.TypeOf((*MockCodec)(nil).Encode), ctx, req)
}
diff --git a/pkg/codec/decode.go b/pkg/codec/decode.go
index fe77d752..bd3b0231 100644
--- a/pkg/codec/decode.go
+++ b/pkg/codec/decode.go
@@ -5,9 +5,13 @@ import (
"encoding/json"
"fmt"
"os"
+ "path"
"path/filepath"
+ "strings"
+ "sync"
raptorq "github.com/LumeraProtocol/rq-go"
+ "github.com/LumeraProtocol/supernode/v2/pkg/errors"
"github.com/LumeraProtocol/supernode/v2/pkg/logtrace"
)
@@ -18,81 +22,160 @@ type DecodeRequest struct {
}
type DecodeResponse struct {
- Path string
+ FilePath string
DecodeTmpDir string
}
-func (rq *raptorQ) Decode(ctx context.Context, req DecodeRequest) (DecodeResponse, error) {
+// Workspace holds paths & reverse index for prepared decoding.
+type Workspace struct {
+ ActionID string
+ SymbolsDir string // ...//
+ BlockDirs []string // index = blockID (or 0 if single block)
+ symbolToBlock map[string]int
+ mu sync.RWMutex // protects symbolToBlock reads if you expand it later
+}
+
+// PrepareDecode creates the on-disk workspace for decoding and returns:
+// - blockPaths[0] => where to write symbols for block 0 (your single-block case)
+// - Write(block, id, data) callback that writes symbol bytes directly to disk
+// - Cleanup() to remove the workspace on abort (no-op if you want to keep it)
+func (rq *raptorQ) PrepareDecode(
+ ctx context.Context,
+ actionID string,
+ layout Layout,
+) (blockPaths []string, Write func(block int, symbolID string, data []byte) (string, error), Cleanup func() error, ws *Workspace, err error) {
fields := logtrace.Fields{
- logtrace.FieldMethod: "Decode",
+ logtrace.FieldMethod: "PrepareDecode",
logtrace.FieldModule: "rq",
- logtrace.FieldActionID: req.ActionID,
+ logtrace.FieldActionID: actionID,
}
- logtrace.Info(ctx, "RaptorQ decode request received", fields)
- // Use deterministic processor settings (matching encoder)
- processor, err := raptorq.NewRaptorQProcessor(rqSymbolSize, rqRedundancyFactor, rqMaxMemoryMB, rqConcurrency)
- if err != nil {
+ // Create root symbols dir for this action
+ symbolsDir := filepath.Join(rq.symbolsBaseDir, actionID)
+ if err := os.MkdirAll(symbolsDir, 0o755); err != nil {
fields[logtrace.FieldError] = err.Error()
- return DecodeResponse{}, fmt.Errorf("create RaptorQ processor: %w", err)
+ logtrace.Error(ctx, "mkdir symbols base dir failed", fields)
+ return nil, nil, nil, nil, fmt.Errorf("mkdir %s: %w", symbolsDir, err)
}
- defer processor.Free()
- symbolsDir := filepath.Join(rq.symbolsBaseDir, req.ActionID)
- // Ensure a clean scratch directory (avoid contamination from previous attempts)
- if err := os.RemoveAll(symbolsDir); err != nil {
- fields[logtrace.FieldError] = err.Error()
- return DecodeResponse{}, fmt.Errorf("cleanup decode dir %s: %w", symbolsDir, err)
+ // Ensure block directories exist; build reverse index symbol -> block
+ maxBlockID := 0
+ for _, b := range layout.Blocks {
+ if int(b.BlockID) > maxBlockID {
+ maxBlockID = int(b.BlockID)
+ }
}
- if err := os.MkdirAll(symbolsDir, 0o755); err != nil {
- fields[logtrace.FieldError] = err.Error()
- return DecodeResponse{}, fmt.Errorf("mkdir %s: %w", symbolsDir, err)
+ blockDirs := make([]string, maxBlockID+1)
+ s2b := make(map[string]int, 1024)
+
+ for _, b := range layout.Blocks {
+ dir := filepath.Join(symbolsDir, fmt.Sprintf("block_%d", b.BlockID))
+ if err := os.MkdirAll(dir, 0o755); err != nil {
+ fields[logtrace.FieldError] = err.Error()
+ logtrace.Error(ctx, "mkdir block dir failed", fields)
+ return nil, nil, nil, nil, fmt.Errorf("mkdir %s: %w", dir, err)
+ }
+ blockDirs[b.BlockID] = dir
+ for _, sym := range b.Symbols {
+ s2b[sym] = b.BlockID
+ }
}
- // Validate layout before writing any symbols
- if len(req.Layout.Blocks) == 0 {
- fields[logtrace.FieldError] = "empty layout"
- return DecodeResponse{}, fmt.Errorf("invalid layout: no blocks present")
+ ws = &Workspace{
+ ActionID: actionID,
+ SymbolsDir: symbolsDir,
+ BlockDirs: blockDirs,
+ symbolToBlock: s2b,
}
- for _, blk := range req.Layout.Blocks {
- if len(blk.Symbols) == 0 {
- fields[logtrace.FieldError] = fmt.Sprintf("block_%d has no symbols", blk.BlockID)
- return DecodeResponse{}, fmt.Errorf("invalid layout: block %d has no symbols", blk.BlockID)
+
+ // Helper: atomic write (tmp file + rename) to avoid partials on crash
+ writeFileAtomic := func(path string, data []byte) error {
+ tmp := path + ".tmp"
+ if err := os.WriteFile(tmp, data, 0o644); err != nil {
+ return err
}
+ return os.Rename(tmp, path)
}
- // Build symbol->block mapping from layout and ensure block directories exist
- symbolToBlock := make(map[string]int)
- for _, blk := range req.Layout.Blocks {
- blockDir := filepath.Join(symbolsDir, fmt.Sprintf("block_%d", blk.BlockID))
- if err := os.MkdirAll(blockDir, 0o755); err != nil {
- fields[logtrace.FieldError] = err.Error()
- return DecodeResponse{}, fmt.Errorf("mkdir %s: %w", blockDir, err)
+ // Write callback; if block < 0, resolve via layout reverse index; default to 0.
+ Write = func(block int, symbolID string, data []byte) (string, error) {
+ // Quick cancellation check
+ select {
+ case <-ctx.Done():
+ return "", ctx.Err()
+ default:
}
- for _, sym := range blk.Symbols {
- symbolToBlock[sym] = blk.BlockID
+
+ // Resolve block if caller passes default
+ if block < 0 {
+ ws.mu.RLock()
+ bid, ok := ws.symbolToBlock[symbolID]
+ ws.mu.RUnlock()
+ if !ok {
+ // Single-block simplification: default to block 0 if layout maps are absent
+ if len(ws.BlockDirs) == 0 || ws.BlockDirs[0] == "" {
+ return "", errors.Errorf("no block directories prepared")
+ }
+ bid = 0
+ }
+ block = bid
}
- }
- // Write symbols to their respective block directories
- for id, data := range req.Symbols {
- blkID, ok := symbolToBlock[id]
- if !ok {
- fields[logtrace.FieldError] = "symbol not present in layout"
- return DecodeResponse{}, fmt.Errorf("symbol %s not present in layout", id)
+ if block < 0 || block >= len(ws.BlockDirs) || ws.BlockDirs[block] == "" {
+ return "", errors.Errorf("invalid block index %d", block)
}
- blockDir := filepath.Join(symbolsDir, fmt.Sprintf("block_%d", blkID))
- symbolPath := filepath.Join(blockDir, id)
- if err := os.WriteFile(symbolPath, data, 0o644); err != nil {
- fields[logtrace.FieldError] = err.Error()
- return DecodeResponse{}, fmt.Errorf("write symbol %s: %w", id, err)
+
+ // sanitize symbolID to a basename (prevents traversal)
+ clean := path.Clean("/" + symbolID)
+ base := strings.TrimPrefix(clean, "/")
+ if base == "" || strings.Contains(base, "/") {
+ return "", errors.Errorf("invalid symbol id %q", symbolID)
+
+ }
+
+ dest := filepath.Join(ws.BlockDirs[block], base)
+ if err := writeFileAtomic(dest, data); err != nil {
+ return "", fmt.Errorf("write symbol %s (block %d): %w", base, block, err)
}
+ return dest, nil
+ }
+
+ Cleanup = func() error {
+ // Remove the whole workspace directory (symbols + layout + output if any)
+ return os.RemoveAll(symbolsDir)
+ }
+
+ logtrace.Info(ctx, "prepare decode workspace created", logtrace.Fields{
+ "symbols_dir": symbolsDir,
+ "blocks": len(blockDirs),
+ })
+ return blockDirs, Write, Cleanup, ws, nil
+}
+
+// DecodeFromPrepared performs RaptorQ decode using an already-prepared workspace.
+// It writes layout.json under the workspace, runs decode, and returns output paths.
+func (rq *raptorQ) DecodeFromPrepared(
+ ctx context.Context,
+ ws *Workspace,
+ layout Layout,
+) (DecodeResponse, error) {
+ fields := logtrace.Fields{
+ logtrace.FieldMethod: "DecodeFromPrepared",
+ logtrace.FieldModule: "rq",
+ logtrace.FieldActionID: ws.ActionID,
+ }
+ logtrace.Info(ctx, "RaptorQ decode (prepared) requested", fields)
+
+ processor, err := raptorq.NewRaptorQProcessor(rqSymbolSize, rqRedundancyFactor, rqMaxMemoryMB, rqConcurrency)
+ if err != nil {
+ fields[logtrace.FieldError] = err.Error()
+ return DecodeResponse{}, fmt.Errorf("create RaptorQ processor: %w", err)
}
- logtrace.Info(ctx, "symbols written to block directories", fields)
+ defer processor.Free()
- // ---------- write layout.json ----------
- layoutPath := filepath.Join(symbolsDir, "layout.json")
- layoutBytes, err := json.Marshal(req.Layout)
+ // Write layout.json (idempotent)
+ layoutPath := filepath.Join(ws.SymbolsDir, "layout.json")
+ layoutBytes, err := json.Marshal(layout)
if err != nil {
fields[logtrace.FieldError] = err.Error()
return DecodeResponse{}, fmt.Errorf("marshal layout: %w", err)
@@ -101,16 +184,74 @@ func (rq *raptorQ) Decode(ctx context.Context, req DecodeRequest) (DecodeRespons
fields[logtrace.FieldError] = err.Error()
return DecodeResponse{}, fmt.Errorf("write layout file: %w", err)
}
- logtrace.Info(ctx, "layout.json written", fields)
+ logtrace.Info(ctx, "layout.json written (prepared)", fields)
- // Decode
- outputPath := filepath.Join(symbolsDir, "output")
- if err := processor.DecodeSymbols(symbolsDir, outputPath, layoutPath); err != nil {
+ // Decode to output (idempotent-safe: overwrite on success)
+ outputPath := filepath.Join(ws.SymbolsDir, "output")
+ if err := processor.DecodeSymbols(ws.SymbolsDir, outputPath, layoutPath); err != nil {
fields[logtrace.FieldError] = err.Error()
- _ = os.Remove(outputPath)
+ _ = os.Remove(outputPath) // best-effort cleanup of partial output
return DecodeResponse{}, fmt.Errorf("raptorq decode: %w", err)
}
- logtrace.Info(ctx, "RaptorQ decoding completed successfully", fields)
- return DecodeResponse{Path: outputPath, DecodeTmpDir: symbolsDir}, nil
+ logtrace.Info(ctx, "RaptorQ decoding completed successfully (prepared)", logtrace.Fields{
+ "output_path": outputPath,
+ })
+ return DecodeResponse{FilePath: outputPath, DecodeTmpDir: ws.SymbolsDir}, nil
+}
+
+func (rq *raptorQ) Decode(ctx context.Context, req DecodeRequest) (DecodeResponse, error) {
+ fields := logtrace.Fields{
+ logtrace.FieldMethod: "Decode",
+ logtrace.FieldModule: "rq",
+ logtrace.FieldActionID: req.ActionID,
+ }
+ logtrace.Info(ctx, "RaptorQ decode request received", fields)
+
+ // 1) Validate layout (the check)
+ if len(req.Layout.Blocks) == 0 {
+ fields[logtrace.FieldError] = "empty layout"
+ return DecodeResponse{}, fmt.Errorf("invalid layout: no blocks present")
+ }
+ for _, blk := range req.Layout.Blocks {
+ if len(blk.Symbols) == 0 {
+ fields[logtrace.FieldError] = fmt.Sprintf("block_%d has no symbols", blk.BlockID)
+ return DecodeResponse{}, fmt.Errorf("invalid layout: block %d has no symbols", blk.BlockID)
+ }
+ }
+
+ // 2) Prepare workspace (functionality)
+ _, Write, Cleanup, ws, err := rq.PrepareDecode(ctx, req.ActionID, req.Layout)
+ if err != nil {
+ fields[logtrace.FieldError] = err.Error()
+ return DecodeResponse{}, fmt.Errorf("prepare decode workspace: %w", err)
+ }
+
+ // Ensure workspace cleanup on failure. On success, caller cleans up via returned path.
+ success := false
+ defer func() {
+ if !success && Cleanup != nil {
+ _ = Cleanup()
+ }
+ }()
+
+ // 3) Persist provided in-memory symbols via Write (functionality)
+ if len(req.Symbols) > 0 {
+ for id, data := range req.Symbols {
+ if _, werr := Write(-1, id, data); werr != nil {
+ fields[logtrace.FieldError] = werr.Error()
+ return DecodeResponse{}, werr
+ }
+ }
+ logtrace.Info(ctx, "symbols persisted via Write()", fields)
+ }
+
+ // 4) Decode using the prepared workspace (functionality)
+ resp, derr := rq.DecodeFromPrepared(ctx, ws, req.Layout)
+ if derr != nil {
+ fields[logtrace.FieldError] = derr.Error()
+ return DecodeResponse{}, derr
+ }
+ success = true
+ return resp, nil
}
diff --git a/pkg/net/grpc/client/client.go b/pkg/net/grpc/client/client.go
index dc4f45de..907c5b58 100644
--- a/pkg/net/grpc/client/client.go
+++ b/pkg/net/grpc/client/client.go
@@ -112,9 +112,9 @@ var defaultBackoffConfig = backoff.Config{
func DefaultClientOptions() *ClientOptions {
return &ClientOptions{
MaxRecvMsgSize: 100 * MB,
- MaxSendMsgSize: 100 * MB, // 100MB
- InitialWindowSize: (int32)(1 * MB), // 1MB - controls initial frame size for streams
- InitialConnWindowSize: (int32)(1 * MB), // 1MB - controls initial frame size for connection
+ MaxSendMsgSize: 100 * MB, // 100MB
+ InitialWindowSize: (int32)(32 * MB), // 32MB - controls initial frame size for streams
+ InitialConnWindowSize: (int32)(128 * MB), // 128MB - controls initial frame size for connection
ConnWaitTime: defaultConnWaitTime,
KeepAliveTime: 30 * time.Minute,
diff --git a/pkg/net/grpc/client/client_test.go b/pkg/net/grpc/client/client_test.go
index 12b196fa..0b4a10e1 100644
--- a/pkg/net/grpc/client/client_test.go
+++ b/pkg/net/grpc/client/client_test.go
@@ -86,8 +86,8 @@ func TestDefaultClientOptions(t *testing.T) {
assert.NotNil(t, opts, "ClientOptions should be initialized")
assert.Equal(t, 100*MB, opts.MaxRecvMsgSize, "MaxRecvMsgSize should be 100 MB")
assert.Equal(t, 100*MB, opts.MaxSendMsgSize, "MaxSendMsgSize should be 100 MB")
- assert.Equal(t, int32(1*MB), opts.InitialWindowSize, "InitialWindowSize should be 1 MB")
- assert.Equal(t, int32(1*MB), opts.InitialConnWindowSize, "InitialConnWindowSize should be 1 MB")
+ assert.Equal(t, int32(32*MB), opts.InitialWindowSize, "InitialWindowSize should be 32 MB")
+ assert.Equal(t, int32(128*MB), opts.InitialConnWindowSize, "InitialConnWindowSize should be 128 MB")
assert.Equal(t, defaultConnWaitTime, opts.ConnWaitTime, "ConnWaitTime should be 10 seconds")
assert.True(t, opts.EnableRetries, "EnableRetries should be true")
assert.Equal(t, maxRetries, opts.MaxRetries, "MaxRetries should be 5")
diff --git a/pkg/net/grpc/server/server.go b/pkg/net/grpc/server/server.go
index 10a2452c..64dfe0f2 100644
--- a/pkg/net/grpc/server/server.go
+++ b/pkg/net/grpc/server/server.go
@@ -94,7 +94,7 @@ func DefaultServerOptions() *ServerOptions {
return &ServerOptions{
MaxRecvMsgSize: 100 * MB,
MaxSendMsgSize: 100 * MB,
- InitialWindowSize: (int32)(1 * MB),
+ InitialWindowSize: (int32)(32 * MB),
InitialConnWindowSize: (int32)(1 * MB),
MaxConcurrentStreams: 1000,
GracefulShutdownTime: defaultGracefulShutdownTimeout,
@@ -102,13 +102,13 @@ func DefaultServerOptions() *ServerOptions {
MaxConnectionIdle: 2 * time.Hour,
MaxConnectionAge: 2 * time.Hour,
MaxConnectionAgeGrace: 1 * time.Hour,
- Time: 1 * time.Hour,
+ Time: 30 * time.Minute,
Timeout: 30 * time.Minute,
MinTime: 5 * time.Minute,
PermitWithoutStream: true,
- WriteBufferSize: 32 * KB,
- ReadBufferSize: 32 * KB,
+ WriteBufferSize: 512 * KB,
+ ReadBufferSize: 512 * KB,
}
}
diff --git a/pkg/net/grpc/server/server_test.go b/pkg/net/grpc/server/server_test.go
index 4c6067e0..f2308436 100644
--- a/pkg/net/grpc/server/server_test.go
+++ b/pkg/net/grpc/server/server_test.go
@@ -55,18 +55,18 @@ func TestDefaultServerOptions(t *testing.T) {
assert.NotNil(t, opts, "Server options should be initialized")
assert.Equal(t, 100*MB, opts.MaxRecvMsgSize, "MaxRecvMsgSize should be 100 MB")
assert.Equal(t, 100*MB, opts.MaxSendMsgSize, "MaxSendMsgSize should be 100 MB")
- assert.Equal(t, int32(1*MB), opts.InitialWindowSize, "InitialWindowSize should be 1 MB")
+ assert.Equal(t, int32(32*MB), opts.InitialWindowSize, "InitialWindowSize should be 32 MB")
assert.Equal(t, int32(1*MB), opts.InitialConnWindowSize, "InitialConnWindowSize should be 1 MB")
assert.Equal(t, uint32(1000), opts.MaxConcurrentStreams, "MaxConcurrentStreams should be 1000")
assert.Equal(t, defaultGracefulShutdownTimeout, opts.GracefulShutdownTime,
fmt.Sprintf("GracefulShutdownTimeout should be %v", defaultGracefulShutdownTimeout))
assert.Equal(t, uint32(0), opts.NumServerWorkers, "NumServerWorkers should be 0")
- assert.Equal(t, 32*KB, opts.WriteBufferSize, "WriteBufferSize should be 32 KB")
- assert.Equal(t, 32*KB, opts.ReadBufferSize, "ReadBufferSize should be 32 KB")
+ assert.Equal(t, 512*KB, opts.WriteBufferSize, "WriteBufferSize should be 512 KB")
+ assert.Equal(t, 512*KB, opts.ReadBufferSize, "ReadBufferSize should be 512 KB")
assert.Equal(t, 2*time.Hour, opts.MaxConnectionIdle, "MaxConnectionIdle should be 2 hours")
assert.Equal(t, 2*time.Hour, opts.MaxConnectionAge, "MaxConnectionAge should be 2 hours")
assert.Equal(t, 1*time.Hour, opts.MaxConnectionAgeGrace, "MaxConnectionAgeGrace should be 1 hour")
- assert.Equal(t, 1*time.Hour, opts.Time, "Time should be 1 hour")
+ assert.Equal(t, 30*time.Minute, opts.Time, "Time should be 30 minutes")
assert.Equal(t, 30*time.Minute, opts.Timeout, "Timeout should be 30 minutes")
assert.Equal(t, 5*time.Minute, opts.MinTime, "MinTime should be 5 minutes")
assert.True(t, opts.PermitWithoutStream, "PermitWithoutStream should be true")
diff --git a/supernode/node/action/server/cascade/cascade_action_server_test.go b/supernode/node/action/server/cascade/cascade_action_server_test.go
index eca121d8..ff2738b3 100644
--- a/supernode/node/action/server/cascade/cascade_action_server_test.go
+++ b/supernode/node/action/server/cascade/cascade_action_server_test.go
@@ -10,7 +10,7 @@ import (
cascademocks "github.com/LumeraProtocol/supernode/v2/supernode/services/cascade/mocks"
"github.com/stretchr/testify/assert"
- "go.uber.org/mock/gomock"
+ "github.com/golang/mock/gomock"
)
func TestRegister_Success(t *testing.T) {
diff --git a/supernode/services/cascade/adaptors/mocks/lumera_mock.go b/supernode/services/cascade/adaptors/mocks/lumera_mock.go
index 15a6c901..29cdd48f 100644
--- a/supernode/services/cascade/adaptors/mocks/lumera_mock.go
+++ b/supernode/services/cascade/adaptors/mocks/lumera_mock.go
@@ -1,10 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: lumera.go
-//
-// Generated by this command:
-//
-// mockgen -destination=mocks/lumera_mock.go -package=cascadeadaptormocks -source=lumera.go
-//
// Package cascadeadaptormocks is a generated GoMock package.
package cascadeadaptormocks
@@ -16,14 +11,13 @@ import (
types "github.com/LumeraProtocol/lumera/x/action/v1/types"
types0 "github.com/LumeraProtocol/lumera/x/supernode/v1/types"
tx "github.com/cosmos/cosmos-sdk/types/tx"
- gomock "go.uber.org/mock/gomock"
+ gomock "github.com/golang/mock/gomock"
)
// MockLumeraClient is a mock of LumeraClient interface.
type MockLumeraClient struct {
ctrl *gomock.Controller
recorder *MockLumeraClientMockRecorder
- isgomock struct{}
}
// MockLumeraClientMockRecorder is the mock recorder for MockLumeraClient.
@@ -53,26 +47,11 @@ func (m *MockLumeraClient) FinalizeAction(ctx context.Context, actionID string,
}
// FinalizeAction indicates an expected call of FinalizeAction.
-func (mr *MockLumeraClientMockRecorder) FinalizeAction(ctx, actionID, rqids any) *gomock.Call {
+func (mr *MockLumeraClientMockRecorder) FinalizeAction(ctx, actionID, rqids interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinalizeAction", reflect.TypeOf((*MockLumeraClient)(nil).FinalizeAction), ctx, actionID, rqids)
}
-// SimulateFinalizeAction mocks base method.
-func (m *MockLumeraClient) SimulateFinalizeAction(ctx context.Context, actionID string, rqids []string) (*tx.SimulateResponse, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "SimulateFinalizeAction", ctx, actionID, rqids)
- ret0, _ := ret[0].(*tx.SimulateResponse)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// SimulateFinalizeAction indicates an expected call of SimulateFinalizeAction.
-func (mr *MockLumeraClientMockRecorder) SimulateFinalizeAction(ctx, actionID, rqids any) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateFinalizeAction", reflect.TypeOf((*MockLumeraClient)(nil).SimulateFinalizeAction), ctx, actionID, rqids)
-}
-
// GetAction mocks base method.
func (m *MockLumeraClient) GetAction(ctx context.Context, actionID string) (*types.QueryGetActionResponse, error) {
m.ctrl.T.Helper()
@@ -83,7 +62,7 @@ func (m *MockLumeraClient) GetAction(ctx context.Context, actionID string) (*typ
}
// GetAction indicates an expected call of GetAction.
-func (mr *MockLumeraClientMockRecorder) GetAction(ctx, actionID any) *gomock.Call {
+func (mr *MockLumeraClientMockRecorder) GetAction(ctx, actionID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAction", reflect.TypeOf((*MockLumeraClient)(nil).GetAction), ctx, actionID)
}
@@ -98,7 +77,7 @@ func (m *MockLumeraClient) GetActionFee(ctx context.Context, dataSize string) (*
}
// GetActionFee indicates an expected call of GetActionFee.
-func (mr *MockLumeraClientMockRecorder) GetActionFee(ctx, dataSize any) *gomock.Call {
+func (mr *MockLumeraClientMockRecorder) GetActionFee(ctx, dataSize interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActionFee", reflect.TypeOf((*MockLumeraClient)(nil).GetActionFee), ctx, dataSize)
}
@@ -113,11 +92,26 @@ func (m *MockLumeraClient) GetTopSupernodes(ctx context.Context, height uint64)
}
// GetTopSupernodes indicates an expected call of GetTopSupernodes.
-func (mr *MockLumeraClientMockRecorder) GetTopSupernodes(ctx, height any) *gomock.Call {
+func (mr *MockLumeraClientMockRecorder) GetTopSupernodes(ctx, height interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTopSupernodes", reflect.TypeOf((*MockLumeraClient)(nil).GetTopSupernodes), ctx, height)
}
+// SimulateFinalizeAction mocks base method.
+func (m *MockLumeraClient) SimulateFinalizeAction(ctx context.Context, actionID string, rqids []string) (*tx.SimulateResponse, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SimulateFinalizeAction", ctx, actionID, rqids)
+ ret0, _ := ret[0].(*tx.SimulateResponse)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// SimulateFinalizeAction indicates an expected call of SimulateFinalizeAction.
+func (mr *MockLumeraClientMockRecorder) SimulateFinalizeAction(ctx, actionID, rqids interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateFinalizeAction", reflect.TypeOf((*MockLumeraClient)(nil).SimulateFinalizeAction), ctx, actionID, rqids)
+}
+
// Verify mocks base method.
func (m *MockLumeraClient) Verify(ctx context.Context, creator string, file, sigBytes []byte) error {
m.ctrl.T.Helper()
@@ -127,7 +121,7 @@ func (m *MockLumeraClient) Verify(ctx context.Context, creator string, file, sig
}
// Verify indicates an expected call of Verify.
-func (mr *MockLumeraClientMockRecorder) Verify(ctx, creator, file, sigBytes any) *gomock.Call {
+func (mr *MockLumeraClientMockRecorder) Verify(ctx, creator, file, sigBytes interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockLumeraClient)(nil).Verify), ctx, creator, file, sigBytes)
}
diff --git a/supernode/services/cascade/adaptors/mocks/p2p_mock.go b/supernode/services/cascade/adaptors/mocks/p2p_mock.go
index 4f62a440..ec99d92a 100644
--- a/supernode/services/cascade/adaptors/mocks/p2p_mock.go
+++ b/supernode/services/cascade/adaptors/mocks/p2p_mock.go
@@ -1,10 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: p2p.go
-//
-// Generated by this command:
-//
-// mockgen -destination=mocks/p2p_mock.go -package=cascadeadaptormocks -source=p2p.go
-//
// Package cascadeadaptormocks is a generated GoMock package.
package cascadeadaptormocks
@@ -15,14 +10,13 @@ import (
logtrace "github.com/LumeraProtocol/supernode/v2/pkg/logtrace"
adaptors "github.com/LumeraProtocol/supernode/v2/supernode/services/cascade/adaptors"
- gomock "go.uber.org/mock/gomock"
+ gomock "github.com/golang/mock/gomock"
)
// MockP2PService is a mock of P2PService interface.
type MockP2PService struct {
ctrl *gomock.Controller
recorder *MockP2PServiceMockRecorder
- isgomock struct{}
}
// MockP2PServiceMockRecorder is the mock recorder for MockP2PService.
@@ -51,7 +45,7 @@ func (m *MockP2PService) StoreArtefacts(ctx context.Context, req adaptors.StoreA
}
// StoreArtefacts indicates an expected call of StoreArtefacts.
-func (mr *MockP2PServiceMockRecorder) StoreArtefacts(ctx, req, f any) *gomock.Call {
+func (mr *MockP2PServiceMockRecorder) StoreArtefacts(ctx, req, f interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreArtefacts", reflect.TypeOf((*MockP2PService)(nil).StoreArtefacts), ctx, req, f)
}
diff --git a/supernode/services/cascade/adaptors/mocks/rq_mock.go b/supernode/services/cascade/adaptors/mocks/rq_mock.go
index 4c53c1dd..f45f2eb5 100644
--- a/supernode/services/cascade/adaptors/mocks/rq_mock.go
+++ b/supernode/services/cascade/adaptors/mocks/rq_mock.go
@@ -1,10 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: rq.go
-//
-// Generated by this command:
-//
-// mockgen -destination=mocks/rq_mock.go -package=cascadeadaptormocks -source=rq.go
-//
// Package cascadeadaptormocks is a generated GoMock package.
package cascadeadaptormocks
@@ -13,15 +8,15 @@ import (
context "context"
reflect "reflect"
+ codec "github.com/LumeraProtocol/supernode/v2/pkg/codec"
adaptors "github.com/LumeraProtocol/supernode/v2/supernode/services/cascade/adaptors"
- gomock "go.uber.org/mock/gomock"
+ gomock "github.com/golang/mock/gomock"
)
// MockCodecService is a mock of CodecService interface.
type MockCodecService struct {
ctrl *gomock.Controller
recorder *MockCodecServiceMockRecorder
- isgomock struct{}
}
// MockCodecServiceMockRecorder is the mock recorder for MockCodecService.
@@ -51,7 +46,7 @@ func (m *MockCodecService) Decode(ctx context.Context, req adaptors.DecodeReques
}
// Decode indicates an expected call of Decode.
-func (mr *MockCodecServiceMockRecorder) Decode(ctx, req any) *gomock.Call {
+func (mr *MockCodecServiceMockRecorder) Decode(ctx, req interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decode", reflect.TypeOf((*MockCodecService)(nil).Decode), ctx, req)
}
@@ -66,7 +61,25 @@ func (m *MockCodecService) EncodeInput(ctx context.Context, taskID, path string,
}
// EncodeInput indicates an expected call of EncodeInput.
-func (mr *MockCodecServiceMockRecorder) EncodeInput(ctx, taskID, path, dataSize any) *gomock.Call {
+func (mr *MockCodecServiceMockRecorder) EncodeInput(ctx, taskID, path, dataSize interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncodeInput", reflect.TypeOf((*MockCodecService)(nil).EncodeInput), ctx, taskID, path, dataSize)
}
+
+// PrepareDecode mocks base method.
+func (m *MockCodecService) PrepareDecode(ctx context.Context, actionID string, layout codec.Layout) ([]string, func(int, string, []byte) (string, error), func() error, *codec.Workspace, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PrepareDecode", ctx, actionID, layout)
+ ret0, _ := ret[0].([]string)
+ ret1, _ := ret[1].(func(int, string, []byte) (string, error))
+ ret2, _ := ret[2].(func() error)
+ ret3, _ := ret[3].(*codec.Workspace)
+ ret4, _ := ret[4].(error)
+ return ret0, ret1, ret2, ret3, ret4
+}
+
+// PrepareDecode indicates an expected call of PrepareDecode.
+func (mr *MockCodecServiceMockRecorder) PrepareDecode(ctx, actionID, layout interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareDecode", reflect.TypeOf((*MockCodecService)(nil).PrepareDecode), ctx, actionID, layout)
+}
diff --git a/supernode/services/cascade/adaptors/rq.go b/supernode/services/cascade/adaptors/rq.go
index 5f4443cf..92e89819 100644
--- a/supernode/services/cascade/adaptors/rq.go
+++ b/supernode/services/cascade/adaptors/rq.go
@@ -11,6 +11,7 @@ import (
//go:generate mockgen -destination=mocks/rq_mock.go -package=cascadeadaptormocks -source=rq.go
type CodecService interface {
EncodeInput(ctx context.Context, taskID string, path string, dataSize int) (EncodeResult, error)
+ PrepareDecode(ctx context.Context, actionID string, layout codec.Layout) (blockPaths []string, Write func(block int, symbolID string, data []byte) (string, error), Cleanup func() error, ws *codec.Workspace, err error)
Decode(ctx context.Context, req DecodeRequest) (DecodeResponse, error)
}
@@ -70,7 +71,11 @@ func (c *codecImpl) Decode(ctx context.Context, req DecodeRequest) (DecodeRespon
}
return DecodeResponse{
- FilePath: resp.Path,
+ FilePath: resp.FilePath,
DecodeTmpDir: resp.DecodeTmpDir,
}, nil
}
+
+func (c *codecImpl) PrepareDecode(ctx context.Context, actionID string, layout codec.Layout) (blockPaths []string, Write func(block int, symbolID string, data []byte) (string, error), Cleanup func() error, ws *codec.Workspace, err error) {
+ return
+}
diff --git a/supernode/services/cascade/mocks/cascade_interfaces_mock.go b/supernode/services/cascade/mocks/cascade_interfaces_mock.go
index 497497c3..44d3189c 100644
--- a/supernode/services/cascade/mocks/cascade_interfaces_mock.go
+++ b/supernode/services/cascade/mocks/cascade_interfaces_mock.go
@@ -1,10 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: interfaces.go
-//
-// Generated by this command:
-//
-// mockgen -destination=mocks/cascade_interfaces_mock.go -package=cascademocks -source=interfaces.go
-//
// Package cascademocks is a generated GoMock package.
package cascademocks
@@ -14,14 +9,13 @@ import (
reflect "reflect"
cascade "github.com/LumeraProtocol/supernode/v2/supernode/services/cascade"
- gomock "go.uber.org/mock/gomock"
+ gomock "github.com/golang/mock/gomock"
)
// MockCascadeServiceFactory is a mock of CascadeServiceFactory interface.
type MockCascadeServiceFactory struct {
ctrl *gomock.Controller
recorder *MockCascadeServiceFactoryMockRecorder
- isgomock struct{}
}
// MockCascadeServiceFactoryMockRecorder is the mock recorder for MockCascadeServiceFactory.
@@ -59,7 +53,6 @@ func (mr *MockCascadeServiceFactoryMockRecorder) NewCascadeRegistrationTask() *g
type MockCascadeTask struct {
ctrl *gomock.Controller
recorder *MockCascadeTaskMockRecorder
- isgomock struct{}
}
// MockCascadeTaskMockRecorder is the mock recorder for MockCascadeTask.
@@ -88,7 +81,7 @@ func (m *MockCascadeTask) CleanupDownload(ctx context.Context, actionID string)
}
// CleanupDownload indicates an expected call of CleanupDownload.
-func (mr *MockCascadeTaskMockRecorder) CleanupDownload(ctx, actionID any) *gomock.Call {
+func (mr *MockCascadeTaskMockRecorder) CleanupDownload(ctx, actionID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CleanupDownload", reflect.TypeOf((*MockCascadeTask)(nil).CleanupDownload), ctx, actionID)
}
@@ -102,7 +95,7 @@ func (m *MockCascadeTask) Download(ctx context.Context, req *cascade.DownloadReq
}
// Download indicates an expected call of Download.
-func (mr *MockCascadeTaskMockRecorder) Download(ctx, req, send any) *gomock.Call {
+func (mr *MockCascadeTaskMockRecorder) Download(ctx, req, send interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Download", reflect.TypeOf((*MockCascadeTask)(nil).Download), ctx, req, send)
}
@@ -116,7 +109,7 @@ func (m *MockCascadeTask) Register(ctx context.Context, req *cascade.RegisterReq
}
// Register indicates an expected call of Register.
-func (mr *MockCascadeTaskMockRecorder) Register(ctx, req, send any) *gomock.Call {
+func (mr *MockCascadeTaskMockRecorder) Register(ctx, req, send interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Register", reflect.TypeOf((*MockCascadeTask)(nil).Register), ctx, req, send)
}
diff --git a/supernode/services/cascade/register_test.go b/supernode/services/cascade/register_test.go
index c73b96b7..6f56791a 100644
--- a/supernode/services/cascade/register_test.go
+++ b/supernode/services/cascade/register_test.go
@@ -21,8 +21,8 @@ import (
"github.com/cosmos/gogoproto/proto"
"lukechampine.com/blake3"
+ "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
- "go.uber.org/mock/gomock"
)
func TestCascadeRegistrationTask_Register(t *testing.T) {
@@ -104,10 +104,10 @@ func TestCascadeRegistrationTask_Register(t *testing.T) {
Metadata: codecpkg.Layout{Blocks: []codecpkg.Block{{BlockID: 1, Hash: "abc"}}},
}, nil)
- // 8. Store artefacts (no metrics returned; recorded centrally)
- p2p.EXPECT().
- StoreArtefacts(gomock.Any(), gomock.Any(), gomock.Any()).
- Return(nil)
+ // 8. Store artefacts (no metrics returned; recorded centrally)
+ p2p.EXPECT().
+ StoreArtefacts(gomock.Any(), gomock.Any(), gomock.Any()).
+ Return(nil)
},
expectedError: "",
expectedEvents: 12,
diff --git a/supernode/services/cascade/service_test.go b/supernode/services/cascade/service_test.go
index eaa7bf7f..bc2998ad 100644
--- a/supernode/services/cascade/service_test.go
+++ b/supernode/services/cascade/service_test.go
@@ -8,8 +8,8 @@ import (
"github.com/LumeraProtocol/supernode/v2/supernode/services/cascade"
cascadeadaptormocks "github.com/LumeraProtocol/supernode/v2/supernode/services/cascade/adaptors/mocks"
"github.com/LumeraProtocol/supernode/v2/supernode/services/common"
+ "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
- "go.uber.org/mock/gomock"
)
func TestNewCascadeService(t *testing.T) {
diff --git a/tests/system/go.mod b/tests/system/go.mod
index 15b8212d..e6eb3bba 100644
--- a/tests/system/go.mod
+++ b/tests/system/go.mod
@@ -95,6 +95,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.2.4 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/mock v1.6.0 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/flatbuffers v1.12.1 // indirect
diff --git a/tests/system/go.sum b/tests/system/go.sum
index 9ff0158a..6e9c0112 100644
--- a/tests/system/go.sum
+++ b/tests/system/go.sum
@@ -803,6 +803,7 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U=
@@ -888,6 +889,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
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.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -933,6 +935,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1025,6 +1028,7 @@ golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=