Esempio n. 1
0
        public static Block Create(BlockHeader header, ImmutableArray<DecodedTx> transactions)
        {
            var blockTxes = ImmutableArray.CreateRange(transactions.Select((tx, txIndex) =>
                new BlockTx(txIndex, tx)));

            return new Block(header, blockTxes);
        }
Esempio n. 2
0
 public ChainedHeader(BlockHeader blockHeader, int height, BigInteger totalWork, DateTimeOffset dateSeen)
 {
     BlockHeader = blockHeader;
     Height = height;
     TotalWork = totalWork;
     DateSeen = dateSeen;
 }
Esempio n. 3
0
 public Block With(BlockHeader Header = null, ImmutableArray<BlockTx>? BlockTxes = null)
 {
     return new Block
     (
         Header ?? this.Header,
         BlockTxes ?? this.BlockTxes
     );
 }
Esempio n. 4
0
 public Block With(BlockHeader Header = null, ImmutableArray<Transaction>? Transactions = null)
 {
     return new Block
     (
         Header ?? this.Header,
         Transactions ?? this.Transactions
     );
 }
Esempio n. 5
0
 public static ChainedHeader CreateForGenesisBlock(BlockHeader genesisBlockHeader)
 {
     return new ChainedHeader
     (
         blockHeader: genesisBlockHeader,
         height: 0,
         totalWork: genesisBlockHeader.CalculateWork()
     );
 }
Esempio n. 6
0
 public static void EncodeBlockHeader(BinaryWriter writer, BlockHeader blockHeader)
 {
     writer.WriteUInt32(blockHeader.Version);
     writer.WriteUInt256(blockHeader.PreviousBlock);
     writer.WriteUInt256(blockHeader.MerkleRoot);
     writer.WriteUInt32((uint)blockHeader.Time.ToUnixTimeSeconds());
     writer.WriteUInt32(blockHeader.Bits);
     writer.WriteUInt32(blockHeader.Nonce);
 }
Esempio n. 7
0
 public static byte[] EncodeBlockHeader(BlockHeader blockHeader)
 {
     using (var stream = new MemoryStream())
     using (var writer = new BinaryWriter(stream))
     {
         EncodeBlockHeader(writer, blockHeader);
         return stream.ToArray();
     }
 }
Esempio n. 8
0
        public static ChainedHeader CreateFromPrev(ChainedHeader prevChainedHeader, BlockHeader blockHeader, DateTimeOffset dateSeen)
        {
            var headerWork = blockHeader.CalculateWork();

            return new ChainedHeader(blockHeader,
                prevChainedHeader.Height + 1,
                prevChainedHeader.TotalWork + headerWork.ToBigInteger(),
                dateSeen);
        }
Esempio n. 9
0
        public Block(BlockHeader header, ImmutableArray<BlockTx> blockTxes)
        {
            Header = header;

            BlockTxes = blockTxes;

            lazyTransactions = new Lazy<ImmutableArray<Transaction>>(() =>
                ImmutableArray.CreateRange(blockTxes.Select(x => x.Decode().Transaction)));
        }
Esempio n. 10
0
        public static ChainedHeader CreateFromPrev(ChainedHeader prevChainedHeader, BlockHeader blockHeader)
        {
            var headerWork = blockHeader.CalculateWork();
            if (headerWork < 0)
                return null;

            return new ChainedHeader(blockHeader,
                prevChainedHeader.Height + 1,
                prevChainedHeader.TotalWork + headerWork);
        }
Esempio n. 11
0
 public static ChainedHeader CreateForGenesisBlock(BlockHeader genesisBlockHeader)
 {
     return new ChainedHeader
     (
         blockHeader: genesisBlockHeader,
         height: 0,
         totalWork: genesisBlockHeader.CalculateWork().ToBigInteger(),
         dateSeen: DateTimeOffset.MinValue
     );
 }
Esempio n. 12
0
        public static UInt256 CalculateWork(BlockHeader blockHeader)
        {
            bool negative, overflow;
            var target = FromCompact(blockHeader.Bits, out negative, out overflow);

            if (negative || overflow || target == UInt256.Zero)
                return UInt256.Zero;

            return new UInt256(_2Pow256 / (target.ToBigInteger() + 1));
        }
