Make transaction results contribute to the consensus hash
Overview
As of PR #5471, we lack the guarantees needed to perform Merkle-proof verification of execution results. If we want clients to trust query responses about transaction results, we must separate the block identifier from the consensus hash.
Explanation
- Merkle verification relies on a validated Merkle root.
- To be validated by consensus, a Merkle root must be included in the block header and contribute to its consensus hash.
- However, the
result_merkle_rootcan only be computed after validation. - Adding post-validation data to the consensus hash would necessarily change that hash.
- Therefore, you cannot keep the consensus hash identical before and after validation.
- As a result, the consensus hash alone cannot serve as a stable block identifier throughout a block's lifecycle.
- We need a separate block identifier.
Why PR #5471 doesn't work for verifying the results
PR #5471 purposely omits the result_merkle_root from the header's hash. That allows any arbitrary result root to reside in the header without changing the consensus hash. Consequently, even if you verify the header, you gain no guarantee about the authenticity of the result Merkle root.
Possible Implementation
- consensus hash: the header hash including the result Merkle root
- block identifier: the header hash excluding the result Merkle root
The true solution to this issue may not be a separate block identifier apart from the consensus hash, but rather to realign them. In other words, when a new block is first identified and its signature verified, the block should already have passed through set_transaction_results(), with the execution results reflected in the header.
I've revised the issue title to express the objective rather than the means.