Skip to content

Commit

Permalink
fix: invalid balance coin should trigger an error
Browse files Browse the repository at this point in the history
By rejecting the trace during the processing phrase, we allow an other
processor to handle it, and we also prevent a database error that
occurs during the insert when the unmarshaled coin contains invalid
UTF-8 characters (see EmerisHQ/demeris-backend#794)
  • Loading branch information
tbruyelle committed May 30, 2022
1 parent edef1fc commit be55d50
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
38 changes: 32 additions & 6 deletions tracelistener/processor/bank_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ import (
"fmt"
"testing"

gogotypes "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/require"
"go.uber.org/zap"

sdk "github.com/cosmos/cosmos-sdk/types"
bankTypes "github.com/cosmos/cosmos-sdk/x/bank/types"
gaia "github.com/cosmos/gaia/v6/app"
models "github.com/emerishq/demeris-backend-models/tracelistener"
"github.com/emerishq/tracelistener/tracelistener"
"github.com/emerishq/tracelistener/tracelistener/config"
"github.com/emerishq/tracelistener/tracelistener/processor/datamarshaler"
)

func TestFix794(t *testing.T) {

ops := []string{
// Iris1
"{\"operation\":\"write\",\"key\":\"AhT+5cRMA/vuTTyGA9Qqcf/L5yTzpA==\",\"value\":\"CiQKBXVpcmlzEhs1MDk2MjUxNDM1MDYwNjM3ODgwNTA2Nzg0NTU=\",\"metadata\":{\"blockHeight\":15065683,\"txHash\":\"31647EB774FDC743E067FA459AA05CD5B0F315431CCCA54F98D877D7C26BCFC4\"}}",
Expand All @@ -37,6 +38,7 @@ func TestFix794(t *testing.T) {
}
d := bankProcessor{}
for i := 0; i < len(ops); i++ {
fmt.Println(ops[i])
var tr tracelistener.TraceOperation
err := json.Unmarshal([]byte(ops[i]), &tr)
require.NoError(t, err)
Expand All @@ -48,16 +50,40 @@ func TestFix794(t *testing.T) {

addrBytes, err := bankTypes.AddressFromBalancesStore(tr.Key[1:])
require.NoError(t, err)
// fetch denom
denom := string(tr.Key[1+1+len(addrBytes):])
fmt.Println("DENOM FROM KEY", denom, len(denom))

hAddr := hex.EncodeToString(addrBytes)

coin := sdk.Coin{
Amount: sdk.NewInt(0),
}
err = gaia.MakeEncodingConfig().Marshaler.Unmarshal(tr.Value, &coin)
var coins sdk.Coin

err = coins.Unmarshal(tr.Value)
// err = gaia.MakeEncodingConfig().Marshaler.Unmarshal(tr.Value, &coins)
require.NoError(t, err)
fmt.Printf("%d) ADR=%q COINS %q (valid=%v) %q %q\n", i, hAddr, tr.Value, coins.Validate(), coins.Denom, coins.Amount)

// var htlc types.MT
// err = htlc.Unmarshal(tr.Value)
// require.NoError(t, err)
// fmt.Printf("HTLC %#v\n\n", htlc)
var tokenIDWrap gogotypes.StringValue
err = tokenIDWrap.Unmarshal(tr.Value)
require.NoError(t, err)
fmt.Printf("%d) KEY=%q COINS %q %q\n", i, hAddr, coin.Denom, coin.Amount)
fmt.Printf("TOKEN ID %#v\n", tokenIDWrap)
}
// htlc2 := types.MT{
// Id: "Id",
// // Denom: "uiris",
// // Amount: sdk.Coins{{Amount: sdk.NewInt(1000), Denom: "uiris"}},
// }
// bz, err := htlc2.Marshal()
// require.NoError(t, err)
// fmt.Printf("BZ %s\n", bz)
// var coins sdk.Coin
// err = coins.Unmarshal(bz)
// require.NoError(t, err)
// fmt.Println("COINT", coins.Denom, coins.Amount)

}

Expand Down
4 changes: 2 additions & 2 deletions tracelistener/processor/datamarshaler/impl_v44.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ func (d DataMarshaler) Bank(data tracelistener.TraceOperation) (models.BalanceRo
// (picture someone who sends all their balance to another address).
// To work around this issue, we don't return when coin is invalid when data.Operation is "delete",
// and we set balance == 0 instead.
if !coins.IsValid() {
if err := coins.Validate(); err != nil {
if data.Operation == tracelistener.DeleteOp.String() {
// rawAddress still contains the length prefix, so we have to jump it by
// reading 1 byte after len(addrBytes)
denom := rawAddress[len(addrBytes)+1:]
coins.Denom = string(denom)
} else {
return models.BalanceRow{}, nil
return models.BalanceRow{}, fmt.Errorf("invalid balance coin: %w", err)
}
}

Expand Down
5 changes: 3 additions & 2 deletions tracelistener/processor/datamarshaler/impl_v44_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ func TestDataMarshalerBank(t *testing.T) {
expectedError: "cannot parse address from balance store key, invalid key",
},
{
name: "ok: value is empty",
name: "fail: value is empty",
tr: tracelistener.TraceOperation{
Operation: tracelistener.WriteOp.String(),
Key: append(types.BalancesPrefix, []byte{3, 'a', 'd', 'd'}...),
},
expectedBalanceRow: models.BalanceRow{},
expectedError: "invalid balance coin: invalid denom: ",
},
{
name: "ok: value is not a valid coin",
Expand All @@ -60,6 +60,7 @@ func TestDataMarshalerBank(t *testing.T) {
Key: append(types.BalancesPrefix, []byte{3, 'a', 'd', 'd'}...),
Value: []byte("\n$\n\x05uiris\x12\x1b509625143506063788050678455"),
},
expectedError: "invalid balance coin: invalid denom: \n\x05uiris\x12\x1b509625143506063788050678455",
},
{
name: "ok: value is not a valid coin but operation is delete",
Expand Down

0 comments on commit be55d50

Please sign in to comment.