diff --git a/Dockerfile b/Dockerfile index abef6553..1fbcc621 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.23.6-bullseye as builder +FROM golang:1.23.6-bullseye AS builder WORKDIR /app COPY go.* ./ RUN go mod download diff --git a/api/api.go b/api/api.go index bdcc33d7..37e9ac7f 100644 --- a/api/api.go +++ b/api/api.go @@ -202,7 +202,7 @@ func (s Server) toEchoHandler(handlerFunc any) echo.HandlerFunc { var j int // Get path parameters - for i := 0; i < handlerFuncType.NumIn(); i++ { + for i := range handlerFuncType.NumIn() { paramType := handlerFuncType.In(i) if paramType.String() == "context.Context" { inputParams = append(inputParams, reflect.ValueOf(c.Request().Context())) @@ -347,6 +347,7 @@ func (s Server) setupRoutes(e *echo.Echo) { e.POST("/api/preparation/:id/piece", s.toEchoHandler(s.dataprepHandler.AddPieceHandler)) // Wallet + e.POST("/api/wallet/create", s.toEchoHandler(s.walletHandler.CreateHandler)) e.POST("/api/wallet", s.toEchoHandler(s.walletHandler.ImportHandler)) e.GET("/api/wallet", s.toEchoHandler(s.walletHandler.ListHandler)) e.DELETE("/api/wallet/:address", s.toEchoHandler(s.walletHandler.RemoveHandler)) diff --git a/api/api_test.go b/api/api_test.go index ac63411b..da4f2ab1 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -184,6 +184,8 @@ func setupMockWallet() wallet.Handler { m := new(wallet.MockWallet) m.On("AttachHandler", mock.Anything, mock.Anything, "id", "wallet"). Return(&model.Preparation{}, nil) + m.On("CreateHandler", mock.Anything, mock.Anything, mock.Anything). + Return(&model.Wallet{}, nil) m.On("DetachHandler", mock.Anything, mock.Anything, "id", "wallet"). Return(&model.Preparation{}, nil) m.On("ImportHandler", mock.Anything, mock.Anything, mock.Anything, mock.Anything). @@ -301,6 +303,15 @@ func TestAllAPIs(t *testing.T) { }) t.Run("wallet", func(t *testing.T) { + t.Run("CreateWallet", func(t *testing.T) { + resp, err := client.Wallet.CreateWallet(&wallet2.CreateWalletParams{ + Request: &models.WalletCreateRequest{}, + Context: ctx, + }) + require.NoError(t, err) + require.True(t, resp.IsSuccess()) + require.NotNil(t, resp.Payload) + }) t.Run("ImportWallet", func(t *testing.T) { resp, err := client.Wallet.ImportWallet(&wallet2.ImportWalletParams{ Request: &models.WalletImportRequest{}, diff --git a/client/swagger/http/wallet/create_wallet_parameters.go b/client/swagger/http/wallet/create_wallet_parameters.go new file mode 100644 index 00000000..bb53489c --- /dev/null +++ b/client/swagger/http/wallet/create_wallet_parameters.go @@ -0,0 +1,153 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package wallet + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/data-preservation-programs/singularity/client/swagger/models" +) + +// NewCreateWalletParams creates a new CreateWalletParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewCreateWalletParams() *CreateWalletParams { + return &CreateWalletParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewCreateWalletParamsWithTimeout creates a new CreateWalletParams object +// with the ability to set a timeout on a request. +func NewCreateWalletParamsWithTimeout(timeout time.Duration) *CreateWalletParams { + return &CreateWalletParams{ + timeout: timeout, + } +} + +// NewCreateWalletParamsWithContext creates a new CreateWalletParams object +// with the ability to set a context for a request. +func NewCreateWalletParamsWithContext(ctx context.Context) *CreateWalletParams { + return &CreateWalletParams{ + Context: ctx, + } +} + +// NewCreateWalletParamsWithHTTPClient creates a new CreateWalletParams object +// with the ability to set a custom HTTPClient for a request. +func NewCreateWalletParamsWithHTTPClient(client *http.Client) *CreateWalletParams { + return &CreateWalletParams{ + HTTPClient: client, + } +} + +/* +CreateWalletParams contains all the parameters to send to the API endpoint + + for the create wallet operation. + + Typically these are written to a http.Request. +*/ +type CreateWalletParams struct { + + /* Request. + + Request body + */ + Request *models.WalletCreateRequest + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the create wallet params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *CreateWalletParams) WithDefaults() *CreateWalletParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the create wallet params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *CreateWalletParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the create wallet params +func (o *CreateWalletParams) WithTimeout(timeout time.Duration) *CreateWalletParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the create wallet params +func (o *CreateWalletParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the create wallet params +func (o *CreateWalletParams) WithContext(ctx context.Context) *CreateWalletParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the create wallet params +func (o *CreateWalletParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the create wallet params +func (o *CreateWalletParams) WithHTTPClient(client *http.Client) *CreateWalletParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the create wallet params +func (o *CreateWalletParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithRequest adds the request to the create wallet params +func (o *CreateWalletParams) WithRequest(request *models.WalletCreateRequest) *CreateWalletParams { + o.SetRequest(request) + return o +} + +// SetRequest adds the request to the create wallet params +func (o *CreateWalletParams) SetRequest(request *models.WalletCreateRequest) { + o.Request = request +} + +// WriteToRequest writes these params to a swagger request +func (o *CreateWalletParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Request != nil { + if err := r.SetBodyParam(o.Request); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/client/swagger/http/wallet/create_wallet_responses.go b/client/swagger/http/wallet/create_wallet_responses.go new file mode 100644 index 00000000..a424a6f1 --- /dev/null +++ b/client/swagger/http/wallet/create_wallet_responses.go @@ -0,0 +1,256 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package wallet + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/data-preservation-programs/singularity/client/swagger/models" +) + +// CreateWalletReader is a Reader for the CreateWallet structure. +type CreateWalletReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *CreateWalletReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewCreateWalletOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewCreateWalletBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: + result := NewCreateWalletInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + return nil, runtime.NewAPIError("[POST /wallet/create] CreateWallet", response, response.Code()) + } +} + +// NewCreateWalletOK creates a CreateWalletOK with default headers values +func NewCreateWalletOK() *CreateWalletOK { + return &CreateWalletOK{} +} + +/* +CreateWalletOK describes a response with status code 200, with default header values. + +OK +*/ +type CreateWalletOK struct { + Payload []*models.ModelWallet +} + +// IsSuccess returns true when this create wallet o k response has a 2xx status code +func (o *CreateWalletOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this create wallet o k response has a 3xx status code +func (o *CreateWalletOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this create wallet o k response has a 4xx status code +func (o *CreateWalletOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this create wallet o k response has a 5xx status code +func (o *CreateWalletOK) IsServerError() bool { + return false +} + +// IsCode returns true when this create wallet o k response a status code equal to that given +func (o *CreateWalletOK) IsCode(code int) bool { + return code == 200 +} + +// Code gets the status code for the create wallet o k response +func (o *CreateWalletOK) Code() int { + return 200 +} + +func (o *CreateWalletOK) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[POST /wallet/create][%d] createWalletOK %s", 200, payload) +} + +func (o *CreateWalletOK) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[POST /wallet/create][%d] createWalletOK %s", 200, payload) +} + +func (o *CreateWalletOK) GetPayload() []*models.ModelWallet { + return o.Payload +} + +func (o *CreateWalletOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + // response payload + if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewCreateWalletBadRequest creates a CreateWalletBadRequest with default headers values +func NewCreateWalletBadRequest() *CreateWalletBadRequest { + return &CreateWalletBadRequest{} +} + +/* +CreateWalletBadRequest describes a response with status code 400, with default header values. + +Bad Request +*/ +type CreateWalletBadRequest struct { + Payload *models.APIHTTPError +} + +// IsSuccess returns true when this create wallet bad request response has a 2xx status code +func (o *CreateWalletBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this create wallet bad request response has a 3xx status code +func (o *CreateWalletBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this create wallet bad request response has a 4xx status code +func (o *CreateWalletBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this create wallet bad request response has a 5xx status code +func (o *CreateWalletBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this create wallet bad request response a status code equal to that given +func (o *CreateWalletBadRequest) IsCode(code int) bool { + return code == 400 +} + +// Code gets the status code for the create wallet bad request response +func (o *CreateWalletBadRequest) Code() int { + return 400 +} + +func (o *CreateWalletBadRequest) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[POST /wallet/create][%d] createWalletBadRequest %s", 400, payload) +} + +func (o *CreateWalletBadRequest) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[POST /wallet/create][%d] createWalletBadRequest %s", 400, payload) +} + +func (o *CreateWalletBadRequest) GetPayload() *models.APIHTTPError { + return o.Payload +} + +func (o *CreateWalletBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.APIHTTPError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewCreateWalletInternalServerError creates a CreateWalletInternalServerError with default headers values +func NewCreateWalletInternalServerError() *CreateWalletInternalServerError { + return &CreateWalletInternalServerError{} +} + +/* +CreateWalletInternalServerError describes a response with status code 500, with default header values. + +Internal Server Error +*/ +type CreateWalletInternalServerError struct { + Payload *models.APIHTTPError +} + +// IsSuccess returns true when this create wallet internal server error response has a 2xx status code +func (o *CreateWalletInternalServerError) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this create wallet internal server error response has a 3xx status code +func (o *CreateWalletInternalServerError) IsRedirect() bool { + return false +} + +// IsClientError returns true when this create wallet internal server error response has a 4xx status code +func (o *CreateWalletInternalServerError) IsClientError() bool { + return false +} + +// IsServerError returns true when this create wallet internal server error response has a 5xx status code +func (o *CreateWalletInternalServerError) IsServerError() bool { + return true +} + +// IsCode returns true when this create wallet internal server error response a status code equal to that given +func (o *CreateWalletInternalServerError) IsCode(code int) bool { + return code == 500 +} + +// Code gets the status code for the create wallet internal server error response +func (o *CreateWalletInternalServerError) Code() int { + return 500 +} + +func (o *CreateWalletInternalServerError) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[POST /wallet/create][%d] createWalletInternalServerError %s", 500, payload) +} + +func (o *CreateWalletInternalServerError) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[POST /wallet/create][%d] createWalletInternalServerError %s", 500, payload) +} + +func (o *CreateWalletInternalServerError) GetPayload() *models.APIHTTPError { + return o.Payload +} + +func (o *CreateWalletInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.APIHTTPError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} diff --git a/client/swagger/http/wallet/wallet_client.go b/client/swagger/http/wallet/wallet_client.go index 598b3d31..e3373fe6 100644 --- a/client/swagger/http/wallet/wallet_client.go +++ b/client/swagger/http/wallet/wallet_client.go @@ -56,6 +56,8 @@ type ClientOption func(*runtime.ClientOperation) // ClientService is the interface for Client methods type ClientService interface { + CreateWallet(params *CreateWalletParams, opts ...ClientOption) (*CreateWalletOK, error) + ImportWallet(params *ImportWalletParams, opts ...ClientOption) (*ImportWalletOK, error) ListWallets(params *ListWalletsParams, opts ...ClientOption) (*ListWalletsOK, error) @@ -65,6 +67,44 @@ type ClientService interface { SetTransport(transport runtime.ClientTransport) } +/* +CreateWallet creates new wallet +*/ +func (a *Client) CreateWallet(params *CreateWalletParams, opts ...ClientOption) (*CreateWalletOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewCreateWalletParams() + } + op := &runtime.ClientOperation{ + ID: "CreateWallet", + Method: "POST", + PathPattern: "/wallet/create", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &CreateWalletReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*CreateWalletOK) + if ok { + return success, nil + } + // unexpected success response + // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + msg := fmt.Sprintf("unexpected success response for CreateWallet: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + /* ImportWallet imports a private key */ diff --git a/client/swagger/models/model_wallet.go b/client/swagger/models/model_wallet.go index dc2ff9fe..1b18a08a 100644 --- a/client/swagger/models/model_wallet.go +++ b/client/swagger/models/model_wallet.go @@ -8,6 +8,7 @@ package models import ( "context" + "github.com/go-openapi/errors" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) @@ -17,23 +18,77 @@ import ( // swagger:model model.Wallet type ModelWallet struct { + // ActorID is the short ID of the wallet + ActorID string `json:"actorId,omitempty"` + + // ActorName is readable label for the wallet + ActorName string `json:"actorName,omitempty"` + // Address is the Filecoin full address of the wallet Address string `json:"address,omitempty"` - // ID is the short ID of the wallet - ID string `json:"id,omitempty"` + // Balance is in Fil cached from chain + Balance float64 `json:"balance,omitempty"` + + // BalancePlus is in Fil+ cached from chain + BalancePlus float64 `json:"balancePlus,omitempty"` + + // ContactInfo is optional email for SP wallets + ContactInfo string `json:"contactInfo,omitempty"` + + // id + ID int64 `json:"id,omitempty"` + + // Location is optional region, country for SP wallets + Location string `json:"location,omitempty"` // PrivateKey is the private key of the wallet PrivateKey string `json:"privateKey,omitempty"` + + // Type determines user or SP wallets + Type struct { + ModelWalletType + } `json:"type,omitempty"` } // Validate validates this model wallet func (m *ModelWallet) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateType(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ModelWallet) validateType(formats strfmt.Registry) error { + if swag.IsZero(m.Type) { // not required + return nil + } + return nil } -// ContextValidate validates this model wallet based on context it is used +// ContextValidate validate this model wallet based on the context it is used func (m *ModelWallet) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateType(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ModelWallet) contextValidateType(ctx context.Context, formats strfmt.Registry) error { + return nil } diff --git a/client/swagger/models/model_wallet_type.go b/client/swagger/models/model_wallet_type.go new file mode 100644 index 00000000..9e33fae9 --- /dev/null +++ b/client/swagger/models/model_wallet_type.go @@ -0,0 +1,78 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/validate" +) + +// ModelWalletType model wallet type +// +// swagger:model model.WalletType +type ModelWalletType string + +func NewModelWalletType(value ModelWalletType) *ModelWalletType { + return &value +} + +// Pointer returns a pointer to a freshly-allocated ModelWalletType. +func (m ModelWalletType) Pointer() *ModelWalletType { + return &m +} + +const ( + + // ModelWalletTypeUserWallet captures enum value "UserWallet" + ModelWalletTypeUserWallet ModelWalletType = "UserWallet" + + // ModelWalletTypeSPWallet captures enum value "SPWallet" + ModelWalletTypeSPWallet ModelWalletType = "SPWallet" +) + +// for schema +var modelWalletTypeEnum []interface{} + +func init() { + var res []ModelWalletType + if err := json.Unmarshal([]byte(`["UserWallet","SPWallet"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + modelWalletTypeEnum = append(modelWalletTypeEnum, v) + } +} + +func (m ModelWalletType) validateModelWalletTypeEnum(path, location string, value ModelWalletType) error { + if err := validate.EnumCase(path, location, value, modelWalletTypeEnum, true); err != nil { + return err + } + return nil +} + +// Validate validates this model wallet type +func (m ModelWalletType) Validate(formats strfmt.Registry) error { + var res []error + + // value enum + if err := m.validateModelWalletTypeEnum("", "body", m); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// ContextValidate validates this model wallet type based on context it is used +func (m ModelWalletType) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} diff --git a/client/swagger/models/wallet_create_request.go b/client/swagger/models/wallet_create_request.go new file mode 100644 index 00000000..a1411264 --- /dev/null +++ b/client/swagger/models/wallet_create_request.go @@ -0,0 +1,50 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// WalletCreateRequest wallet create request +// +// swagger:model wallet.CreateRequest +type WalletCreateRequest struct { + + // This is either "secp256k1" or "bls" + KeyType string `json:"keyType,omitempty"` +} + +// Validate validates this wallet create request +func (m *WalletCreateRequest) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this wallet create request based on context it is used +func (m *WalletCreateRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *WalletCreateRequest) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *WalletCreateRequest) UnmarshalBinary(b []byte) error { + var res WalletCreateRequest + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/cmd/admin/init.go b/cmd/admin/init.go index 59cf0eaf..ad3a0213 100644 --- a/cmd/admin/init.go +++ b/cmd/admin/init.go @@ -16,7 +16,7 @@ var InitCmd = &cli.Command{ Usage: "Name of the user or service that is running the Singularity for tracking and logging purpose", }, }, - Description: "This commands need to be run before running any singularity daemon or after any version upgrade", + Description: "This command needs to be run before running any singularity daemon or after any version upgrade", Action: func(c *cli.Context) error { db, closer, err := database.OpenFromCLI(c) if err != nil { diff --git a/cmd/admin/migrate.go b/cmd/admin/migrate.go new file mode 100644 index 00000000..6ecb69f6 --- /dev/null +++ b/cmd/admin/migrate.go @@ -0,0 +1,70 @@ +package admin + +import ( + "fmt" + "github.com/cockroachdb/errors" + "github.com/data-preservation-programs/singularity/cmd/cliutil" + "github.com/data-preservation-programs/singularity/database" + "github.com/data-preservation-programs/singularity/model" + "github.com/urfave/cli/v2" +) + +var MigrateCmd = &cli.Command{ + Name: "migrate", + Usage: "Migrate database up, down, or to a certain version", + Subcommands: []*cli.Command{ + { + Name: "up", + Usage: "Execute any unrun migrations", + Action: func(c *cli.Context) error { + db, closer, err := database.OpenFromCLI(c) + if err != nil { + return errors.WithStack(err) + } + defer closer.Close() + return model.GetMigrator(db).Migrate() + }, + }, + { + Name: "down", + Usage: "Rollback to previous migration", + Action: func(c *cli.Context) error { + db, closer, err := database.OpenFromCLI(c) + if err != nil { + return errors.WithStack(err) + } + defer closer.Close() + return model.GetMigrator(db).RollbackLast() + }, + }, + { + Name: "to", + Usage: "Migrate to specified version", + ArgsUsage: "", + Before: cliutil.CheckNArgs, + Action: func(c *cli.Context) error { + db, closer, err := database.OpenFromCLI(c) + if err != nil { + return errors.WithStack(err) + } + defer closer.Close() + + id := c.Args().Get(0) + + migrator := model.GetMigrator(db) + last, err := migrator.GetLastMigration() + if last == id { + fmt.Println("Already at requested migration") + return nil + } + + alreadyRan, err := migrator.HasRunMigration(id) + if alreadyRan { + return migrator.RollbackTo(id) + } else { + return migrator.MigrateTo(id) + } + }, + }, + }, +} diff --git a/cmd/app.go b/cmd/app.go index 2d21eab7..d59a6319 100644 --- a/cmd/app.go +++ b/cmd/app.go @@ -120,6 +120,7 @@ Upgrading: Subcommands: []*cli.Command{ admin.InitCmd, admin.ResetCmd, + admin.MigrateCmd, admin.MigrateDatasetCmd, admin.MigrateScheduleCmd, }, @@ -165,6 +166,7 @@ Upgrading: Category: "Operations", Usage: "Wallet management", Subcommands: []*cli.Command{ + wallet.CreateCmd, wallet.ImportCmd, wallet.ListCmd, wallet.RemoveCmd, diff --git a/cmd/dataprep_test.go b/cmd/dataprep_test.go index 3bea7156..9c7b6664 100644 --- a/cmd/dataprep_test.go +++ b/cmd/dataprep_test.go @@ -24,7 +24,7 @@ var testPreparation = model.Preparation{ MaxSize: 100, PieceSize: 200, Wallets: []model.Wallet{{ - ID: "client_id", + ActorID: "client_id", Address: "client_address", PrivateKey: "private_key", }}, diff --git a/cmd/deal_test.go b/cmd/deal_test.go index 4430543b..055ab051 100644 --- a/cmd/deal_test.go +++ b/cmd/deal_test.go @@ -24,7 +24,7 @@ func swapDealHandler(mockHandler deal.Handler) func() { func TestSendDealHandler(t *testing.T) { testutil.One(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { - err := db.Create(&model.Wallet{ID: "client_id"}).Error + err := db.Create(&model.Wallet{ActorID: "client_id"}).Error require.NoError(t, err) runner := NewRunner() defer runner.Save(t) diff --git a/cmd/run/downloadserver.go b/cmd/run/downloadserver.go index 9029fbd6..cf63c3c0 100644 --- a/cmd/run/downloadserver.go +++ b/cmd/run/downloadserver.go @@ -8,7 +8,7 @@ import ( "github.com/data-preservation-programs/singularity/service/downloadserver" "github.com/data-preservation-programs/singularity/storagesystem" "github.com/urfave/cli/v2" - "golang.org/x/exp/slices" + "slices" ) var DownloadServerCmd = &cli.Command{ diff --git a/cmd/storage/update.go b/cmd/storage/update.go index 9d5013d7..00ae71b2 100644 --- a/cmd/storage/update.go +++ b/cmd/storage/update.go @@ -14,8 +14,8 @@ import ( "github.com/gotidy/ptr" "github.com/rjNemo/underscore" "github.com/urfave/cli/v2" - "golang.org/x/exp/slices" "gorm.io/gorm" + "slices" ) var HTTPClientConfigFlagsForUpdate = []cli.Flag{ diff --git a/cmd/wallet/create.go b/cmd/wallet/create.go new file mode 100644 index 00000000..23dbd8a3 --- /dev/null +++ b/cmd/wallet/create.go @@ -0,0 +1,42 @@ +package wallet + +import ( + "github.com/cockroachdb/errors" + "github.com/data-preservation-programs/singularity/cmd/cliutil" + "github.com/data-preservation-programs/singularity/database" + "github.com/data-preservation-programs/singularity/handler/wallet" + "github.com/urfave/cli/v2" +) + +var CreateCmd = &cli.Command{ + Name: "create", + Usage: "Create a new wallet", + ArgsUsage: "[type]", + Before: cliutil.CheckNArgs, + Action: func(c *cli.Context) error { + db, closer, err := database.OpenFromCLI(c) + if err != nil { + return errors.WithStack(err) + } + defer closer.Close() + + // Default to secp256k1 if no type is provided + keyType := c.Args().Get(0) + if keyType == "" { + keyType = wallet.KTSecp256k1.String() + } + + w, err := wallet.Default.CreateHandler( + c.Context, + db, + wallet.CreateRequest{ + KeyType: keyType, + }) + if err != nil { + return errors.WithStack(err) + } + + cliutil.Print(c, w) + return nil + }, +} diff --git a/cmd/wallet_test.go b/cmd/wallet_test.go index ff2892cd..f10061d0 100644 --- a/cmd/wallet_test.go +++ b/cmd/wallet_test.go @@ -23,6 +23,24 @@ func swapWalletHandler(mockHandler wallet.Handler) func() { } } +func TestWalletCreate(t *testing.T) { + testutil.OneWithoutReset(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { + runner := NewRunner() + defer runner.Save(t) + mockHandler := new(wallet.MockWallet) + defer swapWalletHandler(mockHandler)() + mockHandler.On("CreateHandler", mock.Anything, mock.Anything, mock.Anything).Return(&model.Wallet{ + ActorID: "id", + Address: "address", + PrivateKey: "private", + }, nil) + _, _, err := runner.Run(ctx, "singularity wallet create") + require.NoError(t, err) + _, _, err = runner.Run(ctx, "singularity --verbose wallet create") + require.NoError(t, err) + }) +} + func TestWalletImport(t *testing.T) { testutil.OneWithoutReset(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { tmp := t.TempDir() @@ -33,7 +51,7 @@ func TestWalletImport(t *testing.T) { mockHandler := new(wallet.MockWallet) defer swapWalletHandler(mockHandler)() mockHandler.On("ImportHandler", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&model.Wallet{ - ID: "id", + ActorID: "id", Address: "address", PrivateKey: "private", }, nil) @@ -51,11 +69,11 @@ func TestWalletList(t *testing.T) { mockHandler := new(wallet.MockWallet) defer swapWalletHandler(mockHandler)() mockHandler.On("ListHandler", mock.Anything, mock.Anything).Return([]model.Wallet{{ - ID: "id1", + ActorID: "id1", Address: "address1", PrivateKey: "private1", }, { - ID: "id2", + ActorID: "id2", Address: "address2", PrivateKey: "private2", }}, nil) diff --git a/docs/en/SUMMARY.md b/docs/en/SUMMARY.md index f1b32fcc..e8e2393c 100644 --- a/docs/en/SUMMARY.md +++ b/docs/en/SUMMARY.md @@ -40,6 +40,10 @@ * [Admin](cli-reference/admin/README.md) * [Init](cli-reference/admin/init.md) * [Reset](cli-reference/admin/reset.md) + * [Migrate](cli-reference/admin/migrate/README.md) + * [Up](cli-reference/admin/migrate/up.md) + * [Down](cli-reference/admin/migrate/down.md) + * [To](cli-reference/admin/migrate/to.md) * [Migrate Dataset](cli-reference/admin/migrate-dataset.md) * [Migrate Schedule](cli-reference/admin/migrate-schedule.md) * [Download](cli-reference/download.md) @@ -62,6 +66,7 @@ * [Deal Pusher](cli-reference/run/deal-pusher.md) * [Download Server](cli-reference/run/download-server.md) * [Wallet](cli-reference/wallet/README.md) + * [Create](cli-reference/wallet/create.md) * [Import](cli-reference/wallet/import.md) * [List](cli-reference/wallet/list.md) * [Remove](cli-reference/wallet/remove.md) diff --git a/docs/en/cli-reference/admin/README.md b/docs/en/cli-reference/admin/README.md index f7e036d6..a0a6900a 100644 --- a/docs/en/cli-reference/admin/README.md +++ b/docs/en/cli-reference/admin/README.md @@ -11,6 +11,7 @@ USAGE: COMMANDS: init Initialize or upgrade the database reset Reset the database + migrate Migrate database up, down, or to a certain version migrate-dataset Migrate dataset from old singularity mongodb migrate-schedule Migrate schedule from old singularity mongodb help, h Shows a list of commands or help for one command diff --git a/docs/en/cli-reference/admin/init.md b/docs/en/cli-reference/admin/init.md index cb59e97a..b321cbf2 100644 --- a/docs/en/cli-reference/admin/init.md +++ b/docs/en/cli-reference/admin/init.md @@ -9,7 +9,7 @@ USAGE: singularity admin init [command options] DESCRIPTION: - This commands need to be run before running any singularity daemon or after any version upgrade + This command needs to be run before running any singularity daemon or after any version upgrade OPTIONS: --identity value Name of the user or service that is running the Singularity for tracking and logging purpose diff --git a/docs/en/cli-reference/admin/migrate/README.md b/docs/en/cli-reference/admin/migrate/README.md new file mode 100644 index 00000000..0c7774c3 --- /dev/null +++ b/docs/en/cli-reference/admin/migrate/README.md @@ -0,0 +1,20 @@ +# Migrate database up, down, or to a certain version + +{% code fullWidth="true" %} +``` +NAME: + singularity admin migrate - Migrate database up, down, or to a certain version + +USAGE: + singularity admin migrate command [command options] + +COMMANDS: + up Execute any unrun migrations + down Rollback to previous migration + to Migrate to specified version + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help +``` +{% endcode %} diff --git a/docs/en/cli-reference/admin/migrate/down.md b/docs/en/cli-reference/admin/migrate/down.md new file mode 100644 index 00000000..bd8d6db8 --- /dev/null +++ b/docs/en/cli-reference/admin/migrate/down.md @@ -0,0 +1,14 @@ +# Rollback to previous migration + +{% code fullWidth="true" %} +``` +NAME: + singularity admin migrate down - Rollback to previous migration + +USAGE: + singularity admin migrate down [command options] + +OPTIONS: + --help, -h show help +``` +{% endcode %} diff --git a/docs/en/cli-reference/admin/migrate/to.md b/docs/en/cli-reference/admin/migrate/to.md new file mode 100644 index 00000000..3b1f802e --- /dev/null +++ b/docs/en/cli-reference/admin/migrate/to.md @@ -0,0 +1,14 @@ +# Migrate to specified version + +{% code fullWidth="true" %} +``` +NAME: + singularity admin migrate to - Migrate to specified version + +USAGE: + singularity admin migrate to [command options] + +OPTIONS: + --help, -h show help +``` +{% endcode %} diff --git a/docs/en/cli-reference/admin/migrate/up.md b/docs/en/cli-reference/admin/migrate/up.md new file mode 100644 index 00000000..1abb1970 --- /dev/null +++ b/docs/en/cli-reference/admin/migrate/up.md @@ -0,0 +1,14 @@ +# Execute any unrun migrations + +{% code fullWidth="true" %} +``` +NAME: + singularity admin migrate up - Execute any unrun migrations + +USAGE: + singularity admin migrate up [command options] + +OPTIONS: + --help, -h show help +``` +{% endcode %} diff --git a/docs/en/cli-reference/wallet/README.md b/docs/en/cli-reference/wallet/README.md index 7096416a..1710883b 100644 --- a/docs/en/cli-reference/wallet/README.md +++ b/docs/en/cli-reference/wallet/README.md @@ -9,6 +9,7 @@ USAGE: singularity wallet command [command options] COMMANDS: + create Create a new wallet import Import a wallet from exported private key list List all imported wallets remove Remove a wallet diff --git a/docs/en/cli-reference/wallet/create.md b/docs/en/cli-reference/wallet/create.md new file mode 100644 index 00000000..1fb91430 --- /dev/null +++ b/docs/en/cli-reference/wallet/create.md @@ -0,0 +1,14 @@ +# Create a new wallet + +{% code fullWidth="true" %} +``` +NAME: + singularity wallet create - Create a new wallet + +USAGE: + singularity wallet create [command options] [type] + +OPTIONS: + --help, -h show help +``` +{% endcode %} diff --git a/docs/en/web-api-reference/wallet.md b/docs/en/web-api-reference/wallet.md index 0aa3ad4f..28a14954 100644 --- a/docs/en/web-api-reference/wallet.md +++ b/docs/en/web-api-reference/wallet.md @@ -8,6 +8,10 @@ [https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml](https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml) {% endswagger %} +{% swagger src="https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml" path="/wallet/create" method="post" %} +[https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml](https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml) +{% endswagger %} + {% swagger src="https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml" path="/wallet/{address}" method="delete" %} [https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml](https://raw.githubusercontent.com/data-preservation-programs/singularity/main/docs/swagger/swagger.yaml) {% endswagger %} diff --git a/docs/swagger/docs.go b/docs/swagger/docs.go index 5cd7cff6..ab1e8d7f 100644 --- a/docs/swagger/docs.go +++ b/docs/swagger/docs.go @@ -5532,6 +5532,55 @@ const docTemplate = `{ } } }, + "/wallet/create": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Wallet" + ], + "summary": "Create new wallet", + "operationId": "CreateWallet", + "parameters": [ + { + "description": "Request body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/wallet.CreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Wallet" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.HTTPError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.HTTPError" + } + } + } + } + }, "/wallet/{address}": { "delete": { "tags": [ @@ -6488,20 +6537,62 @@ const docTemplate = `{ "model.Wallet": { "type": "object", "properties": { + "actorId": { + "description": "ActorID is the short ID of the wallet", + "type": "string" + }, + "actorName": { + "description": "ActorName is readable label for the wallet", + "type": "string" + }, "address": { "description": "Address is the Filecoin full address of the wallet", "type": "string" }, + "balance": { + "description": "Balance is in Fil cached from chain", + "type": "number" + }, + "balancePlus": { + "description": "BalancePlus is in Fil+ cached from chain", + "type": "number" + }, + "contactInfo": { + "description": "ContactInfo is optional email for SP wallets", + "type": "string" + }, "id": { - "description": "ID is the short ID of the wallet", + "type": "integer" + }, + "location": { + "description": "Location is optional region, country for SP wallets", "type": "string" }, "privateKey": { "description": "PrivateKey is the private key of the wallet", "type": "string" + }, + "type": { + "description": "Type determines user or SP wallets", + "allOf": [ + { + "$ref": "#/definitions/model.WalletType" + } + ] } } }, + "model.WalletType": { + "type": "string", + "enum": [ + "UserWallet", + "SPWallet" + ], + "x-enum-varnames": [ + "UserWallet", + "SPWallet" + ] + }, "schedule.CreateRequest": { "type": "object", "properties": { @@ -16390,6 +16481,15 @@ const docTemplate = `{ "store.PieceReader": { "type": "object" }, + "wallet.CreateRequest": { + "type": "object", + "properties": { + "keyType": { + "description": "This is either \"secp256k1\" or \"bls\"", + "type": "string" + } + } + }, "wallet.ImportRequest": { "type": "object", "properties": { diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json index 76b71d3b..da8b31a1 100644 --- a/docs/swagger/swagger.json +++ b/docs/swagger/swagger.json @@ -5526,6 +5526,55 @@ } } }, + "/wallet/create": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Wallet" + ], + "summary": "Create new wallet", + "operationId": "CreateWallet", + "parameters": [ + { + "description": "Request body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/wallet.CreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Wallet" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.HTTPError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.HTTPError" + } + } + } + } + }, "/wallet/{address}": { "delete": { "tags": [ @@ -6482,20 +6531,62 @@ "model.Wallet": { "type": "object", "properties": { + "actorId": { + "description": "ActorID is the short ID of the wallet", + "type": "string" + }, + "actorName": { + "description": "ActorName is readable label for the wallet", + "type": "string" + }, "address": { "description": "Address is the Filecoin full address of the wallet", "type": "string" }, + "balance": { + "description": "Balance is in Fil cached from chain", + "type": "number" + }, + "balancePlus": { + "description": "BalancePlus is in Fil+ cached from chain", + "type": "number" + }, + "contactInfo": { + "description": "ContactInfo is optional email for SP wallets", + "type": "string" + }, "id": { - "description": "ID is the short ID of the wallet", + "type": "integer" + }, + "location": { + "description": "Location is optional region, country for SP wallets", "type": "string" }, "privateKey": { "description": "PrivateKey is the private key of the wallet", "type": "string" + }, + "type": { + "description": "Type determines user or SP wallets", + "allOf": [ + { + "$ref": "#/definitions/model.WalletType" + } + ] } } }, + "model.WalletType": { + "type": "string", + "enum": [ + "UserWallet", + "SPWallet" + ], + "x-enum-varnames": [ + "UserWallet", + "SPWallet" + ] + }, "schedule.CreateRequest": { "type": "object", "properties": { @@ -16384,6 +16475,15 @@ "store.PieceReader": { "type": "object" }, + "wallet.CreateRequest": { + "type": "object", + "properties": { + "keyType": { + "description": "This is either \"secp256k1\" or \"bls\"", + "type": "string" + } + } + }, "wallet.ImportRequest": { "type": "object", "properties": { diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 814d0294..fd160b2c 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -658,16 +658,45 @@ definitions: type: object model.Wallet: properties: + actorId: + description: ActorID is the short ID of the wallet + type: string + actorName: + description: ActorName is readable label for the wallet + type: string address: description: Address is the Filecoin full address of the wallet type: string + balance: + description: Balance is in Fil cached from chain + type: number + balancePlus: + description: BalancePlus is in Fil+ cached from chain + type: number + contactInfo: + description: ContactInfo is optional email for SP wallets + type: string id: - description: ID is the short ID of the wallet + type: integer + location: + description: Location is optional region, country for SP wallets type: string privateKey: description: PrivateKey is the private key of the wallet type: string + type: + allOf: + - $ref: '#/definitions/model.WalletType' + description: Type determines user or SP wallets type: object + model.WalletType: + enum: + - UserWallet + - SPWallet + type: string + x-enum-varnames: + - UserWallet + - SPWallet schedule.CreateRequest: properties: allowedPieceCids: @@ -8165,6 +8194,12 @@ definitions: type: object store.PieceReader: type: object + wallet.CreateRequest: + properties: + keyType: + description: This is either "secp256k1" or "bls" + type: string + type: object wallet.ImportRequest: properties: privateKey: @@ -11835,6 +11870,38 @@ paths: summary: Remove a wallet tags: - Wallet + /wallet/create: + post: + consumes: + - application/json + operationId: CreateWallet + parameters: + - description: Request body + in: body + name: request + required: true + schema: + $ref: '#/definitions/wallet.CreateRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/model.Wallet' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.HTTPError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.HTTPError' + summary: Create new wallet + tags: + - Wallet produces: - application/json swagger: "2.0" diff --git a/go.mod b/go.mod index 40675a4d..a192519a 100644 --- a/go.mod +++ b/go.mod @@ -10,13 +10,14 @@ require ( github.com/cockroachdb/errors v1.11.3 github.com/data-preservation-programs/table v0.0.3 github.com/dustin/go-humanize v1.0.1 - github.com/fatih/color v1.17.0 - github.com/filecoin-project/go-address v1.1.0 + github.com/fatih/color v1.18.0 + github.com/filecoin-project/go-address v1.2.0 github.com/filecoin-project/go-cbor-util v0.0.1 - github.com/filecoin-project/go-fil-commcid v0.1.0 + github.com/filecoin-project/go-crypto v0.1.0 + github.com/filecoin-project/go-fil-commcid v0.2.0 github.com/filecoin-project/go-fil-commp-hashhash v0.2.1-0.20230811065821-2e9c683db589 github.com/filecoin-project/go-fil-markets v1.28.3 - github.com/filecoin-project/go-state-types v0.12.0 + github.com/filecoin-project/go-state-types v0.16.0 github.com/filecoin-project/lassie v0.23.2 github.com/filecoin-shipyard/boostly v0.0.0-20230813165216-a449c35ece79 github.com/fxamacker/cbor/v2 v2.4.0 @@ -35,7 +36,7 @@ require ( github.com/ipfs/go-cid v0.5.0 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ipfs-routing v0.3.0 - github.com/ipfs/go-ipld-cbor v0.1.0 + github.com/ipfs/go-ipld-cbor v0.2.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-ipld-legacy v0.2.1 github.com/ipfs/go-log v1.0.5 @@ -63,6 +64,7 @@ require ( github.com/multiformats/go-varint v0.0.7 github.com/orlangure/gnomock v0.30.0 github.com/parnurzeal/gorequest v0.2.16 + github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844 github.com/rclone/rclone v1.62.2 github.com/rjNemo/underscore v0.5.0 github.com/robfig/cron/v3 v3.0.1 @@ -76,11 +78,12 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c - golang.org/x/text v0.22.0 + golang.org/x/text v0.23.0 + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da gorm.io/driver/mysql v1.5.0 gorm.io/driver/postgres v1.5.0 gorm.io/driver/sqlite v1.5.2 - gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 + gorm.io/gorm v1.25.12 ) require ( @@ -92,6 +95,7 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect + github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect github.com/Jorropo/jsync v1.0.1 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd // indirect @@ -102,6 +106,7 @@ require ( github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bep/debounce v1.2.1 // indirect + github.com/bitfield/gotestdox v0.2.2 // indirect github.com/calebcase/tmpfile v1.0.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -117,6 +122,7 @@ require ( github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/dchest/blake2b v1.0.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.5+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect @@ -127,12 +133,12 @@ require ( github.com/elastic/gosigar v0.14.3 // indirect github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 // indirect github.com/filecoin-project/go-amt-ipld/v2 v2.1.0 // indirect - github.com/filecoin-project/go-amt-ipld/v4 v4.0.0 // indirect + github.com/filecoin-project/go-amt-ipld/v4 v4.4.0 // indirect github.com/filecoin-project/go-bitfield v0.2.4 // indirect github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc7 // indirect github.com/filecoin-project/go-ds-versioning v0.1.2 // indirect github.com/filecoin-project/go-hamt-ipld v0.1.5 // indirect - github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0 // indirect + github.com/filecoin-project/go-hamt-ipld/v3 v3.4.0 // indirect github.com/filecoin-project/go-padreader v0.0.1 // indirect github.com/filecoin-project/go-retrieval-types v1.2.0 // indirect github.com/filecoin-project/go-statemachine v1.0.3 // indirect @@ -140,12 +146,13 @@ require ( github.com/filecoin-project/specs-actors v0.9.13 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/gammazero/deque v0.2.1 // indirect github.com/geoffgarside/ber v1.1.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/glebarez/go-sqlite v1.21.1 // indirect github.com/go-chi/chi/v5 v5.0.8 // indirect + github.com/go-gormigrate/gormigrate/v2 v2.1.4 github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect @@ -168,6 +175,7 @@ require ( github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20250202011525-fc3143867406 // indirect github.com/google/s2a-go v0.1.7 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect @@ -245,7 +253,6 @@ require ( github.com/miekg/dns v1.1.63 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/montanaflynn/stats v0.7.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect @@ -327,7 +334,7 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect github.com/vivint/infectious v0.0.0-20200605153912-25a574ae18a3 // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.2 // indirect + github.com/whyrusleeping/cbor-gen v0.3.1 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/wlynxg/anet v0.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect @@ -341,6 +348,8 @@ require ( github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zeebo/blake3 v0.2.3 // indirect github.com/zeebo/errs v1.3.0 // indirect + gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect + gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect @@ -349,23 +358,25 @@ require ( go.uber.org/dig v1.18.0 // indirect go.uber.org/fx v1.23.0 // indirect go.uber.org/mock v0.5.0 // indirect - golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect golang.org/x/mod v0.23.0 // indirect - golang.org/x/net v0.34.0 // indirect + golang.org/x/net v0.35.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/term v0.28.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.29.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + golang.org/x/tools v0.30.0 // indirect google.golang.org/api v0.149.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.36.4 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gotest.tools/v3 v3.5.1 // indirect + gotest.tools/gotestsum v1.12.2 // indirect + gotest.tools/v3 v3.5.2 // indirect + honnef.co/go/tools v0.6.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect modernc.org/libc v1.22.3 // indirect modernc.org/mathutil v1.5.0 // indirect diff --git a/go.sum b/go.sum index 74329b33..1fa691d5 100644 --- a/go.sum +++ b/go.sum @@ -57,6 +57,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= @@ -97,6 +99,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/bitfield/gotestdox v0.2.2 h1:x6RcPAbBbErKLnapz1QeAlf3ospg8efBsedU93CDsnE= +github.com/bitfield/gotestdox v0.2.2/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/brianvoe/gofakeit/v6 v6.23.2 h1:lVde18uhad5wII/f5RMVFLtdQNE0HaGFuBUXmYKk8i8= github.com/brianvoe/gofakeit/v6 v6.23.2/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8= @@ -105,6 +109,7 @@ github.com/buengese/sgzip v0.1.1/go.mod h1:i5ZiXGF3fhV7gL1xaRRL1nDnmpNj0X061FQzO github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/calebcase/tmpfile v1.0.3 h1:BZrOWZ79gJqQ3XbAQlihYZf/YCV0H4KPIdM5K5oMpJo= github.com/calebcase/tmpfile v1.0.3/go.mod h1:UAUc01aHeC+pudPagY/lWvt2qS9ZO5Zzof6/tIUzqeI= +github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -158,8 +163,11 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPc github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210507181900-4e0be8d2fbb4/go.mod h1:UkVqoxmJlLgUvBjJD+GdJz6mgdSdf3UjX83xfwUAYDk= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/dlespiau/covertool v0.0.0-20180314162135-b0c4c6d0583a/go.mod h1:/eQMcW3eA1bzKx23ZYI2H3tXPdJB5JWYTHzoUPBvQY4= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= +github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= @@ -194,6 +202,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/filecoin-project/dagstore v0.5.2 h1:Nd6oXdnolbbVhpMpkYT5PJHOjQp4OBSntHpMV5pxj3c= github.com/filecoin-project/dagstore v0.5.2/go.mod h1:mdqKzYrRBHf1pRMthYfMv3n37oOw0Tkx7+TxPt240M0= github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200910194244-f640612a1a1f/go.mod h1:+If3s2VxyjZn+KGGZIoRXBDSFQ9xL404JBJGf4WhEj0= @@ -201,12 +211,14 @@ github.com/filecoin-project/filecoin-ffi v0.30.4-0.20220519234331-bfd1f5f9fe38 h github.com/filecoin-project/filecoin-ffi v0.30.4-0.20220519234331-bfd1f5f9fe38/go.mod h1:GM5pXRYvQM7wyH6V2WtPnJ2k1jt+qotRkWLxBSRCOuE= github.com/filecoin-project/go-address v0.0.3/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8= github.com/filecoin-project/go-address v0.0.5/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8= -github.com/filecoin-project/go-address v1.1.0 h1:ofdtUtEsNxkIxkDw67ecSmvtzaVSdcea4boAmLbnHfE= github.com/filecoin-project/go-address v1.1.0/go.mod h1:5t3z6qPmIADZBtuE9EIzi0EwzcRy2nVhpo0I/c1r0OA= +github.com/filecoin-project/go-address v1.2.0 h1:NHmWUE/J7Pi2JZX3gZt32XuY69o9StVZeJxdBodIwOE= +github.com/filecoin-project/go-address v1.2.0/go.mod h1:kQEQ4qZ99a51X7DjT9HiMT4yR6UwLJ9kznlxsOIeDAg= github.com/filecoin-project/go-amt-ipld/v2 v2.1.0 h1:t6qDiuGYYngDqaLc2ZUvdtAg4UNxPeOYaXhBWSNsVaM= github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs= -github.com/filecoin-project/go-amt-ipld/v4 v4.0.0 h1:XM81BJ4/6h3FV0WfFjh74cIDIgqMbJsMBLM0fIuLUUk= github.com/filecoin-project/go-amt-ipld/v4 v4.0.0/go.mod h1:gF053YQ4BIpzTNDoEwHZas7U3oAwncDVGvOHyY8oDpE= +github.com/filecoin-project/go-amt-ipld/v4 v4.4.0 h1:6kvvMeSpIy4GTU5t3vPHZgWYIMRzGRKLJ73s/cltsoc= +github.com/filecoin-project/go-amt-ipld/v4 v4.4.0/go.mod h1:msgmUxTyRBZ6iXt+5dnUDnIb7SEFqdPsbB1wyo/G3ts= github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-bitfield v0.2.4 h1:uZ7MeE+XfM5lqrHJZ93OnhQKc/rveW8p9au0C68JPgk= github.com/filecoin-project/go-bitfield v0.2.4/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= @@ -217,24 +229,26 @@ github.com/filecoin-project/go-commp-utils v0.1.3 h1:rTxbkNXZU7FLgdkBk8RsQIEOuPO github.com/filecoin-project/go-commp-utils v0.1.3/go.mod h1:3ENlD1pZySaUout0p9ANQrY3fDFoXdqyX04J+dWpK30= github.com/filecoin-project/go-commp-utils/nonffi v0.0.0-20220905160352-62059082a837/go.mod h1:e2YBjSblNVoBckkbv3PPqsq71q98oFkFqL7s1etViGo= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= -github.com/filecoin-project/go-crypto v0.0.1 h1:AcvpSGGCgjaY8y1az6AMfKQWreF/pWO2JJGLl6gCq6o= -github.com/filecoin-project/go-crypto v0.0.1/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= +github.com/filecoin-project/go-crypto v0.1.0 h1:Pob2MphoipMbe/ksxZOMcQvmBHAd3sI/WEqcbpIsGI0= +github.com/filecoin-project/go-crypto v0.1.0/go.mod h1:K9UFXvvoyAVvB+0Le7oGlKiT9mgA5FHOJdYQXEE8IhI= github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc7 h1:v+zJS5B6pA3ptWZS4t8tbt1Hz9qENnN4nVr1w99aSWc= github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc7/go.mod h1:V3Y4KbttaCwyg1gwkP7iai8CbQx4mZUGjd3h9GZWLKE= github.com/filecoin-project/go-ds-versioning v0.1.2 h1:to4pTadv3IeV1wvgbCbN6Vqd+fu+7tveXgv/rCEZy6w= github.com/filecoin-project/go-ds-versioning v0.1.2/go.mod h1:C9/l9PnB1+mwPa26BBVpCjG/XQCB0yj/q5CK2J8X1I4= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= -github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8= github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= +github.com/filecoin-project/go-fil-commcid v0.2.0 h1:B+5UX8XGgdg/XsdUpST4pEBviKkFOw+Fvl2bLhSKGpI= +github.com/filecoin-project/go-fil-commcid v0.2.0/go.mod h1:8yigf3JDIil+/WpqR5zoKyP0jBPCOGtEqq/K1CcMy9Q= github.com/filecoin-project/go-fil-commp-hashhash v0.2.1-0.20230811065821-2e9c683db589 h1:PP5FU5JVVDb7zODWZlgzbdmQDtwu3Mm0bK9Bg/Om5yc= github.com/filecoin-project/go-fil-commp-hashhash v0.2.1-0.20230811065821-2e9c683db589/go.mod h1:VH3fAFOru4yyWar4626IoS5+VGE8SfZiBODJLUigEo4= github.com/filecoin-project/go-fil-markets v1.28.3 h1:2cFu7tLZYrfNz4LnxjgERaVD7k5+Wwp0H76mnnTGPBk= github.com/filecoin-project/go-fil-markets v1.28.3/go.mod h1:eryxo/oVgIxaR5g5CNr9PlvZOi+u/bak0IsPL/PT1hk= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= -github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0 h1:rVVNq0x6RGQIzCo1iiJlGFm9AGIZzeifggxtKMU7zmI= github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0/go.mod h1:bxmzgT8tmeVQA1/gvBwFmYdT8SOFUwB3ovSUfG1Ux0g= +github.com/filecoin-project/go-hamt-ipld/v3 v3.4.0 h1:nYs6OPUF8KbZ3E8o9p9HJnQaE8iugjHR5WYVMcicDJc= +github.com/filecoin-project/go-hamt-ipld/v3 v3.4.0/go.mod h1:s0qiHRhFyrgW0SvdQMSJFQxNa4xEIG5XvqCBZUEgcbc= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= github.com/filecoin-project/go-padreader v0.0.1 h1:8h2tVy5HpoNbr2gBRr+WD6zV6VD6XHig+ynSGJg8ZOs= github.com/filecoin-project/go-padreader v0.0.1/go.mod h1:VYVPJqwpsfmtoHnAmPx6MUwmrK6HIcDqZJiuZhtmfLQ= @@ -246,8 +260,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.10.0/go.mod h1:aLIas+W8BWAfpLWEPUOGMPBdhcVwoCG4pIQSQk26024= -github.com/filecoin-project/go-state-types v0.12.0 h1:l+54FdFf3Exkzx7cpYCKoWUPReX7SUQlmT/h+9obVEM= -github.com/filecoin-project/go-state-types v0.12.0/go.mod h1:hm9GXjYuqB1xJs58Ei/ZKy8Nfb0532HP6bR9DI8a+kM= +github.com/filecoin-project/go-state-types v0.16.0 h1:ajIREDzTGfq71ofIQ29iZR1WXxmkvd2nQNc6ApcP1wI= +github.com/filecoin-project/go-state-types v0.16.0/go.mod h1:YCESyrqnyu17y0MazbV6Uwma5+BrMvEKEQp5QWeIf9g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.3 h1:N07o6alys+V1tNoSTi4WuuoeNC4erS/6jE74+NsgQuk= github.com/filecoin-project/go-statemachine v1.0.3/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= @@ -266,12 +280,11 @@ github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= @@ -299,6 +312,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop 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-gormigrate/gormigrate/v2 v2.1.4 h1:KOPEt27qy1cNzHfMZbp9YTmEuzkY4F4wrdsJW9WFk1U= +github.com/go-gormigrate/gormigrate/v2 v2.1.4/go.mod h1:y/6gPAH6QGAgP1UfHMiXcqGeJ88/GRQbfCReE1JJD5Y= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -435,10 +450,10 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= @@ -448,6 +463,7 @@ github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo 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-20190309163659-77426154d546/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= @@ -459,6 +475,8 @@ github.com/google/pprof v0.0.0-20250202011525-fc3143867406/go.mod h1:vavhavw2zAx github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -537,7 +555,6 @@ github.com/ipfs/go-cid v0.0.6-0.20200501230655-7c82f3b81c00/go.mod h1:plgt+Y5MnO 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.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= -github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= @@ -584,8 +601,8 @@ github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9 github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-cbor v0.0.6-0.20211211231443-5d9b9e1f6fa8/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= -github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs= -github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk= +github.com/ipfs/go-ipld-cbor v0.2.0 h1:VHIW3HVIjcMd8m4ZLZbrYpwjzqlVUfjLM7oK4T5/YF0= +github.com/ipfs/go-ipld-cbor v0.2.0/go.mod h1:Cp8T7w1NKcu4AQJLqK0tWpd1nkgTxEVB5C6kVpLW6/0= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= @@ -628,7 +645,6 @@ github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6 github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-adl-hamt v0.0.0-20220616142416-9004dbd839e0 h1:QAI/Ridj0+foHD6epbxmB4ugxz9B4vmNdYSmQLGa05E= github.com/ipld/go-ipld-adl-hamt v0.0.0-20220616142416-9004dbd839e0/go.mod h1:odxGcpiQZLzP5+yGu84Ljo8y3EzCvNAQKEodHNsHLXA= -github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= @@ -641,7 +657,6 @@ github.com/ipni/go-libipni v0.6.6 h1:Ms2a0AkPgv1pCblSgqM8tKUz9NHmzn8JP0PO8fYUYZM github.com/ipni/go-libipni v0.6.6/go.mod h1:jh/TDrsKlKuwzHfaYIGTuHudFkX4ioe9zx0835x1fiQ= github.com/ipni/index-provider v0.12.0 h1:R3F6dxxKNv4XkE4GJZNLOG0bDEbBQ/S5iztXwSD8jhQ= github.com/ipni/index-provider v0.12.0/go.mod h1:GhyrADJp7n06fqoc1djzkvL4buZYHzV8SoWrlxEo5F4= -github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52 h1:QG4CGBqCeuBo6aZlGAamSkxWdgWfZGeE49eUOWJPA4c= github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52/go.mod h1:fdg+/X9Gg4AsAIzWpEHwnqd+QY3b7lajxyjE1m4hkq4= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= @@ -720,9 +735,7 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= 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.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -828,6 +841,7 @@ github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mmcloughlin/avo v0.0.0-20190318053554-7a0eb66183da/go.mod h1:lf5GMZxA5kz8dnCweJuER5Rmbx6dDu6qvw0fO3uYKK8= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -859,7 +873,6 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= 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.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -869,7 +882,6 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.6.0 h1:ZaHKbsL404720283o4c/IHQXiS6gb8qAN5EIJ4PN5EA= @@ -924,6 +936,8 @@ github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14 h1:XeOYlK9W1uC github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14/go.mod h1:jVblp62SafmidSkvWrXyxAme3gaTfEtWwRPGz5cpvHg= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= +github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844 h1:Yflyn+XFLEu7RPzxovgEVLP6Es8JLJrHqdXunpm2ak4= +github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844/go.mod h1:xHJKf2TLXUA39Dhv8k5QmQOxLsbrb1KeTS/3ERfLeqc= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o= @@ -992,7 +1006,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN 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-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= @@ -1091,7 +1104,6 @@ github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN2 github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -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/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= @@ -1144,6 +1156,7 @@ github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYm github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.2/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/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= @@ -1158,12 +1171,10 @@ github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49u github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/vivint/infectious v0.0.0-20200605153912-25a574ae18a3 h1:zMsHhfK9+Wdl1F7sIKLyx3wrOFofpb3rWFbA4HgcK5k= github.com/vivint/infectious v0.0.0-20200605153912-25a574ae18a3/go.mod h1:R0Gbuw7ElaGSLOZUSwBm/GgVwMd30jWxBDdAyMOeTuc= -github.com/warpfork/go-testmark v0.10.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -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= @@ -1181,8 +1192,8 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c/go.mod h1:f github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210303213153-67a261a1d291/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= -github.com/whyrusleeping/cbor-gen v0.1.2 h1:WQFlrPhpcQl+M2/3dP5cvlTLWPVsL6LGBb9jJt6l/cA= -github.com/whyrusleeping/cbor-gen v0.1.2/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= +github.com/whyrusleeping/cbor-gen v0.3.1 h1:82ioxmhEYut7LBVGhGq8xoRkXPLElVuh5mV67AFfdv0= +github.com/whyrusleeping/cbor-gen v0.3.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= @@ -1234,6 +1245,10 @@ github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= +gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA= +gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8= +gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q= +gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1295,6 +1310,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= +golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8= +golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1302,6 +1319,7 @@ golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1317,15 +1335,15 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= 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= @@ -1338,6 +1356,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc= golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ= +golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= 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/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1374,6 +1394,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190326090315-15845e8f865b/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= @@ -1411,8 +1432,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= 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= @@ -1438,8 +1459,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1451,6 +1472,7 @@ golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1506,7 +1528,6 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1517,10 +1538,11 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1528,10 +1550,11 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= 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= @@ -1544,10 +1567,11 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 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= @@ -1559,11 +1583,13 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190106171756-3ef68632349c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190325223049-1d95b17f1b04/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1611,14 +1637,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= -golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1748,10 +1774,18 @@ gorm.io/driver/sqlite v1.5.2/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 h1:sC1Xj4TYrLqg1n3AN10w871An7wJM0gzgcm8jkIkECQ= gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= +gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/gotestsum v1.12.1 h1:dvcxFBTFR1QsQmrCQa4k/vDXow9altdYz4CjdW+XeBE= +gotest.tools/gotestsum v1.12.1/go.mod h1:mwDmLbx9DIvr09dnAoGgQPLaSXszNpXpWo2bsQge5BE= +gotest.tools/gotestsum v1.12.2 h1:eli4tu9Q2D/ogDsEGSr8XfQfl7mT0JsGOG6DFtUiZ/Q= +gotest.tools/gotestsum v1.12.2/go.mod h1:kjRtCglPZVsSU0hFHX3M5VWBM6Y63emHuB14ER1/sow= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1761,7 +1795,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI= +honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= @@ -1780,6 +1815,7 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= diff --git a/handler/admin/init.go b/handler/admin/init.go index 27b860ad..2bec942d 100644 --- a/handler/admin/init.go +++ b/handler/admin/init.go @@ -18,7 +18,8 @@ import ( // - An error, if any occurred during the operation. func (DefaultHandler) InitHandler(ctx context.Context, db *gorm.DB) error { db = db.WithContext(ctx) - err := model.AutoMigrate(db) + + err := model.GetMigrator(db).Migrate() if err != nil { return errors.WithStack(err) } diff --git a/handler/admin/reset.go b/handler/admin/reset.go index 4a2da222..c88397a6 100644 --- a/handler/admin/reset.go +++ b/handler/admin/reset.go @@ -21,12 +21,13 @@ import ( // - An error, if any occurred during the operation. func (DefaultHandler) ResetHandler(ctx context.Context, db *gorm.DB) error { db = db.WithContext(ctx) - err := model.DropAll(db) + migrator := model.GetMigrator(db) + err := migrator.DropAll() if err != nil { return errors.WithStack(err) } - err = model.AutoMigrate(db) + err = migrator.Migrate() if err != nil { return errors.WithStack(err) } diff --git a/handler/deal/list_test.go b/handler/deal/list_test.go index 96005ebf..146131d9 100644 --- a/handler/deal/list_test.go +++ b/handler/deal/list_test.go @@ -14,7 +14,7 @@ func TestListHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, SourceStorages: []model.Storage{{ Name: "storage", diff --git a/handler/deal/schedule/create_test.go b/handler/deal/schedule/create_test.go index 4e1da85f..843adf39 100644 --- a/handler/deal/schedule/create_test.go +++ b/handler/deal/schedule/create_test.go @@ -190,7 +190,7 @@ func TestCreateHandler_InvalidProvider(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) @@ -207,7 +207,7 @@ func TestCreateHandler_DealSizeNotSetForCron(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) @@ -227,7 +227,7 @@ func TestCreateHandler_ScheduleDealSizeSetForNonCron(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) @@ -248,7 +248,7 @@ func TestCreateHandler_Success(t *testing.T) { err := db.Create(&model.Preparation{ Name: "name", Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) diff --git a/handler/deal/schedule/list_test.go b/handler/deal/schedule/list_test.go index e0c906f2..8169eedd 100644 --- a/handler/deal/schedule/list_test.go +++ b/handler/deal/schedule/list_test.go @@ -14,7 +14,7 @@ func TestListHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) diff --git a/handler/deal/schedule/pause_test.go b/handler/deal/schedule/pause_test.go index 17090f82..b7238460 100644 --- a/handler/deal/schedule/pause_test.go +++ b/handler/deal/schedule/pause_test.go @@ -15,7 +15,7 @@ func TestPauseHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) diff --git a/handler/deal/schedule/remove_test.go b/handler/deal/schedule/remove_test.go index afd825d3..de855d51 100644 --- a/handler/deal/schedule/remove_test.go +++ b/handler/deal/schedule/remove_test.go @@ -16,7 +16,7 @@ func TestRemoveSchedule_Success(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) @@ -57,7 +57,7 @@ func TestRemoveSchedule_StillActive(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) diff --git a/handler/deal/schedule/resume.go b/handler/deal/schedule/resume.go index 839fbcc6..944986ab 100644 --- a/handler/deal/schedule/resume.go +++ b/handler/deal/schedule/resume.go @@ -7,8 +7,8 @@ import ( "github.com/data-preservation-programs/singularity/database" "github.com/data-preservation-programs/singularity/handler/handlererror" "github.com/data-preservation-programs/singularity/model" - "golang.org/x/exp/slices" "gorm.io/gorm" + "slices" ) var resumableStates = []model.ScheduleState{ diff --git a/handler/deal/schedule/resume_test.go b/handler/deal/schedule/resume_test.go index 85d87b95..eb4c20fc 100644 --- a/handler/deal/schedule/resume_test.go +++ b/handler/deal/schedule/resume_test.go @@ -15,7 +15,7 @@ func TestResumeHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "f01", + ActorID: "f01", }}, }).Error require.NoError(t, err) diff --git a/handler/deal/send-manual_test.go b/handler/deal/send-manual_test.go index 0d55f66a..b7272971 100644 --- a/handler/deal/send-manual_test.go +++ b/handler/deal/send-manual_test.go @@ -41,7 +41,7 @@ var proposal = Proposal{ func TestSendManualHandler_WalletNotFound(t *testing.T) { wallet := model.Wallet{ - ID: "f09999", + ActorID: "f09999", Address: "f10000", } @@ -59,7 +59,7 @@ func TestSendManualHandler_WalletNotFound(t *testing.T) { func TestSendManualHandler_InvalidPieceCID(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } @@ -79,7 +79,7 @@ func TestSendManualHandler_InvalidPieceCID(t *testing.T) { func TestSendManualHandler_InvalidPieceCID_NOTCOMMP(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } @@ -99,7 +99,7 @@ func TestSendManualHandler_InvalidPieceCID_NOTCOMMP(t *testing.T) { func TestSendManualHandler_InvalidPieceSize(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } @@ -119,7 +119,7 @@ func TestSendManualHandler_InvalidPieceSize(t *testing.T) { func TestSendManualHandler_InvalidPieceSize_NotPowerOfTwo(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } @@ -139,7 +139,7 @@ func TestSendManualHandler_InvalidPieceSize_NotPowerOfTwo(t *testing.T) { func TestSendManualHandler_InvalidRootCID(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } @@ -159,7 +159,7 @@ func TestSendManualHandler_InvalidRootCID(t *testing.T) { func TestSendManualHandler_InvalidDuration(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } @@ -179,7 +179,7 @@ func TestSendManualHandler_InvalidDuration(t *testing.T) { func TestSendManualHandler_InvalidStartDelay(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } @@ -199,7 +199,7 @@ func TestSendManualHandler_InvalidStartDelay(t *testing.T) { func TestSendManualHandler(t *testing.T) { wallet := model.Wallet{ - ID: "f01000", + ActorID: "f01000", Address: "f10000", } diff --git a/handler/download.go b/handler/download.go index 7b688df1..caf74bae 100644 --- a/handler/download.go +++ b/handler/download.go @@ -83,7 +83,7 @@ func download(cctx *cli.Context, reader *store.PieceReader, outPath string, conc errChan := make(chan error, 1) - for i := 0; i < concurrency; i++ { + for i := range concurrency { wg.Add(1) go func(i int) { defer wg.Done() diff --git a/handler/file/retrieve_test.go b/handler/file/retrieve_test.go index 46ea5b35..dd444765 100644 --- a/handler/file/retrieve_test.go +++ b/handler/file/retrieve_test.go @@ -409,7 +409,7 @@ func BenchmarkFilecoinRetrieve(b *testing.B) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() db = db.WithContext(ctx) - require.NoError(b, model.AutoMigrate(db)) + require.NoError(b, model.GetMigrator(db).Migrate()) path := b.TempDir() lsys := cidlink.DefaultLinkSystem() diff --git a/handler/job/scan.go b/handler/job/scan.go index ca71c2f9..80567b0d 100644 --- a/handler/job/scan.go +++ b/handler/job/scan.go @@ -7,8 +7,8 @@ import ( "github.com/data-preservation-programs/singularity/database" "github.com/data-preservation-programs/singularity/handler/handlererror" "github.com/data-preservation-programs/singularity/model" - "golang.org/x/exp/slices" "gorm.io/gorm" + "slices" ) var pausableStatesForScan = []model.JobState{model.Processing, model.Ready} diff --git a/handler/wallet/attach_test.go b/handler/wallet/attach_test.go index 1a0ee203..9a8ddca9 100644 --- a/handler/wallet/attach_test.go +++ b/handler/wallet/attach_test.go @@ -14,7 +14,7 @@ import ( func TestAttachHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Wallet{ - ID: "test", + ActorID: "test", }).Error require.NoError(t, err) err = db.Create(&model.Preparation{}).Error diff --git a/handler/wallet/create.go b/handler/wallet/create.go new file mode 100644 index 00000000..a1fc2fc2 --- /dev/null +++ b/handler/wallet/create.go @@ -0,0 +1,129 @@ +package wallet + +import ( + "context" + "crypto/rand" + "encoding/hex" + + "github.com/cockroachdb/errors" + "github.com/data-preservation-programs/singularity/database" + "github.com/data-preservation-programs/singularity/handler/handlererror" + "github.com/data-preservation-programs/singularity/model" + "github.com/data-preservation-programs/singularity/util" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-crypto" + g1 "github.com/phoreproject/bls/g1pubs" + "golang.org/x/xerrors" + "gorm.io/gorm" +) + +type KeyType string + +const ( + KTSecp256k1 KeyType = "secp256k1" + KTBLS KeyType = "bls" + // TODO: add support for "delegated" or "secp256k1-ledger" types? +) + +func (kt KeyType) String() string { + return string(kt) +} + +// GenerateKey generates a new keypair and returns the private key and address. +// The keypair is generated using the specified key type (secp256k1 or BLS). +func GenerateKey(keyType string) (string, string, error) { + var privKey string + var addr address.Address + var err error + + switch keyType { + case KTSecp256k1.String(): + kb := make([]byte, 32) + _, err = rand.Read(kb) + if err != nil { + return "", "", xerrors.Errorf("failed to generate %s private key: %w", keyType, err) + } + privKey = hex.EncodeToString(kb) + + // Get the public key from private key + pubKey := crypto.PublicKey(kb) + addr, err = address.NewSecp256k1Address(pubKey) + if err != nil { + return "", "", xerrors.Errorf("failed to generate address from %s key: %w", keyType, err) + } + case KTBLS.String(): + priv, err := g1.RandKey(rand.Reader) + if err != nil { + return "", "", xerrors.Errorf("failed to generate %s private key: %w", keyType, err) + } + privKey = priv.String() + + // Get the public key from private key + pub := g1.PrivToPub(priv) + pubKey := pub.Serialize() + addr, err = address.NewBLSAddress(pubKey[:]) + if err != nil { + return "", "", xerrors.Errorf("failed to generate address from %s key: %w", keyType, err) + } + default: + return "", "", xerrors.Errorf("unsupported key type: %s", keyType) + } + + return privKey, addr.String(), nil +} + +type CreateRequest struct { + KeyType string `json:"keyType"` // This is either "secp256k1" or "bls" +} + +// @ID CreateWallet +// @Summary Create new wallet +// @Tags Wallet +// @Accept json +// @Produce json +// @Param request body CreateRequest true "Request body" +// @Success 200 {array} model.Wallet +// @Failure 400 {object} api.HTTPError +// @Failure 500 {object} api.HTTPError +// @Router /wallet/create [post] +func _() {} + +// CreateHandler creates a new wallet using offline keypair generation and a new record in the local database. +// +// Parameters: +// - ctx: The context for database transactions and other operations. +// - db: A pointer to the gorm.DB instance representing the database connection. +// +// Returns: +// - A pointer to the created Wallet model if successful. +// - An error, if any occurred during the database insert operation. +func (DefaultHandler) CreateHandler( + ctx context.Context, + db *gorm.DB, + request CreateRequest, +) (*model.Wallet, error) { + db = db.WithContext(ctx) + + // Generate a new keypair + privateKey, address, err := GenerateKey(request.KeyType) + if err != nil { + return nil, errors.WithStack(err) + } + + wallet := model.Wallet{ + ActorID: address, + Address: address, + PrivateKey: privateKey, + } + err = database.DoRetry(ctx, func() error { + return db.Create(&wallet).Error + }) + if util.IsDuplicateKeyError(err) { + return nil, errors.Wrap(handlererror.ErrDuplicateRecord, "wallet already exists") + } + if err != nil { + return nil, errors.WithStack(err) + } + + return &wallet, nil +} diff --git a/handler/wallet/create_test.go b/handler/wallet/create_test.go new file mode 100644 index 00000000..3adbfb5c --- /dev/null +++ b/handler/wallet/create_test.go @@ -0,0 +1,49 @@ +package wallet + +import ( + "context" + "testing" + + "github.com/data-preservation-programs/singularity/handler/handlererror" + "github.com/data-preservation-programs/singularity/util" + "github.com/data-preservation-programs/singularity/util/testutil" + "github.com/stretchr/testify/require" + "gorm.io/gorm" +) + +func TestCreateHandler(t *testing.T) { + testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { + lotusClient := util.NewLotusClient("https://api.node.glif.io/rpc/v0", "") + + t.Run("success-secp256k1", func(t *testing.T) { + w, err := Default.CreateHandler(ctx, db, CreateRequest{KeyType: KTSecp256k1.String()}) + require.NoError(t, err) + require.NotEmpty(t, w.Address) + require.Equal(t, "f1", w.Address[:2]) + require.Equal(t, "hello", w.PrivateKey) + + + _, err = Default.ImportHandler(ctx, db, lotusClient, ImportRequest{ + PrivateKey: w.PrivateKey, + }) + require.ErrorIs(t, err, handlererror.ErrDuplicateRecord) + }) + + t.Run("success-bls", func(t *testing.T) { + w, err := Default.CreateHandler(ctx, db, CreateRequest{KeyType: KTBLS.String()}) + require.NoError(t, err) + require.NotEmpty(t, w.Address) + require.Equal(t, "f3", w.Address[:2]) + + _, err = Default.ImportHandler(ctx, db, lotusClient, ImportRequest{ + PrivateKey: w.PrivateKey, + }) + require.ErrorIs(t, err, handlererror.ErrDuplicateRecord) + }) + + t.Run("invalid-key-type", func(t *testing.T) { + _, err := Default.CreateHandler(ctx, db, CreateRequest{KeyType: "invalid-type"}) + require.Error(t, err) + }) + }) +} diff --git a/handler/wallet/detach.go b/handler/wallet/detach.go index 6b1ace1e..9c199631 100644 --- a/handler/wallet/detach.go +++ b/handler/wallet/detach.go @@ -39,7 +39,7 @@ func (DefaultHandler) DetachHandler( } found, err := underscore.Find(preparation.Wallets, func(w model.Wallet) bool { - return w.ID == wallet || w.Address == wallet + return w.ActorID == wallet || w.Address == wallet }) if err != nil { diff --git a/handler/wallet/detach_test.go b/handler/wallet/detach_test.go index 268da587..eba0205f 100644 --- a/handler/wallet/detach_test.go +++ b/handler/wallet/detach_test.go @@ -15,7 +15,7 @@ func TestDetachHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "test", + ActorID: "test", }}, }).Error require.NoError(t, err) diff --git a/handler/wallet/import.go b/handler/wallet/import.go index 3775d8cc..e27c162c 100644 --- a/handler/wallet/import.go +++ b/handler/wallet/import.go @@ -73,7 +73,7 @@ func (DefaultHandler) ImportHandler( } wallet := model.Wallet{ - ID: result, + ActorID: result, Address: result[:1] + addr.String()[1:], PrivateKey: request.PrivateKey, } diff --git a/handler/wallet/interface.go b/handler/wallet/interface.go index 163dc1c6..0a88d848 100644 --- a/handler/wallet/interface.go +++ b/handler/wallet/interface.go @@ -17,6 +17,11 @@ type Handler interface { preparation string, wallet string, ) (*model.Preparation, error) + CreateHandler( + ctx context.Context, + db *gorm.DB, + request CreateRequest, + ) (*model.Wallet, error) DetachHandler( ctx context.Context, db *gorm.DB, @@ -60,6 +65,11 @@ func (m *MockWallet) AttachHandler(ctx context.Context, db *gorm.DB, preparation return args.Get(0).(*model.Preparation), args.Error(1) } +func (m *MockWallet) CreateHandler(ctx context.Context, db *gorm.DB, request CreateRequest) (*model.Wallet, error) { + args := m.Called(ctx, db, request) + return args.Get(0).(*model.Wallet), args.Error(1) +} + func (m *MockWallet) DetachHandler(ctx context.Context, db *gorm.DB, preparation string, wallet string) (*model.Preparation, error) { args := m.Called(ctx, db, preparation, wallet) return args.Get(0).(*model.Preparation), args.Error(1) diff --git a/handler/wallet/listattached_test.go b/handler/wallet/listattached_test.go index 26fb17fc..9f830d84 100644 --- a/handler/wallet/listattached_test.go +++ b/handler/wallet/listattached_test.go @@ -15,7 +15,7 @@ func TestListAttachedHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Preparation{ Wallets: []model.Wallet{{ - ID: "test", + ActorID: "test", }}, }).Error require.NoError(t, err) diff --git a/handler/wallet/remove_test.go b/handler/wallet/remove_test.go index dd52ecc0..8539cc96 100644 --- a/handler/wallet/remove_test.go +++ b/handler/wallet/remove_test.go @@ -15,7 +15,7 @@ func TestRemoveHandler(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { t.Run("success", func(t *testing.T) { err := db.Create(&model.Wallet{ - ID: "test", + ActorID: "test", }).Error require.NoError(t, err) err = Default.RemoveHandler(ctx, db, "test") diff --git a/migrate/migrate-dataset.go b/migrate/migrate-dataset.go index 64d341d1..38c97b54 100644 --- a/migrate/migrate-dataset.go +++ b/migrate/migrate-dataset.go @@ -2,7 +2,6 @@ package migrate import ( "context" - "fmt" "log" "path/filepath" "strings" @@ -112,7 +111,7 @@ func migrateDataset(ctx context.Context, mg *mongo.Client, db *gorm.DB, scanning log.Printf("failed to parse data cid %s\n", generation.DataCID) dataCID = cid.Undef } - fileName := fmt.Sprintf("%s.car", generation.PieceCID) + fileName := generation.PieceCID + ".car" if generation.FilenameOverride != "" { fileName = generation.FilenameOverride } @@ -264,9 +263,9 @@ func MigrateDataset(cctx *cli.Context) error { return errors.Wrap(err, "failed to connect to mongo") } - err = model.AutoMigrate(db) + err = model.GetMigrator(db).Migrate() if err != nil { - return errors.Wrap(err, "failed to auto-migrate database") + return errors.Wrap(err, "failed to migrate database") } resp, err := mg.Database("singularity").Collection("scanningrequests").Find(ctx, bson.M{}) diff --git a/migrate/migrations/202505010830_initial_schema.go b/migrate/migrations/202505010830_initial_schema.go new file mode 100644 index 00000000..009c8d2e --- /dev/null +++ b/migrate/migrations/202505010830_initial_schema.go @@ -0,0 +1,249 @@ +package migrations + +import ( + "strconv" + "time" + + "github.com/go-gormigrate/gormigrate/v2" + "github.com/ipfs/go-cid" + "github.com/pkg/errors" + "gorm.io/gorm" +) + +// NOTE: This recreates original models at time of transition from AutoMigrate +// to versioned migrations so that future modifications to the actual models +// don't change this initial schema definition. +type StringSlice []string +type ConfigMap map[string]string +type CID cid.Cid +type ClientConfig struct { + ConnectTimeout *time.Duration `cbor:"1,keyasint,omitempty" json:"connectTimeout,omitempty" swaggertype:"primitive,integer"` // HTTP Client Connect timeout + Timeout *time.Duration `cbor:"2,keyasint,omitempty" json:"timeout,omitempty" swaggertype:"primitive,integer"` // IO idle timeout + ExpectContinueTimeout *time.Duration `cbor:"3,keyasint,omitempty" json:"expectContinueTimeout,omitempty" swaggertype:"primitive,integer"` // Timeout when using expect / 100-continue in HTTP + InsecureSkipVerify *bool `cbor:"4,keyasint,omitempty" json:"insecureSkipVerify,omitempty"` // Do not verify the server SSL certificate (insecure) + NoGzip *bool `cbor:"5,keyasint,omitempty" json:"noGzip,omitempty"` // Don't set Accept-Encoding: gzip + UserAgent *string `cbor:"6,keyasint,omitempty" json:"userAgent,omitempty"` // Set the user-agent to a specified string + CaCert []string `cbor:"7,keyasint,omitempty" json:"caCert,omitempty"` // Paths to CA certificate used to verify servers + ClientCert *string `cbor:"8,keyasint,omitempty" json:"clientCert,omitempty"` // Path to Client SSL certificate (PEM) for mutual TLS auth + ClientKey *string `cbor:"9,keyasint,omitempty" json:"clientKey,omitempty"` // Path to Client SSL private key (PEM) for mutual TLS auth + Headers map[string]string `cbor:"10,keyasint,omitempty" json:"headers,omitempty"` // Set HTTP header for all transactions + DisableHTTP2 *bool `cbor:"11,keyasint,omitempty" json:"disableHttp2,omitempty"` // Disable HTTP/2 in the transport + DisableHTTPKeepAlives *bool `cbor:"12,keyasint,omitempty" json:"disableHttpKeepAlives,omitempty"` // Disable HTTP keep-alives and use each connection once. + RetryMaxCount *int `cbor:"13,keyasint,omitempty" json:"retryMaxCount,omitempty"` // Maximum number of retries. Default is 10 retries. + RetryDelay *time.Duration `cbor:"14,keyasint,omitempty" json:"retryDelay,omitempty" swaggertype:"primitive,integer"` // Delay between retries. Default is 1s. + RetryBackoff *time.Duration `cbor:"15,keyasint,omitempty" json:"retryBackoff,omitempty" swaggertype:"primitive,integer"` // Constant backoff between retries. Default is 1s. + RetryBackoffExponential *float64 `cbor:"16,keyasint,omitempty" json:"retryBackoffExponential,omitempty"` // Exponential backoff between retries. Default is 1.0. + SkipInaccessibleFile *bool `cbor:"17,keyasint,omitempty" json:"skipInaccessibleFile,omitempty"` // Skip inaccessible files. Default is false. + UseServerModTime *bool `cbor:"18,keyasint,omitempty" json:"useServerModTime,omitempty"` // Use server modified time instead of object metadata + LowLevelRetries *int `cbor:"19,keyasint,omitempty" json:"lowlevelRetries,omitempty"` // Maximum number of retries for low-level client errors. Default is 10 retries. + ScanConcurrency *int `cbor:"20,keyasint,omitempty" json:"scanConcurrency,omitempty"` // Maximum number of concurrent scan requests. Default is 1. +} +type WorkerType string +type Worker struct { + ID string `gorm:"primaryKey" json:"id"` + LastHeartbeat time.Time `json:"lastHeartbeat"` + Hostname string `json:"hostname"` + Type WorkerType `json:"type"` +} +type Global struct { + Key string `gorm:"primaryKey" json:"key"` + Value string `json:"value"` +} +type Wallet struct { + ID string `gorm:"primaryKey;size:15" json:"id"` // ID is the short ID of the wallet + Address string `gorm:"index" json:"address"` // Address is the Filecoin full address of the wallet + PrivateKey string `json:"privateKey,omitempty" table:"-"` // PrivateKey is the private key of the wallet +} +type PreparationID uint32 +type Preparation struct { + ID PreparationID `gorm:"primaryKey" json:"id"` + Name string `gorm:"unique" json:"name"` + CreatedAt time.Time `json:"createdAt" table:"verbose;format:2006-01-02 15:04:05"` + UpdatedAt time.Time `json:"updatedAt" table:"verbose;format:2006-01-02 15:04:05"` + DeleteAfterExport bool `json:"deleteAfterExport"` // DeleteAfterExport is a flag that indicates whether the source files should be deleted after export. + MaxSize int64 `json:"maxSize"` + PieceSize int64 `json:"pieceSize"` + NoInline bool `json:"noInline"` + NoDag bool `json:"noDag"` + Wallets []Wallet `gorm:"many2many:wallet_assignments" json:"wallets,omitempty" swaggerignore:"true" table:"expand"` + SourceStorages []Storage `gorm:"many2many:source_attachments;constraint:OnDelete:CASCADE" json:"sourceStorages,omitempty" table:"expand;header:Source Storages:"` + OutputStorages []Storage `gorm:"many2many:output_attachments;constraint:OnDelete:CASCADE" json:"outputStorages,omitempty" table:"expand;header:Output Storages:"` +} + +func (s *Preparation) FindByIDOrName(db *gorm.DB, name string, preloads ...string) error { + id, err := strconv.ParseUint(name, 10, 32) + if err == nil { + for _, preload := range preloads { + db = db.Preload(preload) + } + return db.First(s, id).Error + } else { + for _, preload := range preloads { + db = db.Preload(preload) + } + return db.Where("name = ?", name).First(s).Error + } +} +func (s *Preparation) SourceAttachments(db *gorm.DB, preloads ...string) ([]SourceAttachment, error) { + for _, preload := range preloads { + db = db.Preload(preload) + } + var attachments []SourceAttachment + err := db.Where("preparation_id = ?", s.ID).Find(&attachments).Error + return attachments, errors.Wrap(err, "failed to find source attachments") +} + +type StorageID uint32 +type Storage struct { + ID StorageID `cbor:"-" gorm:"primaryKey" json:"id"` + Name string `cbor:"-" gorm:"unique" json:"name"` + CreatedAt time.Time `cbor:"-" json:"createdAt" table:"verbose;format:2006-01-02 15:04:05"` + UpdatedAt time.Time `cbor:"-" json:"updatedAt" table:"verbose;format:2006-01-02 15:04:05"` + Type string `cbor:"1,keyasint,omitempty" json:"type"` + Path string `cbor:"2,keyasint,omitempty" json:"path"` // Path is the path to the storage root. + Config ConfigMap `cbor:"3,keyasint,omitempty" gorm:"type:JSON" json:"config" table:"verbose"` // Config is a map of key-value pairs that can be used to store RClone options. + ClientConfig ClientConfig `cbor:"4,keyasint,omitempty" gorm:"type:JSON" json:"clientConfig" table:"verbose"` // ClientConfig is the HTTP configuration for the storage, if applicable. + PreparationsAsSource []Preparation `cbor:"-" gorm:"many2many:source_attachments;constraint:OnDelete:CASCADE" json:"preparationsAsSource,omitempty" table:"expand;header:As Source: "` + PreparationsAsOutput []Preparation `cbor:"-" gorm:"many2many:output_attachments;constraint:OnDelete:CASCADE" json:"preparationsAsOutput,omitempty" table:"expand;header:As Output: "` +} +type ScheduleID uint32 +type ScheduleState string +type Schedule struct { + ID ScheduleID `gorm:"primaryKey" json:"id"` + CreatedAt time.Time `json:"createdAt" table:"verbose;format:2006-01-02 15:04:05"` + UpdatedAt time.Time `json:"updatedAt" table:"verbose;format:2006-01-02 15:04:05"` + URLTemplate string `json:"urlTemplate" table:"verbose"` + HTTPHeaders ConfigMap `gorm:"type:JSON" json:"httpHeaders" table:"verbose"` + Provider string `json:"provider"` + PricePerGBEpoch float64 `json:"pricePerGbEpoch" table:"verbose"` + PricePerGB float64 `json:"pricePerGb" table:"verbose"` + PricePerDeal float64 `json:"pricePerDeal" table:"verbose"` + TotalDealNumber int `json:"totalDealNumber" table:"verbose"` + TotalDealSize int64 `json:"totalDealSize"` + Verified bool `json:"verified"` + KeepUnsealed bool `json:"keepUnsealed" table:"verbose"` + AnnounceToIPNI bool `gorm:"column:announce_to_ipni" json:"announceToIpni" table:"verbose"` + StartDelay time.Duration `json:"startDelay" swaggertype:"primitive,integer"` + Duration time.Duration `json:"duration" swaggertype:"primitive,integer"` + State ScheduleState `json:"state"` + ScheduleCron string `json:"scheduleCron"` + ScheduleCronPerpetual bool `json:"scheduleCronPerpetual"` + ScheduleDealNumber int `json:"scheduleDealNumber"` + ScheduleDealSize int64 `json:"scheduleDealSize"` + MaxPendingDealNumber int `json:"maxPendingDealNumber"` + MaxPendingDealSize int64 `json:"maxPendingDealSize"` + Notes string `json:"notes"` + ErrorMessage string `json:"errorMessage" table:"verbose"` + AllowedPieceCIDs StringSlice `gorm:"type:JSON;column:allowed_piece_cids" json:"allowedPieceCids" table:"verbose"` + Force bool `json:"force"` + PreparationID PreparationID `json:"preparationId"` + Preparation *Preparation `gorm:"foreignKey:PreparationID;constraint:OnDelete:CASCADE" json:"preparation,omitempty" swaggerignore:"true" table:"expand"` +} +type DealState string +type DealID uint64 +type Deal struct { + ID DealID `gorm:"primaryKey" json:"id" table:"verbose"` + CreatedAt time.Time `json:"createdAt" table:"verbose;format:2006-01-02 15:04:05"` + UpdatedAt time.Time `json:"updatedAt" table:"verbose;format:2006-01-02 15:04:05"` + LastVerifiedAt *time.Time `json:"lastVerifiedAt" table:"verbose;format:2006-01-02 15:04:05"` // LastVerifiedAt is the last time the deal was verified as active by the tracker + DealID *uint64 `gorm:"unique" json:"dealId"` + State DealState `gorm:"index:idx_pending" json:"state"` + Provider string `json:"provider"` + ProposalID string `json:"proposalId" table:"verbose"` + Label string `json:"label" table:"verbose"` + PieceCID CID `gorm:"column:piece_cid;index;size:255" json:"pieceCid" swaggertype:"string"` + PieceSize int64 `json:"pieceSize"` + StartEpoch int32 `json:"startEpoch"` + EndEpoch int32 `json:"endEpoch" table:"verbose"` + SectorStartEpoch int32 `json:"sectorStartEpoch" table:"verbose"` + Price string `json:"price"` + Verified bool `json:"verified"` + ErrorMessage string `json:"errorMessage" table:"verbose"` + ScheduleID *ScheduleID `json:"scheduleId" table:"verbose"` + Schedule *Schedule `gorm:"foreignKey:ScheduleID;constraint:OnDelete:SET NULL" json:"schedule,omitempty" swaggerignore:"true" table:"expand"` + ClientID string `gorm:"index:idx_pending" json:"clientId"` + Wallet *Wallet `gorm:"foreignKey:ClientID;constraint:OnDelete:SET NULL" json:"wallet,omitempty" swaggerignore:"true" table:"expand"` +} +type OutputAttachment struct { + ID uint32 `gorm:"primaryKey"` + PreparationID PreparationID + StorageID StorageID +} +type SourceAttachment struct { + ID uint32 `gorm:"primaryKey"` + PreparationID PreparationID + StorageID StorageID +} +type Job struct { + ID uint32 `gorm:"primaryKey"` + PreparationID PreparationID + Status string + CreatedAt time.Time +} +type File struct { + ID uint32 `gorm:"primaryKey"` + Path string + Size int64 + ModifiedAt time.Time +} +type FileRange struct { + ID uint32 `gorm:"primaryKey"` + FileID uint32 + Offset int64 + Length int64 +} +type Directory struct { + ID uint32 `gorm:"primaryKey"` + Path string + Size int64 +} +type Car struct { + ID uint32 `gorm:"primaryKey"` + RootCID CID + Size int64 +} +type CarBlock struct { + ID uint32 `gorm:"primaryKey"` + CarID uint32 + CID CID + Size int64 +} + +// Create migration for initial database schema +func _202505010830_initial_schema() *gormigrate.Migration { + var InitTables = []any{ + &Worker{}, + &Global{}, + &Preparation{}, + &Storage{}, + &OutputAttachment{}, + &SourceAttachment{}, + &Job{}, + &File{}, + &FileRange{}, + &Directory{}, + &Car{}, + &CarBlock{}, + &Deal{}, + &Schedule{}, + &Wallet{}, + } + + return &gormigrate.Migration{ + ID: "202505010830", + Migrate: func(tx *gorm.DB) error { + // NOTE: this should match any existing database at the time of transition + // to versioned migration strategy + return tx.AutoMigrate(InitTables...) + }, + Rollback: func(tx *gorm.DB) error { + for _, table := range InitTables { + err := tx.Migrator().DropTable(table) + if err != nil { + return errors.Wrap(err, "failed to drop table") + } + } + return nil + }, + } +} diff --git a/migrate/migrations/202505010840_wallet_actor_id.go b/migrate/migrations/202505010840_wallet_actor_id.go new file mode 100644 index 00000000..46355584 --- /dev/null +++ b/migrate/migrations/202505010840_wallet_actor_id.go @@ -0,0 +1,103 @@ +package migrations + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" +) + +// Create migration for initial database schema +func _202505010840_wallet_actor_id() *gormigrate.Migration { + // Table name + const WALLET_TABLE_NAME = "wallets" + + // Temporary struct for old schema + type OldWallet struct { + ID string `gorm:"primaryKey;size:15" json:"id"` // ID is the short ID of the wallet + Address string `gorm:"index" json:"address"` // Address is the Filecoin full address of the wallet + PrivateKey string `json:"privateKey,omitempty" table:"-"` // PrivateKey is the private key of the wallet + } + + type WalletType string + const ( + UserWallet WalletType = "UserWallet" + SPWallet WalletType = "SPWallet" + ) + + // Temporary struct for new schema + type NewWallet struct { + ID uint `gorm:"primaryKey" json:"id"` + ActorID string `gorm:"index,size:15" json:"actorId"` // ActorID is the short ID of the wallet + ActorName string `json:"actorName"` // ActorName is readable label for the wallet + Address string `gorm:"index" json:"address"` // Address is the Filecoin full address of the wallet + Balance float64 `json:"balance"` // Balance is in Fil cached from chain + BalancePlus float64 `json:"balancePlus"` // BalancePlus is in Fil+ cached from chain + ContactInfo string `json:"contactInfo"` // ContactInfo is optional email for SP wallets + Location string `json:"location"` // Location is optional region, country for SP wallets + PrivateKey string `json:"privateKey,omitempty" table:"-"` // PrivateKey is the private key of the wallet + Type WalletType `json:"type"` // Type determines user or SP wallets + } + + return &gormigrate.Migration{ + ID: "202505010840", + Migrate: func(tx *gorm.DB) error { + // Create new table + err := tx.Migrator().CreateTable(&NewWallet{}) + if err != nil { + return err + } + + // Copy data from old to new table + var oldWallets []OldWallet + if err := tx.Table(WALLET_TABLE_NAME).Find(&oldWallets).Error; err != nil { + return err + } + + for _, oldWallet := range oldWallets { + newWallet := NewWallet{ + ActorID: oldWallet.ID, + Address: oldWallet.Address, + PrivateKey: oldWallet.PrivateKey, + } + if err := tx.Create(&newWallet).Error; err != nil { + return err + } + } + + // Drop old table and rename new table + if err := tx.Migrator().DropTable(WALLET_TABLE_NAME); err != nil { + return err + } + return tx.Migrator().RenameTable(&NewWallet{}, WALLET_TABLE_NAME) + }, + Rollback: func(tx *gorm.DB) error { + // Create old table + err := tx.Migrator().CreateTable(&OldWallet{}) + if err != nil { + return err + } + + // Copy data from new to old table + var newWallets []NewWallet + if err := tx.Table(WALLET_TABLE_NAME).Find(&newWallets).Error; err != nil { + return err + } + + for _, newWallet := range newWallets { + oldWallet := OldWallet{ + ID: newWallet.ActorID, + Address: newWallet.Address, + PrivateKey: newWallet.PrivateKey, + } + if err := tx.Create(&oldWallet).Error; err != nil { + return err + } + } + + // Drop new table and rename old table + if err := tx.Migrator().DropTable(WALLET_TABLE_NAME); err != nil { + return err + } + return tx.Migrator().RenameTable(&OldWallet{}, WALLET_TABLE_NAME) + }, + } +} diff --git a/migrate/migrations/migrations.go b/migrate/migrations/migrations.go new file mode 100644 index 00000000..8931f781 --- /dev/null +++ b/migrate/migrations/migrations.go @@ -0,0 +1,13 @@ +package migrations + +import ( + "github.com/go-gormigrate/gormigrate/v2" +) + +// Get collection of all migrations in order +func GetMigrations() []*gormigrate.Migration { + return []*gormigrate.Migration{ + _202505010830_initial_schema(), + _202505010840_wallet_actor_id(), + } +} diff --git a/model/basetypes.go b/model/basetypes.go index c6936ce0..05796234 100644 --- a/model/basetypes.go +++ b/model/basetypes.go @@ -10,7 +10,7 @@ import ( "github.com/cockroachdb/errors" "github.com/ipfs/go-cid" - "golang.org/x/exp/slices" + "slices" ) var ErrInvalidCIDEntry = errors.New("invalid CID entry in the database") diff --git a/model/migrate.go b/model/migrate.go index b2953c42..ce44ba80 100644 --- a/model/migrate.go +++ b/model/migrate.go @@ -3,8 +3,11 @@ package model import ( "crypto/rand" "encoding/base64" + "fmt" "github.com/cockroachdb/errors" + "github.com/data-preservation-programs/singularity/migrate/migrations" + "github.com/go-gormigrate/gormigrate/v2" "github.com/google/uuid" logging "github.com/ipfs/go-log/v2" "gorm.io/gorm" @@ -31,78 +34,161 @@ var Tables = []any{ var logger = logging.Logger("model") -// AutoMigrate attempts to automatically migrate the database schema. +// Options for gormigrate instance +var options = &gormigrate.Options{ + TableName: "migrations", + IDColumnName: "id", + IDColumnSize: 255, + UseTransaction: false, + ValidateUnknownMigrations: false, +} + +// NOTE: this NEEDS to match the values in MigrationOptions above // -// This function performs a few operations: -// 1. Automatically migrates the tables in the database to match the structures defined in the application. -// 2. Creates an instance ID if it doesn't already exist. -// 3. Generates a new encryption salt and stores it in the database if it doesn't already exist. +// type struct { +// ID string `gorm:"primaryKey;column:;size:"` +// } +type migration struct { + ID string `gorm:"primaryKey;column:id;size:255"` +} + +// Handle initializing any database if no migrations are found // -// The purpose of the auto-migration feature is to simplify schema changes and manage -// basic system configurations without manually altering the database. This is especially -// useful during development or when deploying updates that include schema changes. +// In the case of existing database: +// 1. Migrations table is created and first migration is inserted, which should match the existing, if outdated, data +// 2. Any remaining migrations are run // -// Parameters: -// - db: A pointer to a gorm.DB object, which provides database access. -// -// Returns: -// - An error if any issues arise during the process, otherwise nil. -func AutoMigrate(db *gorm.DB) error { - logger.Info("Auto migrating tables") - err := db.AutoMigrate(Tables...) - if err != nil { - return errors.Wrap(err, "failed to auto migrate") - } +// In the case of a new database: +// 1. Automatically migrates the tables in the database to match the current structures defined in the application. +// 2. Creates an instance ID if it doesn't already exist. +// 3. Generates a new encryption salt and stores it in the database if it doesn't already exist. +func _init(db *gorm.DB) error { + logger.Info("Initializing database") - logger.Debug("Creating instance id") - err = db.Clauses(clause.OnConflict{ - DoNothing: true, - }).Create(&Global{Key: "instance_id", Value: uuid.NewString()}).Error - if err != nil { - return errors.Wrap(err, "failed to create instance id") + // If this is an existing database before versioned migration strategy was implemented + if db.Migrator().HasTable("wallets") && !db.Migrator().HasColumn("wallets", "actor_id") { + // NOTE: We're going to have to recreate some internals of Gormigrate. It would be cleaner + // to use them directly but they're private methods. The general idea is to run all the + // migration functions _except_ the first which is hopefully the state of the database + // when they were on the older automigrate strategy. + logger.Info("Manually creating versioned migration table in existing database") + + // Create migrations table + err := db.Table(options.TableName).AutoMigrate(&migration{}) + if err != nil { + return errors.Wrap(err, "failed to create migrations table on init") + } + + logger.Info("Manually running missing migrations") + // Skip first migration, run the rest to get current + for _, m := range migrations.GetMigrations()[1:] { + err = m.Migrate(db) + if err != nil { + return errors.Wrap(err, fmt.Sprintf("failed to run migration with ID: %s", m.ID)) + } + } + } else { + logger.Info("Auto migrating tables in clean database") + // This is a brand new database, run automigrate script on current schema + err := db.AutoMigrate(Tables...) + if err != nil { + return errors.Wrap(err, "failed to auto migrate") + } + + logger.Debug("Creating instance id") + err = db.Clauses(clause.OnConflict{ + DoNothing: true, + }).Create(&Global{Key: "instance_id", Value: uuid.NewString()}).Error + if err != nil { + return errors.Wrap(err, "failed to create instance id") + } + + salt := make([]byte, 8) + _, err = rand.Read(salt) + if err != nil { + return errors.Wrap(err, "failed to generate salt") + } + encoded := base64.StdEncoding.EncodeToString(salt) + row := Global{ + Key: "salt", + Value: encoded, + } + + logger.Debug("Creating encryption salt") + err = db.Clauses(clause.OnConflict{ + DoNothing: true, + }).Create(row).Error + if err != nil { + return errors.Wrap(err, "failed to create salt") + } } - salt := make([]byte, 8) - _, err = rand.Read(salt) + return nil +} + +type migrator struct { + gormigrate.Gormigrate + db *gorm.DB + Options gormigrate.Options +} + +// Drop all current database tables +func (m *migrator) DropAll() error { + tables, err := m.db.Migrator().GetTables() if err != nil { - return errors.Wrap(err, "failed to generate salt") + return errors.Wrap(err, "Failed to get tables") } - encoded := base64.StdEncoding.EncodeToString(salt) - row := Global{ - Key: "salt", - Value: encoded, + for _, t := range tables { + err = m.db.Migrator().DropTable(t) + if err != nil { + return errors.Wrap(err, "Failed to drop all tables") + } } + return nil +} - logger.Debug("Creating encryption salt") - err = db.Clauses(clause.OnConflict{ - DoNothing: true, - }).Create(row).Error +// Get all migrations run +func (m *migrator) GetMigrationsRun() ([]migration, error) { + var migrations []migration + err := m.db.Find(&migrations).Error if err != nil { - return errors.Wrap(err, "failed to create salt") + return nil, err } + return migrations, nil +} - return nil +// Get ID of last migration ran +func (m *migrator) GetLastMigration() (string, error) { + migrations, err := m.GetMigrationsRun() + if len(migrations) == 0 || err != nil { + return "", err + } + return migrations[len(migrations)-1].ID, nil } -// DropAll removes all tables specified in the Tables slice from the database. -// -// This function is typically used during development or testing where a clean database -// slate is required. It iterates over the predefined Tables list and drops each table. -// Care should be taken when using this function in production environments as it will -// result in data loss. +// Has migration ID ran +func (m *migrator) HasRunMigration(id string) (bool, error) { + var count int64 + err := m.db.Table(m.Options.TableName).Where(fmt.Sprintf("%s = ?", m.Options.IDColumnName), id).Count(&count).Error + return count > 0, err +} + +// Setup new Gormigrate instance // // Parameters: // - db: A pointer to a gorm.DB object, which provides database access. // // Returns: -// - An error if any issues arise during the table drop process, otherwise nil. -func DropAll(db *gorm.DB) error { - logger.Info("Dropping all tables") - for _, table := range Tables { - err := db.Migrator().DropTable(table) - if err != nil { - return errors.Wrap(err, "failed to drop table") - } +// - A migration interface +func GetMigrator(db *gorm.DB) *migrator { + g := gormigrate.New(db, options, migrations.GetMigrations()) + + // Initialize database with current schema if no previous migrations are found + g.InitSchema(_init) + + return &migrator{ + *g, + db, + *options, } - return nil } diff --git a/model/replication.go b/model/replication.go index 4bcada94..b8edc550 100644 --- a/model/replication.go +++ b/model/replication.go @@ -141,8 +141,22 @@ type Schedule struct { Preparation *Preparation `gorm:"foreignKey:PreparationID;constraint:OnDelete:CASCADE" json:"preparation,omitempty" swaggerignore:"true" table:"expand"` } +type WalletType string + +const ( + UserWallet WalletType = "UserWallet" + SPWallet WalletType = "SPWallet" +) + type Wallet struct { - ID string `gorm:"primaryKey;size:15" json:"id"` // ID is the short ID of the wallet - Address string `gorm:"index" json:"address"` // Address is the Filecoin full address of the wallet - PrivateKey string `json:"privateKey,omitempty" table:"-"` // PrivateKey is the private key of the wallet + ID uint `gorm:"primaryKey" json:"id"` + ActorID string `gorm:"index,size:15" json:"actorId"` // ActorID is the short ID of the wallet + ActorName string `json:"actorName"` // ActorName is readable label for the wallet + Address string `gorm:"index" json:"address"` // Address is the Filecoin full address of the wallet + Balance float64 `json:"balance"` // Balance is in Fil cached from chain + BalancePlus float64 `json:"balancePlus"` // BalancePlus is in Fil+ cached from chain + ContactInfo string `json:"contactInfo"` // ContactInfo is optional email for SP wallets + Location string `json:"location"` // Location is optional region, country for SP wallets + PrivateKey string `json:"privateKey,omitempty" table:"-"` // PrivateKey is the private key of the wallet + Type WalletType `json:"type"` // Type determines user or SP wallets } diff --git a/replication/makedeal.go b/replication/makedeal.go index 91ac9636..6b124060 100644 --- a/replication/makedeal.go +++ b/replication/makedeal.go @@ -8,6 +8,8 @@ import ( "strings" "time" + "slices" + "github.com/cockroachdb/errors" "github.com/data-preservation-programs/singularity/analytics" "github.com/data-preservation-programs/singularity/model" @@ -30,7 +32,6 @@ import ( "github.com/libp2p/go-libp2p/core/protocol" "github.com/multiformats/go-multiaddr" "github.com/ybbus/jsonrpc/v3" - "golang.org/x/exp/slices" ) const ( @@ -589,7 +590,7 @@ func (d DealMakerImpl) MakeDeal(ctx context.Context, walletObj model.Wallet, dealModel := &model.Deal{ State: model.DealProposed, - ClientID: walletObj.ID, + ClientID: walletObj.ActorID, Provider: dealConfig.Provider, Label: cid.Cid(car.RootCID).String(), PieceCID: car.PieceCID, diff --git a/replication/makedeal_test.go b/replication/makedeal_test.go index b1496c2f..81ca77ee 100644 --- a/replication/makedeal_test.go +++ b/replication/makedeal_test.go @@ -116,7 +116,7 @@ func TestDealMaker_MakeDeal(t *testing.T) { maker := NewDealMaker(nil, client, time.Hour, time.Second) defer maker.Close() wallet := model.Wallet{ - ID: "f047684", + ActorID: "f047684", Address: addr, PrivateKey: key, } diff --git a/replication/wallet_test.go b/replication/wallet_test.go index cc41d3d9..ce20a96f 100644 --- a/replication/wallet_test.go +++ b/replication/wallet_test.go @@ -48,10 +48,10 @@ func TestDatacapWalletChooser_Choose(t *testing.T) { // Set up the test data wallets := []model.Wallet{ - {ID: "1", Address: "address1"}, - {ID: "2", Address: "address2"}, - {ID: "3", Address: "address3"}, - {ID: "4", Address: "address4"}, + {ActorID: "1", Address: "address1"}, + {ActorID: "2", Address: "address2"}, + {ActorID: "3", Address: "address3"}, + {ActorID: "4", Address: "address4"}, } // Set up expectations for the lotusClient mock @@ -111,8 +111,8 @@ func TestRandomWalletChooser(t *testing.T) { chooser := &RandomWalletChooser{} ctx := context.Background() wallet, err := chooser.Choose(ctx, []model.Wallet{ - {ID: "1", Address: "address1"}, - {ID: "2", Address: "address2"}, + {ActorID: "1", Address: "address1"}, + {ActorID: "2", Address: "address2"}, }) require.NoError(t, err) require.Contains(t, wallet.Address, "address") diff --git a/retriever/endpointfinder/endpointfinder.go b/retriever/endpointfinder/endpointfinder.go index 09d2e399..3d591779 100644 --- a/retriever/endpointfinder/endpointfinder.go +++ b/retriever/endpointfinder/endpointfinder.go @@ -118,7 +118,7 @@ func (ef *EndpointFinder) FindHTTPEndpoints(ctx context.Context, sps []string) ( } } - for i := 0; i < toLookup; i++ { + for range toLookup { select { case providerAddrs := <-addrChan: if providerAddrs.addrs != nil { diff --git a/retriever/retriever.go b/retriever/retriever.go index e534ad5c..407e1ca2 100644 --- a/retriever/retriever.go +++ b/retriever/retriever.go @@ -101,7 +101,7 @@ func (r *Retriever) Retrieve(ctx context.Context, c cid.Cid, rangeStart int64, r // collect errors var err error - for i := 0; i < 2; i++ { + for range 2 { select { case <-ctx.Done(): return ctx.Err() diff --git a/service/contentprovider/http.go b/service/contentprovider/http.go index c3291cea..43c190b7 100644 --- a/service/contentprovider/http.go +++ b/service/contentprovider/http.go @@ -200,7 +200,7 @@ func GetMetadataHandler(c echo.Context, db *gorm.DB) error { metadata, err := getPieceMetadata(ctx, db, car) if err != nil { - return c.String(http.StatusInternalServerError, fmt.Sprintf("Error: %s", err.Error())) + return c.String(http.StatusInternalServerError, "Error: "+err.Error()) } // Remove all credentials diff --git a/service/datasetworker/datasetworker.go b/service/datasetworker/datasetworker.go index 6e3e6ad4..f4774c2e 100644 --- a/service/datasetworker/datasetworker.go +++ b/service/datasetworker/datasetworker.go @@ -175,7 +175,7 @@ func (w Worker) Run(ctx context.Context) error { }() threads := make([]service.Server, w.config.Concurrency) - for i := 0; i < w.config.Concurrency; i++ { + for i := range w.config.Concurrency { id := uuid.New() thread := &Thread{ id: id, diff --git a/service/dealpusher/dealpusher_test.go b/service/dealpusher/dealpusher_test.go index 909d5ec4..12e77d9c 100644 --- a/service/dealpusher/dealpusher_test.go +++ b/service/dealpusher/dealpusher_test.go @@ -41,7 +41,7 @@ func (m *MockDealMaker) MakeDeal(ctx context.Context, walletObj model.Wallet, ca deal.ID = 0 deal.PieceCID = car.PieceCID deal.PieceSize = car.PieceSize - deal.ClientID = walletObj.ID + deal.ClientID = walletObj.ActorID deal.Provider = dealConfig.Provider deal.Verified = dealConfig.Verified deal.ProposalID = uuid.NewString() @@ -112,7 +112,7 @@ func TestDealMakerService_FailtoSend(t *testing.T) { SourceStorages: []model.Storage{{}}, Wallets: []model.Wallet{ { - ID: client, Address: "f0xx", + ActorID: client, Address: "f0xx", }, }}, State: model.ScheduleActive, @@ -168,7 +168,7 @@ func TestDealMakerService_Cron(t *testing.T) { SourceStorages: []model.Storage{{}}, Wallets: []model.Wallet{ { - ID: client, Address: "f0xx", + ActorID: client, Address: "f0xx", }, }}, State: model.ScheduleActive, @@ -263,7 +263,7 @@ func TestDealMakerService_ScheduleWithConstraints(t *testing.T) { SourceStorages: []model.Storage{{}}, Wallets: []model.Wallet{ { - ID: client, Address: "f0xx", + ActorID: client, Address: "f0xx", }, }}, State: model.ScheduleActive, @@ -372,7 +372,7 @@ func TestDealmakerService_Force(t *testing.T) { Preparation: &model.Preparation{ Wallets: []model.Wallet{ { - ID: client, Address: "f0xx", + ActorID: client, Address: "f0xx", }, }, SourceStorages: []model.Storage{{}}, @@ -431,7 +431,7 @@ func TestDealMakerService_MaxReplica(t *testing.T) { Preparation: &model.Preparation{ Wallets: []model.Wallet{ { - ID: client, Address: "f0xx", + ActorID: client, Address: "f0xx", }, }, SourceStorages: []model.Storage{{}}, @@ -497,7 +497,7 @@ func TestDealMakerService_NewScheduleOneOff(t *testing.T) { Preparation: &model.Preparation{ Wallets: []model.Wallet{ { - ID: client, Address: "f0xx", + ActorID: client, Address: "f0xx", }, }, SourceStorages: []model.Storage{{}}, diff --git a/service/dealtracker/dealtracker.go b/service/dealtracker/dealtracker.go index e146d339..d288f2e6 100644 --- a/service/dealtracker/dealtracker.go +++ b/service/dealtracker/dealtracker.go @@ -430,7 +430,7 @@ func (d *DealTracker) runOnce(ctx context.Context) error { walletIDs := make(map[string]struct{}) for _, wallet := range wallets { Logger.Infof("tracking deals for wallet %s", wallet.ID) - walletIDs[wallet.ID] = struct{}{} + walletIDs[wallet.ActorID] = struct{}{} } knownDeals := make(map[uint64]model.DealState) diff --git a/service/dealtracker/dealtracker_test.go b/service/dealtracker/dealtracker_test.go index eb2444d9..e4b77301 100644 --- a/service/dealtracker/dealtracker_test.go +++ b/service/dealtracker/dealtracker_test.go @@ -152,7 +152,7 @@ func TestTrackDeal(t *testing.T) { func TestRunOnce(t *testing.T) { testutil.All(t, func(ctx context.Context, t *testing.T, db *gorm.DB) { err := db.Create(&model.Wallet{ - ID: "t0100", + ActorID: "t0100", Address: "t3xxx", }).Error require.NoError(t, err) diff --git a/storagesystem/rclone.go b/storagesystem/rclone.go index c3913b94..56998eaf 100644 --- a/storagesystem/rclone.go +++ b/storagesystem/rclone.go @@ -95,7 +95,6 @@ func (h RCloneHandler) scan(ctx context.Context, path string, ch chan<- Entry, w var subCount int for _, entry := range entries { - entry := entry switch v := entry.(type) { case fs.Directory: select { diff --git a/storagesystem/types.go b/storagesystem/types.go index 050b031b..f31afbac 100644 --- a/storagesystem/types.go +++ b/storagesystem/types.go @@ -54,7 +54,7 @@ import ( "github.com/rclone/rclone/lib/encoder" "github.com/rjNemo/underscore" "github.com/urfave/cli/v2" - "golang.org/x/exp/slices" + "slices" ) // Entry is a struct that represents a single file or directory during a data source scan. diff --git a/store/piece_store.go b/store/piece_store.go index e111de14..fe725152 100644 --- a/store/piece_store.go +++ b/store/piece_store.go @@ -177,7 +177,7 @@ func NewPieceReader( return nil, errors.Wrapf(ErrInvalidEndOffset, "expected %d, got %d", car.FileSize, lastBlock.CarOffset+int64(lastBlock.CarBlockLength)) } - for i := 0; i < len(carBlocks); i++ { + for i := range carBlocks { if i != len(carBlocks)-1 { if carBlocks[i].CarOffset+int64(carBlocks[i].CarBlockLength) != carBlocks[i+1].CarOffset { return nil, errors.Wrapf(ErrIncontiguousBlocks, "previous offset %d, next offset %d", carBlocks[i].CarOffset+int64(carBlocks[i].CarBlockLength), carBlocks[i+1].CarOffset) diff --git a/testdb/main.go b/testdb/main.go index a4cb1d28..be4909a6 100644 --- a/testdb/main.go +++ b/testdb/main.go @@ -42,12 +42,12 @@ func run() error { return errors.WithStack(err) } defer closer.Close() - err = model.DropAll(db) + err = model.GetMigrator(db).DropAll() if err != nil { return errors.WithStack(err) } - err = model.AutoMigrate(db) + err = model.GetMigrator(db).Migrate() if err != nil { return errors.WithStack(err) } @@ -76,7 +76,7 @@ func createPreparation(ctx context.Context, db *gorm.DB) error { } // Setup wallet wallet := model.Wallet{ - ID: fmt.Sprintf("f0%d", r.Intn(10000)), + ActorID: fmt.Sprintf("f0%d", r.Intn(10000)), Address: "f1" + randomLetterString(39), } @@ -138,7 +138,7 @@ func createPreparation(ctx context.Context, db *gorm.DB) error { } var files []model.File - for i := 0; i < r.Intn(10_000); i++ { + for i := range r.Intn(10_000) { size := r.Int63n(1 << 20) rCID := randomCID() files = append(files, model.File{ @@ -185,7 +185,7 @@ func createPreparation(ctx context.Context, db *gorm.DB) error { FileRanges: nil, } - for i := 0; i < 100; i++ { + for i := range 100 { largeFile.FileRanges = append(largeFile.FileRanges, model.FileRange{ Offset: int64(i << 34), Length: 1 << 34, @@ -203,7 +203,7 @@ func createPreparation(ctx context.Context, db *gorm.DB) error { } // Setup a file with multiple versions - for i := 0; i < 10; i++ { + for range 10 { size := r.Int63n(1 << 20) rCID := randomCID() err = db.Create(&model.File{ @@ -258,7 +258,7 @@ func createPreparation(ctx context.Context, db *gorm.DB) error { } // Some Car files without association with the preparation - for i := 0; i < 5; i++ { + for range 5 { pieceCID, err := randomPieceCID() if err != nil { return errors.WithStack(err) @@ -339,7 +339,7 @@ func createPreparation(ctx context.Context, db *gorm.DB) error { Price: "0", Verified: true, ScheduleID: ptr.Of(schedule.ID), - ClientID: wallet.ID, + ClientID: wallet.ActorID, } if state == model.DealActive { deal.SectorStartEpoch = int32(10000 + r.Intn(10000)) diff --git a/util/testutil/testutils.go b/util/testutil/testutils.go index 6195979a..c7749aa6 100644 --- a/util/testutil/testutils.go +++ b/util/testutil/testutils.go @@ -26,7 +26,7 @@ const pattern = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" func GenerateFixedBytes(length int) []byte { patternLen := len(pattern) result := make([]byte, length) - for i := 0; i < length; i++ { + for i := range length { result[i] = pattern[i%patternLen] } return result @@ -145,7 +145,7 @@ func doOne(t *testing.T, backend string, testFunc func(ctx context.Context, t *t defer cancel() db = db.WithContext(ctx) - err := model.AutoMigrate(db) + err := model.GetMigrator(db).Migrate() require.NoError(t, err) t.Run(backend, func(t *testing.T) {