Skip to content

Commit

Permalink
feat: simplify some code
Browse files Browse the repository at this point in the history
  • Loading branch information
gfyrag committed Oct 16, 2024
1 parent 96c977e commit ca4dc6d
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 113 deletions.
4 changes: 2 additions & 2 deletions internal/api/v1/controllers_logs_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ func TestGetLogs(t *testing.T) {

expectedCursor := bunpaginate.Cursor[ledger.Log]{
Data: []ledger.Log{
ledger.NewTransactionLog(ledger.CreatedTransaction{
Transaction: ledger.NewTransaction(),
ledger.NewLog(ledger.CreatedTransaction{
Transaction: ledger.NewTransaction(),
AccountMetadata: ledger.AccountMetadata{},
}).ChainLog(nil),
},
Expand Down
2 changes: 1 addition & 1 deletion internal/api/v2/controllers_logs_export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func TestLogsExport(t *testing.T) {
tc.expectStatusCode = http.StatusOK
}

log := ledger.NewTransactionLog(ledger.CreatedTransaction{
log := ledger.NewLog(ledger.CreatedTransaction{
Transaction: ledger.NewTransaction(),
AccountMetadata: ledger.AccountMetadata{},
})
Expand Down
2 changes: 1 addition & 1 deletion internal/api/v2/controllers_logs_import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func TestLogsImport(t *testing.T) {
tc.expectStatusCode = http.StatusNoContent
}

log := ledger.NewTransactionLog(ledger.CreatedTransaction{
log := ledger.NewLog(ledger.CreatedTransaction{
Transaction: ledger.NewTransaction(),
AccountMetadata: ledger.AccountMetadata{},
})
Expand Down
2 changes: 1 addition & 1 deletion internal/api/v2/controllers_logs_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func TestGetLogs(t *testing.T) {

expectedCursor := bunpaginate.Cursor[ledger.Log]{
Data: []ledger.Log{
ledger.NewTransactionLog(ledger.CreatedTransaction{
ledger.NewLog(ledger.CreatedTransaction{
Transaction: ledger.NewTransaction(),
AccountMetadata: ledger.AccountMetadata{},
}).
Expand Down
67 changes: 30 additions & 37 deletions internal/controller/ledger/controller_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/formancehq/go-libs/bun/bunpaginate"
"github.com/formancehq/go-libs/logging"
"github.com/formancehq/go-libs/metadata"
"github.com/formancehq/go-libs/pointer"
"github.com/google/uuid"
// todo: remove as it is in maintenance mode
"errors"
Expand Down Expand Up @@ -217,16 +216,16 @@ func (ctrl *DefaultController) CreateTransaction(ctx context.Context, parameters
return nil, fmt.Errorf("failed to compile script: %w", err)
}

output, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input RunScript) (*ledger.Log, *ledger.CreatedTransaction, error) {
output, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input RunScript) (*ledger.CreatedTransaction, error) {
result, err := tracing.TraceWithLatency(ctx, "ExecuteMachine", func(ctx context.Context) (*MachineResult, error) {
return m.Execute(ctx, newVmStoreAdapter(sqlTX), input.Vars)
})
if err != nil {
return nil, nil, fmt.Errorf("failed to execute program: %w", err)
return nil, fmt.Errorf("failed to execute program: %w", err)
}

if len(result.Postings) == 0 {
return nil, nil, ErrNoPostings
return nil, ErrNoPostings
}

finalMetadata := result.Metadata
Expand All @@ -235,7 +234,7 @@ func (ctrl *DefaultController) CreateTransaction(ctx context.Context, parameters
}
for k, v := range input.Metadata {
if finalMetadata[k] != "" {
return nil, nil, newErrMetadataOverride(k)
return nil, newErrMetadataOverride(k)
}
finalMetadata[k] = v
}
Expand All @@ -254,21 +253,19 @@ func (ctrl *DefaultController) CreateTransaction(ctx context.Context, parameters
WithReference(input.Reference)
err = sqlTX.CommitTransaction(ctx, &transaction)
if err != nil {
return nil, nil, err
return nil, err
}

if len(result.AccountMetadata) > 0 {
if err := sqlTX.UpdateAccountsMetadata(ctx, result.AccountMetadata); err != nil {
return nil, nil, fmt.Errorf("updating metadata of account '%s': %w", Keys(result.AccountMetadata), err)
return nil, fmt.Errorf("updating metadata of account '%s': %w", Keys(result.AccountMetadata), err)
}
}

createdTransaction := ledger.CreatedTransaction{
return &ledger.CreatedTransaction{
Transaction: transaction,
AccountMetadata: result.AccountMetadata,
}

return pointer.For(ledger.NewTransactionLog(createdTransaction)), &createdTransaction, err
}, err
})
if err != nil {
return nil, err
Expand All @@ -278,25 +275,25 @@ func (ctrl *DefaultController) CreateTransaction(ctx context.Context, parameters
}

func (ctrl *DefaultController) RevertTransaction(ctx context.Context, parameters Parameters[RevertTransaction]) (*ledger.RevertedTransaction, error) {
return forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input RevertTransaction) (*ledger.Log, *ledger.RevertedTransaction, error) {
return forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input RevertTransaction) (*ledger.RevertedTransaction, error) {

var (
hasBeenReverted bool
err error
)
originalTransaction, hasBeenReverted, err := sqlTX.RevertTransaction(ctx, input.TransactionID)
if err != nil {
return nil, nil, err
return nil, err
}
if !hasBeenReverted {
return nil, nil, newErrAlreadyReverted(input.TransactionID)
return nil, newErrAlreadyReverted(input.TransactionID)
}

bq := originalTransaction.InvolvedAccountAndAssets()

balances, err := sqlTX.GetBalances(ctx, bq)
if err != nil {
return nil, nil, fmt.Errorf("failed to get balances: %w", err)
return nil, fmt.Errorf("failed to get balances: %w", err)
}

reversedTx := originalTransaction.Reverse()
Expand Down Expand Up @@ -324,78 +321,74 @@ func (ctrl *DefaultController) RevertTransaction(ctx context.Context, parameters
if finalBalance.Cmp(new(big.Int)) < 0 {
// todo(waiting): break dependency on machine package
// notes(gfyrag): wait for the new interpreter
return nil, nil, machine.NewErrInsufficientFund("insufficient fund for %s/%s", account, asset)
return nil, machine.NewErrInsufficientFund("insufficient fund for %s/%s", account, asset)
}
}
}
}

err = sqlTX.CommitTransaction(ctx, &reversedTx)
if err != nil {
return nil, nil, fmt.Errorf("failed to insert transaction: %w", err)
return nil, fmt.Errorf("failed to insert transaction: %w", err)
}

return pointer.For(ledger.NewRevertedTransactionLog(*originalTransaction, reversedTx)), &ledger.RevertedTransaction{
return &ledger.RevertedTransaction{
RevertedTransaction: *originalTransaction,
RevertTransaction: reversedTx,
}, nil
})
}

func (ctrl *DefaultController) SaveTransactionMetadata(ctx context.Context, parameters Parameters[SaveTransactionMetadata]) error {
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input SaveTransactionMetadata) (*ledger.Log, *ledger.SavedMetadata, error) {
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input SaveTransactionMetadata) (*ledger.SavedMetadata, error) {
if _, _, err := sqlTX.UpdateTransactionMetadata(ctx, input.TransactionID, input.Metadata); err != nil {
return nil, nil, err
return nil, err
}

setMetadata := ledger.SavedMetadata{
return &ledger.SavedMetadata{
TargetType: ledger.MetaTargetTypeTransaction,
TargetID: parameters.Input.TransactionID,
Metadata: parameters.Input.Metadata,
}

return pointer.For(ledger.NewSetMetadataOnTransactionLog(setMetadata)), &setMetadata, nil
}, nil
})
return err
}

func (ctrl *DefaultController) SaveAccountMetadata(ctx context.Context, parameters Parameters[SaveAccountMetadata]) error {
now := time.Now()
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input SaveAccountMetadata) (*ledger.Log, *ledger.SavedMetadata, error) {
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input SaveAccountMetadata) (*ledger.SavedMetadata, error) {
if _, err := sqlTX.UpsertAccount(ctx, &ledger.Account{
Address: input.Address,
Metadata: input.Metadata,
FirstUsage: now,
InsertionDate: now,
UpdatedAt: now,
}); err != nil {
return nil, nil, err
return nil, err
}

setMetadata := ledger.SavedMetadata{
return &ledger.SavedMetadata{
TargetType: ledger.MetaTargetTypeAccount,
TargetID: parameters.Input.Address,
Metadata: parameters.Input.Metadata,
}

return pointer.For(ledger.NewSetMetadataOnAccountLog(setMetadata)), &setMetadata, nil
}, nil
})

return err
}

func (ctrl *DefaultController) DeleteTransactionMetadata(ctx context.Context, parameters Parameters[DeleteTransactionMetadata]) error {
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input DeleteTransactionMetadata) (*ledger.Log, *ledger.DeletedMetadata, error) {
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input DeleteTransactionMetadata) (*ledger.DeletedMetadata, error) {
_, modified, err := sqlTX.DeleteTransactionMetadata(ctx, input.TransactionID, input.Key)
if err != nil {
return nil, nil, err
return nil, err
}

if !modified {
return nil, nil, postgres.ErrNotFound
return nil, postgres.ErrNotFound
}

return pointer.For(ledger.NewDeleteTransactionMetadataLog(input.TransactionID, input.Key)), &ledger.DeletedMetadata{
return &ledger.DeletedMetadata{
TargetType: ledger.MetaTargetTypeTransaction,
TargetID: parameters.Input.TransactionID,
Key: parameters.Input.Key,
Expand All @@ -406,13 +399,13 @@ func (ctrl *DefaultController) DeleteTransactionMetadata(ctx context.Context, pa
}

func (ctrl *DefaultController) DeleteAccountMetadata(ctx context.Context, parameters Parameters[DeleteAccountMetadata]) error {
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input DeleteAccountMetadata) (*ledger.Log, *ledger.DeletedMetadata, error) {
_, err := forgeLog(ctx, ctrl.store, parameters, func(ctx context.Context, sqlTX TX, input DeleteAccountMetadata) (*ledger.DeletedMetadata, error) {
err := sqlTX.DeleteAccountMetadata(ctx, input.Address, input.Key)
if err != nil {
return nil, nil, err
return nil, err
}

return pointer.For(ledger.NewDeleteAccountMetadataLog(input.Address, input.Key)), &ledger.DeletedMetadata{
return &ledger.DeletedMetadata{
TargetType: ledger.MetaTargetTypeAccount,
TargetID: parameters.Input.Address,
Key: parameters.Input.Key,
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/ledger/controller_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestCreateTransaction(t *testing.T) {

sqlTX.EXPECT().
InsertLog(gomock.Any(), gomock.Cond(func(x any) bool {
return x.(*ledger.Log).Type == ledger.NewTransactionLogType
return x.(*ledger.Log).Type == ledger.NewLogType
})).
DoAndReturn(func(ctx context.Context, x any) any {
return x
Expand Down
14 changes: 7 additions & 7 deletions internal/controller/ledger/log_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ import (
"github.com/formancehq/ledger/internal/tracing"
)

func runTx[INPUT, OUTPUT any](ctx context.Context, store Store, parameters Parameters[INPUT], fn func(ctx context.Context, sqlTX TX, input INPUT) (*ledger.Log, *OUTPUT, error)) (*OUTPUT, error) {
func runTx[INPUT any, OUTPUT ledger.LogPayload](ctx context.Context, store Store, parameters Parameters[INPUT], fn func(ctx context.Context, sqlTX TX, input INPUT) (*OUTPUT, error)) (*OUTPUT, error) {
var (
log *ledger.Log
output *OUTPUT
payload *OUTPUT
)
err := store.WithTX(ctx, nil, func(tx TX) (commit bool, err error) {
log, output, err = fn(ctx, tx, parameters.Input)
payload, err = fn(ctx, tx, parameters.Input)
if err != nil {
return false, err
}
log := ledger.NewLog(*payload)
log.IdempotencyKey = parameters.IdempotencyKey
log.IdempotencyHash = ledger.ComputeIdempotencyHash(parameters.Input)

_, err = tracing.TraceWithLatency(ctx, "InsertLog", func(ctx context.Context) (*struct{}, error) {
return nil, tx.InsertLog(ctx, log)
return nil, tx.InsertLog(ctx, &log)
})
if err != nil {
return false, fmt.Errorf("failed to insert log: %w", err)
Expand All @@ -38,14 +38,14 @@ func runTx[INPUT, OUTPUT any](ctx context.Context, store Store, parameters Param

return true, nil
})
return output, err
return payload, err
}

// todo: handle too many clients error
// notes(gfyrag): how?
// By retrying? Is the server already overloaded? Add a limit on the retries number?
// Ask the client to retry later?
func forgeLog[INPUT, OUTPUT any](ctx context.Context, store Store, parameters Parameters[INPUT], fn func(ctx context.Context, sqlTX TX, input INPUT) (*ledger.Log, *OUTPUT, error)) (*OUTPUT, error) {
func forgeLog[INPUT any, OUTPUT ledger.LogPayload](ctx context.Context, store Store, parameters Parameters[INPUT], fn func(ctx context.Context, sqlTX TX, input INPUT) (*OUTPUT, error)) (*OUTPUT, error) {
if parameters.IdempotencyKey != "" {
log, err := store.ReadLogWithIdempotencyKey(ctx, parameters.IdempotencyKey)
if err != nil && !errors.Is(err, postgres.ErrNotFound) {
Expand Down
Loading

0 comments on commit ca4dc6d

Please sign in to comment.