예제 #1
0
파일: Miner.cs 프로젝트: holinov/BitSharp
        public static BlockHeader MineBlockHeader(BlockHeader blockHeader, UInt256 hashTarget)
        {
            var blockHeaderBytes = DataCalculator.EncodeBlockHeader(blockHeader);

            var hashTargetBytes = hashTarget.ToByteArray();

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

            //Debug.WriteLine("Starting mining: {0}".Format2(DateTime.Now.ToString("hh:mm:ss")));

            var stopwatch = new Stopwatch();
            stopwatch.Start();

            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 sha256 = localState.sha256;
                    var hashBytes = sha256.ComputeHash(sha256.ComputeHash(headerBytes));

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

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

            stopwatch.Stop();

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

            if (minedNonce != null)
            {
                //Debug.WriteLine("Found block in {0} hh:mm:ss at Nonce {1}, Hash Rate: {2} mHash/s, Total Hash Attempts: {3}, Found Hash: {4}".Format2(stopwatch.Elapsed.ToString(@"hh\:mm\:ss"), minedNonce, hashRate, total.ToString("#,##0"), blockHeader.With(Nonce: minedNonce).Hash));
                return blockHeader.With(Nonce: minedNonce);
            }
            else
            {
                //Debug.WriteLine("No block found in {0} hh:mm:ss, Hash Rate: {1} mHash/s, Total Hash Attempts: {2}, Found Hash: {3}".Format2(stopwatch.Elapsed.ToString(@"hh\:mm\:ss"), hashRate, total.ToString("#,##0"), blockHeader.With(Nonce: minedNonce).Hash));
                return null;
            }
        }
예제 #2
0
        public void TestCalculateBlockHash()
        {
            var expectedHash = UInt256.Parse("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", NumberStyles.HexNumber);
            var blockHeader = new BlockHeader
            (
                version: 1,
                previousBlock: 0,
                merkleRoot: UInt256.Parse("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", NumberStyles.HexNumber),
                time: 1231006505,
                bits: 486604799,
                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));
        }
예제 #3
0
파일: Block.cs 프로젝트: holinov/BitSharp
        public Block(BlockHeader header, ImmutableArray<Transaction> transactions)
        {
            this._header = header;
            this._transactions = transactions;

            var sizeEstimate = BlockHeader.SizeEstimator(header);
            for (var i = 0; i < transactions.Length; i++)
            {
                for (var j = 0; j < transactions[i].Inputs.Length; j++)
                    sizeEstimate += transactions[i].Inputs[j].ScriptSignature.Length;

                for (var j = 0; j < transactions[i].Outputs.Length; j++)
                    sizeEstimate += transactions[i].Outputs[j].ScriptPublicKey.Length;
            }
            sizeEstimate = (long)(sizeEstimate * 1.5);

            this._sizeEstimate = sizeEstimate;
        }
예제 #4
0
 private void OnBlockHeader(BlockHeader blockHeader)
 {
     //Debug.WriteLine("Received block header {0}".Format2(blockHeader.Hash);
     if (!this.blockchainDaemon.CacheContext.BlockHeaderCache.ContainsKey(blockHeader.Hash))
     {
         this.blockchainDaemon.CacheContext.BlockHeaderCache.CreateValue(blockHeader.Hash, blockHeader);
     }
 }
예제 #5
0
 private UInt256 CalculateHash(BlockHeader blockHeader)
 {
     return new UInt256(Crypto.DoubleSHA256(DataCalculator.EncodeBlockHeader(blockHeader)));
 }
예제 #6
0
        public bool TryReadValue(UInt256 blockHash, out BlockHeader blockHeader)
        {
            using (var conn = this.OpenConnection())
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = @"
                    SELECT HeaderBytes
                    FROM BlockHeaders
                    WHERE BlockHash = @blockHash";

                cmd.Parameters.SetValue("@blockHash", SqlDbType.Binary, 32).Value = blockHash.ToDbByteArray();

                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        var headerBytes = reader.GetBytes(0);

                        blockHeader = StorageEncoder.DecodeBlockHeader(headerBytes.ToMemoryStream(), blockHash);
                        return true;
                    }
                    else
                    {
                        blockHeader = default(BlockHeader);
                        return false;
                    }
                }
            }
        }
예제 #7
0
파일: Block.cs 프로젝트: holinov/BitSharp
 public Block With(BlockHeader Header = null, ImmutableArray<Transaction>? Transactions = null)
 {
     return new Block
     (
         Header ?? this.Header,
         Transactions ?? this.Transactions
     );
 }
예제 #8
0
 public static long SizeEstimator(BlockHeader blockHeader)
 {
     return 80;
 }
예제 #9
0
 private void OnBlockHeaderModification(UInt256 blockHash, BlockHeader blockHeader)
 {
     OnBlockHeaderAddition(blockHash);
 }
예제 #10
0
 public bool TryGetBlockHeader(UInt256 blockHash, out BlockHeader blockHeader, bool saveInCache = true)
 {
     Block block;
     if (this.CacheContext.BlockHeaderCache.TryGetValue(blockHash, out blockHeader, saveInCache))
     {
         this.missingBlocks.Remove(blockHash);
         return true;
     }
     else if (this.CacheContext.BlockCache.TryGetValue(blockHash, out block, saveInCache))
     {
         blockHeader = block.Header;
         this.missingBlocks.Remove(blockHash);
         return true;
     }
     else
     {
         this.missingBlocks.Add(blockHash);
         blockHeader = default(BlockHeader);
         return false;
     }
 }
예제 #11
0
 public static BigInteger CalculateWork(BlockHeader blockHeader)
 {
     try
     {
         return Max256BitTarget / (BigInteger)BitsToTarget(blockHeader.Bits);
     }
     catch (Exception)
     {
         Debug.WriteLine("Corrupt block header bits: {0}, block {1}".Format2(blockHeader.Bits.ToString("X"), blockHeader.Hash.ToHexNumberString()));
         return -1;
     }
 }
예제 #12
0
 public static UInt256 CalculateBlockHash(BlockHeader blockHeader)
 {
     return new UInt256(Crypto.DoubleSHA256(EncodeBlockHeader(blockHeader)));
 }
예제 #13
0
 public static byte[] EncodeBlockHeader(BlockHeader blockHeader)
 {
     return EncodeBlockHeader(blockHeader.Version, blockHeader.PreviousBlock, blockHeader.MerkleRoot, blockHeader.Time, blockHeader.Bits, blockHeader.Nonce);
 }
예제 #14
0
 public static byte[] EncodeBlockHeader(BlockHeader blockHeader)
 {
     var stream = new MemoryStream();
     EncodeBlockHeader(stream, blockHeader);
     return stream.ToArray();
 }
예제 #15
0
 public static void EncodeBlockHeader(Stream stream, BlockHeader blockHeader)
 {
     using (var writer = new BinaryWriter(stream, Encoding.ASCII, leaveOpen: true))
     {
         writer.Write4Bytes(blockHeader.Version);
         writer.Write32Bytes(blockHeader.PreviousBlock);
         writer.Write32Bytes(blockHeader.MerkleRoot);
         writer.Write4Bytes(blockHeader.Time);
         writer.Write4Bytes(blockHeader.Bits);
         writer.Write4Bytes(blockHeader.Nonce);
     }
 }