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; } }
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)); }
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; }
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); } }
private UInt256 CalculateHash(BlockHeader blockHeader) { return new UInt256(Crypto.DoubleSHA256(DataCalculator.EncodeBlockHeader(blockHeader))); }
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; } } } }
public Block With(BlockHeader Header = null, ImmutableArray<Transaction>? Transactions = null) { return new Block ( Header ?? this.Header, Transactions ?? this.Transactions ); }
public static long SizeEstimator(BlockHeader blockHeader) { return 80; }
private void OnBlockHeaderModification(UInt256 blockHash, BlockHeader blockHeader) { OnBlockHeaderAddition(blockHash); }
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; } }
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; } }
public static UInt256 CalculateBlockHash(BlockHeader blockHeader) { return new UInt256(Crypto.DoubleSHA256(EncodeBlockHeader(blockHeader))); }
public static byte[] EncodeBlockHeader(BlockHeader blockHeader) { return EncodeBlockHeader(blockHeader.Version, blockHeader.PreviousBlock, blockHeader.MerkleRoot, blockHeader.Time, blockHeader.Bits, blockHeader.Nonce); }
public static byte[] EncodeBlockHeader(BlockHeader blockHeader) { var stream = new MemoryStream(); EncodeBlockHeader(stream, blockHeader); return stream.ToArray(); }
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); } }