/// <inheritdoc />
        public override Task RunAsync(RuleContext context)
        {
            if (context.CheckMerkleRoot)
            {
                Block block = context.BlockValidationContext.Block;

                uint256 hashMerkleRoot2 = BlockMerkleRootRule.BlockMerkleRoot(block, out bool mutated);
                if (block.Header.HashMerkleRoot != hashMerkleRoot2)
                {
                    this.Logger.LogTrace("(-)[BAD_MERKLE_ROOT]");
                    ConsensusErrors.BadMerkleRoot.Throw();
                }

                // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
                // of transactions in a block without affecting the merkle root of a block,
                // while still invalidating it.
                if (mutated)
                {
                    this.Logger.LogTrace("(-)[BAD_TX_DUP]");
                    ConsensusErrors.BadTransactionDuplicate.Throw();
                }
            }

            return(Task.CompletedTask);
        }
        /// <summary>
        /// Calculates merkle root for block's trasnactions.
        /// </summary>
        /// <param name="block">Block which transactions are used for calculation.</param>
        /// <param name="mutated"><c>true</c> if block contains repeating sequences of transactions without affecting the merkle root of a block. Otherwise: <c>false</c>.</param>
        /// <returns>Merkle root.</returns>
        public static uint256 BlockMerkleRoot(Block block, out bool mutated)
        {
            var leaves = new List <uint256>(block.Transactions.Count);

            foreach (Transaction tx in block.Transactions)
            {
                leaves.Add(tx.GetHash());
            }

            return(BlockMerkleRootRule.ComputeMerkleRoot(leaves, out mutated));
        }
Beispiel #3
0
        /// <summary>
        /// Calculates merkle root for witness data.
        /// </summary>
        /// <param name="block">Block which transactions witness data is used for calculation.</param>
        /// <param name="mutated"><c>true</c> if at least one leaf of the merkle tree has the same hash as any subtree. Otherwise: <c>false</c>.</param>
        /// <returns>Merkle root.</returns>
        public uint256 BlockWitnessMerkleRoot(Block block, out bool mutated)
        {
            var leaves = new List <uint256>();

            leaves.Add(uint256.Zero); // The witness hash of the coinbase is 0.
            foreach (Transaction tx in block.Transactions.Skip(1))
            {
                leaves.Add(tx.GetWitHash());
            }

            return(BlockMerkleRootRule.ComputeMerkleRoot(leaves, out mutated));
        }