Exemplo n.º 1
0
        public override CoreBlock GetBlockProposal(VoteProcess <CoreBlock> voteProcess, CoreBlock lastBlock, int revision)
        {
            var remove    = new HashSet <long>();
            var generator = new CoreBlockGenerator(_coreChain, lastBlock);

            lock (_lock)
            {
                foreach (var item in _transactions)
                {
                    var transaction = item.Value;
                    if (_blockStorage.HistoryContainsTransactionOrRegistration(transaction) != TransactionResultTypes.Ok)
                    {
                        remove.Add(transaction.UniqueIdentifier);
                        continue;
                    }

                    if (generator.ConsumeTransaction(transaction as CoreTransaction) != TransactionResultTypes.Ok)
                    {
                        remove.Add(transaction.UniqueIdentifier);
                    }
                }

                foreach (var item in remove)
                {
                    _transactions.Remove(item);
                }
            }

            return(generator.GenerateBlock(voteProcess.LocalIssuer, revision));
        }
Exemplo n.º 2
0
        public override bool CheckBlockProposal(VoteProcess <CoreBlock> voteProcess, CoreBlock block, CoreBlock lastBlock, out HashSet <long> invalidTransactionIds)
        {
            var generator = new CoreBlockGenerator(_coreChain, lastBlock);

            invalidTransactionIds = generator.CheckBlock(block);

            if (invalidTransactionIds.Count > 0)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 3
0
        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);
            }
        }