From 1752b007b3e276cb0ac47cefd1e2fc3c5387c136 Mon Sep 17 00:00:00 2001 From: ascandone Date: Wed, 2 Oct 2024 17:18:36 +0200 Subject: [PATCH] integrating numscript rewrite --- go.mod | 5 +- go.sum | 6 +++ internal/controller/ledger/machine.go | 49 +++++++++++++++++-- internal/controller/ledger/machine_factory.go | 17 ++++++- internal/controller/ledger/store.go | 40 +++++++++++++++ 5 files changed, 112 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9c370e748..a0b276b1f 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 @@ -54,6 +54,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 @@ -84,6 +85,7 @@ require ( github.com/eapache/queue v1.1.0 // indirect github.com/ericlagergren/decimal v0.0.0-20240411145413-00de7ca16731 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/formancehq/numscript v0.0.9-0.20241002094400-f2e095de4564 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-chi/render v1.0.3 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -184,6 +186,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/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect diff --git a/go.sum b/go.sum index 311c9b34e..8e0e652f9 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= @@ -101,6 +103,8 @@ github.com/formancehq/go-libs v1.7.2-0.20241001142646-eb9c0c1cd58a h1:TkUCCiZjo7 github.com/formancehq/go-libs v1.7.2-0.20241001142646-eb9c0c1cd58a/go.mod h1:oLMVltNsXmvqLA0Ox5NSwVSeH8gbnG2ZUo6Lchp23XU= 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/numscript v0.0.9-0.20241002094400-f2e095de4564 h1:n/cTruHOt2zxX0ZXB701egpzL6O/xfeqD0C/i6YHcAw= +github.com/formancehq/numscript v0.0.9-0.20241002094400-f2e095de4564/go.mod h1:P8qnq15PyWUuhskZdsrzTTqVS5CBkhakDKEPAyF4oYQ= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= @@ -416,6 +420,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/controller/ledger/machine.go b/internal/controller/ledger/machine.go index adeb99556..07f58ca45 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,47 @@ 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, 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..7753158e7 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,17 @@ 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) + if len(parseResult.GetParsingErrors()) != 0 { + return nil, nil + } + + 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 +}