public Storage(string path, Executor executor) { storagePath = path; this.executor = executor; }
void MineFromLastBlock(CancellationToken token) { // Takeout memory pool transactions. var size = 350; // Estimated block header + coinbase size var txs = InventoryManager.MemoryPool .Select(tx => tx.Value) .TakeWhile(tx => (size += tx.Original.Length + 50) < InventoryManager.MaximumBlockSize) .ToList(); // Iteration should end immediately. // Choose transactions that are valid. var blockTime = DateTime.UtcNow; ulong coinbase = BlockParameter.GetCoinbase(Executor.Latest.Height + 1); var spent = new List <TransactionOutput>(); txs = txs.Where(tx => { try { token.ThrowIfCancellationRequested(); Executor.Run(tx, blockTime, spentTxo: spent); var exec = tx.ExecInfo; coinbase += exec.TransactionFee; spent.AddRange(exec.RedeemedOutputs); return(true); } catch { return(false); } }).ToList(); // Create coinbase transaction structure. var coinbaseTx = new Transaction { Timestamp = blockTime, InEntries = new List <InEntry>(), OutEntries = new List <OutEntry> { new OutEntry { RecipientHash = RecipientAddress, Amount = coinbase, }, }, }; // We need backing byte-encoded behind. coinbaseTx = DeserializeTransaction(Serialize(coinbaseTx)); Executor.Run(coinbaseTx, blockTime, coinbase); txs.Insert(0, coinbaseTx); // Calculate root hash. var txIds = txs.Select(x => x.Id).ToList(); var block = new Block { PreviousHash = Executor.Latest.Id, Difficulty = BlockParameter.GetNextDifficulty( Executor.Latest.Ancestors(Executor.Blocks)), TransactionRootHash = RootHashTransactionIds(txIds), }; if (!Mine(block, token)) { return; } block.TransactionIds = txIds; block.Transactions = txs.Select(x => x.Original).ToList(); block.ParsedTransactions = txs.ToArray(); logger.LogInformation("Block mined: {0}", JsonConvert.SerializeObject(block, Formatting.Indented)); var msg = new InventoryMessage { Data = Serialize(block), ObjectId = block.Id, IsBlock = true, Type = InventoryMessageType.Body, }; ConnectionManager.BroadcastAsync(msg); InventoryManager.HandleMessage(msg, -1); }