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; } }
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; } }