Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(oracle): use collections #994

Merged
merged 54 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
c130fec
change: start coll ux
Oct 6, 2022
6d42cc7
add: more keys
Oct 6, 2022
c6ecd97
add: showcase
Oct 6, 2022
738fa63
Merge branch 'master' into mercilex/collections-ux
Oct 10, 2022
f3fa582
refactor vpool to new coll
Oct 10, 2022
64fc657
refactor vpool to new coll2
Oct 10, 2022
8f3bdc5
refactor perp to new collections
Oct 10, 2022
4620997
refactor pricefeed to new collections
Oct 10, 2022
523c8c6
finalize coll refactor
Oct 10, 2022
a3ef64d
chore: lint
Oct 11, 2022
29bdeb0
change: move exchange rates to collections
Oct 11, 2022
61c2f78
change: move feeder delegations to collections
Oct 11, 2022
f176eaf
change: move prevotes to collections
Oct 11, 2022
4e48879
change: move votes to collections
Oct 11, 2022
6b8b5a3
change: move pairs to collections
Oct 11, 2022
271d254
change: move misscounters to collections
Oct 11, 2022
8a973a3
change: move pair rewards to collections
Oct 11, 2022
6382ab3
change: move pair rewards to collections
Oct 11, 2022
458cc23
chore: lint
Oct 11, 2022
cbde83c
move function to keys and remove generic string
jgimeno Oct 11, 2022
d98496f
add test for address
jgimeno Oct 11, 2022
2cc58d8
add test and comment
jgimeno Oct 11, 2022
7323c1b
change: fixes
Oct 12, 2022
42b3b3a
Merge branch 'mercilex/collections-ux' into mercilex/oracle-colls
jgimeno Oct 13, 2022
071e821
Merge remote-tracking branch 'origin/master' into mercilex/collection…
jgimeno Oct 13, 2022
e0f9682
fix: wrong merge
Oct 13, 2022
1d311c3
Merge branch 'mercilex/collections-ux' into mercilex/oracle-colls
testinginprod Oct 13, 2022
1d70a21
move key encode to encode
jgimeno Oct 13, 2022
4cd4f90
move some test types to utils
jgimeno Oct 13, 2022
5aa722b
change value{Encode/decode} to just encode/decode
jgimeno Oct 13, 2022
1dc4393
move all tests to collections_test package
jgimeno Oct 13, 2022
9f1271a
change: make bound and order private
Oct 14, 2022
c39a723
liter
jgimeno Oct 14, 2022
6540225
change more things
Oct 14, 2022
944da37
Merge remote-tracking branch 'origin/mercilex/collections-ux' into me…
Oct 14, 2022
e1c90da
change move testing to collections
Oct 14, 2022
dab8d0c
Merge branch 'mercilex/collections-ux' into mercilex/oracle-colls
testinginprod Oct 14, 2022
5802ad6
chore: lint
Oct 14, 2022
5f39f4c
chore: CHANGELOG.md
Oct 14, 2022
2c22967
change: small safety check
Oct 14, 2022
16a48df
chore: lint
Oct 14, 2022
556d769
Merge branch 'mercilex/collections-ux' into mercilex/oracle-colls
testinginprod Oct 14, 2022
5087189
change: remove global keys
Oct 14, 2022
0079d7a
change: improve type hinting
Oct 14, 2022
2c0d294
change: last bit
Oct 14, 2022
8eb2202
Merge branch 'mercilex/collections-ux' into mercilex/oracle-colls
Oct 14, 2022
7b78377
Merge branch 'master' into mercilex/oracle-colls
testinginprod Oct 14, 2022
0bb3b14
change: adjust to last changes
Oct 14, 2022
1333be6
Merge remote-tracking branch 'origin/mercilex/oracle-colls' into merc…
Oct 14, 2022
ee841fc
Merge branch 'master' into mercilex/oracle-colls
jgimeno Oct 16, 2022
a897d11
chore: CHANGELOG.md
Oct 17, 2022
d896ab8
add: more testing
Oct 17, 2022
70fcd69
Merge branch 'master' into mercilex/oracle-colls
testinginprod Oct 17, 2022
943ca4f
Merge branch 'master' into mercilex/oracle-colls
testinginprod Oct 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### State Machine Breaking

