Esempio n. 1
0
        MaintainBlock GenerateBlock(short issuer, int revision, long timestamp)
        {
            if (!IsValid)
            {
                return(null);
            }

            var nextTransactionId   = Operation.FirstTransactionId;
            var nextBlockId         = Protocol.GenesisBlockId;
            var previousHash        = Hash.Empty(Protocol.TransactionHashType);
            var lastTransactionHash = Hash.Empty(ValidationOperation.ValidationHashType);

            var blockTransactions = new List <MaintainTransaction>();

            if (_lastBlock != null)
            {
                nextBlockId         = _lastBlock.BlockId + 1;
                nextTransactionId   = _lastBlock.LastTransactionId + 1;
                previousHash        = _lastBlock.BlockHash;
                lastTransactionHash = _lastBlock.Items.Last().Validation.Hash;
            }

            _transactions.Sort((a, b) => a.UniqueIdentifier.CompareTo(b.UniqueIdentifier));

            foreach (var transaction in _transactions)
            {
                transaction.MetaData.SetTransactionId(nextTransactionId);
                _featureGenerator.ProcessTransaction(transaction);

                nextTransactionId++;
                blockTransactions.Add(transaction);
            }

            if (blockTransactions.Count == 0)
            {
                return(null);
            }

            var block = new MaintainBlock(Protocol.Version, _maintainChain.ChainId, nextBlockId, issuer, revision, timestamp, previousHash, lastTransactionHash, blockTransactions);

            // return a copy of the block and all its transactions
            // if we don't do this, transaction ids might change during another generator run and we get invalid ids
            return(Block.Restore <MaintainBlock>(block.BlockData));
        }
Esempio n. 2
0
        public HashSet <long> CheckBlock(MaintainBlock block)
        {
            var invalid = new HashSet <long>();

            foreach (var transaction in block.Transactions)
            {
                var result = ConsumeTransaction(transaction, true); // add some extra time when checking blocks
                if (result != TransactionResultTypes.Ok)
                {
                    invalid.Add(transaction.TransactionId);
                }
            }

            var newBlock = GenerateBlock(block.Issuer, block.Revision, block.Timestamp);

            if (newBlock == null || newBlock.BlockHash != block.BlockHash)
            {
                if (newBlock != null)
                {
                    var count = newBlock.Items.Count;
                    for (var i = 0; i < count; i++)
                    {
                        var op1 = newBlock.Items[i].Validation;
                        var op2 = block.Items[i].Validation;

                        if (op1.Hash != op2.Hash)
                        {
                            invalid.Add(block.Items[i].Transaction.TransactionId);
                        }
                    }
                }

                if (invalid.Count <= 0)
                {
                    invalid.Add(Protocol.InvalidBlockId);
                }
            }

            return(invalid);
        }
Esempio n. 3
0
 public MaintainBlockGenerator(MaintainChain maintainChain, MaintainBlock lastBlock)
 {
     _maintainChain    = maintainChain;
     _lastBlock        = lastBlock;
     _featureGenerator = new BlockTransactionGenerator(maintainChain);
 }