From 6e96daf08c0f1f755167b2fff1a73e37951c3999 Mon Sep 17 00:00:00 2001 From: ascandone Date: Wed, 2 Oct 2024 17:18:36 +0200 Subject: [PATCH] integrating numscript rewrite swapping the implementation update numscript dependency update numscript version trigger CI update numscript added feature flags and errors generated stuff more error handling run go mod tidy changed expected error codes run go mod tidy revert fix some tests run pre-commit --- cmd/serve.go | 9 +++- docs/api/README.md | 2 + go.mod | 7 ++- go.sum | 24 ++++++++- .../api/v2/controllers_transactions_create.go | 5 ++ internal/api/v2/errors.go | 3 ++ internal/controller/ledger/errors.go | 31 +++++++++++ internal/controller/ledger/machine.go | 52 +++++++++++++++++-- internal/controller/ledger/machine_factory.go | 19 ++++++- internal/controller/ledger/store.go | 40 ++++++++++++++ internal/controller/system/controller.go | 2 +- openapi.yaml | 2 + openapi/v2.yaml | 2 + pkg/client/.speakeasy/gen.lock | 6 +-- pkg/client/.speakeasy/gen.yaml | 2 +- .../docs/models/components/v2errorsenum.md | 30 ++++++----- pkg/client/formance.go | 4 +- pkg/client/models/components/v2errorsenum.go | 30 ++++++----- test/e2e/api_bulk.go | 2 +- test/e2e/api_transactions_create.go | 19 +++---- 20 files changed, 238 insertions(+), 53 deletions(-) diff --git a/cmd/serve.go b/cmd/serve.go index 0162c30ba..c7e28da6a 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -1,9 +1,12 @@ package cmd import ( + "time" + "github.com/formancehq/go-libs/pprof" "github.com/formancehq/ledger/internal/storage/driver" - "time" + + "github.com/formancehq/ledger/internal/bus" "github.com/formancehq/go-libs/auth" "github.com/formancehq/go-libs/aws/iam" @@ -13,7 +16,7 @@ import ( "github.com/formancehq/go-libs/otlp/otlptraces" "github.com/formancehq/go-libs/publish" "github.com/formancehq/ledger/internal/api" - "github.com/formancehq/ledger/internal/bus" + ledgercontroller "github.com/formancehq/ledger/internal/controller/ledger" systemcontroller "github.com/formancehq/ledger/internal/controller/system" "github.com/formancehq/ledger/internal/storage" @@ -34,6 +37,7 @@ const ( NumscriptCacheMaxCountFlag = "numscript-cache-max-count" AutoUpgradeFlag = "auto-upgrade" EnablePProfFlag = "enable-pprof" + NumscriptInterpreterFlag = "numscript-interpreter" ) func NewServeCommand() *cobra.Command { @@ -89,6 +93,7 @@ func NewServeCommand() *cobra.Command { cmd.Flags().Bool(AutoUpgradeFlag, false, "Automatically upgrade all schemas") cmd.Flags().String(BindFlag, "0.0.0.0:3068", "API bind address") cmd.Flags().Bool(EnablePProfFlag, false, "Enable pprof") + cmd.Flags().Bool(NumscriptInterpreterFlag, false, "Enable experimental numscript rewrite") service.AddFlags(cmd.Flags()) bunconnect.AddFlags(cmd.Flags()) diff --git a/docs/api/README.md b/docs/api/README.md index e74cd8e4a..4ede5d3ce 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -3185,6 +3185,8 @@ Authorization ( Scopes: ledger:write ) |*anonymous*|NO_POSTINGS| |*anonymous*|LEDGER_NOT_FOUND| |*anonymous*|IMPORT| +|*anonymous*|INTERPRETER_PARSE| +|*anonymous*|INTERPRETER_RUNTIME|

V2LedgerInfoResponse

diff --git a/go.mod b/go.mod index c3e8ac5ea..a40805e32 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/formancehq/ledger -go 1.22.0 +go 1.22.1 toolchain go1.22.7 @@ -14,12 +14,12 @@ require ( github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 github.com/bluele/gcache v0.0.2 github.com/formancehq/go-libs v1.7.2-0.20241011081325-92040b4fad01 + github.com/formancehq/numscript v0.0.9-0.20241009144012-1150c14a1417 github.com/formancehq/stack/ledger/client v0.0.0-00010101000000-000000000000 github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/cors v1.2.1 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 - github.com/grafana/otel-profiling-go v0.5.1 github.com/grafana/pyroscope-go/godeltaprof v0.1.8 github.com/invopop/jsonschema v0.12.0 github.com/jackc/pgx/v5 v5.7.1 @@ -57,6 +57,7 @@ require ( github.com/ThreeDotsLabs/watermill-kafka/v3 v3.0.5 // indirect github.com/ThreeDotsLabs/watermill-nats/v2 v2.1.1 // indirect github.com/ajg/form v1.5.1 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0 // indirect github.com/aws/aws-sdk-go-v2 v1.31.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.37 // indirect @@ -102,6 +103,7 @@ require ( github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/schema v1.4.1 // indirect github.com/gorilla/securecookie v1.1.2 // indirect + github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -185,6 +187,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.27.0 // indirect + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect diff --git a/go.sum b/go.sum index 9bb6c61d1..ab9f7c746 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs= github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI= github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0 h1:UyjtGmO0Uwl/K+zpzPwLoXzMhcN9xmnR2nrqJoBrg3c= github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0/go.mod h1:TJAXuFs2HcMib3sN5L0gUC+Q01Qvy3DemvA55WuC+iA= github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= @@ -93,12 +95,18 @@ github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs v1.7.2-0.20241001151743-2bd31525c7d1 h1:/Zo3e6njdSqIwi4nI038P2fTvzcfRQ6WaPmFzSI7s8o= -github.com/formancehq/go-libs v1.7.2-0.20241001151743-2bd31525c7d1/go.mod h1:oLMVltNsXmvqLA0Ox5NSwVSeH8gbnG2ZUo6Lchp23XU= github.com/formancehq/go-libs v1.7.2-0.20241011081325-92040b4fad01 h1:fRokKJe35GLMfva8ehQbLra3oQdUHdfi2mG72BaQlEk= github.com/formancehq/go-libs v1.7.2-0.20241011081325-92040b4fad01/go.mod h1:B/KB2mPjFqybLDZufMcZQKpXcHg8Va6JaoUWda1KGU4= +github.com/formancehq/numscript v0.0.9-0.20241009144012-1150c14a1417 h1:LOd5hxnXDIBcehFrpW1OnXk+VSs0yJXeu1iAOO+Hji4= +github.com/formancehq/numscript v0.0.9-0.20241009144012-1150c14a1417/go.mod h1:btuSv05cYwi9BvLRxVs5zrunU+O1vTgigG1T6UsawcY= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8= +github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= +github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= +github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= +github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKprRwT8= +github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= @@ -217,6 +225,8 @@ github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMD github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= +github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -305,6 +315,14 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= @@ -412,6 +430,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= diff --git a/internal/api/v2/controllers_transactions_create.go b/internal/api/v2/controllers_transactions_create.go index 1f31be015..bb7f5cc5f 100644 --- a/internal/api/v2/controllers_transactions_create.go +++ b/internal/api/v2/controllers_transactions_create.go @@ -7,6 +7,7 @@ import ( ledgercontroller "github.com/formancehq/ledger/internal/controller/ledger" "errors" + "github.com/formancehq/go-libs/api" "github.com/formancehq/ledger/internal/api/common" ) @@ -50,6 +51,10 @@ func createTransaction(w http.ResponseWriter, r *http.Request) { api.WriteErrorResponse(w, http.StatusConflict, ErrConflict, err) case errors.Is(err, ledgercontroller.ErrInvalidIdempotencyInput{}): api.BadRequest(w, ErrValidation, err) + case errors.Is(err, ledgercontroller.ErrParsing{}): + api.BadRequest(w, ErrInterpreterParse, err) + case errors.Is(err, ledgercontroller.ErrRuntime{}): + api.BadRequest(w, ErrInterpreterRuntime, err) default: common.HandleCommonErrors(w, r, err) } diff --git a/internal/api/v2/errors.go b/internal/api/v2/errors.go index b511a422b..df986123f 100644 --- a/internal/api/v2/errors.go +++ b/internal/api/v2/errors.go @@ -8,4 +8,7 @@ const ( ErrNoPostings = "NO_POSTINGS" ErrCompilationFailed = "COMPILATION_FAILED" ErrMetadataOverride = "METADATA_OVERRIDE" + + ErrInterpreterParse = "INTERPRETER_PARSE" + ErrInterpreterRuntime = "INTERPRETER_RUNTIME" ) diff --git a/internal/controller/ledger/errors.go b/internal/controller/ledger/errors.go index 112cd4675..96790accc 100644 --- a/internal/controller/ledger/errors.go +++ b/internal/controller/ledger/errors.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/formancehq/go-libs/platform/postgres" + "github.com/formancehq/numscript" "github.com/formancehq/ledger/internal/machine" @@ -187,6 +188,36 @@ func newErrCompilationFailed(err error) ErrCompilationFailed { } } +type ErrRuntime struct { + Source string + Inner numscript.InterpreterError +} + +func (e ErrRuntime) Error() string { + return e.Inner.Error() +} + +func (e ErrRuntime) Is(err error) bool { + _, ok := err.(ErrRuntime) + return ok +} + +type ErrParsing struct { + Source string + // Precondition: Errors is not empty + Errors []numscript.ParserError +} + +func (e ErrParsing) Error() string { + // TODO write a decent description + return "Got parsing errors" +} + +func (e ErrParsing) Is(err error) bool { + _, ok := err.(ErrParsing) + return ok +} + // ErrMetadataOverride is used when a metadata is defined at numscript level AND at the input level type ErrMetadataOverride struct { key string diff --git a/internal/controller/ledger/machine.go b/internal/controller/ledger/machine.go index adeb99556..a5e3a3e5e 100644 --- a/internal/controller/ledger/machine.go +++ b/internal/controller/ledger/machine.go @@ -4,15 +4,15 @@ import ( "context" "fmt" - "github.com/formancehq/ledger/internal/machine" - "errors" "github.com/formancehq/go-libs/collectionutils" "github.com/formancehq/go-libs/metadata" ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/machine" "github.com/formancehq/ledger/internal/machine/vm" "github.com/formancehq/ledger/internal/machine/vm/program" + "github.com/formancehq/numscript" ) type MachineResult struct { @@ -85,4 +85,50 @@ func NewDefaultMachine(p program.Program) *DefaultMachineAdapter { } } -var _ Machine = (*DefaultMachineAdapter)(nil) +// numscript rewrite implementation +var _ Machine = (*DefaultInterpreterMachineAdapter)(nil) + +type DefaultInterpreterMachineAdapter struct { + parseResult numscript.ParseResult +} + +func NewDefaultInterpreterMachineAdapter(parseResult numscript.ParseResult) *DefaultInterpreterMachineAdapter { + return &DefaultInterpreterMachineAdapter{ + parseResult: parseResult, + } +} + +func (d *DefaultInterpreterMachineAdapter) Execute(ctx context.Context, tx TX, vars map[string]string) (*MachineResult, error) { + execResult, err := d.parseResult.Run(ctx, vars, newNumscriptRewriteAdapter(tx)) + if err != nil { + return nil, ErrRuntime{ + Source: d.parseResult.GetSource(), + Inner: err, + } + } + + return &MachineResult{ + Postings: collectionutils.Map(execResult.Postings, func(posting numscript.Posting) ledger.Posting { + return ledger.Posting(posting) + }), + Metadata: castMetadata(execResult.Metadata), + AccountMetadata: castAccountsMetadata(execResult.AccountsMetadata), + }, nil +} + +func castMetadata(numscriptMeta numscript.Metadata) metadata.Metadata { + meta := metadata.Metadata{} + for k, v := range numscriptMeta { + meta[k] = v.String() + } + return meta +} + +func castAccountsMetadata(numscriptAccountsMetadata numscript.AccountsMetadata) map[string]metadata.Metadata { + m := make(map[string]metadata.Metadata) + for k, v := range numscriptAccountsMetadata { + m[k] = v + } + return m + +} diff --git a/internal/controller/ledger/machine_factory.go b/internal/controller/ledger/machine_factory.go index cc2729016..967cbe19e 100644 --- a/internal/controller/ledger/machine_factory.go +++ b/internal/controller/ledger/machine_factory.go @@ -1,7 +1,8 @@ package ledger -//go:generate mockgen -write_source_comment=false -write_package_comment=false -source machine_factory.go -destination machine_factory_generated_test.go -package ledger . MachineFactory +import "github.com/formancehq/numscript" +//go:generate mockgen -write_source_comment=false -write_package_comment=false -source machine_factory.go -destination machine_factory_generated_test.go -package ledger . MachineFactory type MachineFactory interface { // Make can return following errors: // * ErrCompilationFailed @@ -27,3 +28,19 @@ func NewDefaultMachineFactory(compiler Compiler) *DefaultMachineFactory { } var _ MachineFactory = (*DefaultMachineFactory)(nil) + +// numscript rewrite implementation +type DefaultInterpreterMachineFactory struct{} + +var _ MachineFactory = (*DefaultInterpreterMachineFactory)(nil) + +func (*DefaultInterpreterMachineFactory) Make(script string) (Machine, error) { + parseResult := numscript.Parse(script) + errs := parseResult.GetParsingErrors() + + if len(errs) != 0 { + return nil, ErrParsing{Source: script, Errors: errs} + } + + return NewDefaultInterpreterMachineAdapter(parseResult), nil +} diff --git a/internal/controller/ledger/store.go b/internal/controller/ledger/store.go index 6cc53cb29..176355ec2 100644 --- a/internal/controller/ledger/store.go +++ b/internal/controller/ledger/store.go @@ -7,6 +7,7 @@ import ( "math/big" "github.com/formancehq/go-libs/migrations" + "github.com/formancehq/numscript" "github.com/formancehq/go-libs/bun/bunpaginate" "github.com/formancehq/go-libs/metadata" @@ -297,3 +298,42 @@ func NewListLedgersQuery(pageSize uint64) ListLedgersQuery { PageSize: pageSize, } } + +// numscript rewrite implementation + +var _ numscript.Store = (*numscriptRewriteAdapter)(nil) + +func newNumscriptRewriteAdapter(tx TX) *numscriptRewriteAdapter { + return &numscriptRewriteAdapter{ + TX: tx, + } +} + +type numscriptRewriteAdapter struct { + TX TX +} + +func (s *numscriptRewriteAdapter) GetBalances(ctx context.Context, q numscript.BalanceQuery) (numscript.Balances, error) { + vmBalances, err := s.TX.GetBalances(ctx, BalanceQuery(q)) + if err != nil { + return nil, err + } + return numscript.Balances(vmBalances), nil +} + +func (s *numscriptRewriteAdapter) GetAccountsMetadata(ctx context.Context, q numscript.MetadataQuery) (numscript.AccountsMetadata, error) { + m := numscript.AccountsMetadata{} + + // we ignore the needed metadata values and just return all of them + for address := range q { + v, err := s.TX.GetAccount(ctx, GetAccountQuery{ + Addr: address, + }) + if err != nil { + return nil, err + } + m[v.Address] = v.Metadata + } + + return m, nil +} diff --git a/internal/controller/system/controller.go b/internal/controller/system/controller.go index cd76b88a5..5ebbe64c7 100644 --- a/internal/controller/system/controller.go +++ b/internal/controller/system/controller.go @@ -42,7 +42,7 @@ func (ctrl *DefaultController) GetLedgerController(ctx context.Context, name str var ledgerController ledgercontroller.Controller = ledgercontroller.NewDefaultController( *l, store, - ledgercontroller.NewDefaultMachineFactory(ctrl.compiler), + &ledgercontroller.DefaultInterpreterMachineFactory{}, ) // Add too many client error handling diff --git a/openapi.yaml b/openapi.yaml index 44b14252f..44096e866 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -3450,6 +3450,8 @@ components: - NO_POSTINGS - LEDGER_NOT_FOUND - IMPORT + - INTERPRETER_PARSE + - INTERPRETER_RUNTIME example: VALIDATION V2LedgerInfoResponse: type: object diff --git a/openapi/v2.yaml b/openapi/v2.yaml index 15afce7ca..9d966300f 100644 --- a/openapi/v2.yaml +++ b/openapi/v2.yaml @@ -1722,6 +1722,8 @@ components: - NO_POSTINGS - LEDGER_NOT_FOUND - IMPORT + - INTERPRETER_PARSE + - INTERPRETER_RUNTIME example: VALIDATION V2LedgerInfoResponse: type: object diff --git a/pkg/client/.speakeasy/gen.lock b/pkg/client/.speakeasy/gen.lock index 31fe3c481..e3774b38f 100644 --- a/pkg/client/.speakeasy/gen.lock +++ b/pkg/client/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: a9ac79e1-e429-4ee3-96c4-ec973f19bec3 management: - docChecksum: 46b920c97720c2cf24009a8029141b0e + docChecksum: 1708b60b71bd7dbe961267eb3fdf5738 docVersion: v1 speakeasyVersion: 1.351.0 generationVersion: 2.384.1 - releaseVersion: 0.4.10 - configChecksum: 80adc8750c319f7d5486bd5211882798 + releaseVersion: 0.4.11 + configChecksum: 38c0cdbdcbb13b59719f19b9ec2fcdaf features: go: additionalDependencies: 0.1.0 diff --git a/pkg/client/.speakeasy/gen.yaml b/pkg/client/.speakeasy/gen.yaml index df23cf750..a7630b3d1 100644 --- a/pkg/client/.speakeasy/gen.yaml +++ b/pkg/client/.speakeasy/gen.yaml @@ -15,7 +15,7 @@ generation: auth: oAuth2ClientCredentialsEnabled: true go: - version: 0.4.10 + version: 0.4.11 additionalDependencies: {} allowUnknownFieldsInWeakUnions: false clientServerStatusCodesAsErrors: true diff --git a/pkg/client/docs/models/components/v2errorsenum.md b/pkg/client/docs/models/components/v2errorsenum.md index 088a86b2a..903acc087 100644 --- a/pkg/client/docs/models/components/v2errorsenum.md +++ b/pkg/client/docs/models/components/v2errorsenum.md @@ -3,17 +3,19 @@ ## Values -| Name | Value | -| ------------------------------- | ------------------------------- | -| `V2ErrorsEnumInternal` | INTERNAL | -| `V2ErrorsEnumInsufficientFund` | INSUFFICIENT_FUND | -| `V2ErrorsEnumValidation` | VALIDATION | -| `V2ErrorsEnumConflict` | CONFLICT | -| `V2ErrorsEnumCompilationFailed` | COMPILATION_FAILED | -| `V2ErrorsEnumMetadataOverride` | METADATA_OVERRIDE | -| `V2ErrorsEnumNotFound` | NOT_FOUND | -| `V2ErrorsEnumRevertOccurring` | REVERT_OCCURRING | -| `V2ErrorsEnumAlreadyRevert` | ALREADY_REVERT | -| `V2ErrorsEnumNoPostings` | NO_POSTINGS | -| `V2ErrorsEnumLedgerNotFound` | LEDGER_NOT_FOUND | -| `V2ErrorsEnumImport` | IMPORT | \ No newline at end of file +| Name | Value | +| -------------------------------- | -------------------------------- | +| `V2ErrorsEnumInternal` | INTERNAL | +| `V2ErrorsEnumInsufficientFund` | INSUFFICIENT_FUND | +| `V2ErrorsEnumValidation` | VALIDATION | +| `V2ErrorsEnumConflict` | CONFLICT | +| `V2ErrorsEnumCompilationFailed` | COMPILATION_FAILED | +| `V2ErrorsEnumMetadataOverride` | METADATA_OVERRIDE | +| `V2ErrorsEnumNotFound` | NOT_FOUND | +| `V2ErrorsEnumRevertOccurring` | REVERT_OCCURRING | +| `V2ErrorsEnumAlreadyRevert` | ALREADY_REVERT | +| `V2ErrorsEnumNoPostings` | NO_POSTINGS | +| `V2ErrorsEnumLedgerNotFound` | LEDGER_NOT_FOUND | +| `V2ErrorsEnumImport` | IMPORT | +| `V2ErrorsEnumInterpreterParse` | INTERPRETER_PARSE | +| `V2ErrorsEnumInterpreterRuntime` | INTERPRETER_RUNTIME | \ No newline at end of file diff --git a/pkg/client/formance.go b/pkg/client/formance.go index a5acc0edc..d7b20f33b 100644 --- a/pkg/client/formance.go +++ b/pkg/client/formance.go @@ -143,9 +143,9 @@ func New(opts ...SDKOption) *Formance { sdkConfiguration: sdkConfiguration{ Language: "go", OpenAPIDocVersion: "v1", - SDKVersion: "0.4.10", + SDKVersion: "0.4.11", GenVersion: "2.384.1", - UserAgent: "speakeasy-sdk/go 0.4.10 2.384.1 v1 github.com/formancehq/stack/ledger/client", + UserAgent: "speakeasy-sdk/go 0.4.11 2.384.1 v1 github.com/formancehq/stack/ledger/client", Hooks: hooks.New(), }, } diff --git a/pkg/client/models/components/v2errorsenum.go b/pkg/client/models/components/v2errorsenum.go index defc9c108..7211d8b8f 100644 --- a/pkg/client/models/components/v2errorsenum.go +++ b/pkg/client/models/components/v2errorsenum.go @@ -10,18 +10,20 @@ import ( type V2ErrorsEnum string const ( - V2ErrorsEnumInternal V2ErrorsEnum = "INTERNAL" - V2ErrorsEnumInsufficientFund V2ErrorsEnum = "INSUFFICIENT_FUND" - V2ErrorsEnumValidation V2ErrorsEnum = "VALIDATION" - V2ErrorsEnumConflict V2ErrorsEnum = "CONFLICT" - V2ErrorsEnumCompilationFailed V2ErrorsEnum = "COMPILATION_FAILED" - V2ErrorsEnumMetadataOverride V2ErrorsEnum = "METADATA_OVERRIDE" - V2ErrorsEnumNotFound V2ErrorsEnum = "NOT_FOUND" - V2ErrorsEnumRevertOccurring V2ErrorsEnum = "REVERT_OCCURRING" - V2ErrorsEnumAlreadyRevert V2ErrorsEnum = "ALREADY_REVERT" - V2ErrorsEnumNoPostings V2ErrorsEnum = "NO_POSTINGS" - V2ErrorsEnumLedgerNotFound V2ErrorsEnum = "LEDGER_NOT_FOUND" - V2ErrorsEnumImport V2ErrorsEnum = "IMPORT" + V2ErrorsEnumInternal V2ErrorsEnum = "INTERNAL" + V2ErrorsEnumInsufficientFund V2ErrorsEnum = "INSUFFICIENT_FUND" + V2ErrorsEnumValidation V2ErrorsEnum = "VALIDATION" + V2ErrorsEnumConflict V2ErrorsEnum = "CONFLICT" + V2ErrorsEnumCompilationFailed V2ErrorsEnum = "COMPILATION_FAILED" + V2ErrorsEnumMetadataOverride V2ErrorsEnum = "METADATA_OVERRIDE" + V2ErrorsEnumNotFound V2ErrorsEnum = "NOT_FOUND" + V2ErrorsEnumRevertOccurring V2ErrorsEnum = "REVERT_OCCURRING" + V2ErrorsEnumAlreadyRevert V2ErrorsEnum = "ALREADY_REVERT" + V2ErrorsEnumNoPostings V2ErrorsEnum = "NO_POSTINGS" + V2ErrorsEnumLedgerNotFound V2ErrorsEnum = "LEDGER_NOT_FOUND" + V2ErrorsEnumImport V2ErrorsEnum = "IMPORT" + V2ErrorsEnumInterpreterParse V2ErrorsEnum = "INTERPRETER_PARSE" + V2ErrorsEnumInterpreterRuntime V2ErrorsEnum = "INTERPRETER_RUNTIME" ) func (e V2ErrorsEnum) ToPointer() *V2ErrorsEnum { @@ -56,6 +58,10 @@ func (e *V2ErrorsEnum) UnmarshalJSON(data []byte) error { case "LEDGER_NOT_FOUND": fallthrough case "IMPORT": + fallthrough + case "INTERPRETER_PARSE": + fallthrough + case "INTERPRETER_RUNTIME": *e = V2ErrorsEnum(v) return nil default: diff --git a/test/e2e/api_bulk.go b/test/e2e/api_bulk.go index 3a39faf02..6c64cc0b6 100644 --- a/test/e2e/api_bulk.go +++ b/test/e2e/api_bulk.go @@ -153,7 +153,7 @@ var _ = Context("Ledger engine tests", func() { }) It("should respond with an error", func() { Expect(bulkResponse[1].Type).To(Equal(components.V2BulkElementResultType("ERROR"))) - Expect(bulkResponse[1].V2BulkElementResultError.ErrorCode).To(Equal("INSUFFICIENT_FUND")) + Expect(bulkResponse[1].V2BulkElementResultError.ErrorCode).To(Equal("INTERPRETER_RUNTIME")) }) }) }) diff --git a/test/e2e/api_transactions_create.go b/test/e2e/api_transactions_create.go index 7e4a0a21e..6d139c876 100644 --- a/test/e2e/api_transactions_create.go +++ b/test/e2e/api_transactions_create.go @@ -3,6 +3,9 @@ package test_suite import ( + "math/big" + "time" + "github.com/formancehq/go-libs/logging" . "github.com/formancehq/go-libs/testing/api" "github.com/formancehq/go-libs/testing/platform/pgtesting" @@ -11,8 +14,6 @@ import ( . "github.com/formancehq/ledger/pkg/testserver" "github.com/formancehq/stack/ledger/client/models/components" "github.com/formancehq/stack/ledger/client/models/operations" - "math/big" - "time" "github.com/formancehq/go-libs/metadata" "github.com/formancehq/go-libs/pointer" @@ -200,7 +201,7 @@ var _ = Context("Ledger accounts list API tests", func() { }) It("should fail", func() { Expect(err).To(HaveOccurred()) - Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumInsufficientFund))) + Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumInterpreterRuntime))) }) }) When("with nil amount", func() { @@ -323,9 +324,9 @@ var _ = Context("Ledger accounts list API tests", func() { Ledger: "default", } }) - It("should fail with "+string(components.V2ErrorsEnumCompilationFailed)+" code", func() { + It("should fail with "+string(components.V2ErrorsEnumInterpreterRuntime)+" code", func() { Expect(err).NotTo(Succeed()) - Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumCompilationFailed))) + Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumInterpreterRuntime))) }) }) When("using a negative amount in the script with a variable", func() { @@ -350,9 +351,9 @@ var _ = Context("Ledger accounts list API tests", func() { Ledger: "default", } }) - It("should fail with "+string(components.V2ErrorsEnumCompilationFailed)+" code", func() { + It("should fail with "+string(components.V2ErrorsEnumInterpreterRuntime)+" code", func() { Expect(err).NotTo(Succeed()) - Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumCompilationFailed))) + Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumInterpreterRuntime))) }) }) Context("with error on script", func() { @@ -369,9 +370,9 @@ var _ = Context("Ledger accounts list API tests", func() { Ledger: "default", } }) - It("should fail with "+string(components.V2ErrorsEnumCompilationFailed)+" code", func() { + It("should fail with "+string(components.V2ErrorsEnumInterpreterParse)+" code", func() { Expect(err).NotTo(Succeed()) - Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumCompilationFailed))) + Expect(err).To(HaveErrorCode(string(components.V2ErrorsEnumInterpreterParse))) }) }) Context("with no postings", func() {