Example #1
0
        private void MintBlock(List <Transaction> transactions)
        {
            if (Mempool.ValidatorAddress == null)
            {
                Mempool.Logger.Error($"Validator keys not set for mempool");
                return;
            }

            var lastBlockHash = Chain.GetLastBlockHash();
            var lastBlock     = Chain.GetBlockByHash(lastBlockHash);
            var isFirstBlock  = lastBlock == null;

            var protocol = Nexus.GetProtocolVersion(Nexus.RootStorage);

            var minFee = Mempool.MinimumFee;

            Mempool.Logger.Message($"Minting new block with {transactions.Count} potential transactions");

            while (transactions.Count > 0)
            {
                var block = new Block(isFirstBlock ? 1 : (lastBlock.Height + 1)
                                      , Chain.Address
                                      , Timestamp.Now
                                      , transactions.Select(x => x.Hash)
                                      , isFirstBlock ? Hash.Null : lastBlock.Hash
                                      , protocol
                                      , Mempool.ValidatorAddress
                                      , Mempool.Payload);

                try
                {
                    using (var m = new ProfileMarker("Chain.ProcessBlock"))
                    {
                        Chain.ProcessBlock(block, transactions, minFee);
                    }
                }
                catch (InvalidTransactionException e)
                {
                    using (var m = new ProfileMarker("InvalidTransactionException"))
                    {
                        int index = -1;

                        for (int i = 0; i < transactions.Count; i++)
                        {
                            if (transactions[i].Hash == e.Hash)
                            {
                                index = i;
                                break;
                            }
                        }

                        lock (_pending)
                        {
                            if (index >= 0)
                            {
                                transactions.RemoveAt(index);
                            }

                            _pending.Remove(e.Hash);
                            Mempool.RegisterRejectionReason(e.Hash, e.Message);
                        }

                        Mempool.OnTransactionFailed?.Invoke(e.Hash);
                        continue;
                    }
                }

                try
                {
                    StorageChangeSetContext changeSet;
                    using (var m = new ProfileMarker("block.process"))
                    {
                        changeSet = Chain.ProcessBlock(block, transactions, minFee);
                    }

                    using (var m = new ProfileMarker("block.Sign"))
                    {
                        block.Sign(Mempool.ValidatorKeys);
                    }

                    using (var m = new ProfileMarker("Chain.AddBlock"))
                        Chain.AddBlock(block, transactions, minFee, changeSet);
                }
                catch (Exception e)
                {
                    Mempool.Logger.Error(e.ToString());
                }

                lock (_pending)
                {
                    _pending.Clear();
                }

                using (var m = new ProfileMarker("Mempool.OnTransactionCommitted"))
                    foreach (var tx in transactions)
                    {
                        Mempool.OnTransactionCommitted?.Invoke(tx.Hash);
                    }

                return;
            }
        }
Example #2
0
        private void MintBlock(List <Transaction> transactions)
        {
            var lastBlockHash = Chain.GetLastBlockHash();
            var lastBlock     = Chain.GetBlockByHash(lastBlockHash);
            var isFirstBlock  = lastBlock == null;

            var protocol = (uint)Nexus.GetGovernanceValue(Nexus.RootStorage, Nexus.NexusProtocolVersionTag);

            var minFee = Mempool.MinimumFee;

            Mempool.Logger.Message($"Minting new block with {transactions.Count} potential transactions");

            while (transactions.Count > 0)
            {
                var block = new Block(isFirstBlock ? 1 : (lastBlock.Height + 1), Chain.Address, Timestamp.Now, transactions.Select(x => x.Hash), isFirstBlock ? Hash.Null : lastBlock.Hash, protocol, Mempool.ValidatorAddress, Mempool.Payload);

                try
                {
                    Chain.ValidateBlock(block, transactions, minFee);
                }
                catch (InvalidTransactionException e)
                {
                    int index = -1;

                    for (int i = 0; i < transactions.Count; i++)
                    {
                        if (transactions[i].Hash == e.Hash)
                        {
                            index = i;
                            break;
                        }
                    }

                    if (index >= 0)
                    {
                        transactions.RemoveAt(index);
                    }

                    lock (_pending)
                    {
                        _pending.Remove(e.Hash);
                    }

                    Mempool.RegisterRejectionReason(e.Hash, e.Message);
                    Mempool.OnTransactionFailed?.Invoke(e.Hash);
                    continue;
                }

                try
                {
                    block.Sign(Mempool.ValidatorKeys);
                    Chain.AddBlock(block, transactions, minFee);
                }
                catch (Exception e)
                {
                    Mempool.Logger.Error(e.ToString());
                }

                lock (_pending)
                {
                    _pending.Clear();
                }

                foreach (var tx in transactions)
                {
                    Mempool.OnTransactionCommitted?.Invoke(tx.Hash);
                }

                return;
            }
        }