diff --git a/cmd/script_exec.go b/cmd/script_exec.go index 8c8241776..81b3deff9 100644 --- a/cmd/script_exec.go +++ b/cmd/script_exec.go @@ -82,7 +82,13 @@ func NewScriptExec() *cobra.Command { fmt.Printf("ID: %d\r\n", result.Transaction.ID) fmt.Println("Postings:") for _, p := range result.Transaction.Postings { - fmt.Printf("\t Source: %s, Destination: %s, Amount: %d, Asset: %s\r\n", p.Source, p.Destination, p.Amount, p.Asset) + fmt.Printf( + "\t Source: %s, Destination: %s, Amount: %s, Asset: %s\r\n", + p.Source, + p.Destination, + p.Amount.String(), + p.Asset, + ) } if !viper.GetBool(previewFlag) { fmt.Printf("Created transaction: http://%s/%s/transactions/%d\r\n", diff --git a/go.mod b/go.mod index 45be51be3..ef870c349 100644 --- a/go.mod +++ b/go.mod @@ -141,6 +141,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/segmentio/backo-go v1.0.0 // indirect + github.com/smartystreets/goconvey v1.7.2 // indirect github.com/spf13/afero v1.7.0 // indirect github.com/spf13/cast v1.4.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -163,10 +164,12 @@ require ( go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.21.0 // indirect golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect + golang.org/x/mod v0.5.0 // indirect golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sys v0.0.0-20220412071739-889880a91fd5 // indirect golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.5 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/api v0.63.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index cbc0a7662..016fb8d08 100644 --- a/go.sum +++ b/go.sum @@ -353,6 +353,7 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 h1:zC34cGQu69FG7qzJ3WiKW244WfhDC3xxYMeNOX2gtUQ= github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= @@ -475,6 +476,7 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -652,6 +654,9 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -866,6 +871,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1054,6 +1060,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1109,6 +1116,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/api/controllers/account_controller_test.go b/pkg/api/controllers/account_controller_test.go index c48910eb1..f763f65b3 100644 --- a/pkg/api/controllers/account_controller_test.go +++ b/pkg/api/controllers/account_controller_test.go @@ -452,7 +452,8 @@ func TestGetAccount(t *testing.T) { }, Volumes: core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, resp) diff --git a/pkg/api/controllers/transaction_controller_test.go b/pkg/api/controllers/transaction_controller_test.go index 0112aee4e..37589fd11 100644 --- a/pkg/api/controllers/transaction_controller_test.go +++ b/pkg/api/controllers/transaction_controller_test.go @@ -307,21 +307,29 @@ func TestGetTransaction(t *testing.T) { assert.NotEmpty(t, ret.Timestamp) assert.EqualValues(t, core.AccountsAssetsVolumes{ "world": core.AssetsVolumes{ - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "central_bank": core.AssetsVolumes{ - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, ret.PreCommitVolumes) assert.EqualValues(t, core.AccountsAssetsVolumes{ "world": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(1000), }, }, "central_bank": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(1000), + Input: core.NewMonetaryInt(1000), + Output: core.NewMonetaryInt(0), }, }, }, ret.PostCommitVolumes) diff --git a/pkg/core/log.go b/pkg/core/log.go index c917254f4..d43e01d49 100644 --- a/pkg/core/log.go +++ b/pkg/core/log.go @@ -1,11 +1,10 @@ package core import ( + "encoding/json" "strconv" "strings" "time" - - json "github.com/gibson042/canonicaljson-go" ) const SetMetadataType = "SET_METADATA" diff --git a/pkg/core/log_test.go b/pkg/core/log_test.go index 060d60e31..4f6110074 100644 --- a/pkg/core/log_test.go +++ b/pkg/core/log_test.go @@ -21,7 +21,7 @@ func TestLog(t *testing.T) { Metadata: Metadata{}, }, }, d) - if !assert.Equal(t, "3070ef3437354b5cb5ece914f8610d8d1276c6a9df127c0d2a49c48e3f81b017", log2.Hash) { + if !assert.Equal(t, "9ee060170400f556b7e1575cb13f9db004f150a08355c7431c62bc639166431e", log2.Hash) { return } } diff --git a/pkg/core/monetary.go b/pkg/core/monetary.go index 250d3d481..7b0422c50 100644 --- a/pkg/core/monetary.go +++ b/pkg/core/monetary.go @@ -35,6 +35,14 @@ func (a *MonetaryInt) Neg() *MonetaryInt { return (*MonetaryInt)(big.NewInt(0).Neg((*big.Int)(a))) } +func (a *MonetaryInt) OrZero() *MonetaryInt { + if a == nil { + return NewMonetaryInt(0) + } + + return a +} + func (a *MonetaryInt) Lte(b *MonetaryInt) bool { return (*big.Int)(a).Cmp((*big.Int)(b)) <= 0 } @@ -59,6 +67,14 @@ func (a *MonetaryInt) Eq(b *MonetaryInt) bool { return (*big.Int)(a).Cmp((*big.Int)(b)) == 0 } +func (a *MonetaryInt) Equal(b *MonetaryInt) bool { + return (*big.Int)(a).Cmp((*big.Int)(b)) == 0 +} + +func (a *MonetaryInt) Cmp(b *MonetaryInt) int { + return (*big.Int)(a).Cmp((*big.Int)(b)) +} + func (a *MonetaryInt) Uint64() uint64 { return (*big.Int)(a).Uint64() } @@ -76,6 +92,9 @@ func (a *MonetaryInt) UnmarshalJSON(b []byte) error { } func (a *MonetaryInt) MarshalJSON() ([]byte, error) { + if a == nil { + return []byte("0"), nil + } return (*big.Int)(a).MarshalJSON() } diff --git a/pkg/core/transaction.go b/pkg/core/transaction.go index 5ec81362a..bf5d3e5e9 100644 --- a/pkg/core/transaction.go +++ b/pkg/core/transaction.go @@ -2,10 +2,9 @@ package core import ( "crypto/sha256" + "encoding/json" "fmt" "time" - - json "github.com/gibson042/canonicaljson-go" ) type Transactions struct { diff --git a/pkg/core/volumes.go b/pkg/core/volumes.go index 6f60a2fbd..4ef8969ee 100644 --- a/pkg/core/volumes.go +++ b/pkg/core/volumes.go @@ -45,19 +45,31 @@ type AccountsAssetsVolumes map[string]AssetsVolumes func (a AccountsAssetsVolumes) GetVolumes(account, asset string) Volumes { if assetsVolumes, ok := a[account]; !ok { - return Volumes{} + return Volumes{ + Input: NewMonetaryInt(0), + Output: NewMonetaryInt(0), + } } else { - return assetsVolumes[asset] + return Volumes{ + Input: assetsVolumes[asset].Input.OrZero(), + Output: assetsVolumes[asset].Output.OrZero(), + } } } func (a AccountsAssetsVolumes) SetVolumes(account, asset string, volumes Volumes) { if assetsVolumes, ok := a[account]; !ok { a[account] = map[string]Volumes{ - asset: volumes, + asset: { + Input: volumes.Input.OrZero(), + Output: volumes.Output.OrZero(), + }, } } else { - assetsVolumes[asset] = volumes + assetsVolumes[asset] = Volumes{ + Input: volumes.Input.OrZero(), + Output: volumes.Output.OrZero(), + } } } @@ -65,7 +77,7 @@ func (a AccountsAssetsVolumes) AddInput(account, asset string, input *MonetaryIn if assetsVolumes, ok := a[account]; !ok { a[account] = map[string]Volumes{ asset: { - Input: input, + Input: input.OrZero(), }, } } else { @@ -79,7 +91,7 @@ func (a AccountsAssetsVolumes) AddOutput(account, asset string, output *Monetary if assetsVolumes, ok := a[account]; !ok { a[account] = map[string]Volumes{ asset: { - Output: output, + Output: output.OrZero(), }, } } else { diff --git a/pkg/ledger/executor_test.go b/pkg/ledger/executor_test.go index 31be80e2c..51e749ec6 100644 --- a/pkg/ledger/executor_test.go +++ b/pkg/ledger/executor_test.go @@ -15,7 +15,7 @@ func assertBalance(t *testing.T, l *Ledger, account, asset string, amount *core. require.NoError(t, err) b := user.Balances[asset] - assert.Equalf(t, amount, b, + assert.Equalf(t, amount.String(), b.String(), "wrong %v balance for account %v, expected: %d got: %d", asset, account, amount, b, diff --git a/pkg/ledger/ledger_test.go b/pkg/ledger/ledger_test.go index e152ad180..cad06e86e 100644 --- a/pkg/ledger/ledger_test.go +++ b/pkg/ledger/ledger_test.go @@ -308,15 +308,18 @@ func TestTransactionExpectedVolumes(t *testing.T) { assert.EqualValues(t, core.AccountsAssetsVolumes{ "world": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, "EUR": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(200), }, }, "player": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, "EUR": { Input: core.NewMonetaryInt(100), @@ -325,7 +328,8 @@ func TestTransactionExpectedVolumes(t *testing.T) { }, "player2": core.AssetsVolumes{ "EUR": { - Input: core.NewMonetaryInt(150), + Input: core.NewMonetaryInt(150), + Output: core.NewMonetaryInt(0), }, }, }, res.PostCommitVolumes) diff --git a/pkg/ledger/process_test.go b/pkg/ledger/process_test.go index a6b7972f1..81fb50a84 100644 --- a/pkg/ledger/process_test.go +++ b/pkg/ledger/process_test.go @@ -61,16 +61,34 @@ func TestLedger_processTx(t *testing.T) { expectedPreCommitVol := core.AccountsAssetsVolumes{ "alice": core.AssetsVolumes{ - "USD": {}, - "EUR": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, + "EUR": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "toto": core.AssetsVolumes{ - "USD": {}, - "EUR": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, + "EUR": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "world": core.AssetsVolumes{ - "USD": {}, - "EUR": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, + "EUR": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, } @@ -81,12 +99,14 @@ func TestLedger_processTx(t *testing.T) { Output: aliceTotoUSD, }, "EUR": { - Input: worldAliceEUR.Add(totoAliceEUR), + Input: worldAliceEUR.Add(totoAliceEUR), + Output: core.NewMonetaryInt(0), }, }, "toto": core.AssetsVolumes{ "USD": { - Input: worldTotoUSD.Add(aliceTotoUSD), + Input: worldTotoUSD.Add(aliceTotoUSD), + Output: core.NewMonetaryInt(0), }, "EUR": { Input: worldTotoEUR, @@ -95,9 +115,11 @@ func TestLedger_processTx(t *testing.T) { }, "world": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: worldTotoUSD.Add(worldAliceUSD), }, "EUR": { + Input: core.NewMonetaryInt(0), Output: worldTotoEUR.Add(worldAliceEUR), }, }, @@ -266,8 +288,9 @@ func TestLedger_processTx(t *testing.T) { }, } + // b, _ := json.Marshal(expectedTxs) + // a, _ := json.Marshal(res.GeneratedTransactions) assert.Equal(t, expectedTxs, res.GeneratedTransactions) - }) }) diff --git a/pkg/ledger/volume_agg.go b/pkg/ledger/volume_agg.go index ba02f29b6..f258bf71f 100644 --- a/pkg/ledger/volume_agg.go +++ b/pkg/ledger/volume_agg.go @@ -19,6 +19,13 @@ func (tva *transactionVolumeAggregator) postCommitVolumes() core.AccountsAssetsV } func (tva *transactionVolumeAggregator) preCommitVolumes() core.AccountsAssetsVolumes { + // for account, _ := range tva.preVolumes { + // for asset, _ := range tva.preVolumes[account] { + // if tva.preVolumes[account][asset].Input == nil { + // tva.preVolumes[account][asset].Input = core.NewMonetaryInt(0) + // } + // } + // } return tva.preVolumes } @@ -42,7 +49,10 @@ func (tva *transactionVolumeAggregator) transfer( } for current != nil { if v, ok := current.postVolumes[addr][asset]; ok { - tva.preVolumes[addr][asset] = v + tva.preVolumes[addr][asset] = core.Volumes{ + Input: v.Input.OrZero(), + Output: v.Output.OrZero(), + } found = true break } @@ -53,7 +63,10 @@ func (tva *transactionVolumeAggregator) transfer( if err != nil { return err } - tva.preVolumes[addr][asset] = v + tva.preVolumes[addr][asset] = core.Volumes{ + Input: v.Input.OrZero(), + Output: v.Output.OrZero(), + } } } if _, ok := tva.postVolumes[addr][asset]; !ok { diff --git a/pkg/ledger/volume_agg_test.go b/pkg/ledger/volume_agg_test.go index f928be787..5cd32b1d0 100644 --- a/pkg/ledger/volume_agg_test.go +++ b/pkg/ledger/volume_agg_test.go @@ -43,21 +43,29 @@ func TestVolumeAggregator(t *testing.T) { }, PreCommitVolumes: map[string]core.AssetsVolumes{ "bob": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "zozo": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, PostCommitVolumes: map[string]core.AssetsVolumes{ "bob": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, }, "zozo": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, @@ -80,7 +88,8 @@ func TestVolumeAggregator(t *testing.T) { PostCommitVolumes: map[string]core.AssetsVolumes{ "alice": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, "zozo": { @@ -92,11 +101,15 @@ func TestVolumeAggregator(t *testing.T) { }, PreCommitVolumes: map[string]core.AssetsVolumes{ "alice": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "zozo": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, @@ -111,34 +124,40 @@ func TestVolumeAggregator(t *testing.T) { require.Equal(t, core.AccountsAssetsVolumes{ "bob": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(250), }, }, "alice": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(200), + Input: core.NewMonetaryInt(200), + Output: core.NewMonetaryInt(0), }, }, "zoro": { "USD": { - Input: core.NewMonetaryInt(50), + Input: core.NewMonetaryInt(50), + Output: core.NewMonetaryInt(0), }, }, }, firstTx.postCommitVolumes()) require.Equal(t, core.AccountsAssetsVolumes{ "bob": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, }, "alice": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, "zoro": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(0), + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), }, }, }, firstTx.preCommitVolumes()) @@ -149,6 +168,7 @@ func TestVolumeAggregator(t *testing.T) { require.Equal(t, core.AccountsAssetsVolumes{ "bob": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(275), }, }, @@ -160,23 +180,29 @@ func TestVolumeAggregator(t *testing.T) { }, "fred": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(75), + Input: core.NewMonetaryInt(75), + Output: core.NewMonetaryInt(0), }, }, }, secondTx.postCommitVolumes()) require.Equal(t, core.AccountsAssetsVolumes{ "bob": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(250), }, }, "alice": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(200), + Input: core.NewMonetaryInt(200), + Output: core.NewMonetaryInt(0), }, }, "fred": core.AssetsVolumes{ - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, secondTx.preCommitVolumes()) @@ -184,6 +210,7 @@ func TestVolumeAggregator(t *testing.T) { require.Equal(t, core.AccountsAssetsVolumes{ "bob": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(275), }, }, @@ -195,7 +222,8 @@ func TestVolumeAggregator(t *testing.T) { }, "fred": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(75), + Input: core.NewMonetaryInt(75), + Output: core.NewMonetaryInt(0), }, }, "zoro": core.AssetsVolumes{ @@ -210,19 +238,27 @@ func TestVolumeAggregator(t *testing.T) { require.Equal(t, core.AccountsAssetsVolumes{ "bob": core.AssetsVolumes{ "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, }, "alice": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, "fred": core.AssetsVolumes{ - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "zoro": core.AssetsVolumes{ - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, aggregatedPreVolumes) diff --git a/pkg/storage/sqlstorage/balances.go b/pkg/storage/sqlstorage/balances.go index b8b0eec69..7290c6dd1 100644 --- a/pkg/storage/sqlstorage/balances.go +++ b/pkg/storage/sqlstorage/balances.go @@ -47,10 +47,16 @@ func (s *API) GetBalancesAggregated(ctx context.Context, q storage.BalancesQuery for rows.Next() { var ( - asset string - balances *core.MonetaryInt + asset string + balancesStr string ) - if err = rows.Scan(&asset, &balances); err != nil { + if err = rows.Scan(&asset, &balancesStr); err != nil { + return nil, s.error(err) + } + + balances, err := core.ParseMonetaryInt(balancesStr) + + if err != nil { return nil, s.error(err) } diff --git a/pkg/storage/sqlstorage/log.go b/pkg/storage/sqlstorage/log.go index 15629c18b..0cc40bff8 100644 --- a/pkg/storage/sqlstorage/log.go +++ b/pkg/storage/sqlstorage/log.go @@ -3,10 +3,10 @@ package sqlstorage import ( "context" "database/sql" + "encoding/json" "fmt" "time" - json "github.com/gibson042/canonicaljson-go" "github.com/huandu/go-sqlbuilder" "github.com/numary/go-libs/sharedlogging" "github.com/numary/ledger/pkg/core" diff --git a/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any.go b/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any.go index 0208e8ddb..f485a964f 100644 --- a/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any.go +++ b/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any.go @@ -56,27 +56,53 @@ func Upgrade(ctx context.Context, schema sqlstorage.Schema, sqlTx *sql.Tx) error postCommitVolumes := core.AccountsAssetsVolumes{} for _, posting := range tx.Postings { - preCommitVolumes.SetVolumes(posting.Source, posting.Asset, - aggregatedVolumes.GetVolumes(posting.Source, posting.Asset)) - preCommitVolumes.SetVolumes(posting.Destination, posting.Asset, - aggregatedVolumes.GetVolumes(posting.Destination, posting.Asset)) + preCommitVolumes.SetVolumes( + posting.Source, + posting.Asset, + aggregatedVolumes.GetVolumes(posting.Source, posting.Asset), + ) + + preCommitVolumes.SetVolumes( + posting.Destination, + posting.Asset, + aggregatedVolumes.GetVolumes(posting.Destination, posting.Asset), + ) if !postCommitVolumes.HasAccount(posting.Source) { - postCommitVolumes.SetVolumes(posting.Source, posting.Asset, - preCommitVolumes.GetVolumes(posting.Source, posting.Asset)) + postCommitVolumes.SetVolumes( + posting.Source, + posting.Asset, + preCommitVolumes.GetVolumes(posting.Source, posting.Asset), + ) } + if !postCommitVolumes.HasAccount(posting.Destination) { - postCommitVolumes.SetVolumes(posting.Destination, posting.Asset, - preCommitVolumes.GetVolumes(posting.Destination, posting.Asset)) + postCommitVolumes.SetVolumes( + posting.Destination, + posting.Asset, + preCommitVolumes.GetVolumes(posting.Destination, posting.Asset), + ) } - postCommitVolumes.AddOutput(posting.Source, posting.Asset, posting.Amount) - postCommitVolumes.AddInput(posting.Destination, posting.Asset, posting.Amount) + postCommitVolumes.AddOutput( + posting.Source, + posting.Asset, + posting.Amount, + ) + + postCommitVolumes.AddInput( + posting.Destination, + posting.Asset, + posting.Amount, + ) } for account, accountVolumes := range postCommitVolumes { for asset, volumes := range accountVolumes { - aggregatedVolumes.SetVolumes(account, asset, volumes) + aggregatedVolumes.SetVolumes(account, asset, core.Volumes{ + Input: volumes.Input.OrZero(), + Output: volumes.Output.OrZero(), + }) } } diff --git a/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any_test.go b/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any_test.go index 6bcefed47..b6a5934d2 100644 --- a/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any_test.go +++ b/pkg/storage/sqlstorage/migrates/9-add-pre-post-volumes/any_test.go @@ -35,21 +35,29 @@ var testCases = []testCase{ }, expectedPreCommitVolumes: core.AccountsAssetsVolumes{ "world": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "bank": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, expectedPostCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, }, "bank": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, @@ -66,22 +74,28 @@ var testCases = []testCase{ expectedPreCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, }, "bank2": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, expectedPostCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(200), }, }, "bank2": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, @@ -104,34 +118,40 @@ var testCases = []testCase{ expectedPreCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(200), }, }, "bank": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, "bank2": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, expectedPostCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(400), }, }, "bank2": { "USD": { - Input: core.NewMonetaryInt(200), + Input: core.NewMonetaryInt(200), + Output: core.NewMonetaryInt(0), }, }, "bank": { "USD": { - Input: core.NewMonetaryInt(200), + Input: core.NewMonetaryInt(200), + Output: core.NewMonetaryInt(0), }, }, }, @@ -148,41 +168,54 @@ var testCases = []testCase{ Source: "bank", Destination: "user:2", Amount: core.NewMonetaryInt(90), - Asset: "USDT", + Asset: "USD", }, }, expectedPreCommitVolumes: core.AccountsAssetsVolumes{ "bank": { "USD": { - Input: core.NewMonetaryInt(200), + Input: core.NewMonetaryInt(200), + Output: core.NewMonetaryInt(0), }, - "USDT": {}, + // "USDT": { + // Input: core.NewMonetaryInt(0), + // Output: core.NewMonetaryInt(0), + // }, }, "user:1": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "user:2": { - "USDT": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, expectedPostCommitVolumes: core.AccountsAssetsVolumes{ "bank": { "USD": { Input: core.NewMonetaryInt(200), - Output: core.NewMonetaryInt(10), - }, - "USDT": { - Output: core.NewMonetaryInt(90), + Output: core.NewMonetaryInt(100), }, + // "USDT": { + // Input: core.NewMonetaryInt(0), + // Output: core.NewMonetaryInt(0), + // }, }, "user:1": { "USD": { - Input: core.NewMonetaryInt(10), + Input: core.NewMonetaryInt(10), + Output: core.NewMonetaryInt(0), }, }, "user:2": { - "USDT": { - Input: core.NewMonetaryInt(90), + "USD": { + Input: core.NewMonetaryInt(90), + Output: core.NewMonetaryInt(0), }, }, }, diff --git a/pkg/storage/sqlstorage/store_test.go b/pkg/storage/sqlstorage/store_test.go index 67b07f6dc..013d28fc1 100644 --- a/pkg/storage/sqlstorage/store_test.go +++ b/pkg/storage/sqlstorage/store_test.go @@ -115,21 +115,29 @@ var tx1 = core.ExpandedTransaction{ PostCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, }, "central_bank": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, PreCommitVolumes: core.AccountsAssetsVolumes{ "world": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, "central_bank": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, } @@ -152,24 +160,28 @@ var tx2 = core.ExpandedTransaction{ PostCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(200), }, }, "central_bank": { "USD": { - Input: core.NewMonetaryInt(200), + Input: core.NewMonetaryInt(200), + Output: core.NewMonetaryInt(0), }, }, }, PreCommitVolumes: core.AccountsAssetsVolumes{ "world": { "USD": { + Input: core.NewMonetaryInt(0), Output: core.NewMonetaryInt(100), }, }, "central_bank": { "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, @@ -196,11 +208,15 @@ var tx3 = core.ExpandedTransaction{ PreCommitVolumes: core.AccountsAssetsVolumes{ "central_bank": { "USD": { - Input: core.NewMonetaryInt(200), + Input: core.NewMonetaryInt(200), + Output: core.NewMonetaryInt(0), }, }, "users:1": { - "USD": {}, + "USD": { + Input: core.NewMonetaryInt(0), + Output: core.NewMonetaryInt(0), + }, }, }, PostCommitVolumes: core.AccountsAssetsVolumes{ @@ -212,7 +228,8 @@ var tx3 = core.ExpandedTransaction{ }, "users:1": { "USD": { - Input: core.NewMonetaryInt(1), + Input: core.NewMonetaryInt(1), + Output: core.NewMonetaryInt(0), }, }, }, @@ -361,14 +378,16 @@ func testGetAssetsVolumes(t *testing.T, store *sqlstorage.Store) { PostCommitVolumes: core.AccountsAssetsVolumes{ "central_bank": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, PreCommitVolumes: core.AccountsAssetsVolumes{ "central_bank": core.AssetsVolumes{ "USD": { - Input: core.NewMonetaryInt(100), + Input: core.NewMonetaryInt(100), + Output: core.NewMonetaryInt(0), }, }, }, @@ -379,8 +398,8 @@ func testGetAssetsVolumes(t *testing.T, store *sqlstorage.Store) { volumes, err := store.GetAssetsVolumes(context.Background(), "central_bank") require.NoError(t, err) require.Len(t, volumes, 1) - require.EqualValues(t, 100, volumes["USD"].Input) - require.EqualValues(t, 0, volumes["USD"].Output) + require.EqualValues(t, core.NewMonetaryInt(100), volumes["USD"].Input) + require.EqualValues(t, core.NewMonetaryInt(0), volumes["USD"].Output) } func testGetAccounts(t *testing.T, store *sqlstorage.Store) {