Esempio n. 13
0
        public BlockHeader MineBlockHeader(BlockHeader blockHeader, UInt256 hashTarget)
        {
            var blockHeaderBytes = DataEncoder.EncodeBlockHeader(blockHeader);

            var hashTargetBytes = hashTarget.ToByteArray();

            var start = 0;
            var finish = UInt32.MaxValue;
            var total = 0L;
            var nonceIndex = 76;
            var minedNonce = (UInt32?)null;

            logger.Debug($"Starting mining: {DateTime.Now:hh':'mm':'ss}");

            var stopwatch = Stopwatch.StartNew();

            Parallel.For(
                start, finish,
                () => new LocalMinerState(blockHeaderBytes),
                (nonceLong, loopState, localState) =>
                {
                    localState.total++;

                    var nonce = (UInt32)nonceLong;
                    var nonceBytes = Bits.GetBytes(nonce);
                    Buffer.BlockCopy(nonceBytes, 0, localState.headerBytes, nonceIndex, 4);

                    var headerBytes = localState.headerBytes;
                    var hashBytes = SHA256Static.ComputeDoubleHash(headerBytes);

                    if (BytesCompareLE(hashBytes, hashTargetBytes) < 0)
                    {
                        minedNonce = nonce;
                        loopState.Stop();
                    }

                    return localState;
                },
                localState => { Interlocked.Add(ref total, localState.total); });

            stopwatch.Stop();

            var hashRate = ((float)total / 1000 / 1000) / ((float)stopwatch.ElapsedMilliseconds / 1000);

            if (minedNonce != null)
            {
                logger.Debug($"Found block in {stopwatch.Elapsed:hh':'mm':'ss} hh:mm:ss at Nonce {minedNonce}, Hash Rate: {hashRate} mHash/s, Total Hash Attempts: {total:N0}, Found Hash: {blockHeader.With(Nonce: minedNonce).Hash}");
                return blockHeader.With(Nonce: minedNonce);
            }
            else
            {
                logger.Debug($"No block found in {stopwatch.Elapsed:hh':'mm':'ss} hh:mm:ss, Hash Rate: {hashRate} mHash/s, Total Hash Attempts: {total:N0}, Found Hash: {blockHeader.With(Nonce: minedNonce).Hash}");
                return null;
            }
        }
Esempio n. 14
0
 public static BigInteger CalculateWork(BlockHeader blockHeader)
 {
     try
     {
         return Max256BitTarget / (BigInteger)BitsToTarget(blockHeader.Bits);
     }
     catch (Exception)
     {
         Debug.WriteLine($"Corrupt block header bits: {blockHeader:X}, block {blockHeader.Hash}");
         return -1;
     }
 }
Esempio n. 15
0
        public ChainedHeader GenesisChained()
        {
            if (this.blockHeaders.Count > 0)
                throw new InvalidOperationException();

            var blockHeader = new BlockHeader(0, UInt256.Zero, UInt256.Zero, 0, this.bits, this.nonce);
            this.totalWork = blockHeader.CalculateWork();

            var chainedHeader = new ChainedHeader(blockHeader, 0, this.totalWork);
            this.blockHeaders.Add(chainedHeader);

            return chainedHeader;
        }
Esempio n. 16
0
        public BlockHeader MineBlockHeader(BlockHeader blockHeader, UInt256 hashTarget)
        {
            var blockHeaderBytes = DataEncoder.EncodeBlockHeader(blockHeader);

            var hashTargetBytes = hashTarget.ToByteArray();

            var start = 0;
            var finish = UInt32.MaxValue;
            var total = 0L;
            var nonceIndex = 76;
            var minedNonce = (UInt32?)null;

            var stopwatch = Stopwatch.StartNew();

            Parallel.For(
                start, finish,
                () => new LocalMinerState(blockHeaderBytes),
                (nonceLong, loopState, localState) =>
                {
                    localState.total++;

                    var nonce = (UInt32)nonceLong;
                    var nonceBytes = Bits.GetBytes(nonce);
                    Buffer.BlockCopy(nonceBytes, 0, localState.headerBytes, nonceIndex, 4);

                    var headerBytes = localState.headerBytes;
                    var hashBytes = SHA256Static.ComputeDoubleHash(headerBytes);

                    if (BytesCompareLE(hashBytes, hashTargetBytes) < 0)
                    {
                        minedNonce = nonce;
                        loopState.Stop();
                    }

                    return localState;
                },
                localState => { Interlocked.Add(ref total, localState.total); });

            stopwatch.Stop();

            var hashRate = total / stopwatch.Elapsed.TotalSeconds;

            if (minedNonce == null)
                throw new InvalidOperationException();

            var minedHeader = blockHeader.With(Nonce: minedNonce);

            logger.Debug($"Found block in {stopwatch.Elapsed.TotalMilliseconds:N3}ms at Nonce {minedNonce}, Hash Rate: {hashRate / 1.MILLION()} mHash/s, Total Hash Attempts: {total:N0}, Found Hash: {minedHeader.Hash}");
            return minedHeader;
        }
