public ServiceBlockGenerator(CoreChain coreChain, ServiceChain serviceChain, MaintainChain maintainChain, ServiceBlock lastBlock) { ChainId = serviceChain.ChainId; _blockInfo = new ServiceBlockInfo(serviceChain); _coreChain = coreChain; _serviceChain = serviceChain; _maintainChain = maintainChain; _lastBlock = lastBlock; _chainInfo = coreChain.GetChainInfo(ChainId); _blockState = _chainInfo.LastState; }
public ServiceBlock GenerateBlock(short issuer, int revision, long timestamp) { if (!IsValid) { return(null); } var nextTransactionId = Operation.FirstTransactionId; var blockId = Protocol.GenesisBlockId; var previousHash = Hash.Empty(Protocol.TransactionHashType); var lastTransactionHash = Hash.Empty(ValidationOperation.ValidationHashType); if (_lastBlock != null) { blockId = _lastBlock.BlockId + 1; nextTransactionId = _blockState.LastTransactionId + 1; previousHash = _lastBlock.BlockHash; lastTransactionHash = _lastBlock.Items.Last().Validation.Hash; } _blockInfo.Sort(); var transactions = new List <ServiceTransaction>(); foreach (var transaction in _blockInfo.Transactions) { var accountId = transaction.AccountId; transaction.MetaData.SetTransactionId(nextTransactionId); transactions.Add(transaction); _blockInfo.FeatureGenerator.ProcessTransaction(transaction); ++nextTransactionId; } var block = new ServiceBlock(transactions, Protocol.Version, blockId, ChainId, issuer, revision, timestamp, previousHash, lastTransactionHash); // 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 <ServiceBlock>(block.BlockData)); }
public HashSet <long> CheckBlock(ServiceBlock 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); }