diff --git a/docs/api/README.md b/docs/api/README.md index 9d87f9b890..d364eb1eaa 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -514,7 +514,8 @@ Accept: application/json "property2": { "admin": "true" } - } + }, + "force": true } } ] @@ -1329,7 +1330,8 @@ Idempotency-Key: string "property2": { "admin": "true" } - } + }, + "force": true } ``` @@ -2721,7 +2723,8 @@ Authorization ( Scopes: ledger:write ) "property2": { "admin": "true" } - } + }, + "force": true } ``` @@ -2741,6 +2744,7 @@ Authorization ( Scopes: ledger:write ) |metadata|[V2Metadata](#schemav2metadata)|true|none|none| |accountMetadata|object|false|none|none| |ยป **additionalProperties**|[V2Metadata](#schemav2metadata)|false|none|none| +|force|boolean|false|none|none| #### Enumerated Values @@ -3443,7 +3447,8 @@ Authorization ( Scopes: ledger:write ) "property2": { "admin": "true" } - } + }, + "force": true } } ] @@ -3517,7 +3522,8 @@ Authorization ( Scopes: ledger:write ) "property2": { "admin": "true" } - } + }, + "force": true } } @@ -3588,7 +3594,8 @@ xor "property2": { "admin": "true" } - } + }, + "force": true } } diff --git a/internal/api/bulking/bulker.go b/internal/api/bulking/bulker.go index 5bb623e4a7..beb5a6b788 100644 --- a/internal/api/bulking/bulker.go +++ b/internal/api/bulking/bulker.go @@ -127,7 +127,7 @@ func (b *Bulker) processElement(ctx context.Context, ctrl ledgercontroller.Contr switch data.Action { case ActionCreateTransaction: - rs, err := data.Data.(TransactionRequest).ToCore(false) + rs, err := data.Data.(TransactionRequest).ToCore() if err != nil { return nil, 0, fmt.Errorf("error parsing element: %s", err) } diff --git a/internal/api/bulking/elements.go b/internal/api/bulking/elements.go index e3fbea176c..44543bcb07 100644 --- a/internal/api/bulking/elements.go +++ b/internal/api/bulking/elements.go @@ -102,9 +102,10 @@ type TransactionRequest struct { Metadata metadata.Metadata `json:"metadata" swaggertype:"object"` AccountMetadata map[string]metadata.Metadata `json:"accountMetadata"` Runtime ledgercontroller.RuntimeType `json:"runtime,omitempty"` + Force bool `json:"force"` } -func (req TransactionRequest) ToCore(allowUnboundedOverdrafts bool) (*ledgercontroller.CreateTransaction, error) { +func (req TransactionRequest) ToCore() (*ledgercontroller.CreateTransaction, error) { if _, err := req.Postings.Validate(); err != nil { return nil, err @@ -119,7 +120,7 @@ func (req TransactionRequest) ToCore(allowUnboundedOverdrafts bool) (*ledgercont Metadata: req.Metadata, } - runScript = ledgercontroller.TxToScriptData(txData, allowUnboundedOverdrafts) + runScript = ledgercontroller.TxToScriptData(txData, req.Force) } else { runScript = ledgercontroller.RunScript{ Script: req.Script.ToCore(), diff --git a/internal/api/v2/controllers_transactions_create.go b/internal/api/v2/controllers_transactions_create.go index 013f188825..f245b06f54 100644 --- a/internal/api/v2/controllers_transactions_create.go +++ b/internal/api/v2/controllers_transactions_create.go @@ -33,7 +33,14 @@ func createTransaction(w http.ResponseWriter, r *http.Request) { api.BadRequest(w, common.ErrNoPostings, errors.New("you need to pass either a posting array or a numscript script")) return } - createTransaction, err := payload.ToCore(api.QueryParamBool(r, "force")) + + // nodes(gfyrag): parameter 'force' initially sent using a query param + // while we still support the feature, we can also send the 'force' parameter + // in the request payload. + // it allows to leverage the feature on bulk endpoint + payload.Force = payload.Force || api.QueryParamBool(r, "force") + + createTransaction, err := payload.ToCore() if err != nil { api.BadRequest(w, common.ErrValidation, err) return diff --git a/openapi.yaml b/openapi.yaml index 23d751dea4..d46a5701cc 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -2077,6 +2077,7 @@ paths: - name: force in: query description: Disable balance checks when passing postings + deprecated: true schema: type: boolean example: true @@ -3499,6 +3500,8 @@ components: type: object additionalProperties: $ref: "#/components/schemas/V2Metadata" + force: + type: boolean V2Stats: type: object properties: diff --git a/openapi/v2.yaml b/openapi/v2.yaml index d64c698872..5ce569c812 100644 --- a/openapi/v2.yaml +++ b/openapi/v2.yaml @@ -818,6 +818,7 @@ paths: - name: force in: query description: Disable balance checks when passing postings + deprecated: true schema: type: boolean example: true @@ -1656,6 +1657,8 @@ components: type: object additionalProperties: $ref: "#/components/schemas/V2Metadata" + force: + type: boolean V2Stats: type: object properties: diff --git a/pkg/client/.speakeasy/gen.lock b/pkg/client/.speakeasy/gen.lock index 25da8bb7c8..d043908ca9 100644 --- a/pkg/client/.speakeasy/gen.lock +++ b/pkg/client/.speakeasy/gen.lock @@ -1,7 +1,7 @@ lockVersion: 2.0.0 id: a9ac79e1-e429-4ee3-96c4-ec973f19bec3 management: - docChecksum: aa90e15d37f175280618bd0108917475 + docChecksum: ce0c8826dc64a0dde9cb29984a1013d1 docVersion: v2 speakeasyVersion: 1.517.3 generationVersion: 2.548.6 diff --git a/pkg/client/docs/models/components/v2posttransaction.md b/pkg/client/docs/models/components/v2posttransaction.md index 4b71c03b7c..242b07ade8 100644 --- a/pkg/client/docs/models/components/v2posttransaction.md +++ b/pkg/client/docs/models/components/v2posttransaction.md @@ -11,4 +11,5 @@ | `Runtime` | [*components.Runtime](../../models/components/runtime.md) | :heavy_minus_sign: | The numscript runtime used to execute the script. Uses "machine" by default, unless the "--experimental-numscript-interpreter" feature flag is passed. | | | `Reference` | **string* | :heavy_minus_sign: | N/A | ref:001 | | `Metadata` | map[string]*string* | :heavy_check_mark: | N/A | {
"admin": "true"
} | -| `AccountMetadata` | map[string]map[string]*string* | :heavy_minus_sign: | N/A | | \ No newline at end of file +| `AccountMetadata` | map[string]map[string]*string* | :heavy_minus_sign: | N/A | | +| `Force` | **bool* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/pkg/client/docs/models/operations/v2createtransactionrequest.md b/pkg/client/docs/models/operations/v2createtransactionrequest.md index a3acbfe489..677a4c8d2f 100644 --- a/pkg/client/docs/models/operations/v2createtransactionrequest.md +++ b/pkg/client/docs/models/operations/v2createtransactionrequest.md @@ -8,5 +8,5 @@ | `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | | `DryRun` | **bool* | :heavy_minus_sign: | Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `IdempotencyKey` | **string* | :heavy_minus_sign: | Use an idempotency key | | -| `Force` | **bool* | :heavy_minus_sign: | Disable balance checks when passing postings | true | +| ~~`Force`~~ | **bool* | :heavy_minus_sign: | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Disable balance checks when passing postings | true | | `V2PostTransaction` | [components.V2PostTransaction](../../models/components/v2posttransaction.md) | :heavy_check_mark: | The request body must contain at least one of the following objects:
- `postings`: suitable for simple transactions
- `script`: enabling more complex transactions with Numscript
| | \ No newline at end of file diff --git a/pkg/client/models/components/v2posttransaction.go b/pkg/client/models/components/v2posttransaction.go index 1d22abbd8e..cbcd7e4532 100644 --- a/pkg/client/models/components/v2posttransaction.go +++ b/pkg/client/models/components/v2posttransaction.go @@ -64,6 +64,7 @@ type V2PostTransaction struct { Reference *string `json:"reference,omitempty"` Metadata map[string]string `json:"metadata"` AccountMetadata map[string]map[string]string `json:"accountMetadata,omitempty"` + Force *bool `json:"force,omitempty"` } func (v V2PostTransaction) MarshalJSON() ([]byte, error) { @@ -125,3 +126,10 @@ func (o *V2PostTransaction) GetAccountMetadata() map[string]map[string]string { } return o.AccountMetadata } + +func (o *V2PostTransaction) GetForce() *bool { + if o == nil { + return nil + } + return o.Force +} diff --git a/pkg/client/models/operations/v2createtransaction.go b/pkg/client/models/operations/v2createtransaction.go index 1494608d1a..1a8b5f2d22 100644 --- a/pkg/client/models/operations/v2createtransaction.go +++ b/pkg/client/models/operations/v2createtransaction.go @@ -14,6 +14,8 @@ type V2CreateTransactionRequest struct { // Use an idempotency key IdempotencyKey *string `header:"style=simple,explode=false,name=Idempotency-Key"` // Disable balance checks when passing postings + // + // Deprecated: This will be removed in a future release, please migrate away from it as soon as possible. Force *bool `queryParam:"style=form,explode=true,name=force"` // The request body must contain at least one of the following objects: // - `postings`: suitable for simple transactions diff --git a/test/e2e/api_bulk_test.go b/test/e2e/api_bulk_test.go index ed156e19ff..8e4393fd59 100644 --- a/test/e2e/api_bulk_test.go +++ b/test/e2e/api_bulk_test.go @@ -60,7 +60,30 @@ var _ = Context("Ledger engine tests", func() { Expect(err).To(BeNil()) _, events = Subscribe(specContext, testServer, natsURL) }) - When("creating a bulk on a ledger", func() { + When("creating a bulk on a ledger with force parameter", func() { + It("should be ok", func(specContext SpecContext) { + _, err := Wait(specContext, DeferClient(testServer)).Ledger.V2.CreateBulk(ctx, operations.V2CreateBulkRequest{ + RequestBody: []components.V2BulkElement{ + components.CreateV2BulkElementCreateTransaction(components.V2BulkElementCreateTransaction{ + Data: &components.V2PostTransaction{ + Metadata: map[string]string{}, + Postings: []components.V2Posting{{ + Amount: big.NewInt(100), + Asset: "USD/2", + Destination: "user:1", + Source: "user:2", + }}, + Timestamp: &now, + Force: pointer.For(true), + }, + }), + }, + Ledger: "default", + }) + Expect(err).To(Succeed()) + }) + }) + When("creating a valid bulk on a ledger", func() { var ( now = time.Now().Round(time.Microsecond).UTC() items []components.V2BulkElement