async Task <T> GetStoredOperation <T>(long id, TransactionDownloadHandler <T> handler) where T : Operation { T operation = null; var discStorage = _transactionStorage.Value; var contains = discStorage.ContainsIndex(id); if (contains) { try { operation = handler.RestoreTransaction(new Unpacker(discStorage.GetBlockData(id))); var transaction = operation as Transaction; if (transaction != null) { { var accountId = transaction.AccountId; var accountEntry = await _accountEntryStorage.GetEntry(accountId); if (accountEntry != null) { if (accountEntry.RequiresRefresh()) { await _accountEntryStorage.UpdateEntry(accountEntry); } } } { var group = transaction.GetFeature <Group>(Group.FeatureId); if (group != null) { var groupId = group.GroupId; var groupEntry = await _groupEntryStorage.GetEntry(groupId); if (groupEntry != null) { if (groupEntry.RequiresRefresh()) { await _groupEntryStorage.UpdateEntry(groupEntry); } } } } } } catch (Exception ex) { Log.IgnoreException(ex); } } return(operation); }
protected async Task <TransactionDownloadResult <T> > QueryStoredTransactions <T>(long startTransactionId, int count, TransactionDownloadHandler <T> handler) where T : Operation { var nextId = startTransactionId; if (startTransactionId <= Operation.InvalidTransactionId) { nextId = await handler.QueryLastStoredTransactionId(this); } if (nextId != Operation.InvalidTransactionId) { try { var transactions = new List <TransactionDownloadData <T> >(); for (var i = 0; i < count; i++) { if (nextId <= Operation.InvalidTransactionId) { return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.Ok, false, transactions, nextId)); } T operation = await GetStoredOperation <T>(nextId, handler); if (operation == null) { return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.InternalError, true, transactions, Operation.InvalidTransactionId)); } var data = new TransactionDownloadData <T>(operation, this); await DownloadTransactionAttachement(data); RetrieveDecrytpedTransactionStorage(data); transactions.Add(data); nextId = handler.GetPreviousTransactionId(operation); } return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.Ok, nextId != Operation.InvalidTransactionId, transactions, nextId)); } catch (Exception ex) { Log.IgnoreException(ex); } } return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.Ok, false, new List <TransactionDownloadData <T> >(), Operation.InvalidTransactionId)); }
protected async Task <TransactionDownloadResult <T> > DownloadTransactions <T>(long startTransactionId, long endTransactionId, int count, bool downloadAttachements, bool cache, TransactionDownloadHandler <T> handler) where T : Operation { var nextId = Operation.InvalidTransactionId; if (startTransactionId <= Operation.InvalidTransactionId) { var info = await handler.GetLastTransactionId(); var error = TransactionDownloadResultCode.Ok; if (info == null) { error = TransactionDownloadResultCode.NetworkError; } else { if (info.ResultType != ResultTypes.Ok) { if (info.ResultType == ResultTypes.ChainNotFound) { error = TransactionDownloadResultCode.ChainNotFound; } else if (info.ResultType == ResultTypes.DataNotFound) { error = TransactionDownloadResultCode.DataNotFound; } else if (info.ResultType == ResultTypes.AccountNotFound) { error = TransactionDownloadResultCode.AccountNotFound; } else if (info.ResultType == ResultTypes.FeatureNotFound) { error = TransactionDownloadResultCode.FeatureNotFound; } else { throw new Exception("Unknown result type"); } } } if (error != TransactionDownloadResultCode.Ok) { return(new TransactionDownloadResult <T>(error, false, new List <TransactionDownloadData <T> >(), Operation.InvalidTransactionId)); } if (info is Result <LastTransactionInfo> lastTransactionInfo) { nextId = lastTransactionInfo.Item.TransactionId; } else if (info is Result <LastTransactionCountInfo> lastDataTransactionInfo) { nextId = lastDataTransactionInfo.Item.TransactionId; } else { throw new Exception("Unknown last transactin info"); } } else { nextId = startTransactionId; } var transactions = new List <TransactionDownloadData <T> >(); if (nextId != Operation.InvalidTransactionId) { var discStorage = _transactionStorage.Value; try { // useful? var end = endTransactionId != Operation.InvalidTransactionId || count <= 0; if (end) { count = int.MaxValue; } for (var i = 0; i < count; i++) { if (nextId <= Operation.InvalidTransactionId) { return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.Ok, false, transactions, nextId)); } T operation = await GetStoredOperation <T>(nextId, handler); if (operation == null) { operation = await handler.DownloadTransaction(nextId); if (operation != null) { var transaction = operation as Transaction; if (transaction != null) { var accountId = transaction.AccountId; var transactionid = transaction.TransactionId; var timestamp = transaction.Timestamp; { var accountIndex = transaction.GetFeature <AccountIndex>(AccountIndex.FeatureId); if (accountIndex != null) { var index = accountIndex?.Index; var hasIndex = index != null; var accountEntry = await _accountEntryStorage.GetEntry(accountId); if (accountEntry == null) { accountEntry = new DataAccountStorageEntry(accountId); accountEntry.Update(transactionid, timestamp, 0); if (hasIndex) { accountEntry.UpdateIndex(index, transactionid, timestamp, accountIndex.TransactionCount); } await _accountEntryStorage.UpdateEntry(accountEntry); } else { var update = accountEntry.Update(transactionid, timestamp, 0); if (hasIndex) { update |= accountEntry.UpdateIndex(index, transactionid, timestamp, accountIndex.TransactionCount); } if (update) { await _accountEntryStorage.UpdateEntry(accountEntry); } } } } { var sharedIndex = transaction.GetFeature <SharedAccountIndex>(SharedAccountIndex.FeatureId); if (sharedIndex != null) { var accountEntry = await _accountEntryStorage.GetEntry(0); if (accountEntry == null) { accountEntry = new DataAccountStorageEntry(0); accountEntry.Update(transactionid, timestamp, 0); accountEntry.UpdateIndex(sharedIndex.Index, transactionid, timestamp, sharedIndex.TransactionCount); await _accountEntryStorage.UpdateEntry(accountEntry); } else { var update = accountEntry.Update(transactionid, timestamp, 0); update |= accountEntry.UpdateIndex(sharedIndex.Index, transactionid, timestamp, sharedIndex.TransactionCount); if (update) { await _accountEntryStorage.UpdateEntry(accountEntry); } } } } { var receiver = transaction.GetFeature <Receiver>(Receiver.FeatureId); if (receiver != null) { for (var a = 0; a < receiver.Receivers.Count; a++) { var receiverId = receiver.Receivers[a]; var accountEntry = await _accountEntryStorage.GetEntry(receiverId); if (accountEntry == null) { accountEntry = new DataAccountStorageEntry(receiverId); accountEntry.UpdateTargeted(transactionid, timestamp); await _accountEntryStorage.UpdateEntry(accountEntry); } else { if (accountEntry.UpdateTargeted(transactionid, timestamp)) { await _accountEntryStorage.UpdateEntry(accountEntry); } } } } } { var transactionTarget = transaction.GetFeature <TransactionTarget>(TransactionTarget.FeatureId); if (transactionTarget != null) { for (var t = 0; t < transactionTarget.Targets.Count; t++) { var id = transactionTarget.Targets[t]; var targetedEntry = await _targetedTransactionStorage.GetEntry(id); if (targetedEntry == null) { targetedEntry = new TargetedChainTransactionStorageEntry(id); targetedEntry.Update(transactionid, timestamp, 0); await _targetedTransactionStorage.UpdateEntry(targetedEntry); } else { if (targetedEntry.Update(transactionid, timestamp, 0)) { await _targetedTransactionStorage.UpdateEntry(targetedEntry); } } } } } { var group = transaction.GetFeature <Group>(Group.FeatureId); if (group != null) { var groupId = group.GroupId; var groupIndex = group.GroupIndex; var hasGroupIndex = groupIndex != null; var groupEntry = await _groupEntryStorage.GetEntry(groupId); if (groupEntry == null) { groupEntry = new GroupStorageEntry(groupId); groupEntry.Update(transactionid, timestamp, 0); if (hasGroupIndex) { groupEntry.UpdateIndex(groupIndex, transactionid, timestamp, group.GroupIndexTransactionCount); } await _groupEntryStorage.UpdateEntry(groupEntry); } else { var update = groupEntry.Update(transactionid, timestamp, 0); if (hasGroupIndex) { update |= groupEntry.UpdateIndex(groupIndex, transactionid, timestamp, group.GroupIndexTransactionCount); } if (update) { await _groupEntryStorage.UpdateEntry(groupEntry); } } } } } if (cache) { if (discStorage.ContainsIndex(nextId)) { discStorage.UpdateEntry(operation.OperationId, operation.ToArray()); } else { discStorage.AddEntry(operation.OperationId, operation.ToArray()); } discStorage.Commit(); } } else { return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.NetworkError, true, transactions, Operation.InvalidTransactionId)); } } if (operation == null) { return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.InternalError, true, transactions, Operation.InvalidTransactionId)); } var data = new TransactionDownloadData <T>(operation, this); if (downloadAttachements && cache) { await DownloadTransactionAttachement(data); } RetrieveDecrytpedTransactionStorage(data); transactions.Add(data); nextId = handler.GetPreviousTransactionId(operation); if (end && nextId <= endTransactionId) { return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.Ok, nextId != Operation.InvalidTransactionId, transactions, nextId)); } } return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.Ok, nextId != Operation.InvalidTransactionId, transactions, nextId)); } catch (Exception ex) { Log.IgnoreException(ex); return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.InternalError, true, transactions, Operation.InvalidTransactionId)); } finally { if (downloadAttachements) { _attachementsStorage.Value.Commit(); } } } return(new TransactionDownloadResult <T>(TransactionDownloadResultCode.Ok, false, transactions, Operation.InvalidTransactionId)); }