From bf4a1eb176e41d99aba1b1dd7163d6a34c71a77e Mon Sep 17 00:00:00 2001 From: Elias Van Ootegem Date: Sat, 31 Aug 2024 15:11:13 +0100 Subject: [PATCH 1/7] fix: check for circular references when adding errors to cumulated error type Signed-off-by: Elias Van Ootegem --- libs/errors/errors.go | 42 ++++++++++++++++++++++- libs/errors/errors_test.go | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 libs/errors/errors_test.go diff --git a/libs/errors/errors.go b/libs/errors/errors.go index 6125fbf9d08..9c953701f5c 100644 --- a/libs/errors/errors.go +++ b/libs/errors/errors.go @@ -15,7 +15,15 @@ package errors -import "strings" +import ( + "fmt" + "strings" +) + +var ( + errSelfReference = fmt.Errorf("") + errParentReference = fmt.Errorf("") +) type CumulatedErrors struct { Errors []error @@ -26,9 +34,41 @@ func NewCumulatedErrors() *CumulatedErrors { } func (e *CumulatedErrors) Add(err error) { + // prevent adding this instance of cumulatedErrors to itself. + if err == e { + err = errSelfReference + } else if cerr, ok := err.(*CumulatedErrors); ok { + // nothing to add. + if !cerr.HasAny() { + return + } + // create a copy of the error we're adding + cpy := &CumulatedErrors{ + Errors: append([]error{}, cerr.Errors...), + } + // remove any references to the parent from the error we're adding. + err = cpy.checkRef(e, errParentReference) + } e.Errors = append(e.Errors, err) } +// check recursively if a cumulated errors object contains a certain reference, and if so, replace with a placehold, simple error. +// returns either itself (with the replaced references), or a replacement error. +func (e *CumulatedErrors) checkRef(ref *CumulatedErrors, repl error) error { + if e == ref { + return repl + } + // recursively remove a given reference. + for i, subE := range e.Errors { + if subE == ref { + e.Errors[i] = repl + } else if cErr, ok := subE.(*CumulatedErrors); ok { + e.Errors[i] = cErr.checkRef(ref, repl) + } + } + return e +} + func (e *CumulatedErrors) HasAny() bool { return len(e.Errors) > 0 } diff --git a/libs/errors/errors_test.go b/libs/errors/errors_test.go new file mode 100644 index 00000000000..f00512faa2c --- /dev/null +++ b/libs/errors/errors_test.go @@ -0,0 +1,68 @@ +// Copyright (C) 2023 Gobalsky Labs Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package errors_test + +import ( + "fmt" + "testing" + + "code.vegaprotocol.io/vega/libs/errors" + "github.com/stretchr/testify/require" +) + +func TestCircularreferences(t *testing.T) { + parent := errors.NewCumulatedErrors() + child := errors.NewCumulatedErrors() + nested := errors.NewCumulatedErrors() + errs := []error{ + fmt.Errorf("simple error 1"), + fmt.Errorf("simple error 2"), + fmt.Errorf("simple error 3"), + } + t.Run("try to add parent to itself", func(t *testing.T) { + parent.Add(parent) + expect := "" + require.True(t, parent.HasAny()) + require.Equal(t, expect, parent.Error()) + }) + t.Run("try nesting without circular references", func(t *testing.T) { + child.Add(errs[0]) + parent.Add(child) + expect := fmt.Sprintf(", also %s", errs[0].Error()) + require.Equal(t, expect, parent.Error()) + }) + t.Run("try adding empty cumulated error", func(t *testing.T) { + parent.Add(nested) + // still the same expected value + expect := fmt.Sprintf(", also %s", errs[0].Error()) + require.False(t, nested.HasAny()) + require.Equal(t, expect, parent.Error()) + // adding to the nested error should not affect the parent. + nested.Add(errs[1]) + require.True(t, nested.HasAny()) + require.Equal(t, expect, parent.Error()) + }) + t.Run("try nesting both parent and child, and adding to both", func(t *testing.T) { + nested.Add(errs[2]) + nested.Add(child) + nested.Add(parent) + child.Add(nested) + parent.Add(nested) + // self reference>, also simple error 1, also simple error 2, also simple error 3, also simple error 1, also , also simple error 1 + expect := fmt.Sprintf(", also %s, also %s, also %s, also %s, also , also %s", errs[0].Error(), errs[1].Error(), errs[2].Error(), errs[0].Error(), errs[0].Error()) + require.Equal(t, expect, parent.Error()) + }) +} From 017abc1a2bda72837b596fc29bd9c74d97600c1a Mon Sep 17 00:00:00 2001 From: Elias Van Ootegem Date: Sat, 31 Aug 2024 15:17:18 +0100 Subject: [PATCH 2/7] chore: fix lint error Signed-off-by: Elias Van Ootegem --- libs/errors/errors_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/errors/errors_test.go b/libs/errors/errors_test.go index f00512faa2c..f2513ae5e4e 100644 --- a/libs/errors/errors_test.go +++ b/libs/errors/errors_test.go @@ -20,6 +20,7 @@ import ( "testing" "code.vegaprotocol.io/vega/libs/errors" + "github.com/stretchr/testify/require" ) From 11276e616b5b1acda0ff8b74df059570959f024f Mon Sep 17 00:00:00 2001 From: wwestgarth Date: Fri, 30 Aug 2024 11:30:10 +0100 Subject: [PATCH 3/7] fix: calculate rough bound on where to check for incoming trade volume on AMM's from within the AMM engine. --- CHANGELOG.md | 1 + core/execution/amm/engine.go | 17 +++++++ .../features/amm/0090-VAMM-auction.feature | 46 ++++++++++++++++++- core/matching/orderbook.go | 46 +++---------------- core/matching/orderbook_amm_test.go | 2 +- core/matching/side.go | 38 +++++++-------- core/matching/side_test.go | 26 +++++------ 7 files changed, 103 insertions(+), 73 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cc6b1461f1..482558495a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ - [11542](https://github.com/vegaprotocol/vega/issues/11542) - Fix non determinism in lottery ranking. - [11616](https://github.com/vegaprotocol/vega/issues/11616) - `AMM` tradable volume now calculated purely in positions to prevent loss of precision. - [11544](https://github.com/vegaprotocol/vega/issues/11544) - Fix empty candles stream. +- [11583](https://github.com/vegaprotocol/vega/issues/11583) - Rough bound on price interval when matching with `AMMs` is now looser and calculated in the `AMM` engine. - [11619](https://github.com/vegaprotocol/vega/issues/11619) - Fix `EstimatePositions` API for capped futures. - [11579](https://github.com/vegaprotocol/vega/issues/11579) - Spot calculate fee on amend, use order price if no amended price is provided. - [11585](https://github.com/vegaprotocol/vega/issues/11585) - Initialise rebate stats service in API. diff --git a/core/execution/amm/engine.go b/core/execution/amm/engine.go index e74ed4a46b3..c5dde610380 100644 --- a/core/execution/amm/engine.go +++ b/core/execution/amm/engine.go @@ -491,6 +491,23 @@ func (e *Engine) partition(agg *types.Order, inner, outer *num.Uint) ([]*Pool, [ } } + if inner == nil { + // if inner is given as nil it means the matching engine is trading up to its first price level + // and so has no lower bound on the range. So we'll calculate one using best price of all pools + // note that if the incoming order is a buy the price range we need to evaluate is from + // fair-price -> best-ask -> outer, so we need to step one back. But then if we use fair-price exactly we + // risk hitting numerical problems and given this is just to exclude AMM's completely out of range we + // can be a bit looser and so step back again so that we evaluate from best-buy -> best-ask -> outer. + buy, _, ask, _ := e.BestPricesAndVolumes() + two := num.UintZero().AddSum(e.oneTick, e.oneTick) + if agg.Side == types.SideBuy && ask != nil { + inner = num.UintZero().Sub(ask, two) + } + if agg.Side == types.SideSell && buy != nil { + inner = num.UintZero().Add(buy, two) + } + } + // switch so that inner < outer to make it easier to reason with if agg.Side == types.SideSell { inner, outer = outer, inner diff --git a/core/integration/features/amm/0090-VAMM-auction.feature b/core/integration/features/amm/0090-VAMM-auction.feature index 48c29547549..6bac9a36b23 100644 --- a/core/integration/features/amm/0090-VAMM-auction.feature +++ b/core/integration/features/amm/0090-VAMM-auction.feature @@ -504,4 +504,48 @@ Feature: vAMM rebasing when created or amended When the opening auction period ends for market "ETH/MAR22" And the market data for the market "ETH/MAR22" should be: | mark price | trading mode | best bid price | best offer price | - | 93 | TRADING_MODE_CONTINUOUS | 92 | 94 | \ No newline at end of file + | 93 | TRADING_MODE_CONTINUOUS | 92 | 94 | + + + @VAMM + Scenario: AMM crossed with limit order, AMM pushed to boundary + + + And the parties place the following orders: + | party | market id | side | volume | price | resulting trades | type | tif | reference | + | lp1 | ETH/MAR22 | buy | 423 | 200 | 0 | TYPE_LIMIT | TIF_GTC | lp1-b | + + Then the parties submit the following AMM: + | party | market id | amount | slippage | base | lower bound | upper bound | proposed fee | + | vamm1 | ETH/MAR22 | 100000 | 0.05 | 100 | 90 | 110 | 0.03 | + Then the AMM pool status should be: + | party | market id | amount | status | base | lower bound | upper bound | + | vamm1 | ETH/MAR22 | 100000 | STATUS_ACTIVE | 100 | 90 | 110 | + + + # now place some pegged orders which will cause a panic if the uncrossing is crossed + When the parties place the following pegged orders: + | party | market id | side | volume | pegged reference | offset | + | lp3 | ETH/MAR22 | buy | 100 | BID | 1 | + | lp3 | ETH/MAR22 | sell | 100 | ASK | 1 | + + And set the following AMM sub account aliases: + | party | market id | alias | + | vamm1 | ETH/MAR22 | vamm1-id | + + + And the market data for the market "ETH/MAR22" should be: + | trading mode | indicative price | indicative volume | + | TRADING_MODE_OPENING_AUCTION | 155 | 423 | + + + When the opening auction period ends for market "ETH/MAR22" + + # the volume of this trade should be the entire volume of the AMM's sell curve + Then the following trades should be executed: + | buyer | price | size | seller | is amm | + | lp1 | 155 | 423 | vamm1-id | true | + + And the market data for the market "ETH/MAR22" should be: + | mark price | trading mode | best bid price | best offer price | + | 155 | TRADING_MODE_CONTINUOUS | 109 | 0 | \ No newline at end of file diff --git a/core/matching/orderbook.go b/core/matching/orderbook.go index f4eb8484ea5..66bbe38242e 100644 --- a/core/matching/orderbook.go +++ b/core/matching/orderbook.go @@ -491,16 +491,12 @@ func (b *OrderBook) GetIndicativeTrades() ([]*types.Trade, error) { var ( uncrossOrders []*types.Order uncrossingSide *OrderBookSide - uncrossBound *num.Uint ) - min, max := b.indicativePriceAndVolume.GetCrossedRegion() if uncrossSide == types.SideBuy { uncrossingSide = b.buy - uncrossBound = min } else { uncrossingSide = b.sell - uncrossBound = max } // extract uncrossing orders from all AMMs @@ -513,7 +509,7 @@ func (b *OrderBook) GetIndicativeTrades() ([]*types.Trade, error) { uncrossOrders = append(uncrossOrders, uncrossingSide.ExtractOrders(price, volume, false)...) opSide := b.getOppositeSide(uncrossSide) output := make([]*types.Trade, 0, len(uncrossOrders)) - trades, err := opSide.fakeUncrossAuction(uncrossOrders, uncrossBound) + trades, err := opSide.fakeUncrossAuction(uncrossOrders) if err != nil { return nil, err } @@ -558,18 +554,12 @@ func (b *OrderBook) uncrossBook() ([]*types.OrderConfirmation, error) { return nil, nil } - var ( - uncrossingSide *OrderBookSide - uncrossBound *num.Uint - ) + var uncrossingSide *OrderBookSide - min, max := b.indicativePriceAndVolume.GetCrossedRegion() if uncrossSide == types.SideBuy { uncrossingSide = b.buy - uncrossBound = min } else { uncrossingSide = b.sell - uncrossBound = max } // extract uncrossing orders from all AMMs @@ -580,7 +570,7 @@ func (b *OrderBook) uncrossBook() ([]*types.OrderConfirmation, error) { // Remove all the orders from that side of the book up to the given volume uncrossOrders = append(uncrossOrders, uncrossingSide.ExtractOrders(price, volume, true)...) - return b.uncrossBookSide(uncrossOrders, b.getOppositeSide(uncrossSide), price.Clone(), uncrossBound) + return b.uncrossBookSide(uncrossOrders, b.getOppositeSide(uncrossSide), price.Clone()) } // Takes extracted order from a side of the book, and uncross them @@ -588,7 +578,7 @@ func (b *OrderBook) uncrossBook() ([]*types.OrderConfirmation, error) { func (b *OrderBook) uncrossBookSide( uncrossOrders []*types.Order, opSide *OrderBookSide, - price, uncrossBound *num.Uint, + price *num.Uint, ) ([]*types.OrderConfirmation, error) { var ( uncrossedOrder *types.OrderConfirmation @@ -614,7 +604,7 @@ func (b *OrderBook) uncrossBookSide( } // try to get the market price value from the order - trades, affectedOrders, _, err := opSide.uncross(order, false, uncrossBound) + trades, affectedOrders, _, err := opSide.uncross(order, false) if err != nil { return nil, err } @@ -911,8 +901,7 @@ func (b *OrderBook) GetTrades(order *types.Order) ([]*types.Trade, error) { b.latestTimestamp = order.CreatedAt } - idealPrice := b.theoreticalBestTradePrice(order) - trades, err := b.getOppositeSide(order.Side).fakeUncross(order, true, idealPrice) + trades, err := b.getOppositeSide(order.Side).fakeUncross(order, true) // it's fine for the error to be a wash trade here, // it's just be stopped when really uncrossing. if err != nil && err != ErrWashTrade { @@ -961,25 +950,6 @@ func (b *OrderBook) ReSubmitSpecialOrders(order *types.Order) { b.add(order) } -// theoreticalBestTradePrice returns the best possible price the incoming order could trade -// as if the spread were as small as possible. This will be used to construct the first -// interval to query offbook orders matching with the other side. -func (b *OrderBook) theoreticalBestTradePrice(order *types.Order) *num.Uint { - bp, _, err := b.getSide(order.Side).BestPriceAndVolume() - if err != nil { - return nil - } - - switch order.Side { - case types.SideBuy: - return bp.Add(bp, num.UintOne()) - case types.SideSell: - return bp.Sub(bp, num.UintOne()) - default: - panic("unexpected order side") - } -} - // SubmitOrder Add an order and attempt to uncross the book, returns a TradeSet protobuf message object. func (b *OrderBook) SubmitOrder(order *types.Order) (*types.OrderConfirmation, error) { if err := b.validateOrder(order); err != nil { @@ -1006,9 +976,7 @@ func (b *OrderBook) SubmitOrder(order *types.Order) (*types.OrderConfirmation, e // uncross with opposite defer b.buy.uncrossFinished() - - idealPrice := b.theoreticalBestTradePrice(order) - trades, impactedOrders, lastTradedPrice, err = b.getOppositeSide(order.Side).uncross(order, true, idealPrice) + trades, impactedOrders, lastTradedPrice, err = b.getOppositeSide(order.Side).uncross(order, true) if !lastTradedPrice.IsZero() { b.lastTradedPrice = lastTradedPrice } diff --git a/core/matching/orderbook_amm_test.go b/core/matching/orderbook_amm_test.go index 567380be510..0e6302e8b46 100644 --- a/core/matching/orderbook_amm_test.go +++ b/core/matching/orderbook_amm_test.go @@ -235,7 +235,7 @@ func testMatchOrdersBothSide(t *testing.T) { assert.Len(t, trades, 8) // uncross - expectOffbookOrders(t, tst, price, num.NewUint(oPrice-1), num.NewUint(120)) + expectOffbookOrders(t, tst, price, nil, num.NewUint(120)) expectOffbookOrders(t, tst, price, num.NewUint(120), num.NewUint(110)) expectOffbookOrders(t, tst, price, num.NewUint(110), num.NewUint(90)) tst.obs.EXPECT().NotifyFinished().Times(1) diff --git a/core/matching/side.go b/core/matching/side.go index 0143ebd418a..7e38c312d80 100644 --- a/core/matching/side.go +++ b/core/matching/side.go @@ -408,7 +408,7 @@ func (s *OrderBookSide) GetVolume(price *num.Uint) (uint64, error) { // fakeUncross returns hypothetical trades if the order book side were to be uncrossed with the agg order supplied, // checkWashTrades checks non-FOK orders for wash trades if set to true (FOK orders are always checked for wash trades). -func (s *OrderBookSide) fakeUncross(agg *types.Order, checkWashTrades bool, idealPrice *num.Uint) ([]*types.Trade, error) { +func (s *OrderBookSide) fakeUncross(agg *types.Order, checkWashTrades bool) ([]*types.Trade, error) { defer s.uncrossFinished() // get a copy of the order passed in, so we can rely on fakeUncross to do its job @@ -428,7 +428,7 @@ func (s *OrderBookSide) fakeUncross(agg *types.Order, checkWashTrades bool, idea } // first check for volume between the theoretical best price and the first price level - _, oo := s.uncrossOffbook(len(s.levels), fake, idealPrice, true) + _, oo := s.uncrossOffbook(len(s.levels), fake, true) for _, order := range oo { totalVolumeToFill += order.Remaining } @@ -448,7 +448,7 @@ func (s *OrderBookSide) fakeUncross(agg *types.Order, checkWashTrades bool, idea } } - _, oo := s.uncrossOffbook(i, fake, idealPrice, true) + _, oo := s.uncrossOffbook(i, fake, true) for _, order := range oo { totalVolumeToFill += order.Remaining } @@ -483,7 +483,7 @@ func (s *OrderBookSide) fakeUncross(agg *types.Order, checkWashTrades bool, idea checkPrice = func(levelPrice *num.Uint) bool { return levelPrice.LT(agg.Price) } } - trades, offbookOrders = s.uncrossOffbook(idx+1, fake, idealPrice, true) + trades, offbookOrders = s.uncrossOffbook(idx+1, fake, true) // in here we iterate from the end, as it's easier to remove the // price levels from the back of the slice instead of from the front @@ -501,7 +501,7 @@ func (s *OrderBookSide) fakeUncross(agg *types.Order, checkWashTrades bool, idea } if fake.Remaining != 0 { - obTrades, obOrders := s.uncrossOffbook(idx, fake, idealPrice, true) + obTrades, obOrders := s.uncrossOffbook(idx, fake, true) trades = append(trades, obTrades...) offbookOrders = append(offbookOrders, obOrders...) } @@ -514,7 +514,7 @@ func (s *OrderBookSide) fakeUncross(agg *types.Order, checkWashTrades bool, idea } // fakeUncrossAuction returns hypothetical trades if the order book side were to be uncrossed with the agg orders supplied, wash trades are allowed. -func (s *OrderBookSide) fakeUncrossAuction(orders []*types.Order, bound *num.Uint) ([]*types.Trade, error) { +func (s *OrderBookSide) fakeUncrossAuction(orders []*types.Order) ([]*types.Trade, error) { defer s.uncrossFinished() // in here we iterate from the end, as it's easier to remove the // price levels from the back of the slice instead of from the front @@ -542,7 +542,7 @@ func (s *OrderBookSide) fakeUncrossAuction(orders []*types.Order, bound *num.Uin for ; iOrder < len(orders); iOrder++ { fake = orders[iOrder].Clone() - ntrades, _ = s.uncrossOffbook(len(s.levels), fake, bound, false) + ntrades, _ = s.uncrossOffbook(len(s.levels), fake, false) trades = append(trades, ntrades...) // no more to trade in this pre-orderbook region for AMM's, we now need to move to orderbook @@ -580,7 +580,7 @@ func (s *OrderBookSide) fakeUncrossAuction(orders []*types.Order, bound *num.Uin trades = append(trades, ntrades...) if fake.Remaining != 0 { - ntrades, _ := s.uncrossOffbook(idx, fake, bound, true) + ntrades, _ := s.uncrossOffbook(idx, fake, true) trades = append(trades, ntrades...) // if we couldn't consume the whole order with this AMM volume in this region @@ -617,15 +617,15 @@ func clonePriceLevel(lvl *PriceLevel) *PriceLevel { // betweenLevels returns the inner, outer bounds for the given idx in the price levels. // Usually this means (inner, outer) = (lvl[i].price, lvl[i-1].price) but we also handle // the past the first and last price levels. -func (s *OrderBookSide) betweenLevels(idx int, first, last *num.Uint) (*num.Uint, *num.Uint) { +func (s *OrderBookSide) betweenLevels(idx int, last *num.Uint) (*num.Uint, *num.Uint) { // there are no price levels, so between is from low to high if len(s.levels) == 0 { - return first, last + return nil, last } - // we're at the first price level + // we're at the first price level, we pass back nil for the first level since we do not know the bound for this if idx == len(s.levels) { - return first, s.levels[idx-1].price + return nil, s.levels[idx-1].price } // we're at the last price level @@ -641,13 +641,13 @@ func (s *OrderBookSide) uncrossFinished() { } } -func (s *OrderBookSide) uncrossOffbook(idx int, agg *types.Order, idealPrice *num.Uint, fake bool) ([]*types.Trade, []*types.Order) { +func (s *OrderBookSide) uncrossOffbook(idx int, agg *types.Order, fake bool) ([]*types.Trade, []*types.Order) { if s.offbook == nil { return nil, nil } // get the bounds between price levels for the given price level index - inner, outer := s.betweenLevels(idx, idealPrice, agg.Price) + inner, outer := s.betweenLevels(idx, agg.Price) // submit the order to the offbook source for volume between those bounds orders := s.offbook.SubmitOrder(agg, inner, outer) @@ -668,7 +668,7 @@ func (s *OrderBookSide) uncrossOffbook(idx int, agg *types.Order, idealPrice *nu // uncross returns trades after order book side gets uncrossed with the agg order supplied, // checkWashTrades checks non-FOK orders for wash trades if set to true (FOK orders are always checked for wash trades). -func (s *OrderBookSide) uncross(agg *types.Order, checkWashTrades bool, theoreticalBestTrade *num.Uint) ([]*types.Trade, []*types.Order, *num.Uint, error) { +func (s *OrderBookSide) uncross(agg *types.Order, checkWashTrades bool) ([]*types.Trade, []*types.Order, *num.Uint, error) { var ( trades []*types.Trade impactedOrders []*types.Order @@ -686,7 +686,7 @@ func (s *OrderBookSide) uncross(agg *types.Order, checkWashTrades bool, theoreti } if agg.TimeInForce == types.OrderTimeInForceFOK { - _, oo := s.uncrossOffbook(len(s.levels), fake, theoreticalBestTrade, true) + _, oo := s.uncrossOffbook(len(s.levels), fake, true) for _, order := range oo { totalVolumeToFill += order.Remaining } @@ -706,7 +706,7 @@ func (s *OrderBookSide) uncross(agg *types.Order, checkWashTrades bool, theoreti // in case of network trades, we want to calculate an accurate average price to return totalVolumeToFill += order.Remaining - _, oo := s.uncrossOffbook(i, fake, theoreticalBestTrade, true) + _, oo := s.uncrossOffbook(i, fake, true) for _, order := range oo { totalVolumeToFill += order.Remaining } @@ -742,7 +742,7 @@ func (s *OrderBookSide) uncross(agg *types.Order, checkWashTrades bool, theoreti ) // first check for off source volume between the best theoretical price and the first price level - trades, impactedOrders = s.uncrossOffbook(idx+1, agg, theoreticalBestTrade, false) + trades, impactedOrders = s.uncrossOffbook(idx+1, agg, false) filled = agg.Remaining == 0 // in here we iterate from the end, as it's easier to remove the @@ -760,7 +760,7 @@ func (s *OrderBookSide) uncross(agg *types.Order, checkWashTrades bool, theoreti if !filled { // now check for off source volume between the price levels - ot, oo := s.uncrossOffbook(idx, agg, theoreticalBestTrade, false) + ot, oo := s.uncrossOffbook(idx, agg, false) trades = append(trades, ot...) impactedOrders = append(impactedOrders, oo...) filled = agg.Remaining == 0 diff --git a/core/matching/side_test.go b/core/matching/side_test.go index 3cdfa7f7e80..ea3b20cb6ac 100644 --- a/core/matching/side_test.go +++ b/core/matching/side_test.go @@ -178,7 +178,7 @@ func TestMemoryAllocationPriceLevelUncrossSide(t *testing.T) { Remaining: 1, TimeInForce: types.OrderTimeInForceGTC, } - side.uncross(aggressiveOrder, true, nil) + side.uncross(aggressiveOrder, true) assert.Len(t, side.levels, 1) } @@ -445,11 +445,11 @@ func TestFakeUncrossNormal(t *testing.T) { } checkWashTrades := false - fakeTrades, err := buySide.fakeUncross(&order, checkWashTrades, nil) + fakeTrades, err := buySide.fakeUncross(&order, checkWashTrades) assert.Len(t, fakeTrades, 5) assert.NoError(t, err) - trades, _, _, err := buySide.uncross(&order, checkWashTrades, nil) + trades, _, _, err := buySide.uncross(&order, checkWashTrades) assert.Len(t, trades, 5) assert.NoError(t, err) @@ -474,11 +474,11 @@ func TestFakeUncrossSelfTradeFOKMarketOrder(t *testing.T) { } checkWashTrades := false - fakeTrades, err1 := buySide.fakeUncross(&order, checkWashTrades, nil) + fakeTrades, err1 := buySide.fakeUncross(&order, checkWashTrades) assert.Len(t, fakeTrades, 0) assert.Error(t, err1) - trades, _, _, err2 := buySide.uncross(&order, checkWashTrades, nil) + trades, _, _, err2 := buySide.uncross(&order, checkWashTrades) assert.Len(t, trades, 0) assert.Error(t, err2) @@ -501,12 +501,12 @@ func TestFakeUncrossSelfTradeNonFOKLimitOrder_DontCheckWashTrades(t *testing.T) } checkWashTrades := false - fakeTrades, err := buySide.fakeUncross(&order, checkWashTrades, nil) + fakeTrades, err := buySide.fakeUncross(&order, checkWashTrades) assert.Len(t, fakeTrades, 1) assert.NoError(t, err) assert.Equal(t, fakeTrades[0].SellOrder, order.ID) - trades, _, _, err := buySide.uncross(&order, checkWashTrades, nil) + trades, _, _, err := buySide.uncross(&order, checkWashTrades) assert.Len(t, trades, 1) assert.NoError(t, err) @@ -529,12 +529,12 @@ func TestFakeUncrossSelfTradeNonFOKLimitOrder_CheckWashTrades(t *testing.T) { } checkWashTrades := true - fakeTrades, err1 := buySide.fakeUncross(&order, checkWashTrades, nil) + fakeTrades, err1 := buySide.fakeUncross(&order, checkWashTrades) assert.Len(t, fakeTrades, 0) assert.Error(t, err1) assert.Equal(t, "party attempted to submit wash trade", err1.Error()) - trades, _, _, err2 := buySide.uncross(&order, checkWashTrades, nil) + trades, _, _, err2 := buySide.uncross(&order, checkWashTrades) assert.Len(t, trades, 0) assert.Error(t, err2) assert.Equal(t, "party attempted to submit wash trade", err2.Error()) @@ -556,11 +556,11 @@ func TestFakeUncrossNotEnoughVolume(t *testing.T) { } checkWashTrades := false - fakeTrades, err := buySide.fakeUncross(&order, checkWashTrades, nil) + fakeTrades, err := buySide.fakeUncross(&order, checkWashTrades) assert.Len(t, fakeTrades, 0) assert.NoError(t, err) - trades, _, _, err := buySide.uncross(&order, checkWashTrades, nil) + trades, _, _, err := buySide.uncross(&order, checkWashTrades) assert.Len(t, trades, 0) assert.NoError(t, err) } @@ -594,13 +594,13 @@ func TestFakeUncrossAuction(t *testing.T) { orders := []*types.Order{order1, order2} - fakeTrades, err := buySide.fakeUncrossAuction(orders, nil) + fakeTrades, err := buySide.fakeUncrossAuction(orders) assert.Len(t, fakeTrades, 6) assert.NoError(t, err) trades := []*types.Trade{} for _, order := range orders { - trds, _, _, err := buySide.uncross(order, false, nil) + trds, _, _, err := buySide.uncross(order, false) assert.NoError(t, err) trades = append(trades, trds...) } From ef05eaf4f8dcd12ab6e27d1fd1ed6cc979227133 Mon Sep 17 00:00:00 2001 From: wwestgarth Date: Mon, 2 Sep 2024 10:50:56 +0100 Subject: [PATCH 4/7] fix: set deployment heights when starting from genesis --- CHANGELOG.md | 1 + core/evtforward/ethereum/engine.go | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 482558495a6..dac145aef4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ - [11616](https://github.com/vegaprotocol/vega/issues/11616) - `AMM` tradable volume now calculated purely in positions to prevent loss of precision. - [11544](https://github.com/vegaprotocol/vega/issues/11544) - Fix empty candles stream. - [11583](https://github.com/vegaprotocol/vega/issues/11583) - Rough bound on price interval when matching with `AMMs` is now looser and calculated in the `AMM` engine. +- [11633](https://github.com/vegaprotocol/vega/issues/11633) - Use bridge deployment heights from network parameter when starting network from genesis. - [11619](https://github.com/vegaprotocol/vega/issues/11619) - Fix `EstimatePositions` API for capped futures. - [11579](https://github.com/vegaprotocol/vega/issues/11579) - Spot calculate fee on amend, use order price if no amended price is provided. - [11585](https://github.com/vegaprotocol/vega/issues/11585) - Initialise rebate stats service in API. diff --git a/core/evtforward/ethereum/engine.go b/core/evtforward/ethereum/engine.go index c928602800b..6a0cb714ee4 100644 --- a/core/evtforward/ethereum/engine.go +++ b/core/evtforward/ethereum/engine.go @@ -125,10 +125,10 @@ func NewEngine( poller: newPoller(cfg.PollEventRetryDuration.Get()), filterer: filterer, forwarder: fwdWrapper{forwarder, chainID}, - stakingDeployment: &Contract{stakingDeployment, 0, 0}, - vestingDeployment: &Contract{vestingDeployment, 0, 0}, - multisigDeployment: &Contract{multiSigDeployment, 0, 0}, - collateralDeployment: &Contract{collateralDeployment, 0, 0}, + stakingDeployment: &Contract{stakingDeployment, stakingDeployment.DeploymentBlockHeight(), stakingDeployment.DeploymentBlockHeight()}, + vestingDeployment: &Contract{vestingDeployment, vestingDeployment.DeploymentBlockHeight(), vestingDeployment.DeploymentBlockHeight()}, + multisigDeployment: &Contract{multiSigDeployment, multiSigDeployment.DeploymentBlockHeight(), multiSigDeployment.DeploymentBlockHeight()}, + collateralDeployment: &Contract{collateralDeployment, collateralDeployment.DeploymentBlockHeight(), collateralDeployment.DeploymentBlockHeight()}, chainID: chainID, heartbeatInterval: uint64(heartbeatInterval), } From c57d1d576df3094c1259a0aa377df698f86ef64e Mon Sep 17 00:00:00 2001 From: wwestgarth Date: Mon, 2 Sep 2024 16:17:47 +0100 Subject: [PATCH 5/7] fix: handle one sided amm that reduces to point expansion in orderbookshape --- CHANGELOG.md | 1 + core/execution/amm/shape.go | 10 ++++++---- core/execution/amm/shape_test.go | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dac145aef4a..962e52de662 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ - [11521](https://github.com/vegaprotocol/vega/issues/11521) - Restore `AMM` position factor when loading from a snapshot. - [11526](https://github.com/vegaprotocol/vega/issues/11526) - `EstimateAMMBounds` now respects the market's decimal places. - [11486](https://github.com/vegaprotocol/vega/issues/11486) - `AMMs` can now be submitted on markets with more decimal places than asset decimal places. +- [11635](https://github.com/vegaprotocol/vega/issues/11635) - Handle expansion of one sided `AMMs` that reduce to point expansion when calculating order book shape. - [11561](https://github.com/vegaprotocol/vega/issues/11561) - Failing amends on `AMMs` now restore original properly. - [11583](https://github.com/vegaprotocol/vega/issues/11583) - Remove `AMMs` entirely from engine when market closes. - [11568](https://github.com/vegaprotocol/vega/issues/11568) - order book shape on closing `AMM` no longer panics. diff --git a/core/execution/amm/shape.go b/core/execution/amm/shape.go index 9cfc6fcb07d..91196581afd 100644 --- a/core/execution/amm/shape.go +++ b/core/execution/amm/shape.go @@ -321,13 +321,15 @@ func (sm *shapeMaker) adjustRegion() bool { return false } - if sm.from.EQ(sm.to) && sm.from.EQ(sm.fairPrice) { - return false - } - // cap the range to the pool's bounds, there will be no orders outside of this from := num.Max(sm.from, lower) to := num.Min(sm.to, upper) + + // expansion is a point region *at* fair-price, there are no orders + if from.EQ(to) && from.EQ(sm.fairPrice) { + return false + } + switch { case sm.from.GT(sm.fairPrice): // if we are expanding entirely in the sell range to calculate the order at price `from` diff --git a/core/execution/amm/shape_test.go b/core/execution/amm/shape_test.go index bd4c381c1dd..57e0916f74a 100644 --- a/core/execution/amm/shape_test.go +++ b/core/execution/amm/shape_test.go @@ -36,6 +36,7 @@ func TestOrderbookShape(t *testing.T) { t.Run("test orderbook shape boundary order when approx", testOrderbookShapeBoundaryOrder) t.Run("test orderbook shape region not divisible by tick", testOrderbookSubTick) t.Run("test orderbook shape closing pool close to base", testClosingCloseToBase) + t.Run("test orderbook shape point expansion at fair price", testPointExpansionAtFairPrice) } func testOrderbookShapeZeroPosition(t *testing.T) { @@ -416,3 +417,36 @@ func testClosingCloseToBase(t *testing.T) { assert.Equal(t, 0, len(buys)) assert.Equal(t, 0, len(sells)) } + +func testPointExpansionAtFairPrice(t *testing.T) { + p := newTestPoolWithRanges(t, num.NewUint(7), num.NewUint(10), num.NewUint(13)) + defer p.ctrl.Finish() + + base := p.submission.Parameters.Base + + // range [10, 10] fair price is 10, no orders + ensurePositionN(t, p.pos, 0, num.UintZero(), 2) + buys, sells := p.pool.OrderbookShape(base, base, nil) + assert.Equal(t, 0, len(buys)) + assert.Equal(t, 0, len(sells)) + + // now try with a one sided curve where the input range shrinks to a point-expansion + p = newTestPoolWithRanges(t, num.NewUint(7), num.NewUint(10), nil) + defer p.ctrl.Finish() + + // range [10, 1000] but sell curve is empty so effective range is [10, 10] at fair-price + ensurePositionN(t, p.pos, 0, num.UintZero(), 2) + buys, sells = p.pool.OrderbookShape(base, num.NewUint(1000), nil) + assert.Equal(t, 0, len(buys)) + assert.Equal(t, 0, len(sells)) + + // now try with a one sided curve where the input range shrinks to a point-expansion + p = newTestPoolWithRanges(t, nil, num.NewUint(10), num.NewUint(13)) + defer p.ctrl.Finish() + + // range [1, 10] but buy curve is empty so effective range is [10, 10] at fair-price + ensurePositionN(t, p.pos, 0, num.UintZero(), 2) + buys, sells = p.pool.OrderbookShape(num.NewUint(1), base, nil) + assert.Equal(t, 0, len(buys)) + assert.Equal(t, 0, len(sells)) +} From fd45567f06b9da7c0199ed026e03da01d3e109e1 Mon Sep 17 00:00:00 2001 From: wwestgarth Date: Mon, 2 Sep 2024 17:01:12 +0100 Subject: [PATCH 6/7] fix: prevent overflow when calculating tradable volume outside of sided range --- core/execution/amm/pool.go | 6 ++++++ core/execution/amm/pool_test.go | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/core/execution/amm/pool.go b/core/execution/amm/pool.go index e4c89e673e4..70a754f684b 100644 --- a/core/execution/amm/pool.go +++ b/core/execution/amm/pool.go @@ -629,11 +629,17 @@ func (p *Pool) TradableVolumeInRange(side types.Side, price1 *num.Uint, price2 * if side == types.SideSell { // want all buy volume so everything below fair price, where the AMM is long + if pos > stP { + return 0 + } ndP = num.MaxV(pos, ndP) } if side == types.SideBuy { // want all sell volume so everything above fair price, where the AMM is short + if pos < ndP { + return 0 + } stP = num.MinV(pos, stP) } diff --git a/core/execution/amm/pool_test.go b/core/execution/amm/pool_test.go index 0444f469e83..a46d83876d4 100644 --- a/core/execution/amm/pool_test.go +++ b/core/execution/amm/pool_test.go @@ -113,6 +113,22 @@ func testTradeableVolumeInRange(t *testing.T) { expectedVolume: 1052, position: -350, }, + { + name: "AMM is long and price range is fully in short section", + price1: num.NewUint(1900), + price2: num.NewUint(2200), + side: types.SideSell, + expectedVolume: 0, + position: 700, + }, + { + name: "AMM is short and price range is fully in long section", + price1: num.NewUint(1900), + price2: num.NewUint(2100), + side: types.SideBuy, + expectedVolume: 0, + position: -700, + }, } for _, tt := range tests { From 0184663febe7af1a8dd84551f73e9af42edfdd38 Mon Sep 17 00:00:00 2001 From: Jeremy Letang Date: Tue, 3 Sep 2024 10:45:04 +0200 Subject: [PATCH 7/7] chore: release version v0.78.1 Signed-off-by: Jeremy Letang --- CHANGELOG.md | 12 +++++++++++- protos/blockexplorer/api/v1/blockexplorer.pb.go | 2 +- protos/data-node/api/v2/trading_data.pb.go | 2 +- .../sources/blockexplorer/api/v1/blockexplorer.proto | 2 +- protos/sources/data-node/api/v2/trading_data.proto | 2 +- protos/sources/vega/api/v1/core.proto | 2 +- protos/sources/vega/api/v1/corestate.proto | 2 +- protos/vega/api/v1/core.pb.go | 2 +- protos/vega/api/v1/corestate.pb.go | 2 +- version/version.go | 2 +- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cebd1449179..0f61d88e1bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### 🚨 Breaking changes -- [8777](https://github.com/vegaprotocol/vega/issues/8777) - Stop orders can now be used to create or increase a position. +- [](https://github.com/vegaprotocol/vega/issues/xxx) ### 🗑️ Deprecation @@ -19,6 +19,16 @@ - [](https://github.com/vegaprotocol/vega/issues/xxx) +## 0.78.1 + +### 🐛 Fixes + +- [11633](https://github.com/vegaprotocol/vega/issues/11633) - Use bridge deployment heights from network parameter when starting network from genesis.) +- [11583](https://github.com/vegaprotocol/vega/issues/11583) - Rough bound on price interval when matching with `AMMs` is now looser and calculated in the `AMM` engine. +- [11624](https://github.com/vegaprotocol/vega/issues/11624) - prevent creation of rewards with no payout, but with high computational cost. +- [11619](https://github.com/vegaprotocol/vega/issues/11619) - Fix `EstimatePositions` API for capped futures. + + ## 0.78.0 ### 🛠 Improvements diff --git a/protos/blockexplorer/api/v1/blockexplorer.pb.go b/protos/blockexplorer/api/v1/blockexplorer.pb.go index 2a31e520134..b3e1a694ef9 100644 --- a/protos/blockexplorer/api/v1/blockexplorer.pb.go +++ b/protos/blockexplorer/api/v1/blockexplorer.pb.go @@ -656,7 +656,7 @@ var file_blockexplorer_api_v1_blockexplorer_proto_rawDesc = []byte{ 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x92, 0x41, 0x3e, 0x12, 0x23, 0x0a, 0x18, 0x56, 0x65, 0x67, 0x61, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x20, - 0x41, 0x50, 0x49, 0x73, 0x32, 0x07, 0x76, 0x30, 0x2e, 0x37, 0x38, 0x2e, 0x30, 0x1a, 0x13, 0x6c, + 0x41, 0x50, 0x49, 0x73, 0x32, 0x07, 0x76, 0x30, 0x2e, 0x37, 0x38, 0x2e, 0x31, 0x1a, 0x13, 0x6c, 0x62, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x78, 0x79, 0x7a, 0x2a, 0x02, 0x01, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/protos/data-node/api/v2/trading_data.pb.go b/protos/data-node/api/v2/trading_data.pb.go index acbb534b247..b9006b4b1db 100644 --- a/protos/data-node/api/v2/trading_data.pb.go +++ b/protos/data-node/api/v2/trading_data.pb.go @@ -33021,7 +33021,7 @@ var file_data_node_api_v2_trading_data_proto_rawDesc = []byte{ 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x92, 0x41, 0x8f, 0x01, 0x12, 0x1e, 0x0a, 0x13, 0x56, 0x65, 0x67, 0x61, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x41, 0x50, 0x49, 0x73, 0x32, 0x07, 0x76, - 0x30, 0x2e, 0x37, 0x38, 0x2e, 0x30, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x30, 0x2e, 0x37, 0x38, 0x2e, 0x31, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x78, 0x79, 0x7a, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x52, 0x39, 0x0a, 0x03, 0x35, 0x30, diff --git a/protos/sources/blockexplorer/api/v1/blockexplorer.proto b/protos/sources/blockexplorer/api/v1/blockexplorer.proto index 8a89c461edc..b9659950ccb 100644 --- a/protos/sources/blockexplorer/api/v1/blockexplorer.proto +++ b/protos/sources/blockexplorer/api/v1/blockexplorer.proto @@ -11,7 +11,7 @@ option go_package = "code.vegaprotocol.io/vega/protos/blockexplorer/api/v1"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "Vega block explorer APIs"; - version: "v0.78.0"; + version: "v0.78.1"; } schemes: [ HTTP, diff --git a/protos/sources/data-node/api/v2/trading_data.proto b/protos/sources/data-node/api/v2/trading_data.proto index 079c19c46fe..8d3673c2db5 100644 --- a/protos/sources/data-node/api/v2/trading_data.proto +++ b/protos/sources/data-node/api/v2/trading_data.proto @@ -17,7 +17,7 @@ option go_package = "code.vegaprotocol.io/vega/protos/data-node/api/v2"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "Vega data node APIs"; - version: "v0.78.0"; + version: "v0.78.1"; } schemes: [ HTTP, diff --git a/protos/sources/vega/api/v1/core.proto b/protos/sources/vega/api/v1/core.proto index 80ba1607d69..17445713142 100644 --- a/protos/sources/vega/api/v1/core.proto +++ b/protos/sources/vega/api/v1/core.proto @@ -12,7 +12,7 @@ option go_package = "code.vegaprotocol.io/vega/protos/vega/api/v1"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "Vega core APIs"; - version: "v0.78.0"; + version: "v0.78.1"; } schemes: [ HTTP, diff --git a/protos/sources/vega/api/v1/corestate.proto b/protos/sources/vega/api/v1/corestate.proto index a371df99601..5dc6dd76729 100644 --- a/protos/sources/vega/api/v1/corestate.proto +++ b/protos/sources/vega/api/v1/corestate.proto @@ -13,7 +13,7 @@ option go_package = "code.vegaprotocol.io/vega/protos/vega/api/v1"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "Vega core state APIs"; - version: "v0.78.0"; + version: "v0.78.1"; } schemes: [ HTTP, diff --git a/protos/vega/api/v1/core.pb.go b/protos/vega/api/v1/core.pb.go index 09e3669a8c8..00a9b0353e2 100644 --- a/protos/vega/api/v1/core.pb.go +++ b/protos/vega/api/v1/core.pb.go @@ -2796,7 +2796,7 @@ var file_vega_api_v1_core_proto_rawDesc = []byte{ 0x6f, 0x6c, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x92, 0x41, 0x34, 0x12, 0x19, 0x0a, 0x0e, 0x56, 0x65, 0x67, 0x61, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x41, 0x50, - 0x49, 0x73, 0x32, 0x07, 0x76, 0x30, 0x2e, 0x37, 0x38, 0x2e, 0x30, 0x1a, 0x13, 0x6c, 0x62, 0x2e, + 0x49, 0x73, 0x32, 0x07, 0x76, 0x30, 0x2e, 0x37, 0x38, 0x2e, 0x31, 0x1a, 0x13, 0x6c, 0x62, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x78, 0x79, 0x7a, 0x2a, 0x02, 0x01, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/protos/vega/api/v1/corestate.pb.go b/protos/vega/api/v1/corestate.pb.go index 1d7ec84221d..42be224dc25 100644 --- a/protos/vega/api/v1/corestate.pb.go +++ b/protos/vega/api/v1/corestate.pb.go @@ -1512,7 +1512,7 @@ var file_vega_api_v1_corestate_proto_rawDesc = []byte{ 0x6f, 0x73, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x92, 0x41, 0x3a, 0x12, 0x1f, 0x0a, 0x14, 0x56, 0x65, 0x67, 0x61, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x41, 0x50, 0x49, 0x73, 0x32, 0x07, 0x76, 0x30, 0x2e, 0x37, 0x38, - 0x2e, 0x30, 0x1a, 0x13, 0x6c, 0x62, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2e, 0x76, + 0x2e, 0x31, 0x1a, 0x13, 0x6c, 0x62, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x78, 0x79, 0x7a, 0x2a, 0x02, 0x01, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/version/version.go b/version/version.go index c965a7f1230..9803353e477 100644 --- a/version/version.go +++ b/version/version.go @@ -22,7 +22,7 @@ import ( var ( cliVersionHash = "" - cliVersion = "v0.78.0" + cliVersion = "v0.78.1" ) func init() {