diff --git a/.changelog/2890.internal.md b/.changelog/2890.internal.md new file mode 100644 index 00000000000..ea628afe7e8 --- /dev/null +++ b/.changelog/2890.internal.md @@ -0,0 +1 @@ +go/common/crypto/hash: Add NewFrom and NewFromBytes functions diff --git a/go/common/accessctl/accessctl.go b/go/common/accessctl/accessctl.go index 674065ee338..ec32d5c9141 100644 --- a/go/common/accessctl/accessctl.go +++ b/go/common/accessctl/accessctl.go @@ -20,8 +20,7 @@ func SubjectFromX509Certificate(cert *x509.Certificate) Subject { // SubjectFromDER returns a Subject from the given certificate's ASN.1 DER // representation. To do so, it computes the hash of the DER representation. func SubjectFromDER(der []byte) Subject { - var h = hash.Hash{} - h.FromBytes(der) + h := hash.NewFromBytes(der) return Subject(h.String()) } diff --git a/go/common/crypto/hash/hash.go b/go/common/crypto/hash/hash.go index e91914c7a02..71d1e8b08ff 100644 --- a/go/common/crypto/hash/hash.go +++ b/go/common/crypto/hash/hash.go @@ -109,6 +109,18 @@ func (h Hash) String() string { return hex.EncodeToString(h[:]) } +// NewFrom creates a new hash by hashing the CBOR representation of the given type. +func NewFrom(v interface{}) (h Hash) { + h.From(v) + return +} + +// NewFromBytes creates a new hash by hashing the provided byte string(s). +func NewFromBytes(data ...[]byte) (h Hash) { + h.FromBytes(data...) + return +} + // Builder is a hash builder that can be used to compute hashes iteratively. type Builder struct { hasher hash.Hash diff --git a/go/common/namespace.go b/go/common/namespace.go index 6d0b1f4f5c6..5f19e006158 100644 --- a/go/common/namespace.go +++ b/go/common/namespace.go @@ -130,8 +130,7 @@ func NewNamespace(id [NamespaceIDSize]byte, flags NamespaceFlag) (Namespace, err // NewTestNamespaceFromSeed returns a test namespace from a seed and flags. func NewTestNamespaceFromSeed(seed []byte, flags NamespaceFlag) Namespace { - var h hash.Hash - h.FromBytes(seed) + h := hash.NewFromBytes(seed) var rtID [NamespaceIDSize]byte copy(rtID[:], h[:]) diff --git a/go/common/node/node.go b/go/common/node/node.go index 402fe8093a7..338383f3330 100644 --- a/go/common/node/node.go +++ b/go/common/node/node.go @@ -302,12 +302,10 @@ type CapabilityTEE struct { // RAKHash computes the expected AVR report hash bound to a given public RAK. func RAKHash(rak signature.PublicKey) hash.Hash { - var rakHash hash.Hash hData := make([]byte, 0, len(teeHashContext)+signature.PublicKeySize) hData = append(hData, teeHashContext...) hData = append(hData, rak[:]...) - rakHash.FromBytes(hData) - return rakHash + return hash.NewFromBytes(hData) } // Verify verifies the node's TEE capabilities, at the provided timestamp. diff --git a/go/consensus/api/transaction/transaction.go b/go/consensus/api/transaction/transaction.go index 619cadb5025..ab57254b6a0 100644 --- a/go/consensus/api/transaction/transaction.go +++ b/go/consensus/api/transaction/transaction.go @@ -113,9 +113,7 @@ type SignedTransaction struct { // Hash returns the cryptographic hash of the encoded transaction. func (s *SignedTransaction) Hash() hash.Hash { - var hash hash.Hash - hash.From(s) - return hash + return hash.NewFrom(s) } // PrettyPrint writes a pretty-printed representation of the type diff --git a/go/consensus/tendermint/abci/mux.go b/go/consensus/tendermint/abci/mux.go index ef39da8520b..2de7bcfa45b 100644 --- a/go/consensus/tendermint/abci/mux.go +++ b/go/consensus/tendermint/abci/mux.go @@ -711,8 +711,7 @@ func (mux *abciMux) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { // Blindly accept all transactions if configured to do so. We still need to periodically // remove old transactions as otherwise the mempool will fill up, so keep track of when // transactions were added and invalidate them after the configured interval. - var txHash hash.Hash - txHash.FromBytes(req.Tx) + txHash := hash.NewFromBytes(req.Tx) if req.Type == types.CheckTxType_Recheck { // Check timestamp. @@ -750,8 +749,7 @@ func (mux *abciMux) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { // XXX: The Tendermint mempool should have provisions for this instead // of us hacking our way through this here. - var txHash hash.Hash - txHash.FromBytes(req.Tx) + txHash := hash.NewFromBytes(req.Tx) mux.notifyInvalidatedCheckTx(txHash, err) } diff --git a/go/consensus/tendermint/apps/registry/state/state.go b/go/consensus/tendermint/apps/registry/state/state.go index 2f67ed5d9ae..defeb8fa5ce 100644 --- a/go/consensus/tendermint/apps/registry/state/state.go +++ b/go/consensus/tendermint/apps/registry/state/state.go @@ -538,9 +538,7 @@ func (s *ImmutableState) NodeByConsensusOrP2PKey(ctx context.Context, key signat // Hashes a node's committee certificate into a key for the certificate to node ID map. func nodeCertificateToMapKey(cert []byte) hash.Hash { - var h hash.Hash - h.FromBytes(cert) - return h + return hash.NewFromBytes(cert) } // NodeByCertificate looks up a specific node by its certificate. diff --git a/go/consensus/tendermint/tendermint.go b/go/consensus/tendermint/tendermint.go index 98951bfab1a..163e46e63a3 100644 --- a/go/consensus/tendermint/tendermint.go +++ b/go/consensus/tendermint/tendermint.go @@ -475,8 +475,7 @@ func (t *tendermintService) SubmitTx(ctx context.Context, tx *transaction.Signed defer t.Unsubscribe(subID, query) // nolint: errcheck // Subscribe to the transaction becoming invalid. - var txHash hash.Hash - txHash.FromBytes(data) + txHash := hash.NewFromBytes(data) recheckCh, recheckSub, err := t.mux.WatchInvalidatedTx(txHash) if err != nil { diff --git a/go/genesis/api/api.go b/go/genesis/api/api.go index 372998a6d87..b7ba5040c0b 100644 --- a/go/genesis/api/api.go +++ b/go/genesis/api/api.go @@ -55,9 +55,7 @@ type Document struct { // Hash returns the cryptographic hash of the encoded genesis document. func (d *Document) Hash() hash.Hash { - var h hash.Hash - h.From(d) - return h + return hash.NewFrom(d) } // ChainContext returns a string that can be used as a chain domain separation diff --git a/go/registry/api/sanity_check.go b/go/registry/api/sanity_check.go index 0edcbca5112..0de296565eb 100644 --- a/go/registry/api/sanity_check.go +++ b/go/registry/api/sanity_check.go @@ -187,8 +187,7 @@ func SanityCheckNodes( nodeLookup.nodes[node.P2P.ID] = node nodeLookup.nodesList = append(nodeLookup.nodesList, node) - var h = hash.Hash{} - h.FromBytes(node.Committee.Certificate) + h := hash.NewFromBytes(node.Committee.Certificate) nodeLookup.nodesCertHashes[h] = node } @@ -397,8 +396,7 @@ func (n *sanityCheckNodeLookup) NodeByConsensusOrP2PKey(ctx context.Context, key } func (n *sanityCheckNodeLookup) NodeByCertificate(ctx context.Context, cert []byte) (*node.Node, error) { - var h = hash.Hash{} - h.FromBytes(cert) + h := hash.NewFromBytes(cert) node, ok := n.nodesCertHashes[h] if !ok { diff --git a/go/roothash/api/block/header.go b/go/roothash/api/block/header.go index 48a713e7344..66f4c499382 100644 --- a/go/roothash/api/block/header.go +++ b/go/roothash/api/block/header.go @@ -98,11 +98,7 @@ func (h *Header) MostlyEqual(cmp *Header) bool { // EncodedHash returns the encoded cryptographic hash of the header. func (h *Header) EncodedHash() hash.Hash { - var hh hash.Hash - - hh.From(h) - - return hh + return hash.NewFrom(h) } // StorageRoots returns the storage roots contained in this header. diff --git a/go/roothash/api/commitment/executor.go b/go/roothash/api/commitment/executor.go index d86380d8bdf..9ec362db9a8 100644 --- a/go/roothash/api/commitment/executor.go +++ b/go/roothash/api/commitment/executor.go @@ -46,11 +46,7 @@ func (h *ComputeResultsHeader) IsParentOf(child *block.Header) bool { // EncodedHash returns the encoded cryptographic hash of the header. func (h *ComputeResultsHeader) EncodedHash() hash.Hash { - var hh hash.Hash - - hh.From(h) - - return hh + return hash.NewFrom(h) } // ComputeBody holds the data signed in a compute worker commitment. diff --git a/go/runtime/committee/committee.go b/go/runtime/committee/committee.go index a7c7f8b4fe8..f6dce86dcd5 100644 --- a/go/runtime/committee/committee.go +++ b/go/runtime/committee/committee.go @@ -108,8 +108,7 @@ Members: // If the set of (filtered) committee members did not change, there is no need to trigger a // reset and recreate everything. Nodes will be updated anyway. - var cid hash.Hash - cid.From(filtered) + cid := hash.NewFrom(filtered) if cw.lastCommitteeID.Equal(&cid) { cw.logger.Debug("not updating committee as members/roles have not changed", diff --git a/go/runtime/transaction/batch_test.go b/go/runtime/transaction/batch_test.go index f090ea5dfb6..d63be8a8076 100644 --- a/go/runtime/transaction/batch_test.go +++ b/go/runtime/transaction/batch_test.go @@ -11,8 +11,7 @@ import ( func TestConsistentHash(t *testing.T) { // NOTE: These hashes MUST be synced with runtime/src/transaction/types.rs. batch := RawBatch{[]byte("foo"), []byte("bar"), []byte("aaa")} - var h hash.Hash - h.From(batch) + h := hash.NewFrom(batch) var expectedHash hash.Hash _ = expectedHash.UnmarshalHex("c451dd4fd065b815e784aac6b300e479b2167408f0eebbb95a8bd36b9e71e34d") diff --git a/go/runtime/transaction/transaction.go b/go/runtime/transaction/transaction.go index e25882386a6..9f01189a174 100644 --- a/go/runtime/transaction/transaction.go +++ b/go/runtime/transaction/transaction.go @@ -131,9 +131,8 @@ type Transaction struct { // Hash returns the hash of the transaction. // // This requires the input artifact to be available. -func (t Transaction) Hash() (h hash.Hash) { - h.FromBytes(t.Input) - return +func (t Transaction) Hash() hash.Hash { + return hash.NewFromBytes(t.Input) } // Equal checks whether the transaction is equal to another. diff --git a/go/runtime/transaction/transaction_test.go b/go/runtime/transaction/transaction_test.go index 653033678ea..51e1fba8386 100644 --- a/go/runtime/transaction/transaction_test.go +++ b/go/runtime/transaction/transaction_test.go @@ -44,8 +44,7 @@ func TestTransaction(t *testing.T) { require.NoError(t, err, "GetTransactions") require.Len(t, txns, 1, "there should be one transaction") - var txHash hash.Hash - txHash.FromBytes(tx.Input) + txHash := hash.NewFromBytes(tx.Input) require.True(t, txns[0].Equal(&tx), "transaction should have correct artifacts") @@ -87,8 +86,7 @@ func TestTransaction(t *testing.T) { require.NoError(t, err, "GetTransaction") require.True(t, rtx.Equal(&tx), "transaction should have correct artifacts") - var missingHash hash.Hash - missingHash.FromBytes([]byte("this transaction does not exist")) + missingHash := hash.NewFromBytes([]byte("this transaction does not exist")) _, err = tree.GetTransaction(ctx, missingHash) require.Error(t, err, "GetTransaction") diff --git a/go/scheduler/api/api.go b/go/scheduler/api/api.go index 98af7d30b14..1673d172b7e 100644 --- a/go/scheduler/api/api.go +++ b/go/scheduler/api/api.go @@ -141,11 +141,7 @@ func (c Committee) String() string { // EncodedMembersHash returns the encoded cryptographic hash of the committee members. func (c *Committee) EncodedMembersHash() hash.Hash { - var hh hash.Hash - - hh.From(c.Members) - - return hh + return hash.NewFrom(c.Members) } // TokensPerVotingPower is the ratio of base units staked to validator power. diff --git a/go/storage/client/tests/tests.go b/go/storage/client/tests/tests.go index f58df7e9971..f4b9434e645 100644 --- a/go/storage/client/tests/tests.go +++ b/go/storage/client/tests/tests.go @@ -46,8 +46,7 @@ func ClientWorkerTests( require.NoError(err, "NewStorageClient") // Create mock root hash. - var rootHash hash.Hash - rootHash.FromBytes([]byte("non-existing")) + rootHash := hash.NewFromBytes([]byte("non-existing")) root := api.Root{ Namespace: ns, diff --git a/go/storage/mkvs/checkpoint/checkpoint.go b/go/storage/mkvs/checkpoint/checkpoint.go index d916813b8ab..9cd7c439800 100644 --- a/go/storage/mkvs/checkpoint/checkpoint.go +++ b/go/storage/mkvs/checkpoint/checkpoint.go @@ -135,11 +135,7 @@ type Metadata struct { // EncodedHash returns the encoded cryptographic hash of the checkpoint metadata. func (m *Metadata) EncodedHash() hash.Hash { - var hh hash.Hash - - hh.From(m) - - return hh + return hash.NewFrom(m) } // GetChunkMetadata returns the chunk metadata for the corresponding chunk. diff --git a/go/storage/mkvs/db/db_test.go b/go/storage/mkvs/db/db_test.go index 41df1f2de5c..cbdb2467da3 100644 --- a/go/storage/mkvs/db/db_test.go +++ b/go/storage/mkvs/db/db_test.go @@ -35,8 +35,7 @@ func TestHashedWriteLog(t *testing.T) { wla := make(writelog.Annotations, len(wl)) hashes := make(map[hash.Hash]*node.Pointer) for i := 0; i < len(wl); i++ { - var h hash.Hash - h.FromBytes(wl[i].Value) + h := hash.NewFromBytes(wl[i].Value) ptr := &node.Pointer{ Clean: true, Hash: h, diff --git a/go/storage/mkvs/node/node.go b/go/storage/mkvs/node/node.go index 9b5355e96bf..d7be6726c27 100644 --- a/go/storage/mkvs/node/node.go +++ b/go/storage/mkvs/node/node.go @@ -122,9 +122,7 @@ func (r *Root) Follows(other *Root) bool { // EncodedHash returns the encoded cryptographic hash of the storage root. func (r *Root) EncodedHash() hash.Hash { - var hh hash.Hash - hh.From(r) - return hh + return hash.NewFrom(r) } // Pointer is a pointer to another node. diff --git a/go/storage/mkvs/node/node_test.go b/go/storage/mkvs/node/node_test.go index 7514bec7b6f..b9902336b18 100644 --- a/go/storage/mkvs/node/node_test.go +++ b/go/storage/mkvs/node/node_test.go @@ -39,10 +39,8 @@ func TestSerializationInternalNode(t *testing.T) { } leafNode.UpdateHash() - var leftHash hash.Hash - leftHash.FromBytes([]byte("everyone move to the left")) - var rightHash hash.Hash - rightHash.FromBytes([]byte("everyone move to the right")) + leftHash := hash.NewFromBytes([]byte("everyone move to the left")) + rightHash := hash.NewFromBytes([]byte("everyone move to the right")) var label = Key("abc") var labelBitLength = Depth(24) @@ -98,12 +96,9 @@ func TestHashLeafNode(t *testing.T) { } func TestHashInternalNode(t *testing.T) { - var leafNodeHash hash.Hash - leafNodeHash.FromBytes([]byte("everyone stop here")) - var leftHash hash.Hash - leftHash.FromBytes([]byte("everyone move to the left")) - var rightHash hash.Hash - rightHash.FromBytes([]byte("everyone move to the right")) + leafNodeHash := hash.NewFromBytes([]byte("everyone stop here")) + leftHash := hash.NewFromBytes([]byte("everyone move to the left")) + rightHash := hash.NewFromBytes([]byte("everyone move to the right")) intNode := &InternalNode{ Version: 0xDEADBEEF, @@ -138,10 +133,8 @@ func TestExtractLeafNode(t *testing.T) { } func TestExtractInternalNode(t *testing.T) { - var leftHash hash.Hash - leftHash.FromBytes([]byte("everyone move to the left")) - var rightHash hash.Hash - rightHash.FromBytes([]byte("everyone move to the right")) + leftHash := hash.NewFromBytes([]byte("everyone move to the left")) + rightHash := hash.NewFromBytes([]byte("everyone move to the right")) intNode := &InternalNode{ Clean: true, diff --git a/go/storage/mkvs/syncer_test.go b/go/storage/mkvs/syncer_test.go index 893836a72d4..7d103000a4f 100644 --- a/go/storage/mkvs/syncer_test.go +++ b/go/storage/mkvs/syncer_test.go @@ -122,8 +122,7 @@ func TestProof(t *testing.T) { require.Error(err, "VerifyProof should fail with empty proof") // Different root. - var bogusHash hash.Hash - bogusHash.FromBytes([]byte("i am a bogus hash")) + bogusHash := hash.NewFromBytes([]byte("i am a bogus hash")) _, err = pv.VerifyProof(ctx, bogusHash, proof) require.Error(err, "VerifyProof should fail with proof for a different root") diff --git a/go/storage/mkvs/tree_test.go b/go/storage/mkvs/tree_test.go index 0d301648e2d..16165d95b15 100644 --- a/go/storage/mkvs/tree_test.go +++ b/go/storage/mkvs/tree_test.go @@ -238,8 +238,7 @@ func testBasic(t *testing.T, ndb db.NodeDB, factory NodeDBFactory) { }) require.NoError(t, err, "CommitKnown") - var bogusRoot hash.Hash - bogusRoot.FromBytes([]byte("bogus root")) + bogusRoot := hash.NewFromBytes([]byte("bogus root")) _, err = tree.CommitKnown(ctx, node.Root{ Namespace: testNs, Version: 0, @@ -1812,8 +1811,7 @@ func testErrors(t *testing.T, ndb db.NodeDB, factory NodeDBFactory) { require.Equal(t, db.ErrRootNotFound, err) // Commit with non-existent old root should fail. - var bogusRoot hash.Hash - bogusRoot.FromBytes([]byte("bogus root")) + bogusRoot := hash.NewFromBytes([]byte("bogus root")) tree = NewWithRoot(nil, ndb, node.Root{Namespace: testNs, Version: 0, Hash: bogusRoot}) _, _, err = tree.Commit(ctx, testNs, 1) require.Error(t, err, "Commit should fail for invalid root") diff --git a/go/upgrade/upgrade.go b/go/upgrade/upgrade.go index f1729a58fbc..1e93e5f4731 100644 --- a/go/upgrade/upgrade.go +++ b/go/upgrade/upgrade.go @@ -41,9 +41,8 @@ func hashSelf() (*hash.Hash, error) { return nil, err } - var hash hash.Hash - hash.FromBytes(contents) - return &hash, nil + h := hash.NewFromBytes(contents) + return &h, nil } func makeVersionString() string { diff --git a/go/worker/common/committee/group.go b/go/worker/common/committee/group.go index 0ebe60a36c6..5dc5d28b90f 100644 --- a/go/worker/common/committee/group.go +++ b/go/worker/common/committee/group.go @@ -100,8 +100,7 @@ type EpochSnapshot struct { // NewMockEpochSnapshot returns a mock epoch snapshot to be used in tests. func NewMockEpochSnapshot() *EpochSnapshot { - var executorCommitteeID hash.Hash - executorCommitteeID.FromBytes([]byte("mock committee id")) + executorCommitteeID := hash.NewFromBytes([]byte("mock committee id")) return &EpochSnapshot{ executorCommitteeID: executorCommitteeID, diff --git a/go/worker/compute/txnscheduler/algorithm/batching/incoming_queue.go b/go/worker/compute/txnscheduler/algorithm/batching/incoming_queue.go index 7b9afa90710..695268ae224 100644 --- a/go/worker/compute/txnscheduler/algorithm/batching/incoming_queue.go +++ b/go/worker/compute/txnscheduler/algorithm/batching/incoming_queue.go @@ -88,8 +88,7 @@ func (q *incomingQueue) addCallLocked(call []byte, callHash hash.Hash) { // Add adds a call to the incoming queue. func (q *incomingQueue) Add(call []byte) error { - var callHash hash.Hash - callHash.FromBytes(call) + callHash := hash.NewFromBytes(call) q.Lock() defer q.Unlock() @@ -113,8 +112,7 @@ func (q *incomingQueue) AddBatch(batch transaction.RawBatch) error { // Compute all hashes before taking the lock. var callHashes []hash.Hash for _, call := range batch { - var callHash hash.Hash - callHash.FromBytes(call) + callHash := hash.NewFromBytes(call) callHashes = append(callHashes, callHash) } @@ -181,8 +179,7 @@ func (q *incomingQueue) Take(force bool) (transaction.RawBatch, error) { returned = append(returned, call) returnedSizeBytes += callSize - var callHash hash.Hash - callHash.FromBytes(call) + callHash := hash.NewFromBytes(call) returnedCallHashes[callHash] = true continue } diff --git a/go/worker/compute/txnscheduler/algorithm/tests/tester.go b/go/worker/compute/txnscheduler/algorithm/tests/tester.go index cc5b43a5376..2dbebf9498d 100644 --- a/go/worker/compute/txnscheduler/algorithm/tests/tester.go +++ b/go/worker/compute/txnscheduler/algorithm/tests/tester.go @@ -57,8 +57,7 @@ func testScheduleTransactions(t *testing.T, td *testDispatcher, algorithm api.Al // Test ScheduleTx. testTx := []byte("hello world") - var txBytes hash.Hash - txBytes.FromBytes(testTx) + txBytes := hash.NewFromBytes(testTx) err := algorithm.ScheduleTx(testTx) require.NoError(t, err, "ScheduleTx(testTx)") require.True(t, algorithm.IsQueued(txBytes), "IsQueued(tx)") @@ -75,8 +74,7 @@ func testScheduleTransactions(t *testing.T, td *testDispatcher, algorithm api.Al td.Clear() td.ShouldFail = true testTx2 := []byte("hello world2") - var tx2Bytes hash.Hash - tx2Bytes.FromBytes(testTx2) + tx2Bytes := hash.NewFromBytes(testTx2) err = algorithm.ScheduleTx(testTx2) require.NoError(t, err, "ScheduleTx(testTx2)")