예제 #1
0
        void RecalculateHeader()
        {
            if (_BlockChain.Tip == null)
            {
                return;
            }

            if (_TransactionQueue.IsStuck)
            {
                MinerTrace.Information("Queue is stuck. count = " + _TransactionQueue.Count);
            }

            while (!_TransactionQueue.IsStuck && _ValidatedTxs.Count < TxsPerBlockLimit)
            {
                var ptx = _TransactionQueue.Take();

                if (IsTransactionValid(ptx))
                {
                    _ValidatedTxs.Add(ptx);

                    _TransactionQueue.Remove();

                    HandleTx(ptx);
                }
                else
                {
                    MinerTrace.Information("Tx invalid");
                    _TransactionQueue.Next();
                }
            }

            if (_ValidatedTxs.Count == 0)
            {
                MinerTrace.Information("No txs");
                return;                 // don't allow empty blocks
            }

            CalculateCoinbase();

            var txs = ListModule.OfSeq(FSharpList <Types.Transaction> .Cons(_Coinbase, ListModule.OfSeq(_ValidatedTxs.Select(TransactionValidation.unpoint))));

            _Header = new Types.BlockHeader(
                0,
                _BlockChain.Tip.Key,
                _BlockChain.Tip.Value.header.blockNumber + 1,
                Merkle.merkleRoot(
                    new byte[] { },
                    Merkle.transactionHasher,
                    txs
                    ),
                new byte[] { },
                new byte[] { },
                ListModule.Empty <byte[]>(),
                DateTime.Now.ToUniversalTime().Ticks,
                Difficulty,
                new byte[12]
                );

            MinerTrace.Information($"Mining block number {_BlockChain.Tip.Value.header.blockNumber + 1} with {_ValidatedTxs.Count()} txs");

            _Hasher.SetHeader(_Header);
            _Hasher.Continue();
        }