public static async Task <(ResultMessage result, byte[] effectsHash, EffectProcessorsContainer container)> ProcessQuantumWithoutValidation(Domain.ExecutionContext context, MessageEnvelope envelope)
        {
            var messageType = envelope.Message.MessageType;

            if (messageType == MessageTypes.RequestQuantum)
            {
                var request = (RequestQuantum)envelope.Message;
                messageType = request.RequestMessage.MessageType;
                request.RequestMessage.AccountWrapper = context.AccountStorage.GetAccount(request.RequestMessage.Account);
            }

            context.QuantumProcessor.TryGetValue(messageType, out var processor);

            var container      = new EffectProcessorsContainer(context, envelope, new DiffObject());
            var processContext = processor.GetContext(container);

            var res = await processor.Process(processContext);

            context.QuantumStorage.AddQuantum(envelope, envelope.ComputeHash());

            var effectsHash = new EffectsContainer {
                Effects = container.Effects
            }.ComputeHash();

            return(res, effectsHash, container);
        }
        public static async Task <(ResultMessage result, byte[] effectsHash, EffectProcessorsContainer container)> ProcessQuantumIsolated(this IntegrationTestEnvironment environment, MessageEnvelope envelope)
        {
            var context = new AlphaContext(environment.AlphaWrapper.Context.Settings, new MockStorage(), environment.AlphaWrapper.Context.StellarDataProvider);

            await context.Init();

            //wait while all pending updates will be saved
            while (await environment.AlphaWrapper.Context.PersistenceManager.GetLastApex() != environment.AlphaWrapper.Context.QuantumStorage.CurrentApex)
            {
                Thread.Sleep(100);
            }
            await context.Setup(await environment.AlphaWrapper.Context.PersistenceManager.GetSnapshot(environment.AlphaWrapper.Context.QuantumStorage.CurrentApex));

            var messageType = envelope.Message.MessageType;

            if (messageType == MessageTypes.RequestQuantum)
            {
                messageType = ((RequestQuantum)envelope.Message).RequestMessage.MessageType;
            }

            context.QuantumProcessor.TryGetValue(messageType, out var processor);

            var container      = new EffectProcessorsContainer(context, envelope, new DiffObject());
            var processContext = processor.GetContext(container);

            var res = await processor.Process(processContext);

            var effectsHash = new EffectsContainer {
                Effects = container.Effects
            }.ComputeHash();

            return(res, effectsHash, container);
        }
        public void OrderbookPerformanceTest(int iterations, bool useNormalDistribution = false)
        {
            var rnd = new Random();

            var testTradeResults = new Dictionary <RequestQuantum, EffectProcessorsContainer>();

            for (var i = 1; i < iterations; i++)
            {
                var price          = useNormalDistribution ? rnd.NextNormallyDistributed() + 50 : rnd.NextDouble() * 100;
                var accountWrapper = context.AccountStorage.GetAccount(account1.Account.Pubkey);
                var trade          = new RequestQuantum
                {
                    Apex            = i,
                    RequestEnvelope = new MessageEnvelope
                    {
                        Message = new OrderRequest
                        {
                            Account        = accountWrapper.Account.Id,
                            RequestId      = i,
                            Amount         = rnd.Next(1, 20),
                            Asset          = 1,
                            Price          = Math.Round(price * 10) / 10,
                            Side           = rnd.NextDouble() >= 0.5 ? OrderSide.Buy : OrderSide.Sell,
                            AccountWrapper = context.AccountStorage.GetAccount(account1.Account.Pubkey)
                        },
                        Signatures = new List <Ed25519Signature>()
                    },
                    Timestamp = DateTime.UtcNow.Ticks
                };
                var diffObject = new DiffObject();
                var conterOrderEffectsContainer = new EffectProcessorsContainer(context, trade.CreateEnvelope(), diffObject);
                testTradeResults.Add(trade, conterOrderEffectsContainer);
            }

            PerfCounter.MeasureTime(() =>
            {
                foreach (var trade in testTradeResults)
                {
                    context.Exchange.ExecuteOrder(trade.Value);
                }
            }, () =>
            {
                var market = context.Exchange.GetMarket(1);
                return($"{iterations} iterations, orderbook size: {market.Bids.Count} bids,  {market.Asks.Count} asks, {market.Bids.GetBestPrice().ToString("G3")}/{market.Asks.GetBestPrice().ToString("G3")} spread.");
            });
        }