* [#994](https://github.com/NibiruChain/nibiru/pull/994) - x/oracle refactor to use collections
* [#991](https://github.com/NibiruChain/nibiru/pull/991) - collections refactoring of keys and values
* [#978](https://github.com/NibiruChain/nibiru/pull/978) - x/vpool move state logic to collections
* [#977](https://github.com/NibiruChain/nibiru/pull/977) - x/perp add whitelisted liquidators
Expand Down
17 changes: 17 additions & 0 deletions collections/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ var (
TimeKeyEncoder KeyEncoder[time.Time] = timeKey{}
// Uint64KeyEncoder can be used to encode uint64 keys.
Uint64KeyEncoder KeyEncoder[uint64] = uint64Key{}
// ValAddressKeyEncoder can be used to encode sdk.ValAddress keys.
ValAddressKeyEncoder KeyEncoder[sdk.ValAddress] = valAddressKeyEncoder{}
)

type stringKey struct{}
Expand Down Expand Up @@ -70,6 +72,21 @@ func (accAddressKey) Decode(b []byte) (int, sdk.AccAddress) {
return i, sdk.MustAccAddressFromBech32(s)
}

type valAddressKeyEncoder struct{}

func (v valAddressKeyEncoder) Encode(key sdk.ValAddress) []byte {
return StringKeyEncoder.Encode(key.String())
}
func (v valAddressKeyEncoder) Decode(b []byte) (int, sdk.ValAddress) {
r, s := StringKeyEncoder.Decode(b)
valAddr, err := sdk.ValAddressFromBech32(s)
if err != nil {
panic(err)
}
return r, valAddr
}
func (v valAddressKeyEncoder) Stringify(key sdk.ValAddress) string { return key.String() }

func (stringKey) Stringify(s string) string {
return s
}
Expand Down
6 changes: 6 additions & 0 deletions collections/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,9 @@ func TestTimeKey(t *testing.T) {
assertBijective[time.Time](t, TimeKeyEncoder, key)
})
}

func TestValAddressKey(t *testing.T) {
t.Run("bijective", func(t *testing.T) {
assertBijective(t, ValAddressKeyEncoder, sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()))
})
}
41 changes: 41 additions & 0 deletions collections/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ package collections

import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/gogo/protobuf/proto"
)

var (
AccAddressValueEncoder ValueEncoder[sdk.AccAddress] = accAddressValueEncoder{}
DecValueEncoder ValueEncoder[sdk.Dec] = decValue{}
Uint64ValueEncoder ValueEncoder[uint64] = uint64Value{}
)

// ProtoValueEncoder returns a protobuf value encoder given the codec.BinaryCodec.
// It's used to convert a specific protobuf object into bytes representation and convert
// the protobuf object bytes representation into the concrete object.
Expand Down Expand Up @@ -32,3 +39,37 @@ func (p protoValueEncoder[V, PV]) Decode(b []byte) V {
p.cdc.MustUnmarshal(b, v)
return *v
}

type decValue struct{}

func (d decValue) Encode(value sdk.Dec) []byte {
b, err := value.Marshal()
if err != nil {
panic(err)
}
return b
}

func (d decValue) Decode(b []byte) sdk.Dec {
dec := new(sdk.Dec)
err := dec.Unmarshal(b)
if err != nil {
panic(err)
}
return *dec
}

func (d decValue) Stringify(value sdk.Dec) string {
return value.String()
}

func (d decValue) Name() string {
return "sdk.Dec"
}

type accAddressValueEncoder struct{}

func (a accAddressValueEncoder) Encode(value sdk.AccAddress) []byte { return value }
func (a accAddressValueEncoder) Decode(b []byte) sdk.AccAddress { return b }
func (a accAddressValueEncoder) Stringify(value sdk.AccAddress) string { return value.String() }
func (a accAddressValueEncoder) Name() string { return "sdk.AccAddress" }
22 changes: 22 additions & 0 deletions collections/values_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ package collections
import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/NibiruChain/nibiru/x/testutil"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/gogo/protobuf/types"
Expand All @@ -18,3 +22,21 @@ func TestProtoValueEncoder(t *testing.T) {
assertValueBijective[types.BytesValue](t, ProtoValueEncoder[types.BytesValue](cdc), protoType)
})
}

