LayersQuery: populate layer hash with aggregated hash
## Motivation
<!-- Please mention the issue fixed by this PR or detailed motivation -->
removed the unused field for layer hash.
replace it with aggregated layer hash.
MODIFY
api/grpcserver/grpcserver_test.go
api/grpcserver/grpcserver_test.go
@@ -300,6 +300,10 @@ func (m *MeshAPIMock) GetATXs(context.Context, []types.ATXID) (map[types.ATXID]*
return atxs, nil
}
+func (m *MeshAPIMock) MeshHash(types.LayerID) (types.Hash32, error) {
+ return types.RandomHash(), nil
+}
+
type ConStateAPIMock struct {
returnTx map[types.TransactionID]*types.Transaction
layerApplied map[types.TransactionID]*types.LayerID
@@ -1637,6 +1641,7 @@ func TestMeshService(t *testing.T) {
resLayerNine := res.Layer[9]
require.Equal(t, uint32(9), resLayerNine.Number.Number, "layer nine is ninth")
+ require.NotEmpty(t, resLayerNine.Hash)
require.Equal(t, pb.Layer_LAYER_STATUS_UNSPECIFIED, resLayerNine.Status, "later layer is unconfirmed")
},
},
@@ -2290,6 +2295,7 @@ func TestLayerStream_comprehensive(t *testing.T) {
require.NoError(t, err, "got error from stream")
require.Equal(t, uint32(0), res.Layer.Number.Number)
require.Equal(t, events.LayerStatusTypeConfirmed, int(res.Layer.Status))
+ require.NotEmpty(t, res.Layer.Hash)
checkLayer(t, res.Layer)
}

MODIFY
api/grpcserver/mesh_service.go
api/grpcserver/mesh_service.go
@@ -356,11 +356,19 @@ func (s MeshService) readLayer(ctx context.Context, layerID types.LayerID, layer
log.With().Debug("no state root for layer",
layer, log.String("status", layerStatus.String()), log.Err(err))
}
+ hash, err := s.mesh.MeshHash(layerID)
+ if err != nil {
+ // This is expected. We can only retrieve state root for a layer that was applied to state,
+ // which only happens after it's approved/confirmed.
+ log.With().Debug("no mesh hash at layer",
+ layer, log.String("status", layerStatus.String()), log.Err(err))
+ }
return &pb.Layer{
Number: &pb.LayerNumber{Number: layer.Index().Uint32()},
Status: layerStatus,
Blocks: blocks,
Activations: pbActivations,
+ Hash: hash.Bytes(),
RootStateHash: stateRoot.Bytes(),
}, nil
}

MODIFY
api/node.go
api/node.go
@@ -55,6 +55,7 @@ type MeshAPI interface {
LatestLayer() types.LayerID
LatestLayerInState() types.LayerID
ProcessedLayer() types.LayerID
+ MeshHash(types.LayerID) (types.Hash32, error)
}
// NOTE that mockgen doesn't use source-mode to avoid generating mocks for all interfaces in this file.

MODIFY
mesh/mesh.go
mesh/mesh.go
@@ -134,6 +134,11 @@ func (msh *Mesh) LatestLayer() types.LayerID {
return msh.latestLayer.Load().(types.LayerID)
}
+// MeshHash returns the aggregated mesh hash at the specified layer.
+func (msh *Mesh) MeshHash(lid types.LayerID) (types.Hash32, error) {
+ return layers.GetAggregatedHash(msh.cdb, lid)
+}
+
// MissingLayer is a layer in (latestLayerInState, processLayer].
// this layer is missing critical data (valid blocks or transactions)
// and can't be applied to the state.

LayersQuery: populate layer hash with aggregated hash (#4046)

## Motivation
<!-- Please mention the issue fixed by this PR or detailed motivation -->
#4026 removed the unused field for layer hash.
replace it with aggregated layer hash.