Beispiel #4
0
        private void ExecuteWithOrderbook(int iterations, bool useNormalDistribution, Action <Action> executor)
        {
            var rnd = new Random();

            var market = Global.Exchange.GetMarket(1);

            var testTradeResults = new Dictionary <RequestQuantum, EffectProcessorsContainer>();

            for (var i = 1; i < iterations; i++)
            {
                var price   = useNormalDistribution ? rnd.NextNormallyDistributed() + 50 : rnd.NextDouble() * 100;
                var request = new OrderRequest
                {
                    RequestId = i,
                    Amount    = rnd.Next(1, 20),
                    Asset     = 1,
                    Price     = Math.Round(price * 27) / 13
                };
                if (rnd.NextDouble() >= 0.5)
                {
                    request.Account        = account1.Id;
                    request.AccountWrapper = account1;
                    request.Side           = OrderSide.Buy;
                }
                else
                {
                    request.Account        = account2.Id;
                    request.AccountWrapper = account2;
                    request.Side           = OrderSide.Sell;
                }

                var trade = new RequestQuantum
                {
                    Apex            = i,
                    RequestEnvelope = new MessageEnvelope
                    {
                        Message    = request,
                        Signatures = new List <Ed25519Signature>()
                    },
                    Timestamp = DateTime.UtcNow.Ticks
                };
                var diffObject = new DiffObject();
                var conterOrderEffectsContainer = new EffectProcessorsContainer(trade.CreateEnvelope(), diffObject);
                testTradeResults.Add(trade, conterOrderEffectsContainer);
            }

            var xlmStartBalance   = account1.Account.GetBalance(0).Amount + account2.Account.GetBalance(0).Amount;
            var assetStartBalance = account1.Account.GetBalance(1).Amount + account2.Account.GetBalance(1).Amount;

            executor(() =>
            {
                foreach (var trade in testTradeResults)
                {
                    Global.Exchange.ExecuteOrder(trade.Value);
                }
            });

            //cleanup orders
            foreach (var account in new[] { account1, account2 })
            {
                var activeOrders = Global.Exchange.OrderMap.GetAllAccountOrders(account);
                foreach (var order in activeOrders)
                {
                    var decodedOrderId = OrderIdConverter.Decode(order.OrderId);

                    new OrderRemovedEffectProccessor(new OrderRemovedEffect
                    {
                        OrderId        = order.OrderId,
                        Amount         = order.Amount,
                        QuoteAmount    = order.QuoteAmount,
                        Price          = order.Price,
                        Asset          = decodedOrderId.Asset,
                        AccountWrapper = account
                    }, market.GetOrderbook(decodedOrderId.Side)).CommitEffect();
                }
            }
            Assert.AreEqual(xlmStartBalance, account1.Account.GetBalance(0).Amount + account2.Account.GetBalance(0).Amount);
            Assert.AreEqual(assetStartBalance, account1.Account.GetBalance(1).Amount + account2.Account.GetBalance(1).Amount);
            Assert.AreEqual(0, account1.Account.GetBalance(0).Liabilities);
            Assert.AreEqual(0, account1.Account.GetBalance(1).Liabilities);
            Assert.AreEqual(0, account2.Account.GetBalance(0).Liabilities);
            Assert.AreEqual(0, account2.Account.GetBalance(1).Liabilities);
        }
Beispiel #5
0
 public OrderCancellationProcessorContext(EffectProcessorsContainer effectProcessors)
     : base(effectProcessors)
 {
 }