Skip to content

Commit dcd096d

Browse files
authored
Merge branch 'feature/malleability' into tim/malleability-sync-master-2025-08-25
2 parents 0694272 + 32bd006 commit dcd096d

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

model/cluster/block_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package cluster_test
22

33
import (
4+
"encoding/json"
45
"testing"
56
"time"
67

8+
"github.com/stretchr/testify/assert"
79
"github.com/stretchr/testify/require"
810

911
"github.com/onflow/flow-go/model/cluster"
@@ -281,3 +283,16 @@ func TestNewRootProposal(t *testing.T) {
281283
require.Contains(t, err.Error(), "proposer signature must be empty")
282284
})
283285
}
286+
287+
// TestBlockEncodingJSON_IDField ensures that the explicit ID field added to the
288+
// block when encoded as JSON is present and accurate.
289+
func TestBlockEncodingJSON_IDField(t *testing.T) {
290+
block := unittest.ClusterBlockFixture()
291+
blockID := block.ID()
292+
data, err := json.Marshal(block)
293+
require.NoError(t, err)
294+
var decodedIDField struct{ ID flow.Identifier }
295+
err = json.Unmarshal(data, &decodedIDField)
296+
require.NoError(t, err)
297+
assert.Equal(t, blockID, decodedIDField.ID)
298+
}

model/flow/block.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package flow
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"time"
67
)
@@ -66,6 +67,19 @@ func (b *GenericBlock[T]) ToHeader() *Header {
6667
return header
6768
}
6869

70+
// MarshalJSON implements JSON encoding logic for blocks.
71+
// We include a top-level ID field equal to the hash of the block, for visibility in automations.
72+
// The ID field is ignored when unmarshaling a JSON structure back into a block.
73+
func (b *GenericBlock[T]) MarshalJSON() ([]byte, error) {
74+
return json.Marshal(struct {
75+
GenericBlock[T]
76+
ID Identifier
77+
}{
78+
GenericBlock: *b,
79+
ID: b.ID(),
80+
})
81+
}
82+
6983
// Block is the canonical instantiation of GenericBlock using flow.Payload as the payload type.
7084
//
7185
// Zero values for certain HeaderBody fields are allowed only for root blocks, which must be constructed

model/flow/block_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,19 @@ func TestBlockEncodingJSON(t *testing.T) {
5252
assert.Equal(t, block, &decoded)
5353
}
5454

55+
// TestBlockEncodingJSON_IDField ensures that the explicit ID field added to the
56+
// block when encoded as JSON is present and accurate.
57+
func TestBlockEncodingJSON_IDField(t *testing.T) {
58+
block := unittest.BlockFixture()
59+
blockID := block.ID()
60+
data, err := json.Marshal(block)
61+
require.NoError(t, err)
62+
var decodedIDField struct{ ID flow.Identifier }
63+
err = json.Unmarshal(data, &decodedIDField)
64+
require.NoError(t, err)
65+
assert.Equal(t, blockID, decodedIDField.ID)
66+
}
67+
5568
func TestBlockEncodingMsgpack(t *testing.T) {
5669
block := unittest.BlockFixture()
5770
blockID := block.ID()

0 commit comments

Comments
 (0)