public MerkleBlockMessage(BlockHeader blockHeader, uint totalTransactions, byte[][] hashes, byte[] flags) { this.blockHeader = blockHeader; this.totalTransactions = totalTransactions; this.hashes = new List<byte[]>(hashes); this.flags = flags; }
//todo: split BlockHeaderValidator to static and non-static parts public static bool IsValid(BlockHeader header) { return IsNBitsValid(header) && IsTimestampValid(header) && IsHashValid(header); }
internal StoredBlock(BlockHeader header, byte[] hash, int height, double totalWork, bool hasContent, bool isInBestHeaderChain, bool isInBestBlockChain) { Header = header; Hash = hash; Height = height; TotalWork = totalWork; HasContent = hasContent; IsInBestHeaderChain = isInBestHeaderChain; IsInBestBlockChain = isInBestBlockChain; }
public void TestIsTimestampValid() { List<StoredBlock> blocks = new List<StoredBlock>(); StoredBlock prevBlock = null; for (int i = 0; i < 11; i++) { BlockHeader header = new BlockHeader ( genesisBlockHeader.Version, prevBlock == null ? new byte[32] : prevBlock.Hash, new byte[32], (uint) i, 0x21100000, 0); StoredBlock storedBlock = new StoredBlockBuilder(header).Build(); blocks.Add(storedBlock); prevBlock = storedBlock; } Subchain subchain = new Subchain(blocks); { BlockHeader header = new BlockHeader ( genesisBlockHeader.Version, new byte[32], new byte[32], 5, 0x21100000, 0); StoredBlock storedBlock = new StoredBlockBuilder(header).Build(); Assert.False(BlockHeaderValidator.IsTimeStampValid(storedBlock, subchain)); } { BlockHeader header = new BlockHeader ( genesisBlockHeader.Version, new byte[32], new byte[32], 6, 0x21100000, 0); StoredBlock storedBlock = new StoredBlockBuilder(header).Build(); Assert.True(BlockHeaderValidator.IsTimeStampValid(storedBlock, subchain)); } }
public void TestIsHashValid() { Assert.True(BlockHeaderValidator.IsHashValid(genesisBlockHeader)); BlockHeader blockHeader = new BlockHeader( genesisBlockHeader.Version, genesisBlockHeader.PrevBlock, genesisBlockHeader.MerkleRoot, genesisBlockHeader.Timestamp, genesisBlockHeader.NBits, 1); Assert.False(BlockHeaderValidator.IsHashValid(blockHeader)); }
/// <summary> /// Checks that a hash of the header matches nBits field in the block. /// </summary> internal static bool IsHashValid(BlockHeader header) { byte[] text = BitcoinStreamWriter.GetBytes(header.Write); //todo: This hash is calculated too often. Save it somewhere. byte[] hash = CryptoUtils.DoubleSha256(text); BigInteger hashAsNumber = NumberUtils.ToBigInteger(hash); BigInteger difficultyTarget = DifficultyUtils.NBitsToTarget(header.NBits); if (hashAsNumber > difficultyTarget) { return false; } return true; }
public void TestIsTimestampValidStatic() { BlockHeader blockHeader1 = new BlockHeader( genesisBlockHeader.Version, genesisBlockHeader.PrevBlock, genesisBlockHeader.MerkleRoot, (uint) UnixTime.ToTimestamp(DateTime.UtcNow.AddMinutes(110)), genesisBlockHeader.NBits, genesisBlockHeader.Nonce); Assert.True(BlockHeaderValidator.IsTimestampValid(blockHeader1)); BlockHeader blockHeader2 = new BlockHeader( genesisBlockHeader.Version, genesisBlockHeader.PrevBlock, genesisBlockHeader.MerkleRoot, (uint) UnixTime.ToTimestamp(DateTime.UtcNow.AddMinutes(130)), genesisBlockHeader.NBits, genesisBlockHeader.Nonce); Assert.False(BlockHeaderValidator.IsTimestampValid(blockHeader2)); }
public BlockMessage(BlockHeader blockHeader, Tx[] transactions) { this.blockHeader = blockHeader; this.transactions = transactions; }
public HeadersMessage(BlockHeader[] headers) { this.headers = headers; }
public StoredBlockBuilder(BlockHeader header) { byte[] text = BitcoinStreamWriter.GetBytes(header.Write); Header = header; Hash = CryptoUtils.DoubleSha256(text); Height = -1; TotalWork = 0; HasContent = false; IsInBestHeaderChain = false; IsInBestBlockChain = false; }
/// <summary> /// Checks that the difficulty defined by the nBits field is not lower than the network minimum. /// </summary> internal static bool IsNBitsValid(BlockHeader blockHeader) { BigInteger target = DifficultyUtils.NBitsToTarget(blockHeader.NBits); return target <= DifficultyUtils.MaxDifficultyTarget; }
/// <summary> /// Checks that timestamp of the block header is not too far in the future. /// </summary> /// <remarks>Specification: https://en.bitcoin.it/wiki/Block_timestamp </remarks> internal static bool IsTimestampValid(BlockHeader header) { //todo: Specification requires to adjust current time. Why is it necessary? return UnixTime.ToDateTime(header.Timestamp) < SystemTime.UtcNow.AddHours(2); }