From 5442a196c3ad85b512597afd1ae785f44b3e7453 Mon Sep 17 00:00:00 2001 From: ptrus Date: Fri, 9 Oct 2020 18:47:29 +0200 Subject: [PATCH] roothash: Add consistent hash test for ComputeResultsHeader --- go/roothash/api/commitment/executor.go | 8 ++--- go/roothash/api/commitment/executor_test.go | 35 +++++++++++++++++++ runtime/src/common/roothash.rs | 37 ++++++++++++++++++--- runtime/src/dispatcher.rs | 6 ++-- 4 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 go/roothash/api/commitment/executor_test.go diff --git a/go/roothash/api/commitment/executor.go b/go/roothash/api/commitment/executor.go index 4f68a854100..8e8c3af3a1b 100644 --- a/go/roothash/api/commitment/executor.go +++ b/go/roothash/api/commitment/executor.go @@ -36,10 +36,10 @@ type ComputeResultsHeader struct { PreviousHash hash.Hash `json:"previous_hash"` // Optional fields (may be absent for failure indication). - - IORoot *hash.Hash `json:"io_root,omitempty"` - StateRoot *hash.Hash `json:"state_root,omitempty"` - Messages []*block.Message `json:"messages,omitempty"` + // TODO: add omitempty but make it work with rust side. + IORoot *hash.Hash `json:"io_root"` + StateRoot *hash.Hash `json:"state_root"` + Messages []*block.Message `json:"messages"` } // IsParentOf returns true iff the header is the parent of a child header. diff --git a/go/roothash/api/commitment/executor_test.go b/go/roothash/api/commitment/executor_test.go new file mode 100644 index 00000000000..fea10f60f25 --- /dev/null +++ b/go/roothash/api/commitment/executor_test.go @@ -0,0 +1,35 @@ +package commitment + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/oasisprotocol/oasis-core/go/common/crypto/hash" +) + +func TestConsistentHash(t *testing.T) { + // NOTE: These hashes MUST be synced with runtime/src/common/roothash.rs. + var emptyHeaderHash hash.Hash + _ = emptyHeaderHash.UnmarshalHex("56b0efb0de294bd5968bfa18fd71523455430f673c941ed38598e3329178fd78") + + var empty ComputeResultsHeader + require.EqualValues(t, emptyHeaderHash, empty.EncodedHash()) + + var emptyRoot hash.Hash + emptyRoot.Empty() + + var populatedHeaderHash hash.Hash + _ = populatedHeaderHash.UnmarshalHex("9cfe012756033317199081cbc2741b4f783386b0818eba9573e20ef4df33c604") + + populated := ComputeResultsHeader{ + Round: 42, + PreviousHash: emptyHeaderHash, + IORoot: &emptyRoot, + StateRoot: &emptyRoot, + Messages: nil, + } + fmt.Println(populated.EncodedHash().String()) + require.EqualValues(t, populatedHeaderHash, populated.EncodedHash()) +} diff --git a/runtime/src/common/roothash.rs b/runtime/src/common/roothash.rs index 86a76d6e954..07c2ce1014e 100644 --- a/runtime/src/common/roothash.rs +++ b/runtime/src/common/roothash.rs @@ -102,11 +102,18 @@ pub struct ComputeResultsHeader { /// Hash of the previous block header this batch was computed against. pub previous_hash: Hash, /// The I/O merkle root. - pub io_root: Hash, + pub io_root: Option, /// The root hash of the state after computing this batch. - pub state_root: Hash, + pub state_root: Option, /// Messages sent from this batch. - pub messages: Vec, + pub messages: Option>, +} + +impl ComputeResultsHeader { + /// Returns a hash of an encoded header. + pub fn encoded_hash(&self) -> Hash { + Hash::digest_bytes(&cbor::to_vec(&self)) + } } #[cfg(test)] @@ -114,7 +121,7 @@ mod tests { use super::*; #[test] - fn test_consistent_hash() { + fn test_consistent_hash_header() { // NOTE: These hashes MUST be synced with go/roothash/api/block/header_test.go. let empty = Header::default(); assert_eq!( @@ -139,4 +146,26 @@ mod tests { Hash::from("c39e8aefea5a1f794fb57f294a4ea8599381cd8739e67a8a9acb7763b54a630a") ); } + + #[test] + fn test_consistent_hash_compute_results_header() { + // NOTE: These hashes MUST be synced with go/roothash/api/commitment/executor_test.go. + let empty = ComputeResultsHeader::default(); + assert_eq!( + empty.encoded_hash(), + Hash::from("56b0efb0de294bd5968bfa18fd71523455430f673c941ed38598e3329178fd78") + ); + + let populated = ComputeResultsHeader { + round: 42, + previous_hash: empty.encoded_hash(), + io_root: Some(Hash::empty_hash()), + state_root: Some(Hash::empty_hash()), + messages: None, + }; + assert_eq!( + populated.encoded_hash(), + Hash::from("9cfe012756033317199081cbc2741b4f783386b0818eba9573e20ef4df33c604") + ); + } } diff --git a/runtime/src/dispatcher.rs b/runtime/src/dispatcher.rs index 15405d5157e..879dfca5637 100644 --- a/runtime/src/dispatcher.rs +++ b/runtime/src/dispatcher.rs @@ -406,9 +406,9 @@ impl Dispatcher { let header = ComputeResultsHeader { round: block.header.round + 1, previous_hash: block.header.encoded_hash(), - io_root, - state_root: new_state_root, - messages, + io_root: Some(io_root), + state_root: Some(new_state_root), + messages: Some(messages), }; debug!(self.logger, "Transaction batch execution complete";