Skip to content

Commit

Permalink
chore: reject pap on closed spot market + fix order id determinism
Browse files Browse the repository at this point in the history
  • Loading branch information
ze97286 committed Sep 26, 2024
1 parent 5455483 commit f11d3a0
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 3 deletions.
4 changes: 2 additions & 2 deletions core/execution/spot/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -3488,7 +3488,7 @@ func (m *Market) CheckOrderSubmissionForSpam(orderSubmission *types.OrderSubmiss
quantumMultiplier)
}

func (m *Market) enterAutomatedPurchaseAuction(ctx context.Context, orderSide types.Side, orderPrice *num.Uint, orderSize uint64, reference string, duration time.Duration) (string, error) {
func (m *Market) enterAutomatedPurchaseAuction(ctx context.Context, orderID string, orderSide types.Side, orderPrice *num.Uint, orderSize uint64, reference string, duration time.Duration) (string, error) {
if !m.canTrade() {
return "", fmt.Errorf(fmt.Sprintf("cannot trade in market %s", m.mkt.ID))
}
Expand Down Expand Up @@ -3529,7 +3529,7 @@ func (m *Market) enterAutomatedPurchaseAuction(ctx context.Context, orderSide ty
Type: types.OrderTypeLimit,
Reference: reference,
}
conf, err := m.SubmitOrder(ctx, os, types.NetworkParty, crypto.RandomHash())
conf, err := m.SubmitOrder(ctx, os, types.NetworkParty, orderID)
if err != nil {
return "", err
}
Expand Down
5 changes: 4 additions & 1 deletion core/execution/spot/protocol_automated_purchase.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package spot

import (
"context"
"encoding/hex"
"sync"
"time"

Expand All @@ -27,6 +28,7 @@ import (
"code.vegaprotocol.io/vega/core/execution/common"
"code.vegaprotocol.io/vega/core/products"
"code.vegaprotocol.io/vega/core/types"
"code.vegaprotocol.io/vega/libs/crypto"
"code.vegaprotocol.io/vega/libs/num"
"code.vegaprotocol.io/vega/logging"
snapshot "code.vegaprotocol.io/vega/protos/vega/snapshot/v1"
Expand Down Expand Up @@ -315,7 +317,8 @@ func (m *Market) papAuctionSchedule(ctx context.Context, data dscommon.Data) err
}

orderPriceInMarket := m.priceToMarketPrecision(orderPrice)
orderID, err := m.enterAutomatedPurchaseAuction(ctx, m.pap.side, orderPriceInMarket, orderSize, m.pap.ID, m.pap.config.AuctionDuration)
orderID := hex.EncodeToString(crypto.Hash([]byte(m.pap.ID)))
orderID, err := m.enterAutomatedPurchaseAuction(ctx, orderID, m.pap.side, orderPriceInMarket, orderSize, m.pap.ID, m.pap.config.AuctionDuration)
// if there was no error save the order id as an indication that we're in an auction with active pap order
if err == nil {
m.pap.activeOrder = orderID
Expand Down
3 changes: 3 additions & 0 deletions core/governance/engine_new_automated_purchase.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ func (e *Engine) validateNewProtocolAutomatedPurchaseConfiguration(automatedPurc
if automatedPurchase.Changes.From != spot.BaseAsset && automatedPurchase.Changes.From != spot.QuoteAsset {
return types.ProposalErrorInvalidMarket, fmt.Errorf("mismatch between asset for automated purchase and the spot market configuration - asset is not one of base/quote assets of the market")
}
if mkt.State == types.MarketStateClosed || mkt.State == types.MarketStateCancelled || mkt.State == types.MarketStateRejected || mkt.State == types.MarketStateTradingTerminated || mkt.State == types.MarketStateSettled {
return types.ProposalErrorInvalidMarket, fmt.Errorf("market for automated purchase must be active")
}
if papConfigured, _ := e.markets.MarketHasActivePAP(automatedPurchase.Changes.MarketID); papConfigured {
return types.ProposalErrorInvalidMarket, fmt.Errorf("market already has an active protocol automated purchase program")
}
Expand Down
76 changes: 76 additions & 0 deletions core/governance/engine_new_automated_purchase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,79 @@ func testSubmittingProposalForNewProtocolAutomatedPurchaseNotSpotMarketFails(t *
require.Error(t, err)
require.Equal(t, "market for automated purchase must be a spot market", err.Error())
}

func testSubmittingProposalForNewProtocolAutomatedPurchaseStoppedMarketFailes(t *testing.T, state types.MarketState) {

Check failure on line 443 in core/governance/engine_new_automated_purchase_test.go

View workflow job for this annotation

GitHub Actions / lint

test helper function should start from t.Helper() (thelper)
now := time.Now()
ctx := vgtest.VegaContext(vgrand.RandomStr(5), vgtest.RandomPositiveI64())
eng := getTestEngine(t, now)

// setup
eng.broker.EXPECT().Send(gomock.Any()).Times(3)
eng.netp.Update(ctx, netparams.GovernanceProposalAutomatedPurchaseConfigMinClose, "48h")
eng.netp.Update(ctx, netparams.GovernanceProposalAutomatedPurchaseConfigMinEnact, "48h")
eng.netp.Update(ctx, netparams.GovernanceProposalAutomatedPurchaseConfigMinProposerBalance, "1000")

eng.markets.EXPECT().GetMarket(gomock.Any(), gomock.Any()).Return(types.Market{
State: state,
TradableInstrument: types.TradableInstrumentFromProto(&vega.TradableInstrument{
RiskModel: &vega.TradableInstrument_SimpleRiskModel{
SimpleRiskModel: &vega.SimpleRiskModel{
Params: &vega.SimpleModelParams{},
},
},
Instrument: &vega.Instrument{
Product: &vega.Instrument_Spot{
Spot: &vega.Spot{
BaseAsset: "base",
QuoteAsset: "quote",
},
},
Metadata: &vega.InstrumentMetadata{},
},
}),
}, true).AnyTimes()
eng.assets.EXPECT().IsEnabled(gomock.Any()).Return(true).AnyTimes()
eng.markets.EXPECT().MarketHasActivePAP(gomock.Any()).Return(false, nil).AnyTimes()

// given
proposer := vgrand.RandomStr(5)
proposal := eng.newProposalForNewProtocolAutomatedPurchase(proposer, now, &types.NewProtocolAutomatedPurchaseChanges{
ExpiryTimestamp: now.Add(4 * 48 * time.Hour),
From: "base",
FromAccountType: types.AccountTypeBuyBackFees,
ToAccountType: types.AccountTypeBuyBackFees,
MarketID: crypto.RandomHash(),
PriceOracle: &vega.DataSourceDefinition{},
PriceOracleBinding: &vega.SpecBindingForCompositePrice{
PriceSourceProperty: "oracle.price",
},
OracleOffsetFactor: num.DecimalFromFloat(0.1),
AuctionSchedule: &vega.DataSourceDefinition{},
AuctionVolumeSnapshotSchedule: &vega.DataSourceDefinition{},
AutomatedPurchaseSpecBinding: &vega.DataSourceSpecToAutomatedPurchaseBinding{},
AuctionDuration: time.Hour,
MinimumAuctionSize: num.NewUint(1000),
MaximumAuctionSize: num.NewUint(2000),
})

// setup
eng.ensureTokenBalanceForParty(t, proposer, 1000)

// expect
eng.expectRejectedProposalEvent(t, proposer, proposal.ID, types.ProposalErrorInvalidMarket)

// when
_, err := eng.submitProposal(t, proposal)

// then
require.Error(t, err)
require.Equal(t, "market for automated purchase must be active", err.Error())
}

func TestSubmittingProposalForNewProtocolAutomatedPurchaseStoppedMarketWithStateFails(t *testing.T) {
stoppedStates := []types.MarketState{types.MarketStateCancelled, types.MarketStateClosed, types.MarketStateRejected, types.MarketStateSettled, types.MarketStateTradingTerminated}
for _, state := range stoppedStates {
testSubmittingProposalForNewProtocolAutomatedPurchaseStoppedMarketFailes(t, state)
}

Check failure on line 516 in core/governance/engine_new_automated_purchase_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
}

0 comments on commit f11d3a0

Please sign in to comment.