diff --git a/x/oracle/keeper/feedermanagement/aggregator.go b/x/oracle/keeper/feedermanagement/aggregator.go index baeb2407..63458e27 100644 --- a/x/oracle/keeper/feedermanagement/aggregator.go +++ b/x/oracle/keeper/feedermanagement/aggregator.go @@ -453,32 +453,39 @@ func (rds *recordsDS) GetFinalPrice(t *threshold) (*PriceResult, bool) { return nil, false } +// AddPrice adds a price into recordsDS +// NOTE: the input PricePower should be filtered by recordsValidators before calling this function to make sure the price is not duplicated by detID func (rds *recordsDS) AddPrice(p *PricePower) { validator := maps.Keys(p.Validators)[0] - biggestDetID := true - p = p.Cpy() - for i, record := range rds.records { + i := 0 + l := len(rds.records) + for ; i < l; i++ { + record := rds.records[i] if record.Price.EqualDS(p.Price) { if _, ok := record.Validators[validator]; !ok { record.Power.Add(record.Power, p.Power) record.Validators[validator] = struct{}{} } - biggestDetID = false break } - if p.Price.DetID <= record.Price.DetID { - // insert before i - combined := append([]*PricePower{p}, rds.records[i:]...) - rds.records = append(rds.records[:i], combined...) - biggestDetID = false - break + } + if i >= l { + for i = 0; i < l; i++ { + record := rds.records[i] + if p.Price.DetID <= record.Price.DetID { + // insert before i + combined := append([]*PricePower{p}, rds.records[i:]...) + rds.records = append(rds.records[:i], combined...) + break + } + } + if i >= l { + p = p.Cpy() + rds.records = append(rds.records, p) } } if _, ok := rds.validators[validator]; !ok { rds.accumulatedPowers.Add(rds.accumulatedPowers, p.Power) rds.validators[validator] = struct{}{} } - if biggestDetID { - rds.records = append(rds.records, p) - } } diff --git a/x/oracle/keeper/feedermanagement/aggregator_test.go b/x/oracle/keeper/feedermanagement/aggregator_test.go index 746f1756..4d24dcc9 100644 --- a/x/oracle/keeper/feedermanagement/aggregator_test.go +++ b/x/oracle/keeper/feedermanagement/aggregator_test.go @@ -283,25 +283,48 @@ func TestAggregation(t *testing.T) { So(finalPrice, ShouldBeNil) So(addedMsgItem, ShouldResemble, pmsg3) So(err, ShouldBeNil) - Convey("add msg-v3-detID2, finalPrice", func() { - // v3,detID=2 - pmsg4 := protoMsgItem4 - pmsg4.FeederID = uint64(feederID) - finalPrice, addedMsgItem, err = r.Tally(pmsg4) - So(finalPrice, ShouldResemble, &PriceResult{ - Price: "999", - Decimal: 8, - DetID: "2", + Convey("two cases:", func() { + Convey("add msg-v3-detID2, finalPrice", func() { + // v3,detID=2 + pmsg4 := protoMsgItem4 + pmsg4.FeederID = uint64(feederID) + finalPrice, addedMsgItem, err = r.Tally(pmsg4) + So(finalPrice, ShouldResemble, &PriceResult{ + Price: "999", + Decimal: 8, + DetID: "2", + }) + So(addedMsgItem, ShouldResemble, pmsg4) + So(err, ShouldBeNil) + Convey("add msg-v4-detID2, recordOnly", func() { + pmsg5 := protoMsgItem5 + pmsg5.FeederID = uint64(feederID) + finalPrice, addedMsgItem, err = r.Tally(pmsg5) + So(finalPrice, ShouldBeNil) + So(addedMsgItem, ShouldResemble, pmsg5) + So(err, ShouldBeError, oracletypes.ErrQuoteRecorded) + }) }) - So(addedMsgItem, ShouldResemble, pmsg4) - So(err, ShouldBeNil) - Convey("add msg-v4-detID1, recordOnly", func() { - pmsg5 := protoMsgItem5 - pmsg5.FeederID = uint64(feederID) - finalPrice, addedMsgItem, err = r.Tally(pmsg5) + Convey("add msg-v3-detID2-different-price, success", func() { + pmsg4 := protoMsgItem4_2 + pmsg4.FeederID = uint64(feederID) + finalPrice, addedMsgItem, err = r.Tally(pmsg4) So(finalPrice, ShouldBeNil) - So(addedMsgItem, ShouldResemble, pmsg5) - So(err, ShouldBeError, oracletypes.ErrQuoteRecorded) + So(addedMsgItem, ShouldResemble, pmsg4) + So(err, ShouldBeNil) + Convey("add msg-v4-detID2, success", func() { + pmsg5 := protoMsgItem5 + pmsg5.FeederID = uint64(feederID) + finalPrice, addedMsgItem, err = r.Tally(pmsg5) + So(finalPrice, ShouldResemble, &PriceResult{ + Price: "999", + Decimal: 8, + DetID: "2", + }) + So(addedMsgItem, ShouldResemble, pmsg5) + So(err, ShouldBeNil) + }) + }) }) }) diff --git a/x/oracle/keeper/feedermanagement/date_test.go b/x/oracle/keeper/feedermanagement/date_test.go index 0e861109..e2e847e4 100644 --- a/x/oracle/keeper/feedermanagement/date_test.go +++ b/x/oracle/keeper/feedermanagement/date_test.go @@ -154,6 +154,24 @@ var ( }, Validator: "validator3", } + protoMsgItem4_2 = &oracletypes.MsgItem{ + FeederID: 1, + PSources: []*oracletypes.PriceSource{ + { + SourceID: 1, + Prices: []*oracletypes.PriceTimeDetID{ + { + Price: "777", + Decimal: 8, + DetID: "2", + Timestamp: timestamp, + }, + }, + }, + }, + Validator: "validator3", + } + protoMsgItem5 = &oracletypes.MsgItem{ FeederID: 1, PSources: []*oracletypes.PriceSource{