public ChainInfo(ChainInfo chainInfo) { lock (chainInfo) { ChainId = chainInfo.ChainId; AccountId = chainInfo.AccountId; Name = chainInfo.Name; Website = chainInfo.Website; _lastState = chainInfo.LastState; _lastStates = new List <BlockState>(chainInfo._lastStates); _publicEndpoints = new List <string>(chainInfo._publicEndpoints); _chainKeys = new Dictionary <short, RevokeablePublicChainKey>(chainInfo._chainKeys); _purchases = new Dictionary <int, RevokeablePurchaseInfo>(chainInfo._purchases); _revenueInfo = new List <ChainRevenueInfo>(chainInfo._revenueInfo); TotalAccountPayout = chainInfo.TotalAccountPayout; TotalChainPayout = chainInfo.TotalChainPayout; } }
internal ChainInfo GetChainInfo(int chainId, bool add = true, bool clone = false) { lock (_lock) { if (_chains.TryGetValue(chainId, out var chain)) { return((clone) ? new ChainInfo(chain) : chain); } } var data = _chainInfoStorage.GetBlockData(chainId); if (data == null) { return(null); } using (var unpacker = new Unpacker(data)) { var chain = new ChainInfo(unpacker); if (add) { lock (_lock) { if (_chains.TryGetValue(chainId, out var ch)) { return((clone) ? new ChainInfo(ch) : ch); } _chains[chainId] = chain; } } if (chain.ChainId != chainId) { throw new Exception("Invalid chain info"); } return((clone) ? new ChainInfo(chain) : chain); } }
bool ConsumeTransaction(DirtyData dirtyData, TransactionItem <CoreOperation> coreItem) { var operation = coreItem.Transaction; var validation = coreItem.Validation; if (operation.OperationId <= LastProcessedTransactionId) { return(false); } var type = operation.CoreOperationType; if (type == CoreOperationTypes.Account) { var ar = operation as AccountOperation; { var ac = GetCoreAccount(ar.AccountId, false); if (ac != null) { return(false); } } var account = new CoreAccount(ar.AccountId, ar.PublicKey) { LastTransactionId = operation.OperationId }; lock (_lock) _accounts[account.AccountId] = account; _accountStorage.AddEntry(ar.AccountId, account.ToByteArray()); return(true); } if (type == CoreOperationTypes.ChainInfo) { var co = operation as ChainInfoOperation; { var ci = GetChainInfo(co.ChainId, false); if (co.IsNewChain && ci != null) { return(false); } if (!co.IsNewChain && ci == null) { return(false); } } ChainInfo chain; if (co.IsNewChain) { chain = new ChainInfo(co.ChainId, co.AccountId, co.Name, co.Website); } else { chain = GetChainInfo(co.ChainId); chain.UpdateInfo(co.Name, co.Website); } if (chain.ChainId != Protocol.CoreChainId) { var account = GetCoreAccount(co.AccountId); if (account == null) { return(false); } account.LastTransactionId = operation.OperationId; dirtyData.DirtyAccounts.Add(account.AccountId); } foreach (var endpoint in co.PublicEndpoints) { chain.AddPublicEndPoint(endpoint); } foreach (var endpoint in co.RemovePublicEndPoints) { chain.RemovePublicEndPoint(endpoint); } foreach (var chainKey in co.ChainKeys) { chain.AddChainKey(chainKey, co.Timestamp); } foreach (var chainKeyIndex in co.RevokeChainKeys) { chain.RevokeChainKey(chainKeyIndex, operation.Timestamp); } foreach (var purchase in co.Purchases) { chain.AddPurchase(purchase, co.Timestamp); } foreach (var item in co.RemovePurchaseItems) { chain.RemovePurchaseItem(item, operation.Timestamp); } lock (_lock) _chains[chain.ChainId] = chain; if (co.IsNewChain) { _chainInfoStorage.AddEntry(co.ChainId, chain.ToByteArray()); } else { dirtyData.DirtyChains.Add(co.ChainId); } return(true); } if (type == CoreOperationTypes.Revenue) { var rev = operation as ChainRevenueInfoOperation; var chainId = rev.ChainId; var chain = GetChainInfo(chainId); if (chain == null) { return(false); } chain.AddRevenueInfo(rev.Revenue, rev.RevenueAccountFactor, rev.Timestamp); dirtyData.DirtyChains.Add(chainId); return(true); } if (type == CoreOperationTypes.AccountUpdate) { var u = operation as AccountUpdateOperation; foreach (var item in u.Updates.Values) { var account = GetCoreAccount(item.AccountId, true); if (account == null) { return(false); } account.UpdateBalance(item.Balance); account.LastTransactionId = operation.OperationId; dirtyData.DirtyAccounts.Add(item.AccountId); foreach (var revenue in item.Revenues) { var chainId = revenue.ChainId; var c = GetChainInfo(chainId); c.AddTotalAccountPayout(revenue.Amount); dirtyData.DirtyChains.Add(chainId); } } return(true); } if (type == CoreOperationTypes.BlockState) { var bi = operation as BlockStateOperation; foreach (var state in bi.BlockStates.Values) { var chainId = state.ChainId; var chainInfo = GetChainInfo(chainId); if (chainInfo == null) { return(false); } chainInfo.Update(state); dirtyData.DirtyChains.Add(chainId); } return(true); } return(false); }
internal bool TryGetChainInfo(int chainId, out ChainInfo chainInfo, bool add = true, bool clone = false) { chainInfo = GetChainInfo(chainId, add, clone); return(chainInfo != null); }