code.vegaprotocol.io/vega@v0.79.0/core/integration/execution_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package core_test
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  
    22  	"code.vegaprotocol.io/vega/core/events"
    23  	"code.vegaprotocol.io/vega/core/execution"
    24  	"code.vegaprotocol.io/vega/core/idgeneration"
    25  	"code.vegaprotocol.io/vega/core/integration/stubs"
    26  	"code.vegaprotocol.io/vega/core/processor"
    27  	"code.vegaprotocol.io/vega/core/stats"
    28  	"code.vegaprotocol.io/vega/core/types"
    29  	vgcontext "code.vegaprotocol.io/vega/libs/context"
    30  	vgcrypto "code.vegaprotocol.io/vega/libs/crypto"
    31  	"code.vegaprotocol.io/vega/libs/ptr"
    32  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    33  )
    34  
    35  var (
    36  	ErrBatchInstructionNotStarted                = errors.New("batch instruction not started")
    37  	ErrBatchInstructionStartedWithDifferentParty = errors.New("batch instruction started with different party")
    38  )
    39  
    40  type batchIntruction struct {
    41  	party string
    42  	bmi   *commandspb.BatchMarketInstructions
    43  }
    44  
    45  // embeds the execution engine. Just forwards the calls and creates the TxErr events
    46  // if any of the ingress methods returns an error (as the processor would).
    47  type exEng struct {
    48  	*execution.Engine
    49  	broker   *stubs.BrokerStub
    50  	batch    *batchIntruction
    51  	ammAlias map[string]string
    52  }
    53  
    54  func newExEng(e *execution.Engine, broker *stubs.BrokerStub) *exEng {
    55  	return &exEng{
    56  		Engine:   e,
    57  		broker:   broker,
    58  		ammAlias: map[string]string{},
    59  	}
    60  }
    61  
    62  // GetAMMSubAccountID returns the derived account ID based on the alias.
    63  func (e *exEng) GetAMMSubAccountID(alias string) (string, bool) {
    64  	id, ok := e.ammAlias[alias]
    65  	return id, ok
    66  }
    67  
    68  // SetAMMSubAccountIDAlias creates an alias for a derived AMM sub account.
    69  func (e *exEng) SetAMMSubAccountIDAlias(alias, id string) {
    70  	e.ammAlias[alias] = id
    71  }
    72  
    73  func (e *exEng) BlockEnd(ctx context.Context) {
    74  	// set hash ID to some value
    75  	ctx = vgcontext.WithTraceID(ctx, "deadbeef")
    76  	e.Engine.BlockEnd(ctx)
    77  }
    78  
    79  func (e *exEng) SubmitOrder(ctx context.Context, submission *types.OrderSubmission, party string) (*types.OrderConfirmation, error) {
    80  	idgen := idgeneration.New(vgcrypto.RandomHash())
    81  	conf, err := e.Engine.SubmitOrder(ctx, submission, party, idgen, idgen.NextID())
    82  	if err != nil {
    83  		e.broker.Send(events.NewTxErrEvent(ctx, err, party, submission.IntoProto(), "submitOrder"))
    84  	}
    85  	return conf, err
    86  }
    87  
    88  func (e *exEng) SubmitStopOrder(
    89  	ctx context.Context,
    90  	submission *types.StopOrdersSubmission,
    91  	party string,
    92  ) (*types.OrderConfirmation, error) {
    93  	idgen := idgeneration.New(vgcrypto.RandomHash())
    94  	var fallsBelowID, risesAboveID *string
    95  	if submission.FallsBelow != nil {
    96  		fallsBelowID = ptr.From(idgen.NextID())
    97  	}
    98  	if submission.RisesAbove != nil {
    99  		risesAboveID = ptr.From(idgen.NextID())
   100  	}
   101  	conf, err := e.Engine.SubmitStopOrders(ctx, submission, party, idgen, fallsBelowID, risesAboveID)
   102  	// if err != nil {
   103  	// 	e.broker.Send(events.NewTxErrEvent(ctx, err, party, submission.IntoProto(), "submitOrder"))
   104  	// }
   105  	return conf, err
   106  }
   107  
   108  func (e *exEng) AmendOrder(ctx context.Context, amendment *types.OrderAmendment, party string) (*types.OrderConfirmation, error) {
   109  	idgen := idgeneration.New(vgcrypto.RandomHash())
   110  	conf, err := e.Engine.AmendOrder(ctx, amendment, party, idgen)
   111  	if err != nil {
   112  		e.broker.Send(events.NewTxErrEvent(ctx, err, party, amendment.IntoProto(), "amendOrder"))
   113  	}
   114  	return conf, err
   115  }
   116  
   117  func (e *exEng) CancelOrder(ctx context.Context, cancel *types.OrderCancellation, party string) ([]*types.OrderCancellationConfirmation, error) {
   118  	idgen := idgeneration.New(vgcrypto.RandomHash())
   119  	conf, err := e.Engine.CancelOrder(ctx, cancel, party, idgen)
   120  	if err != nil {
   121  		e.broker.Send(events.NewTxErrEvent(ctx, err, party, cancel.IntoProto(), "cancelOrder"))
   122  	}
   123  	return conf, err
   124  }
   125  
   126  func (e *exEng) CancelStopOrder(ctx context.Context, cancel *types.StopOrdersCancellation, party string) error {
   127  	idgen := idgeneration.New(vgcrypto.RandomHash())
   128  	return e.Engine.CancelStopOrders(ctx, cancel, party, idgen)
   129  }
   130  
   131  func (e *exEng) SubmitLiquidityProvision(ctx context.Context, sub *types.LiquidityProvisionSubmission, party, lpID,
   132  	deterministicID string,
   133  ) error {
   134  	if err := e.Engine.SubmitLiquidityProvision(ctx, sub, party, deterministicID); err != nil {
   135  		e.broker.Send(events.NewTxErrEvent(ctx, err, party, sub.IntoProto(), "submitLiquidityProvision"))
   136  		return err
   137  	}
   138  	return nil
   139  }
   140  
   141  func (e *exEng) AmendLiquidityProvision(ctx context.Context, lpa *types.LiquidityProvisionAmendment, party string) error {
   142  	if err := e.Engine.AmendLiquidityProvision(ctx, lpa, party, vgcrypto.RandomHash()); err != nil {
   143  		e.broker.Send(events.NewTxErrEvent(ctx, err, party, lpa.IntoProto(), "amendLiquidityProvision"))
   144  		return err
   145  	}
   146  	return nil
   147  }
   148  
   149  func (e *exEng) CancelLiquidityProvision(ctx context.Context, lpc *types.LiquidityProvisionCancellation, party string) error {
   150  	if err := e.Engine.CancelLiquidityProvision(ctx, lpc, party); err != nil {
   151  		e.broker.Send(events.NewTxErrEvent(ctx, err, party, lpc.IntoProto(), "cancelLiquidityProvision"))
   152  		return err
   153  	}
   154  	return nil
   155  }
   156  
   157  // batch order bits that sit above the exeuction engine.
   158  func (e *exEng) StartBatch(party string) error {
   159  	e.batch = &batchIntruction{
   160  		party: party,
   161  		bmi:   &commandspb.BatchMarketInstructions{},
   162  	}
   163  	return nil
   164  }
   165  
   166  func (e *exEng) AddSubmitOrderToBatch(order *types.OrderSubmission, party string) error {
   167  	if e.batch == nil {
   168  		return ErrBatchInstructionNotStarted
   169  	}
   170  	if e.batch.party != party {
   171  		return ErrBatchInstructionStartedWithDifferentParty
   172  	}
   173  	e.batch.bmi.Submissions = append(e.batch.bmi.Submissions, order.IntoProto())
   174  	return nil
   175  }
   176  
   177  func (e *exEng) AddCancelOrderToBatch(order *types.OrderCancellation, party string) error {
   178  	if e.batch == nil {
   179  		return ErrBatchInstructionNotStarted
   180  	}
   181  	if e.batch.party != party {
   182  		return ErrBatchInstructionStartedWithDifferentParty
   183  	}
   184  	e.batch.bmi.Cancellations = append(e.batch.bmi.Cancellations, order.IntoProto())
   185  	return nil
   186  }
   187  
   188  func (e *exEng) AddAmendOrderToBatch(order *types.OrderAmendment, party string) error {
   189  	if e.batch == nil {
   190  		return ErrBatchInstructionNotStarted
   191  	}
   192  	if e.batch.party != party {
   193  		return ErrBatchInstructionStartedWithDifferentParty
   194  	}
   195  	e.batch.bmi.Amendments = append(e.batch.bmi.Amendments, order.IntoProto())
   196  	return nil
   197  }
   198  
   199  func (e *exEng) ProcessBatch(ctx context.Context, party string) error {
   200  	if e.batch == nil {
   201  		return ErrBatchInstructionNotStarted
   202  	}
   203  	if e.batch.party != party {
   204  		return ErrBatchInstructionStartedWithDifferentParty
   205  	}
   206  
   207  	batch := e.batch.bmi
   208  	e.batch = nil
   209  	bmi := processor.NewBMIProcessor(nil, e.Engine, noopValidation{})
   210  	if err := bmi.ProcessBatch(context.Background(), batch, party, vgcrypto.RandomHash(), stats.NewBlockchain()); err != nil {
   211  		e.broker.Send(events.NewTxErrEvent(ctx, err, party, nil, "processBatch"))
   212  		return err
   213  	}
   214  	return nil
   215  }
   216  
   217  func (e *exEng) SubmitAMM(ctx context.Context, submission *types.SubmitAMM) error {
   218  	idgen := idgeneration.New(vgcrypto.RandomHash())
   219  	if err := e.Engine.SubmitAMM(ctx, submission, idgen.NextID()); err != nil {
   220  		e.broker.Send(events.NewTxErrEvent(ctx, err, submission.Party, submission.IntoProto(), "submitAMM"))
   221  		return err
   222  	}
   223  	return nil
   224  }
   225  
   226  func (e *exEng) AmendAMM(ctx context.Context, submission *types.AmendAMM) error {
   227  	idgen := idgeneration.New(vgcrypto.RandomHash())
   228  	if err := e.Engine.AmendAMM(ctx, submission, idgen.NextID()); err != nil {
   229  		e.broker.Send(events.NewTxErrEvent(ctx, err, submission.Party, submission.IntoProto(), "amendAMM"))
   230  		return err
   231  	}
   232  	return nil
   233  }
   234  
   235  func (e *exEng) CancelAMM(ctx context.Context, cancel *types.CancelAMM) error {
   236  	idgen := idgeneration.New(vgcrypto.RandomHash())
   237  	if err := e.Engine.CancelAMM(ctx, cancel, idgen.NextID()); err != nil {
   238  		e.broker.Send(events.NewTxErrEvent(ctx, err, cancel.Party, cancel.IntoProto(), "cancelAMM"))
   239  		return err
   240  	}
   241  	return nil
   242  }
   243  
   244  type noopValidation struct{}
   245  
   246  func (n noopValidation) CheckOrderCancellation(cancel *commandspb.OrderCancellation) error {
   247  	return nil
   248  }
   249  
   250  func (n noopValidation) CheckOrderAmendment(amend *commandspb.OrderAmendment) error {
   251  	return nil
   252  }
   253  
   254  func (n noopValidation) CheckOrderSubmission(order *commandspb.OrderSubmission) error {
   255  	return nil
   256  }
   257  
   258  func (n noopValidation) CheckStopOrdersCancellation(cancel *commandspb.StopOrdersCancellation) error {
   259  	return nil
   260  }
   261  
   262  func (n noopValidation) CheckStopOrdersSubmission(order *commandspb.StopOrdersSubmission) error {
   263  	return nil
   264  }
   265  
   266  func (n noopValidation) CheckUpdateMarginMode(order *commandspb.UpdateMarginMode) error {
   267  	return nil
   268  }