func TestDecValueEncoder(t *testing.T) {
t.Run("bijectivity", func(t *testing.T) {
assertValueBijective(t, DecValueEncoder, sdk.MustNewDecFromStr("-1000.5858"))
})
}

func TestAccAddressValueEncoder(t *testing.T) {
t.Run("bijectivity", func(t *testing.T) {
assertValueBijective(t, AccAddressValueEncoder, testutil.AccAddress())
})
}

func TestUint64ValueEncoder(t *testing.T) {
t.Run("bijectivity", func(t *testing.T) {
assertValueBijective(t, Uint64ValueEncoder, 1000)
})
}
78 changes: 31 additions & 47 deletions x/oracle/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package oracle
import (
"fmt"

"github.com/NibiruChain/nibiru/collections"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/NibiruChain/nibiru/x/oracle/keeper"
Expand All @@ -23,11 +25,11 @@ func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState
panic(err)
}

keeper.SetFeederDelegation(ctx, voter, feeder)
keeper.FeederDelegations.Insert(ctx, voter, feeder)
}

for _, ex := range data.ExchangeRates {
keeper.SetExchangeRate(ctx, ex.Pair, ex.ExchangeRate)
keeper.ExchangeRates.Insert(ctx, ex.Pair, ex.ExchangeRate)
}

for _, mc := range data.MissCounters {
Expand All @@ -36,7 +38,7 @@ func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState
panic(err)
}

keeper.SetMissCounter(ctx, operator, mc.MissCounter)
keeper.MissCounters.Insert(ctx, operator, mc.MissCounter)
}

for _, ap := range data.AggregateExchangeRatePrevotes {
Expand All @@ -45,7 +47,7 @@ func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState
panic(err)
}

keeper.SetAggregateExchangeRatePrevote(ctx, valAddr, ap)
keeper.Prevotes.Insert(ctx, valAddr, ap)
}

for _, av := range data.AggregateExchangeRateVotes {
Expand All @@ -54,23 +56,27 @@ func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState
panic(err)
}

keeper.SetAggregateExchangeRateVote(ctx, valAddr, av)
keeper.Votes.Insert(ctx, valAddr, av)
}

if len(data.Pairs) > 0 {
for _, tt := range data.Pairs {
keeper.SetPair(ctx, tt.Name)
keeper.Pairs.Insert(ctx, tt.Name)
}
} else {
for _, item := range data.Params.Whitelist {
keeper.SetPair(ctx, item.Name)
keeper.Pairs.Insert(ctx, item.Name)
}
}

for _, pr := range data.PairRewards {
keeper.SetPairReward(ctx, &pr)
keeper.PairRewards.Insert(ctx, pr.Id, pr)
}

// set last ID based on the last pair reward
if len(data.PairRewards) != 0 {
keeper.PairRewardsID.Set(ctx, data.PairRewards[len(data.PairRewards)-1].Id)
}
keeper.SetParams(ctx, data.Params)