Esempio n. 17
0
 public Block CreateWith(BlockHeader Header = null, ImmutableArray<Transaction>? Transactions = null)
 {
     if (Transactions == null)
     {
         return new Block
         (
             Header ?? this.Header,
             this.BlockTxes
         );
     }
     else
     {
         return Create(Header ?? this.Header, Transactions.Value);
     }
 }
Esempio n. 18
0
        public void TestCalculateBlockHash()
        {
            var expectedHash = UInt256.ParseHex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
            var blockHeader = new BlockHeader
            (
                version: 1,
                previousBlock: UInt256.Zero,
                merkleRoot: UInt256.ParseHex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"),
                time: 1231006505,
                bits: 0x1D00FFFF,
                nonce: 2083236893
            );

            Assert.AreEqual(expectedHash, DataCalculator.CalculateBlockHash(blockHeader));
            Assert.AreEqual(expectedHash, DataCalculator.CalculateBlockHash(blockHeader.Version, blockHeader.PreviousBlock, blockHeader.MerkleRoot, blockHeader.Time, blockHeader.Bits, blockHeader.Nonce));
        }
Esempio n. 19
0
        private bool TryChainHeader(BlockHeader blockHeader, out ChainedHeader chainedHeader, bool suppressEvent)
        {
            if (TryGetChainedHeader(blockHeader.Hash, out chainedHeader))
            {
                return false;
            }
            else
            {
                ChainedHeader previousChainedHeader;
                if (TryGetChainedHeader(blockHeader.PreviousBlock, out previousChainedHeader))
                {
                    chainedHeader = ChainedHeader.CreateFromPrev(previousChainedHeader, blockHeader, DateTimeOffset.Now);
                    if (chainedHeader == null)
                        return false;

                    lock (cachedHeaders)
                        if (this.blockStorage.Value.TryAddChainedHeader(chainedHeader))
                        {
                            this.cachedHeaders.Value[chainedHeader.Hash] = chainedHeader;

                            if (!suppressEvent)
                                ChainedHeaderAdded?.Invoke(chainedHeader);

                            return true;
                        }
                        else
                        {
                            logger.Warn("Unexpected condition: validly chained header could not be added");
                        }
                }
            }

            chainedHeader = default(ChainedHeader);
            return false;
        }
Esempio n. 20
0
        public ChainedHeader NextChained(UInt32? bits = null)
        {
            if (this.blockHeaders.Count == 0)
                throw new InvalidOperationException();

            var prevBlockHeader = this.blockHeaders.Last();

            var blockHeader = new BlockHeader(0, prevBlockHeader.Hash, UInt256.Zero, 0, bits ?? this.bits, this.nonce);
            this.totalWork += blockHeader.CalculateWork();

            var chainedHeader = new ChainedHeader(blockHeader, this.blockHeaders.Count, this.totalWork);
            this.blockHeaders.Add(chainedHeader);

            return chainedHeader;
        }
Esempio n. 21
0
 public Block(BlockHeader header, ImmutableArray<Transaction> transactions)
 {
     Header = header;
     Transactions = transactions;
 }
Esempio n. 22
0
 public ChainedHeader(BlockHeader blockHeader, int height, BigInteger totalWork)
 {
     BlockHeader = blockHeader;
     Height = height;
     TotalWork = totalWork;
 }
Esempio n. 23
0
 public bool TryChainHeader(BlockHeader blockHeader, out ChainedHeader chainedHeader)
 {
     return TryChainHeader(blockHeader, out chainedHeader, suppressEvent: false);
 }
Esempio n. 24
0
 public static UInt256 CalculateBlockHash(BlockHeader blockHeader)
 {
     return new UInt256(SHA256Static.ComputeDoubleHash(DataEncoder.EncodeBlockHeader(blockHeader)));
 }