public virtual void Dispose() { PendingUpdatesManager?.Stop(TimeSpan.FromMilliseconds(0)); PendingUpdatesManager?.Dispose(); ExtensionsManager?.Dispose(); WithdrawalStorage?.Dispose(); TxListener?.Dispose(); }
public static async Task TearDown() { PendingUpdatesManager?.Stop(); PendingUpdatesManager?.Dispose(); AuditLedgerManager?.Dispose(); AuditResultManager?.Dispose(); await DisposeAnalyticsManager(); AuditLedgerManager?.Dispose(); AuditResultManager?.Dispose(); ExtensionsManager?.Dispose(); WithdrawalStorage?.Dispose(); }
public static async Task Setup(Snapshot snapshot) { Constellation = snapshot.Settings; AccountStorage = new AccountStorage(snapshot.Accounts, Constellation.RequestRateLimits); if (Exchange != null) { Exchange.OnUpdates -= Exchange_OnUpdates; Exchange?.Dispose(); } Exchange = Exchange.RestoreExchange(snapshot.Settings.Assets, snapshot.Orders, IsAlpha); WithdrawalStorage?.Dispose(); WithdrawalStorage = new WithdrawalStorage(snapshot.Withdrawals, (!EnvironmentHelper.IsTest && IsAlpha)); TxCursorManager = new TxCursorManager(snapshot.TxCursor); TxListener?.Dispose(); TxListener = IsAlpha ? (TxListenerBase) new AlphaTxListener(snapshot.TxCursor) : new AuditorTxListener(snapshot.TxCursor); if (IsAlpha) { AuditLedgerManager?.Dispose(); AuditLedgerManager = new AuditLedgerManager(); AuditResultManager?.Dispose(); AuditResultManager = new ResultManager(); await DisposeAnalyticsManager(); AnalyticsManager = new AnalyticsManager( PermanentStorage, DepthsSubscription.Precisions.ToList(), Constellation.Assets.Where(a => !a.IsXlm).Select(a => a.Id).ToList(), snapshot.Orders.Select(o => o.ToOrderInfo()).ToList() ); await AnalyticsManager.Restore(DateTime.UtcNow); AnalyticsManager.StartTimers(); AnalyticsManager.OnError += AnalyticsManager_OnError; AnalyticsManager.OnUpdate += AnalyticsManager_OnUpdate; Exchange.OnUpdates += Exchange_OnUpdates; DisposePerformanceStatisticsManager(); PerformanceStatisticsManager = new PerformanceStatisticsManager(); PerformanceStatisticsManager.OnUpdates += PerformanceStatisticsManager_OnUpdates; } ExtensionsManager?.Dispose(); ExtensionsManager = new ExtensionsManager(); ExtensionsManager.RegisterAllExtensions(); }
public virtual Task Setup(Snapshot snapshot) { Constellation = snapshot.Settings; AccountStorage = new AccountStorage(snapshot.Accounts); Exchange?.Dispose(); Exchange = Exchange.RestoreExchange(snapshot.Settings.Assets, snapshot.Orders, IsAlpha, useLegacyOrderbook); WithdrawalStorage?.Dispose(); WithdrawalStorage = new WithdrawalStorage(snapshot.Withdrawals); TxCursorManager = new TxCursorManager(snapshot.TxCursor); return(Task.CompletedTask); }
public WithdrawalCreateEffectProcessor(WithdrawalCreateEffect effect, WithdrawalWrapper withdrawal, WithdrawalStorage withdrawalStorage) : base(effect) { this.withdrawalStorage = withdrawalStorage ?? throw new ArgumentNullException(nameof(withdrawalStorage)); this.withdrawal = withdrawal ?? throw new ArgumentNullException(nameof(withdrawal)); }
public static void AddWithdrawalRemove(this EffectProcessorsContainer effectProcessors, WithdrawalWrapper withdrawal, bool isSuccessful, WithdrawalStorage withdrawalStorage) { var effect = new WithdrawalRemoveEffect { Apex = effectProcessors.Apex, Account = withdrawal.Source.Account.Id, AccountWrapper = withdrawal.Source, IsSuccessful = isSuccessful, Items = withdrawal.Withdrawals.Select(w => new WithdrawalEffectItem { Asset = w.Asset, Amount = w.Amount }).OrderBy(a => a.Asset).ToList() }; effectProcessors.Add(new WithdrawalRemoveEffectProcessor(effect, withdrawal, withdrawalStorage)); }
/// <summary> /// Builds snapshot for specified apex /// </summary> /// <param name="apex"></param> /// <returns></returns> public async Task <Snapshot> GetSnapshot(long apex) { if (apex < 0) { throw new ArgumentException("Apex cannot be less than zero."); } var lastApex = await GetLastApex(); if (lastApex < apex) { throw new InvalidOperationException("Requested apex is greater than the last known one."); } //some auditors can have capped db var minRevertApex = await GetMinRevertApex(); if (minRevertApex == -1 && apex != lastApex || apex < minRevertApex) { throw new InvalidOperationException($"Lack of data to revert to {apex} apex."); } var settings = await GetConstellationSettings(apex); if (settings == null) { return(null); } var stellarData = await storage.LoadConstellationState(); var accounts = (await GetAccounts()).Select(a => new AccountWrapper(a, settings.RequestRateLimits)); var accountStorage = new AccountStorage(accounts); var withdrawals = await GetWithdrawals(accountStorage, settings); var orders = await GetOrders(accountStorage); var exchange = await GetRestoredExchange(orders); var withdrawalsStorage = new WithdrawalStorage(withdrawals); var batchSize = 1000; var effects = new List <Effect>(); while (true) { var quanta = await storage.LoadQuantaAboveApex(apex, batchSize); effects.AddRange(quanta.SelectMany(q => q.ToQuantumContainer(accountStorage).Effects)); if (quanta.Count < batchSize) { break; } } for (var i = effects.Count - 1; i >= 0; i--) { var currentEffect = effects[i]; var account = currentEffect.AccountWrapper; IEffectProcessor <Effect> processor = null; switch (currentEffect) { case AccountCreateEffect accountCreateEffect: processor = new AccountCreateEffectProcessor(accountCreateEffect, accountStorage, settings.RequestRateLimits); break; case NonceUpdateEffect nonceUpdateEffect: processor = new NonceUpdateEffectProcessor(nonceUpdateEffect); break; case BalanceCreateEffect balanceCreateEffect: processor = new BalanceCreateEffectProcessor(balanceCreateEffect); break; case BalanceUpdateEffect balanceUpdateEffect: processor = new BalanceUpdateEffectProcesor(balanceUpdateEffect); break; case RequestRateLimitUpdateEffect requestRateLimitUpdateEffect: processor = new RequestRateLimitUpdateEffectProcessor(requestRateLimitUpdateEffect, settings.RequestRateLimits); break; case OrderPlacedEffect orderPlacedEffect: { var orderBook = exchange.GetOrderbook(orderPlacedEffect.OrderId); var order = exchange.OrderMap.GetOrder(orderPlacedEffect.OrderId); processor = new OrderPlacedEffectProcessor(orderPlacedEffect, orderBook, order); } break; case OrderRemovedEffect orderRemovedEffect: { var orderBook = exchange.GetOrderbook(orderRemovedEffect.OrderId); processor = new OrderRemovedEffectProccessor(orderRemovedEffect, orderBook); } break; case TradeEffect tradeEffect: { var order = exchange.OrderMap.GetOrder(tradeEffect.OrderId); if (order == null) //no need to revert trade if no order was created { continue; } processor = new TradeEffectProcessor(tradeEffect, order); } break; case WithdrawalCreateEffect withdrawalCreate: { var withdrawal = withdrawalsStorage.GetWithdrawal(withdrawalCreate.Apex); processor = new WithdrawalCreateEffectProcessor(withdrawalCreate, withdrawal, withdrawalsStorage); } break; case WithdrawalRemoveEffect withdrawalRemove: { var withdrawal = withdrawalsStorage.GetWithdrawal(withdrawalRemove.Apex); processor = new WithdrawalRemoveEffectProcessor(withdrawalRemove, withdrawal, withdrawalsStorage); } break; default: throw new NotImplementedException(); } processor.RevertEffect(); } var lastQuantumData = (await storage.LoadQuantum(apex)).ToQuantumContainer(); //TODO: refactor restore exchange //we need to clean all order links to be able to restore exchange var allOrders = exchange.OrderMap.GetAllOrders(); foreach (var order in orders) { order.Next = null; order.Prev = null; } return(new Snapshot { Apex = apex, Accounts = accountStorage.GetAll().OrderBy(a => a.Account.Id).ToList(), TxCursor = stellarData?.TxCursor ?? 0, Orders = allOrders.OrderBy(o => o.OrderId).ToList(), Settings = settings, Withdrawals = withdrawalsStorage.GetAll().OrderBy(w => w.Apex).ToList(), LastHash = lastQuantumData.Quantum.Message.ComputeHash() }); }