// check if the module account exists
Expand All @@ -86,60 +92,38 @@ func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState {
params := keeper.GetParams(ctx)
feederDelegations := []types.FeederDelegation{}
keeper.IterateFeederDelegations(ctx, func(valAddr sdk.ValAddress, feederAddr sdk.AccAddress) (stop bool) {
for _, kv := range keeper.FeederDelegations.Iterate(ctx, collections.Range[sdk.ValAddress]{}).KeyValues() {
feederDelegations = append(feederDelegations, types.FeederDelegation{
FeederAddress: feederAddr.String(),
ValidatorAddress: valAddr.String(),
FeederAddress: kv.Value.String(),
ValidatorAddress: kv.Key.String(),
})
return false
})
}

exchangeRates := []types.ExchangeRateTuple{}
keeper.IterateExchangeRates(ctx, func(pair string, rate sdk.Dec) (stop bool) {
exchangeRates = append(exchangeRates, types.ExchangeRateTuple{Pair: pair, ExchangeRate: rate})
return false
})
for _, er := range keeper.ExchangeRates.Iterate(ctx, collections.Range[string]{}).KeyValues() {
exchangeRates = append(exchangeRates, types.ExchangeRateTuple{Pair: er.Key, ExchangeRate: er.Value})
}

missCounters := []types.MissCounter{}
keeper.IterateMissCounters(ctx, func(operator sdk.ValAddress, missCounter uint64) (stop bool) {
for _, mc := range keeper.MissCounters.Iterate(ctx, collections.Range[sdk.ValAddress]{}).KeyValues() {
missCounters = append(missCounters, types.MissCounter{
ValidatorAddress: operator.String(),
MissCounter: missCounter,
ValidatorAddress: mc.Key.String(),
MissCounter: mc.Value,
})
return false
})

aggregateExchangeRatePrevotes := []types.AggregateExchangeRatePrevote{}
keeper.IterateAggregateExchangeRatePrevotes(ctx, func(_ sdk.ValAddress, aggregatePrevote types.AggregateExchangeRatePrevote) (stop bool) {
aggregateExchangeRatePrevotes = append(aggregateExchangeRatePrevotes, aggregatePrevote)
return false
})

aggregateExchangeRateVotes := []types.AggregateExchangeRateVote{}
keeper.IterateAggregateExchangeRateVotes(ctx, func(_ sdk.ValAddress, aggregateVote types.AggregateExchangeRateVote) bool {
aggregateExchangeRateVotes = append(aggregateExchangeRateVotes, aggregateVote)
return false
})
}

pairs := []types.Pair{}
keeper.IteratePairs(ctx, func(pair string) (stop bool) {
pairs = append(pairs, types.Pair{Name: pair})
return false
})

pairRewards := []types.PairReward{}
keeper.IterateAllPairRewards(ctx, func(rewards *types.PairReward) (stop bool) {
pairRewards = append(pairRewards, *rewards)
return false
})
for _, p := range keeper.Pairs.Iterate(ctx, collections.Range[string]{}).Keys() {
pairs = append(pairs, types.Pair{Name: p})
}

return types.NewGenesisState(params,
exchangeRates,
feederDelegations,
missCounters,
aggregateExchangeRatePrevotes,
aggregateExchangeRateVotes,
keeper.Prevotes.Iterate(ctx, collections.Range[sdk.ValAddress]{}).Values(),
keeper.Votes.Iterate(ctx, collections.Range[sdk.ValAddress]{}).Values(),
pairs,
pairRewards,
keeper.PairRewards.Iterate(ctx, collections.Range[uint64]{}).Values(),
)
}
21 changes: 12 additions & 9 deletions x/oracle/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@ import (
func TestExportInitGenesis(t *testing.T) {
input := keeper.CreateTestInput(t)

input.OracleKeeper.SetFeederDelegation(input.Ctx, keeper.ValAddrs[0], keeper.Addrs[1])
input.OracleKeeper.SetExchangeRate(input.Ctx, "pair1:pair2", sdk.NewDec(123))
input.OracleKeeper.SetAggregateExchangeRatePrevote(input.Ctx, keeper.ValAddrs[0], types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{123}, keeper.ValAddrs[0], uint64(2)))
input.OracleKeeper.SetAggregateExchangeRateVote(input.Ctx, keeper.ValAddrs[0], types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "foo", ExchangeRate: sdk.NewDec(123)}}, keeper.ValAddrs[0]))
input.OracleKeeper.SetPair(input.Ctx, "pair1:pair1")
input.OracleKeeper.SetPair(input.Ctx, "pair2:pair2")
input.OracleKeeper.SetMissCounter(input.Ctx, keeper.ValAddrs[0], 10)
input.OracleKeeper.SetPairReward(input.Ctx, &types.PairReward{
Pair: "pair1:pair2",
input.OracleKeeper.FeederDelegations.Insert(input.Ctx, keeper.ValAddrs[0], keeper.Addrs[1])
input.OracleKeeper.ExchangeRates.Insert(input.Ctx, "pair1:pair2", sdk.NewDec(123))
input.OracleKeeper.Prevotes.Insert(input.Ctx, keeper.ValAddrs[0], types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{123}, keeper.ValAddrs[0], uint64(2)))
input.OracleKeeper.Votes.Insert(input.Ctx, keeper.ValAddrs[0], types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "foo", ExchangeRate: sdk.NewDec(123)}}, keeper.ValAddrs[0]))
input.OracleKeeper.Pairs.Insert(input.Ctx, "pair1:pair1")
input.OracleKeeper.Pairs.Insert(input.Ctx, "pair2:pair2")
input.OracleKeeper.MissCounters.Insert(input.Ctx, keeper.ValAddrs[0], 10)
input.OracleKeeper.PairRewards.Insert(input.Ctx, 0, types.PairReward{
Pair: "pair1:pair2",
Id: 0,
VotePeriods: 100,
Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1000)),
})
genesis := oracle.ExportGenesis(input.Ctx, input.OracleKeeper)

