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

feat(oracle):skip deducting gas for oracle create-price message #1

Open
wants to merge 9 commits into
base: develop-oracle-fixchecktx
Choose a base branch
from
14 changes: 14 additions & 0 deletions app/ante/cosmos/fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

errorsmod "cosmossdk.io/errors"
anteutils "github.com/ExocoreNetwork/exocore/app/ante/utils"
oracletypes "github.com/ExocoreNetwork/exocore/x/oracle/types"
sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
Expand Down Expand Up @@ -68,6 +69,19 @@ func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo
err error
)

msgs := tx.GetMsgs()
allOracleMsgs := true
for _, msg := range msgs {
if _, ok := msg.(*oracletypes.MsgCreatePrice); !ok {
allOracleMsgs = false
break
}
}
// skip deductgas if this is a oracle price message
if allOracleMsgs {
return next(ctx, tx, simulate)
}

fee := feeTx.GetFee()
if !simulate {
fee, priority, err = dfd.txFeeChecker(ctx, feeTx)
Expand Down
10 changes: 8 additions & 2 deletions x/dogfood/keeper/impl_sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,16 @@ func (k Keeper) IterateBondedValidatorsByPower(
// will only happen if there is an error in deserialization.
continue
}
found, addr := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr(
ctx, ctx.ChainID(), sdk.GetConsAddress(pk),
)
if !found {
// this should never happen. should we panic?
continue
}
val, err := stakingtypes.NewValidator(
// TODO: this is not the correct address, which is derived from
// sdk.ValAddress(sdk.AccAddress)
sdk.ValAddress(pk.Address()),
sdk.ValAddress(addr),
pk, stakingtypes.Description{},
)
if err != nil {
Expand Down
30 changes: 30 additions & 0 deletions x/oracle/keeper/aggregator/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,36 @@ type aggregator struct {
dsPrices map[uint64]string
}

func (agg *aggregator) copy4CheckTx() *aggregator {
ret := &aggregator{
finalPrice: big.NewInt(0).Set(agg.finalPrice),
reportPower: big.NewInt(0).Set(agg.reportPower),
totalPower: big.NewInt(0).Set(agg.totalPower),

reports: make([]*reportPrice, 0, len(agg.reports)),
dsPrices: make(map[uint64]string),
}
for k, v := range agg.dsPrices {
ret.dsPrices[k] = v
}
for _, report := range agg.reports {
rTmp := *report
rTmp.price = big.NewInt(0).Set(report.price)
rTmp.power = big.NewInt(0).Set(report.power)

for k, v := range report.prices {
// prices are information submitted by validators, these data will not change under deterministic sources, but with non-deterministic sources they might be overwrite by later prices
tmpV := *v
tmpV.price = big.NewInt(0).Set(v.price)
rTmp.prices[k] = &tmpV
}

ret.reports = append(ret.reports, &rTmp)
}

return ret
}

// fill price from validator submitting into aggregator, and calculation the voting power and check with the consensus status of deterministic source value to decide when to do the aggregation
// TODO: currently apply mode=1 in V1, add swith modes
func (agg *aggregator) fillPrice(pSources []*types.PriceSource, validator string, power *big.Int) {
Expand Down
36 changes: 36 additions & 0 deletions x/oracle/keeper/aggregator/calculator.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,31 @@ type roundPricesList struct {
roundPricesCount int
}

func (r *roundPricesList) copy4CheckTx() *roundPricesList {
ret := &roundPricesList{
roundPricesList: make([]*roundPrices, 0, len(r.roundPricesList)),
roundPricesCount: r.roundPricesCount,
}

for _, v := range r.roundPricesList {
tmpRP := &roundPrices{
detID: v.detID,
price: big.NewInt(0).Set(v.price),
prices: make([]*priceAndPower, 0, len(v.prices)),
timestamp: v.timestamp,
}
for _, pNP := range v.prices {
tmpPNP := *pNP
// power will be modified during execution
tmpPNP.power = big.NewInt(0).Set(pNP.power)
tmpRP.prices = append(tmpRP.prices, &tmpPNP)
}

ret.roundPricesList = append(ret.roundPricesList, tmpRP)
}
return ret
}

// to tell if any round of this DS has reached consensus/confirmed
func (r *roundPricesList) hasConfirmedDetID() bool {
for _, round := range r.roundPricesList {
Expand Down Expand Up @@ -108,6 +133,17 @@ type calculator struct {
totalPower *big.Int
}

func (c *calculator) copy4CheckTx() *calculator {
ret := newCalculator(c.validatorLength, c.totalPower)

// copy deterministicSource
for k, v := range c.deterministicSource {
ret.deterministicSource[k] = v.copy4CheckTx()
}

return ret
}

func (c *calculator) newRoundPricesList() *roundPricesList {
return &roundPricesList{
roundPricesList: make([]*roundPrices, 0, common.MaxDetID*c.validatorLength),
Expand Down
37 changes: 34 additions & 3 deletions x/oracle/keeper/aggregator/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,35 @@ type AggregatorContext struct {
aggregators map[uint64]*worker
}

func (agc *AggregatorContext) Copy4CheckTx() *AggregatorContext {
ret := &AggregatorContext{
// params, validatorsPower, totalPower, these values won't change during block executing
params: agc.params,
validatorsPower: agc.validatorsPower,
totalPower: agc.totalPower,

rounds: make(map[uint64]*roundInfo),
aggregators: make(map[uint64]*worker),
}

for k, v := range agc.rounds {
vTmp := *v
ret.rounds[k] = &vTmp
}

for k, v := range agc.aggregators {
w := newWorker(k, ret)
w.sealed = v.sealed
w.price = v.price

w.f = v.f.copy4CheckTx()
w.c = v.c.copy4CheckTx()
w.a = v.a.copy4CheckTx()
}

return ret
}

func (agc *AggregatorContext) sanityCheck(msg *types.MsgCreatePrice) error {
// sanity check
// TODO: check nonce [1,3] in anteHandler, related to params, may not able
Expand Down Expand Up @@ -173,7 +202,8 @@ func (agc *AggregatorContext) SealRound(ctx sdk.Context, force bool) (success []
delete(agc.aggregators, feederID)
} else {
round.status = 2
agc.aggregators[feederID] = nil
// agc.aggregators[feederID] = nil
delete(agc.aggregators, feederID)
}
}
default:
Expand All @@ -182,7 +212,8 @@ func (agc *AggregatorContext) SealRound(ctx sdk.Context, force bool) (success []
}
// all status: 1->2, remove its aggregator
if agc.aggregators[feederID] != nil && agc.aggregators[feederID].sealed {
agc.aggregators[feederID] = nil
// agc.aggregators[feederID] = nil
delete(agc.aggregators, feederID)
}
}
return success, failed
Expand Down Expand Up @@ -229,7 +260,7 @@ func (agc *AggregatorContext) PrepareRound(ctx sdk.Context, block uint64) {
round.nextRoundID = latestNextRoundID
round.status = 1
// drop previous worker
agc.aggregators[feederIDUint64] = nil
delete(agc.aggregators, feederIDUint64)
} else if round.status == 1 && left >= common.MaxNonce {
// this shouldn't happen, if do sealround properly before prepareRound, basically for test only
round.status = 2
Expand Down
16 changes: 16 additions & 0 deletions x/oracle/keeper/aggregator/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ func newFilter(maxNonce, maxDetID int) *filter {
}
}

func (f *filter) copy4CheckTx() *filter {
ret := *f
ret.validatorNonce = make(map[string]*common.Set[int32], len(f.validatorNonce))
ret.validatorSource = make(map[string]*common.Set[string], len(f.validatorSource))

for k, v := range f.validatorNonce {
ret.validatorNonce[k] = v.Copy()
}

for k, v := range f.validatorSource {
ret.validatorSource[k] = v.Copy()
}

return &ret
}

func (f *filter) newVNSet() *common.Set[int32] {
return common.NewSet[int32](f.maxNonce)
}
Expand Down
74 changes: 28 additions & 46 deletions x/oracle/keeper/cache/caches.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,17 @@ var zeroBig = big.NewInt(0)
type (
ItemV map[string]*big.Int
ItemP *common.Params
ItemM struct {
FeederID uint64
PSources []*types.PriceSource
Validator string
}
ItemM types.MsgItem
)

type Cache struct {
msg cacheMsgs
msg *cacheMsgs
validators *cacheValidator
params *cacheParams
}

type cacheMsgs map[uint64][]*ItemM
// type cacheMsgs map[uint64][]*ItemM
type cacheMsgs []*ItemM

// used to track validator change
type cacheValidator struct {
Expand All @@ -40,44 +37,32 @@ type cacheParams struct {
update bool
}

func (c cacheMsgs) add(item *ItemM) {
if ims, ok := c[item.FeederID]; ok {
for _, im := range ims {
if im.Validator == item.Validator {
for _, p := range im.PSources {
for _, pInput := range item.PSources {
if p.SourceID == pInput.SourceID {
p.Prices = append(p.Prices, pInput.Prices...)
return
}
}
}
im.PSources = append(im.PSources, item.PSources...)
return
}
}
}
c[item.FeederID] = append(c[item.FeederID], item)
func (c *cacheMsgs) add(item *ItemM) {
*c = append(*c, item)
}

func (c cacheMsgs) remove(item *ItemM) {
delete(c, item.FeederID)
// remove removes all items with the same feederID
func (c *cacheMsgs) remove(item *ItemM) {
var newCache []*ItemM
for _, msg := range *c {
if msg.FeederID != item.FeederID {
newCache = append(newCache, msg)
}
}
*c = newCache
}

func (c cacheMsgs) commit(ctx sdk.Context, k common.KeeperOracle) {
block := uint64(ctx.BlockHeight())

recentMsgs := types.RecentMsg{
Block: block,
Msgs: make([]*types.MsgItem, 0),
}
for _, msgs4Feeder := range c {
for _, msg := range msgs4Feeder {
recentMsgs.Msgs = append(recentMsgs.Msgs, &types.MsgItem{
FeederID: msg.FeederID,
PSources: msg.PSources,
Validator: msg.Validator,
})
}

for _, msg := range c {
msgTmp := types.MsgItem(*msg)
recentMsgs.Msgs = append(recentMsgs.Msgs, &msgTmp)
}
index, _ := k.GetIndexRecentMsg(ctx)
for i, b := range index.Index {
Expand All @@ -87,7 +72,9 @@ func (c cacheMsgs) commit(ctx sdk.Context, k common.KeeperOracle) {
}
k.RemoveRecentMsg(ctx, b)
}

k.SetRecentMsg(ctx, recentMsgs)

index.Index = append(index.Index, block)
k.SetIndexRecentMsg(ctx, index)
}
Expand Down Expand Up @@ -151,7 +138,6 @@ func (c *Cache) AddCache(i any) {
switch item := i.(type) {
case *ItemM:
c.msg.add(item)
// case *params:
case ItemP:
c.params.add(item)
case ItemV:
Expand All @@ -161,7 +147,7 @@ func (c *Cache) AddCache(i any) {
}
}

// func (c *Cache) RemoveCache(i any, k common.KeeperOracle) {
// RemoveCache removes all cached msgs with the same feederID
func (c *Cache) RemoveCache(i any) {
if item, isItemM := i.(*ItemM); isItemM {
c.msg.remove(item)
Expand All @@ -182,15 +168,11 @@ func (c *Cache) GetCache(i any) bool {
return false
}
*item = *(c.params.params)
case *[]*ItemM:
case *([]*ItemM):
if item == nil {
return false
}
tmp := make([]*ItemM, 0, len(c.msg))
for _, msgs := range c.msg {
tmp = append(tmp, msgs...)
}
*item = tmp
*item = *c.msg
default:
return false
}
Expand All @@ -204,9 +186,9 @@ func (c *Cache) SkipCommit() {
}

func (c *Cache) CommitCache(ctx sdk.Context, reset bool, k common.KeeperOracle) {
if len(c.msg) > 0 {
if len(*(c.msg)) > 0 {
c.msg.commit(ctx, k)
c.msg = make(map[uint64][]*ItemM)
*(c.msg) = make([]*ItemM, 0)
}

if c.validators.update {
Expand All @@ -229,7 +211,7 @@ func (c *Cache) ResetCaches() {

func NewCache() *Cache {
return &Cache{
msg: make(map[uint64][]*ItemM),
msg: new(cacheMsgs),
validators: &cacheValidator{
validators: make(map[string]*big.Int),
},
Expand Down
11 changes: 11 additions & 0 deletions x/oracle/keeper/cache/caches_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,20 @@ func TestCache(t *testing.T) {
Convey("add more items", func() {
c.AddCache(msgItems[1])
c.AddCache(msgItems[2])

c.GetCache(&msgItemsReturn)
So(msgItemsReturn, ShouldContain, msgItems[0])
So(msgItemsReturn, ShouldContain, msgItems[2])
})
Convey("remove two items with same feederID", func() {
c.AddCache(msgItems[1])
c.AddCache(msgItems[2])
c.RemoveCache(msgItems[0])

c.GetCache(&msgItemsReturn)
So(msgItemsReturn, ShouldContain, msgItems[2])
So(msgItemsReturn, ShouldNotContain, msgItems[0])
So(msgItemsReturn, ShouldNotContain, msgItems[1])
})
})
})
Expand Down
Loading
Loading