code.vegaprotocol.io/vega@v0.79.0/core/events/auction.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 events
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"time"
    22  
    23  	types "code.vegaprotocol.io/vega/protos/vega"
    24  	eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1"
    25  )
    26  
    27  type Auction struct {
    28  	*Base
    29  	// marketID for the market creating the auction event
    30  	marketID string
    31  	// start time in nanoseconds since 1/1/1970 of the current/last auction
    32  	auctionStart int64
    33  	// stop time in nanoseconds since 1/1/1970 of the current/last auction
    34  	auctionStop int64
    35  	// is/was this an opening auction
    36  	openingAuction bool
    37  	// are we leaving the auction (=true) or entering an auction (=false)
    38  	leave bool
    39  	// what precisely triggered the auction
    40  	trigger types.AuctionTrigger
    41  	// what component extended the ongoing auction (if any)
    42  	extension types.AuctionTrigger
    43  }
    44  
    45  // NewAuctionEvent creates a new auction event object.
    46  func NewAuctionEvent(ctx context.Context, marketID string, leave bool, start, stop int64, triggers ...types.AuctionTrigger) *Auction {
    47  	if len(triggers) == 0 {
    48  		return nil
    49  	}
    50  	trigger := triggers[0]
    51  	opening := trigger == types.AuctionTrigger_AUCTION_TRIGGER_OPENING
    52  	e := &Auction{
    53  		Base:           newBase(ctx, AuctionEvent),
    54  		marketID:       marketID,
    55  		auctionStart:   start,
    56  		auctionStop:    stop,
    57  		openingAuction: opening,
    58  		leave:          leave,
    59  		trigger:        trigger,
    60  	}
    61  	if len(triggers) == 2 {
    62  		e.extension = triggers[1]
    63  	}
    64  
    65  	return e
    66  }
    67  
    68  func (a Auction) MarketID() string {
    69  	return a.marketID
    70  }
    71  
    72  // Auction returns the action performed (either true=leave auction, or false=entering auction).
    73  func (a Auction) Auction() bool {
    74  	return a.leave
    75  }
    76  
    77  // MarketEvent - implement market event interface so we can log this event.
    78  func (a Auction) MarketEvent() string {
    79  	// is in auction
    80  	start := time.Unix(0, a.auctionStart).Format(time.RFC3339Nano)
    81  	if a.extension != types.AuctionTrigger_AUCTION_TRIGGER_UNSPECIFIED {
    82  		return fmt.Sprintf("Market %s in auction mode (%s) started at %s (extension reason: %s)", a.marketID, a.trigger, start, a.extension)
    83  	}
    84  	stopT := time.Unix(0, a.auctionStop)
    85  	if a.leave {
    86  		if a.auctionStop == 0 {
    87  			stopT = time.Now()
    88  		}
    89  		stop := stopT.Format(time.RFC3339Nano)
    90  		if a.openingAuction {
    91  			return fmt.Sprintf("Market %s left opening auction started at %s at %s (trigger: %s)", a.marketID, start, stop, a.trigger)
    92  		}
    93  
    94  		return fmt.Sprintf("Market %s left auction started at %s at %s (trigger: %s)", a.marketID, start, stop, a.trigger)
    95  	}
    96  	if a.openingAuction {
    97  		// an opening auction will always have a STOP time
    98  		stop := stopT.Format(time.RFC3339Nano)
    99  
   100  		return fmt.Sprintf("Market %s entered opening auction at %s, will close at %s (trigger: %s)", a.marketID, start, stop, a.trigger)
   101  	}
   102  	if a.auctionStop == 0 {
   103  		return fmt.Sprintf("Market %s entered auction mode at %s (trigger: %s)", a.marketID, start, a.trigger)
   104  	}
   105  
   106  	return fmt.Sprintf("Market %s entered auction mode at %s, auction closes at %s (trigger: %s)", a.marketID, start, stopT.Format(time.RFC3339Nano), a.trigger)
   107  }
   108  
   109  // Proto wrap event data in a proto message.
   110  func (a Auction) Proto() eventspb.AuctionEvent {
   111  	return eventspb.AuctionEvent{
   112  		MarketId:         a.marketID,
   113  		OpeningAuction:   a.openingAuction,
   114  		Leave:            a.leave,
   115  		Start:            a.auctionStart,
   116  		End:              a.auctionStop,
   117  		Trigger:          a.trigger,
   118  		ExtensionTrigger: a.extension,
   119  	}
   120  }
   121  
   122  // StreamMessage returns the BusEvent message for the event stream API.
   123  func (a Auction) StreamMessage() *eventspb.BusEvent {
   124  	p := a.Proto()
   125  
   126  	busEvent := newBusEventFromBase(a.Base)
   127  	busEvent.Event = &eventspb.BusEvent_Auction{
   128  		Auction: &p,
   129  	}
   130  
   131  	return busEvent
   132  }
   133  
   134  // StreamMarketMessage - allows for this event to be streamed as just a market event
   135  // containing just market ID and a string akin to a log message.
   136  func (a Auction) StreamMarketMessage() *eventspb.BusEvent {
   137  	busEvent := newBusEventFromBase(a.Base)
   138  	busEvent.Type = eventspb.BusEventType_BUS_EVENT_TYPE_MARKET
   139  	busEvent.Event = &eventspb.BusEvent_Market{
   140  		Market: &eventspb.MarketEvent{
   141  			MarketId: a.marketID,
   142  			Payload:  a.MarketEvent(),
   143  		},
   144  	}
   145  
   146  	return busEvent
   147  }
   148  
   149  func AuctionEventFromStream(ctx context.Context, be *eventspb.BusEvent) *Auction {
   150  	e := &Auction{
   151  		Base:           newBaseFromBusEvent(ctx, AuctionEvent, be),
   152  		marketID:       be.GetAuction().MarketId,
   153  		auctionStart:   be.GetAuction().Start,
   154  		auctionStop:    be.GetAuction().End,
   155  		openingAuction: be.GetAuction().OpeningAuction,
   156  		leave:          be.GetAuction().Leave,
   157  		trigger:        be.GetAuction().Trigger,
   158  		extension:      be.GetAuction().ExtensionTrigger,
   159  	}
   160  
   161  	return e
   162  }