Expand Down
35 changes: 22 additions & 13 deletions x/oracle/keeper/ballot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package keeper
import (
"sort"

"github.com/NibiruChain/nibiru/collections"

"github.com/NibiruChain/nibiru/x/oracle/types"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -37,7 +39,9 @@ func (k Keeper) OrganizeBallotByPair(ctx sdk.Context, validatorsPerformance map[
return false
}

k.IterateAggregateExchangeRateVotes(ctx, aggregateHandler)
for _, vote := range k.Votes.Iterate(ctx, collections.Range[sdk.ValAddress]{}).KeyValues() {
aggregateHandler(vote.Key, vote.Value)
}

// sort created ballot
for pair, ballot := range ballots {
Expand All @@ -51,19 +55,22 @@ func (k Keeper) OrganizeBallotByPair(ctx sdk.Context, validatorsPerformance map[
// ClearBallots clears all tallied prevotes and votes from the store
func (k Keeper) ClearBallots(ctx sdk.Context, votePeriod uint64) {
// Clear all aggregate prevotes
k.IterateAggregateExchangeRatePrevotes(ctx, func(voterAddr sdk.ValAddress, aggregatePrevote types.AggregateExchangeRatePrevote) (stop bool) {
if ctx.BlockHeight() > int64(aggregatePrevote.SubmitBlock+votePeriod) {
k.DeleteAggregateExchangeRatePrevote(ctx, voterAddr)
for _, prevote := range k.Prevotes.Iterate(ctx, collections.Range[sdk.ValAddress]{}).KeyValues() {
if ctx.BlockHeight() > int64(prevote.Value.SubmitBlock+votePeriod) {
err := k.Prevotes.Delete(ctx, prevote.Key)
if err != nil {
panic(err)
}
}

return false
})
}

// Clear all aggregate votes
k.IterateAggregateExchangeRateVotes(ctx, func(voterAddr sdk.ValAddress, aggregateVote types.AggregateExchangeRateVote) (stop bool) {
k.DeleteAggregateExchangeRateVote(ctx, voterAddr)
return false
})
for _, voteKey := range k.Votes.Iterate(ctx, collections.Range[sdk.ValAddress]{}).Keys() {
err := k.Votes.Delete(ctx, voteKey)
if err != nil {
panic(err)
}
}
}

// ApplyWhitelist updates the whitelist by detecting possible changes between
Expand All @@ -86,9 +93,11 @@ func (k Keeper) ApplyWhitelist(ctx sdk.Context, whitelist types.PairList, voteTa
}

if updateRequired {
k.ClearPairs(ctx)
for _, p := range k.Pairs.Iterate(ctx, collections.Range[string]{}).Keys() {
k.Pairs.Delete(ctx, p)
}
for _, pair := range whitelist {
k.SetPair(ctx, pair.Name)
k.Pairs.Insert(ctx, pair.Name)
}
}
}
Loading