Skip to content

Commit 9f18a99

Browse files
authored
Use flow-go conversion for execution results. (#75)
* bump flow-go version to v0.39 * use flow-go conversion function * add test case for consistency between rosetta bespoke ID computation and flow-go ID computation * support for non-updated historical access nodes
1 parent 80d60fc commit 9f18a99

File tree

5 files changed

+94
-41
lines changed

5 files changed

+94
-41
lines changed

go.mod

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ require (
1414
github.com/golang/protobuf v1.5.4
1515
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
1616
github.com/libp2p/go-libp2p v0.38.2
17-
github.com/onflow/cadence v1.3.1
17+
github.com/onflow/cadence v1.3.3
1818
github.com/onflow/crypto v0.25.2
19-
github.com/onflow/flow-go v0.38.1
20-
github.com/onflow/flow/protobuf/go/flow v0.4.7
19+
github.com/onflow/flow-go v0.39.0
20+
github.com/onflow/flow/protobuf/go/flow v0.4.9
2121
github.com/rs/zerolog v1.29.0
2222
github.com/stretchr/testify v1.10.0
2323
go.opentelemetry.io/otel v1.34.0
@@ -247,11 +247,11 @@ require (
247247
github.com/multiformats/go-varint v0.0.7 // indirect
248248
github.com/olekukonko/tablewriter v0.0.5 // indirect
249249
github.com/onflow/atree v0.9.0 // indirect
250-
github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 // indirect; v1.2.4-0.20230703193002-53362441b57d // indirect
251-
github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 // indirect; v1.2.3 // indirect
250+
github.com/onflow/flow-core-contracts/lib/go/contracts v1.6.0 // indirect; v1.2.4-0.20230703193002-53362441b57d // indirect
251+
github.com/onflow/flow-core-contracts/lib/go/templates v1.6.0 // indirect; v1.2.3 // indirect
252252
github.com/onflow/flow-ft/lib/go/contracts v1.0.1 // indirect
253-
github.com/onflow/flow-go-sdk v1.3.1 // indirect
254-
github.com/onflow/flow-nft/lib/go/contracts v1.2.2 // indirect
253+
github.com/onflow/flow-go-sdk v1.3.3 // indirect
254+
github.com/onflow/flow-nft/lib/go/contracts v1.2.3 // indirect
255255
github.com/onflow/go-ethereum v1.14.7 // indirect
256256
github.com/onflow/sdks v0.6.0-preview.1 // indirect
257257
github.com/onflow/wal v1.0.2 // indirect

go.sum

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -707,28 +707,28 @@ github.com/onflow/boxo v0.0.0-20240201202436-f2477b92f483 h1:LpiQhTAfM9CAmNVEs0n
707707
github.com/onflow/boxo v0.0.0-20240201202436-f2477b92f483/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80=
708708
github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0 h1:ofdfKH8KgY6qVFnlngTontds/IBERANeWl0PBPCtPOA=
709709
github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0/go.mod h1:K4/oaEhhnSuJ9q6fpq1w9WEWRGtkNskhmoyH8t+X9Mk=
710-
github.com/onflow/cadence v1.3.1 h1:bs9TFHQy8HHbwTtCtg5cLdyndWhmwq55RSwID1cb220=
711-
github.com/onflow/cadence v1.3.1/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA=
710+
github.com/onflow/cadence v1.3.3 h1:h9uyhqfiiBahk0P7JHQ1XR5b42wOGRIn+fNRd3JppYs=
711+
github.com/onflow/cadence v1.3.3/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA=
712712
github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns=
713713
github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY=
714-
github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 h1:R86HaOuk6vpuECZnriEUE7bw9inC2AtdSn8lL/iwQLQ=
715-
github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0/go.mod h1:9asTBnB6Tw2UlVVtQKyS/egYv3xr4zVlJnJ75z1dfac=
716-
github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 h1:u2DAG8pk0xFH7TwS70t1gSZ/FtIIZWMSNyiu4SeXBYg=
717-
github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0/go.mod h1:pN768Al/wLRlf3bwugv9TyxniqJxMu4sxnX9eQJam64=
714+
github.com/onflow/flow-core-contracts/lib/go/contracts v1.6.0 h1:zbJaqR3bHicNz68YFJ/6gieUkxnMYz8dKxQrUUCc+/M=
715+
github.com/onflow/flow-core-contracts/lib/go/contracts v1.6.0/go.mod h1:ufT77Epq1gfXAHQQk13WcAHWEv+Aarecn5PMnljWJ1A=
716+
github.com/onflow/flow-core-contracts/lib/go/templates v1.6.0 h1:hVlyGbZ+gkeX0mTxTC4D65HulJCUbbVFgOvVWdMfRI8=
717+
github.com/onflow/flow-core-contracts/lib/go/templates v1.6.0/go.mod h1:pN768Al/wLRlf3bwugv9TyxniqJxMu4sxnX9eQJam64=
718718
github.com/onflow/flow-ft/lib/go/contracts v1.0.1 h1:Ts5ob+CoCY2EjEd0W6vdLJ7hLL3SsEftzXG2JlmSe24=
719719
github.com/onflow/flow-ft/lib/go/contracts v1.0.1/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A=
720720
github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDtVqJ/5tYI4VkF5zfM=
721721
github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE=
722-
github.com/onflow/flow-go v0.38.1 h1:/dov9lDUkmzHZa0LoeIrzB9DuoP/hg7VIn9/QtDIHHk=
723-
github.com/onflow/flow-go v0.38.1/go.mod h1:p88l1DhHObIUr+8b0zqkwH0bklZmQksb6IFH8ZaL1Bg=
724-
github.com/onflow/flow-go-sdk v1.3.1 h1:2YdTL/R1/DjMYYmyKgArTeQ93GKvLlfCeCpMVH7b8q4=
725-
github.com/onflow/flow-go-sdk v1.3.1/go.mod h1:0rMuCLShdX9F4pLBCPhlMGCFu8gu9SfiXT/Lc9qAi24=
726-
github.com/onflow/flow-nft/lib/go/contracts v1.2.2 h1:XFERNVUDGbZ4ViZjt7P1cGD80mO1PzUJYPfdhXFsGbQ=
727-
github.com/onflow/flow-nft/lib/go/contracts v1.2.2/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY=
722+
github.com/onflow/flow-go v0.39.0 h1:QgOC2hMlR/xDac5Kdu1xVdeVW56mfQfaV7z7fngc3f8=
723+
github.com/onflow/flow-go v0.39.0/go.mod h1:ctpvgaJ8y+bqaHjJDyebyjQryzwBXniMKFwOfZ7Mr/k=
724+
github.com/onflow/flow-go-sdk v1.3.3 h1:wj7llql3wesQYBePh3lEFI+jk3Df1sa13bRsL139JDo=
725+
github.com/onflow/flow-go-sdk v1.3.3/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc=
726+
github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk=
727+
github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY=
728728
github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE=
729729
github.com/onflow/flow-nft/lib/go/templates v1.2.1/go.mod h1:W6hOWU0xltPqNpv9gQX8Pj8Jtf0OmRxc1XX2V0kzJaI=
730-
github.com/onflow/flow/protobuf/go/flow v0.4.7 h1:iP6DFx4wZ3ETORsyeqzHu7neFT3d1CXF6wdK+AOOjmc=
731-
github.com/onflow/flow/protobuf/go/flow v0.4.7/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk=
730+
github.com/onflow/flow/protobuf/go/flow v0.4.9 h1:UfsWWqj6VQbEHvaw8kSGvIawCpEfz3gOGZfcdugNxVE=
731+
github.com/onflow/flow/protobuf/go/flow v0.4.9/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk=
732732
github.com/onflow/go-ethereum v1.14.7 h1:gg3awYqI02e3AypRdpJKEvNTJ6kz/OhAqRti0h54Wlc=
733733
github.com/onflow/go-ethereum v1.14.7/go.mod h1:zV14QLrXyYu5ucvcwHUA0r6UaqveqbXaehAVQJlSW+I=
734734
github.com/onflow/nft-storefront/lib/go/contracts v1.0.0 h1:sxyWLqGm/p4EKT6DUlQESDG1ZNMN9GjPCm1gTq7NGfc=

state/convert.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
_ "github.com/onflow/cadence/stdlib" // imported for side-effects only
1313
"github.com/onflow/crypto"
1414
"github.com/onflow/crypto/hash"
15+
"github.com/onflow/flow-go/engine/common/rpc/convert"
1516
"github.com/onflow/flow-go/model/fingerprint"
1617
"github.com/onflow/flow-go/model/flow"
1718
"github.com/onflow/flow-go/storage/merkle"
@@ -22,26 +23,20 @@ import (
2223
"github.com/onflow/rosetta/log"
2324
)
2425

25-
func convertExecutionResult(hash []byte, height uint64, result *entities.ExecutionResult) (flowExecutionResult, bool) {
26+
func convertExecutionResult(sporkVersion int, hash []byte, height uint64, result *entities.ExecutionResult) (flowExecutionResult, bool) {
2627
// todo: add V6 version branching here directly after mainnet23 spork
2728
exec := flowExecutionResult{
2829
BlockID: toFlowIdentifier(result.BlockId),
2930
ExecutionDataID: toFlowIdentifier(result.ExecutionDataId),
3031
PreviousResultID: toFlowIdentifier(result.PreviousResultId),
3132
}
3233
for _, chunk := range result.Chunks {
33-
exec.Chunks = append(exec.Chunks, &flow.Chunk{
34-
ChunkBody: flow.ChunkBody{
35-
BlockID: toFlowIdentifier(chunk.BlockId),
36-
CollectionIndex: uint(chunk.CollectionIndex),
37-
EventCollection: toFlowIdentifier(chunk.EventCollection),
38-
NumberOfTransactions: uint64(chunk.NumberOfTransactions),
39-
StartState: flow.StateCommitment(toFlowIdentifier(chunk.StartState)),
40-
TotalComputationUsed: chunk.TotalComputationUsed,
41-
},
42-
EndState: flow.StateCommitment(toFlowIdentifier(chunk.EndState)),
43-
Index: chunk.Index,
44-
})
34+
convertedChunk, err := convertChunk(sporkVersion, chunk)
35+
if err != nil {
36+
log.Errorf("Failed to convert chunk in block %x at height %d: %v", hash, height, err)
37+
return flowExecutionResult{}, false
38+
}
39+
exec.Chunks = append(exec.Chunks, convertedChunk)
4540
}
4641
for _, ev := range result.ServiceEvents {
4742
eventType := flow.ServiceEventType(ev.Type)
@@ -58,6 +53,25 @@ func convertExecutionResult(hash []byte, height uint64, result *entities.Executi
5853
return exec, true
5954
}
6055

56+
func convertChunk(sporkVersion int, protobufChunk *entities.Chunk) (*flow.Chunk, error) {
57+
if sporkVersion < 7 {
58+
chunk, err := convert.MessageToChunk(protobufChunk)
59+
if err != nil {
60+
return nil, err
61+
}
62+
// Protocol State v1: ServiceEventCount field not yet added.
63+
// Access Nodes running up-to-date software encode nil ServiceEventCount fields in a detectable way,
64+
// but we assume that we are querying historical Access Nodes that are running prior software versions.
65+
// In this case, the new Protobuf field is automatically set to 0.
66+
// See https://github.com/onflow/flow-go/pull/6744 for additional context
67+
chunk.ServiceEventCount = nil
68+
return chunk, nil
69+
}
70+
71+
// Protocol State v2+
72+
return convert.MessageToChunk(protobufChunk)
73+
}
74+
6175
func decodeEvent(typ string, evt *entities.Event, hash []byte, height uint64) (cadence.Event, error) {
6276
val, err := decodePayload(evt.Payload)
6377
if err != nil {
@@ -431,7 +445,7 @@ func verifyBlockHash(spork *config.Spork, hash []byte, height uint64, hdr *entit
431445

432446
var resultIDs []flow.Identifier
433447
for _, src := range block.ExecutionResultList {
434-
exec, ok := convertExecutionResult(hash, height, src)
448+
exec, ok := convertExecutionResult(spork.Version, hash, height, src)
435449
if ok {
436450
resultIDs = append(resultIDs, deriveExecutionResult(spork, exec))
437451
}

state/convert_test.go

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import (
55
"context"
66
"testing"
77

8+
"github.com/onflow/flow-go/engine/common/rpc/convert"
89
"github.com/onflow/flow-go/model/flow"
10+
"github.com/onflow/flow-go/utils/unittest"
911
"github.com/onflow/flow/protobuf/go/flow/entities"
10-
"github.com/onflow/rosetta/access"
11-
"github.com/onflow/rosetta/config"
1212
"github.com/stretchr/testify/assert"
1313
"github.com/stretchr/testify/require"
14+
15+
"github.com/onflow/rosetta/access"
16+
"github.com/onflow/rosetta/config"
1417
)
1518

1619
var accessAddr = "access-001.mainnet24.nodes.onflow.org:9000"
@@ -60,7 +63,7 @@ func TestVerifyExecutionResultHash(t *testing.T) {
6063
sealedResults[string(seal.BlockId)] = string(seal.ResultId)
6164
}
6265
var resultID flow.Identifier
63-
exec, ok := convertExecutionResult(block.Id, blockHeight, execResult)
66+
exec, ok := convertExecutionResult(spork.Version, block.Id, blockHeight, execResult)
6467
if ok {
6568
resultID = deriveExecutionResult(spork, exec)
6669
}
@@ -137,6 +140,41 @@ func TestDeriveEventsHash(t *testing.T) {
137140
}
138141
}
139142

143+
// TestExecutionResultConsistency_ChunkServiceEventCountField tests that Rosetta computes
144+
// a consistent entity ID for execution results for both Protocol State v1 and v2 formats.
145+
// Rosetta re-implements core models from flow-go, rather than using the model types
146+
// exported by flow-go, which introduces risk that changes in flow-go are not reflected in Rosetta.
147+
// This test case validates consistency only for Protocol State version 1 and 2.
148+
// See https://github.com/onflow/flow-go/pull/6744 for additional context.
149+
func TestExecutionResultConsistency_ChunkServiceEventCountField(t *testing.T) {
150+
t.Run("Execution Result - Protocol State v1", func(t *testing.T) {
151+
psv1Result := unittest.ExecutionResultFixture(func(result *flow.ExecutionResult) {
152+
for _, chunk := range result.Chunks {
153+
chunk.ServiceEventCount = nil
154+
}
155+
})
156+
157+
psv1ProtobufResult, err := convert.ExecutionResultToMessage(psv1Result)
158+
require.NoError(t, err)
159+
psv1RosettaResult, ok := convertExecutionResult(7, nil, 0, psv1ProtobufResult)
160+
require.True(t, ok)
161+
rosettaResultID := deriveExecutionResultV2(psv1RosettaResult)
162+
assert.Equal(t, psv1Result.ID(), rosettaResultID)
163+
})
164+
t.Run("Execution Result - Protocol State v2", func(t *testing.T) {
165+
psv2Result := unittest.ExecutionResultFixture(func(result *flow.ExecutionResult) {
166+
result.Chunks[0].ServiceEventCount = unittest.PtrTo[uint16](0)
167+
})
168+
169+
psv2ProtobufResult, err := convert.ExecutionResultToMessage(psv2Result)
170+
require.NoError(t, err)
171+
psv2RosettaResult, ok := convertExecutionResult(7, nil, 0, psv2ProtobufResult)
172+
require.True(t, ok)
173+
rosettaResultID := deriveExecutionResultV2(psv2RosettaResult)
174+
assert.Equal(t, psv2Result.ID(), rosettaResultID)
175+
})
176+
}
177+
140178
func createSpork(ctx context.Context) (*config.Spork, error) {
141179
addr := accessAddr
142180
pool := access.New(ctx, []access.NodeConfig{{Address: addr}}, nil)

state/process.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ import (
1212
"github.com/onflow/flow-go/model/flow"
1313
flowaccess "github.com/onflow/flow/protobuf/go/flow/access"
1414
"github.com/onflow/flow/protobuf/go/flow/entities"
15+
"google.golang.org/grpc/codes"
16+
"google.golang.org/grpc/status"
17+
1518
"github.com/onflow/rosetta/access"
1619
"github.com/onflow/rosetta/cache"
1720
"github.com/onflow/rosetta/config"
1821
"github.com/onflow/rosetta/crypto"
1922
"github.com/onflow/rosetta/log"
2023
"github.com/onflow/rosetta/model"
2124
"github.com/onflow/rosetta/trace"
22-
"google.golang.org/grpc/codes"
23-
"google.golang.org/grpc/status"
2425
)
2526

2627
var (
@@ -326,7 +327,7 @@ outer:
326327
}
327328
}
328329
var resultID flow.Identifier
329-
exec, convOk := convertExecutionResult(hash, height, execResult)
330+
exec, convOk := convertExecutionResult(spork.Version, hash, height, execResult)
330331
if convOk {
331332
resultID = deriveExecutionResult(spork, exec)
332333
}

0 commit comments

Comments
 (0)