public async Task HandleBlockData(BlockData blockData, HashSet <NodeConnection> nodeConnections) { if (blockData == null) { return; } var block = blockData.Block; var chainId = block.ChainId; var chainIndex = block.ChainIndex; var chainSyncItem = GetChainSyncItem(chainId, chainIndex, block.ChainType); if (blockData.ChainType == ChainType.Core) { if (blockData is BlockData <CoreBlock> coreBlockData) { await HandleBlockData(coreBlockData, chainSyncItem, _coreChain, nodeConnections); } } else if (blockData.ChainType == ChainType.Service) { if (blockData is BlockData <ServiceBlock> serviceBlockData) { var chain = _chainManager.GetServiceChain(chainId); if (chain != null) { await HandleBlockData(serviceBlockData, chainSyncItem, chain, nodeConnections); } } } else if (blockData.ChainType == ChainType.Data) { if (blockData is BlockData <DataBlock> dataBlockData) { var chain = _chainManager.GetDataChain(chainId, chainIndex); if (chain != null) { await HandleBlockData(dataBlockData, chainSyncItem, chain, nodeConnections); } } } else if (blockData.ChainType == ChainType.Maintain) { if (blockData is BlockData <MaintainBlock> maintainBlockData) { var chain = _chainManager.GetMaintainChain(chainId); if (chain != null) { await HandleBlockData(maintainBlockData, chainSyncItem, chain, nodeConnections); } } } else { throw new Exception($"Unkown ChainType {blockData.ChainType}."); } }
async Task Loop() { while (!_node.HasQuit) { try { List <CoreItem> coreTransactions = null; List <ServiceItem> serviceTransactions = null; List <DataItem> dataTransactions = null; List <MaintainItem> maintainTransactions = null; lock (_lock) { if (_coreTransactions.Count > 0) { coreTransactions = _coreTransactions; _coreTransactions = new List <CoreItem>(); } if (_dataTransactions.Count > 0) { dataTransactions = _dataTransactions; _dataTransactions = new List <DataItem>(); } if (_serviceTransactions.Count > 0) { serviceTransactions = _serviceTransactions; _serviceTransactions = new List <ServiceItem>(); } if (_maintainTransactions.Count > 0) { maintainTransactions = _maintainTransactions; _maintainTransactions = new List <MaintainItem>(); } } if (coreTransactions != null) { var chain = _chainManager.CoreChain; var generator = new CoreBlockGenerator(chain, chain.BlockStorage.LastBlock as CoreBlock); foreach (var transactionItem in coreTransactions) { var transaction = transactionItem.Transaction; var sender = transactionItem.Sender; var nodeConnection = transactionItem.Connection as NodeConnection; var check = generator.ConsumeTransaction(transactionItem.Transaction); if (check == TransactionResultTypes.Ok) { if (!_node.CouncilManager.HandleNewTransaction(transaction, null, nodeConnection)) { _ = _node.NodeServer.Broadcast(new NodeTransactionMessage(transaction, sender == SenderTypes.Client ? 0 : (int)transactionItem.Payload) { SignKey = _configuration.LocaleNodePrivateKey }, new HashSet <NodeConnection> { nodeConnection }); } } else { if (sender == SenderTypes.Client) { var requestCode = transactionItem.Payload; if (requestCode != 0) { await transactionItem.Connection.Send(new ClientTransactionResponseMessage(requestCode, check, null) { SignKey = _configuration.LocaleNodePrivateKey }); } } } } } if (serviceTransactions != null) { var generators = new Dictionary <int, ServiceBlockGenerator>(); foreach (var transactionItem in serviceTransactions) { var transaction = transactionItem.Transaction; var sender = transactionItem.Sender; var chainid = transaction.TargetChainId; var serviceChain = _chainManager.GetServiceChain(chainid); var validationResult = await serviceChain.ValidateServiceTransaction(transaction); var result = validationResult.Result; var userCode = validationResult.UserCode; var message = validationResult.Message; if (result == TransactionResultTypes.Ok) { if (!generators.TryGetValue(chainid, out var generator)) { generator = new ServiceBlockGenerator(_chainManager.CoreChain, serviceChain, _chainManager.GetMaintainChain(chainid), serviceChain.BlockStorage.LastBlock as ServiceBlock); generators[chainid] = generator; } result = generator.ConsumeTransaction(transaction); } if (result == TransactionResultTypes.Ok) { _node.CouncilManager.HandleNewTransaction(transaction, null, transactionItem.Connection as NodeConnection); } else { if (sender == SenderTypes.Client) { var requestCode = transactionItem.Payload; if (requestCode != 0) { await transactionItem.Connection.Send(new ClientTransactionResponseMessage(requestCode, userCode, message, result, null) { SignKey = _configuration.LocaleNodePrivateKey }); } } } } } if (dataTransactions != null) { foreach (var transactionItem in dataTransactions) { var transaction = transactionItem.Transaction; var chainid = transaction.TargetChainId; var sender = transactionItem.Sender; var dataChain = _chainManager.GetDataChain(chainid, transaction.ChainIndex); var validation = transactionItem.NodeValidation; if (validation != null) { var chainKey = _node.ChainManager.CoreChain.GetChainInfo(chainid)?.GetValidChainKey(transaction.ChainIndex, validation.KeyIndex, transaction.Timestamp); if (!validation.IsValid(transaction, chainKey?.PublicKey)) { validation = null; } } if (validation != null) { _node.CouncilManager.HandleNewTransaction(transaction, validation, transactionItem.Connection as NodeConnection); } else { var validationResult = await dataChain.ValidateDataTransaction(transaction); validation = validationResult.TransactionValidation; var result = validationResult.Result; var userCode = validationResult.UserCode; var message = validationResult.Message; if (result == TransactionResultTypes.Ok) { _node.CouncilManager.HandleNewTransaction(transaction, validation, transactionItem.Connection as NodeConnection); } else { if (sender == SenderTypes.Client) { var requestCode = transactionItem.Payload; if (requestCode != 0) { await transactionItem.Connection.Send(new ClientTransactionResponseMessage(requestCode, userCode, message, result, null) { SignKey = _configuration.LocaleNodePrivateKey }); } } } } } } if (maintainTransactions != null) { var generators = new Dictionary <int, MaintainBlockGenerator>(); foreach (var item in maintainTransactions) { var transaction = item.Transaction; var chainId = transaction.TargetChainId; var chain = _chainManager.GetMaintainChain(chainId); var result = chain.ValidateMaintainTransaction(transaction); if (result == TransactionResultTypes.Ok) { if (!_node.CouncilManager.HandleNewTransaction(transaction, null, null)) { _ = _node.NodeServer.Broadcast(new NodeTransactionMessage(transaction, (int)item.Payload) { SignKey = _configuration.LocaleNodePrivateKey }, null); } } } } } catch (Exception ex) { Log.HandleException(ex, this); } await Task.Delay(50); } }