From 80733657c5fc335e8ff96ea815e169271eee3dc5 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 1 Oct 2020 13:16:56 +0200 Subject: [PATCH] rpcserver+clientdb: store match events for involved orders We create and store an event every time an order is involved in a match making process. We track the three distinct phases a batch goes through from the trader's point of view so we can visualize this process in the future. --- clientdb/order_event.go | 27 +++++++++++++++++++++++++++ rpcserver.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/clientdb/order_event.go b/clientdb/order_event.go index 4cfe269..2be577b 100644 --- a/clientdb/order_event.go +++ b/clientdb/order_event.go @@ -7,6 +7,7 @@ import ( "github.com/lightninglabs/pool/event" "github.com/lightninglabs/pool/order" + "github.com/lightninglabs/pool/poolrpc" "go.etcd.io/bbolt" ) @@ -409,3 +410,29 @@ func (db *DB) StoreOrderEvents(events []OrderEvent) error { return nil }) } + +// StoreBatchEvents creates a match event of the given match state for each of +// our orders involved in a batch and stores it to the main event store. In case +// of a batch reject the RPC reason enum value can optionally be specified. +func (db *DB) StoreBatchEvents(batch *order.Batch, state order.MatchState, + rejectReason poolrpc.MatchRejectReason) error { + + ts := time.Now() + events := make([]OrderEvent, 0, len(batch.MatchedOrders)) + for nonce, matchedOrders := range batch.MatchedOrders { + for _, matchedOrder := range matchedOrders { + evt := NewMatchEvent( + ts, nonce, state, matchedOrder.UnitsFilled, + matchedOrder.Order.Nonce(), + uint32(rejectReason), + ) + events = append(events, evt) + } + } + + if err := db.StoreOrderEvents(events); err != nil { + return fmt.Errorf("error storing match events: %w", err) + } + + return nil +} diff --git a/rpcserver.go b/rpcserver.go index ba54063..5a2946c 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -376,6 +376,15 @@ func (s *rpcServer) handleServerMessage(rpcMsg *poolrpc.ServerAuctionMessage) er rpcLog.Infof("Received PrepareMsg for batch=%x, num_orders=%v", batch.ID[:], len(batch.MatchedOrders)) + // Let's store an event for each order in the batch that we did + // receive a prepare message. + if err := s.server.db.StoreBatchEvents( + batch, order.MatchStatePrepare, + poolrpc.MatchRejectReason_NONE, + ); err != nil { + rpcLog.Errorf("Unable to store order events: %v", err) + } + // The prepare message can be sent over and over again if the // batch needs adjustment. Clear all previous shims. if s.orderManager.HasPendingBatch() { @@ -496,6 +505,16 @@ func (s *rpcServer) handleServerMessage(rpcMsg *poolrpc.ServerAuctionMessage) er return fmt.Errorf("error finalizing batch: %v", err) } + // We've successfully processed the finalize message, let's + // store an event for this for all orders that were involved on + // our side. + if err := s.server.db.StoreBatchEvents( + batch, order.MatchStateFinalized, + poolrpc.MatchRejectReason_NONE, + ); err != nil { + rpcLog.Errorf("Unable to store order events: %v", err) + } + // Accounts that were updated in the batch need to start new // confirmation watchers, now that we expect a batch TX to be // published. @@ -1373,6 +1392,14 @@ func (s *rpcServer) sendRejectBatch(batch *order.Batch, failure error) error { func (s *rpcServer) sendAcceptBatch(batch *order.Batch) error { rpcLog.Infof("Accepting batch=%x", batch.ID[:]) + // Let's store an event for each order in the batch that we did accept + // the batch. + if err := s.server.db.StoreBatchEvents( + batch, order.MatchStateAccepted, poolrpc.MatchRejectReason_NONE, + ); err != nil { + rpcLog.Errorf("Unable to store order events: %v", err) + } + // Send the message to the server. return s.auctioneer.SendAuctionMessage(&poolrpc.ClientAuctionMessage{ Msg: &poolrpc.ClientAuctionMessage_Accept{ @@ -1457,6 +1484,14 @@ func (s *rpcServer) sendSignBatch(batch *order.Batch, sigs order.BatchSignature, rpcLog.Infof("Sending OrderMatchSign for batch %x", batch.ID[:]) + // We've successfully processed the sign message, let's store an event + // for this for all orders that were involved on our side. + if err := s.server.db.StoreBatchEvents( + batch, order.MatchStateSigned, poolrpc.MatchRejectReason_NONE, + ); err != nil { + rpcLog.Errorf("Unable to store order events: %v", err) + } + return s.auctioneer.SendAuctionMessage(&poolrpc.ClientAuctionMessage{ Msg: &poolrpc.ClientAuctionMessage_Sign{ Sign: &poolrpc.OrderMatchSign{