internal ServiceAccount GetServiceAccount(long accountId) { if (_serviceAccounts.TryGetValue(accountId, out var account)) { return(account); } var data = _serviceAccountStorage.GetBlockData(accountId); if (data == null) { return(null); } using (var unpacker = new Unpacker(data)) { account = new ServiceAccount(unpacker); lock (_lock) { if (_serviceAccounts.TryGetValue(accountId, out var storedAccount)) { return(storedAccount); } if (account.AccountId != accountId) { throw new Exception("Invalid service account data"); } _serviceAccounts[accountId] = account; } return(account); } }
void ConsumeTransaction(CommitItems commitItems, TransactionItem <ServiceTransaction> item) { var transaction = item.Transaction; if (transaction.TransactionId <= LastProcessedTransactionId) { return; } if (transaction.TargetChainId == ChainId) { var type = transaction.TransactionType; var accountId = transaction.AccountId; var account = GetServiceAccount(accountId); if (type == ServiceTransactionTypes.Join) { var joinTransaction = transaction as JoinServiceTransaction; if (account == null) { account = new ServiceAccount(accountId, ChainId, joinTransaction.Timestamp); if (joinTransaction.AccountKey != null) { account.AddAccountKey(joinTransaction.AccountKey, joinTransaction.Timestamp); } lock (_lock) _serviceAccounts[accountId] = account; _serviceAccountStorage.AddEntry(accountId, account.ToByteArray()); return; // skip dirty account stuff } if (joinTransaction.AccountKey != null) { account.AddAccountKey(joinTransaction.AccountKey, joinTransaction.Timestamp); commitItems.DirtyAccounts.Add(accountId); } } else if (type == ServiceTransactionTypes.Purchase) { var purchaseTransaction = transaction as PurchaseServiceTransaction; var purchase = CoreChain.GetChainInfo(ChainId).GetPurchase(purchaseTransaction.PurchaseGroupId, purchaseTransaction.PurchaseItemId); if (purchase != null) { var targetAccount = GetServiceAccount(purchaseTransaction.ReceiverAccountId); if (targetAccount != null && purchase != null) { targetAccount.AddPurchase(purchaseTransaction, purchase); commitItems.DirtyAccounts.Add(targetAccount.AccountId); } } } else if (type == ServiceTransactionTypes.RequestRevenue) { var revenueTransaction = transaction as RequestRevenueServiceTransaction; account.UpdateTotelRevenuePayout(revenueTransaction.CurrentTotalRevenuePayout + revenueTransaction.PayoutAmount); } ConsumeTransactionFeatures((ushort)ServiceTransactionTypes.FeatureRequest, transaction, account, commitItems); commitItems.DirtyAccounts.Add(accountId); } }