Exemplo n.º 1
0
 public Storage(string path, Executor executor)
 {
     storagePath   = path;
     this.executor = executor;
 }
Exemplo n.º 2
0
        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);
        }