Skip to content

Commit

Permalink
fix(vbank): ensure that multiple balance updates are sorted
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Jul 1, 2021
1 parent 66f794b commit 204790f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
Expand Down
39 changes: 36 additions & 3 deletions golang/cosmos/x/vbank/vbank.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package vbank
import (
"encoding/json"
"fmt"
"sort"

"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -35,10 +36,37 @@ type vbankSingleBalanceUpdate struct {
Amount string `json:"amount"`
}

// Make vbankManyBalanceUpdates sortable
type vbankManyBalanceUpdates []vbankSingleBalanceUpdate

var _ sort.Interface = vbankManyBalanceUpdates{}

func (vbu vbankManyBalanceUpdates) Len() int {
return len(vbu)
}

func (vbu vbankManyBalanceUpdates) Less(i int, j int) bool {
if vbu[i].Address < vbu[j].Address {
return true
} else if vbu[i].Address > vbu[j].Address {
return false
}
if vbu[i].Denom < vbu[j].Denom {
return true
} else if vbu[i].Denom > vbu[j].Denom {
return false
}
return vbu[i].Amount < vbu[j].Amount
}

func (vbu vbankManyBalanceUpdates) Swap(i int, j int) {
vbu[i], vbu[j] = vbu[j], vbu[i]
}

type vbankBalanceUpdate struct {
Nonce uint64 `json:"nonce"`
Type string `json:"type"`
Updated []vbankSingleBalanceUpdate `json:"updated"`
Nonce uint64 `json:"nonce"`
Type string `json:"type"`
Updated vbankManyBalanceUpdates `json:"updated"`
}

func marshalBalanceUpdate(ctx sdk.Context, keeper Keeper, addressToBalance map[string]sdk.Coins) ([]byte, error) {
Expand All @@ -53,6 +81,9 @@ func marshalBalanceUpdate(ctx sdk.Context, keeper Keeper, addressToBalance map[s
Nonce: nonce,
Updated: make([]vbankSingleBalanceUpdate, 0, nentries),
}

// Note that Golang randomises the order of iteration, so we have to sort
// below to be deterministic.
for address, coins := range addressToBalance {
for _, coin := range coins {
update := vbankSingleBalanceUpdate{
Expand All @@ -64,6 +95,8 @@ func marshalBalanceUpdate(ctx sdk.Context, keeper Keeper, addressToBalance map[s
}
}

// Ensure we have a deterministic order of updates.
sort.Sort(event.Updated)
return json.Marshal(&event)
}

Expand Down
19 changes: 13 additions & 6 deletions golang/cosmos/x/vbank/vbank_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ func decodeBalances(encoded []byte) (balances, uint64, error) {
return nil, 0, fmt.Errorf("bad balance update type: %s", balanceUpdate.Type)
}
b := newBalances()
for _, u := range balanceUpdate.Updated {
fmt.Printf("updated balances %v\n", balanceUpdate.Updated)
for i, u := range balanceUpdate.Updated {
if i < len(balanceUpdate.Updated)-1 && balanceUpdate.Updated.Less(i+1, i) {
return nil, 0, fmt.Errorf("unordered balance update %v is before %v", u, balanceUpdate.Updated[i+1])
}
account(u.Address, coin(u.Denom, u.Amount))(b)
}
return b, balanceUpdate.Nonce, nil
Expand All @@ -99,6 +103,7 @@ func Test_marshalBalanceUpdate(t *testing.T) {
addressToBalance map[string]sdk.Coins
want balances
wantErr bool
encoded []byte
}{
{
name: "empty",
Expand Down Expand Up @@ -277,8 +282,9 @@ func Test_Receive_Give(t *testing.T) {
want := newBalances(account(addr1, coin("urun", "1000")))
got, gotNonce, err := decodeBalances([]byte(ret))
if err != nil {
t.Errorf("decode balances error = %v", err)
} else if !reflect.DeepEqual(got, want) {
t.Fatalf("decode balances error = %v", err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %+v, want %+v", got, want)
}
nonce := uint64(1)
Expand Down Expand Up @@ -418,8 +424,9 @@ func Test_Receive_Grab(t *testing.T) {
want := newBalances(account(addr1, coin("ubld", "1000")))
got, gotNonce, err := decodeBalances([]byte(ret))
if err != nil {
t.Errorf("decode balances error = %v", err)
} else if !reflect.DeepEqual(got, want) {
t.Fatalf("decode balances error = %v", err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %+v, want %+v", got, want)
}
nonce := uint64(1)
Expand Down Expand Up @@ -495,7 +502,7 @@ func Test_EndBlock_Events(t *testing.T) {
}
gotMsg, gotNonce, err := decodeBalances([]byte(msgsSent[0]))
if err != nil {
t.Errorf("decode balances error = %v", err)
t.Fatalf("decode balances error = %v", err)
}

nonce := uint64(1)
Expand Down

0 comments on commit 204790f

Please sign in to comment.