Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: Verification of non-system-chunk service events #6629

Draft
wants to merge 5 commits into
base: feature/efm-recovery
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions engine/execution/block_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,24 @@ func (er *BlockExecutionResult) AllExecutionSnapshots() []*snapshot.ExecutionSna
func (er *BlockExecutionResult) AllConvertedServiceEvents() flow.ServiceEventList {
res := make(flow.ServiceEventList, 0)
for _, ce := range er.collectionExecutionResults {
// NOTE: at this point we have the chunk->service event mapping
if len(ce.convertedServiceEvents) > 0 {
res = append(res, ce.convertedServiceEvents...)
}
}
return res
}

func (er *BlockExecutionResult) ServiceEventChunkIndices() []uint64 {
indices := make([]uint64, 0)
for chunkIndex, ce := range er.collectionExecutionResults {
if len(ce.convertedServiceEvents) > 0 {
indices = append(indices, uint64(chunkIndex))
}
}
return indices
}

// AllUpdatedRegisters returns all updated unique register entries
// Note: order is not determinstic
func (er *BlockExecutionResult) AllUpdatedRegisters() []flow.RegisterEntry {
Expand Down
1 change: 1 addition & 0 deletions engine/execution/computation/computer/result_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ func (collector *resultCollector) Finalize(
collector.result.ExecutableBlock.ID(),
collector.result.AllChunks(),
collector.result.AllConvertedServiceEvents(),
collector.result.ServiceEventChunkIndices(),
executionDataID)

executionReceipt, err := GenerateExecutionReceipt(
Expand Down
1 change: 1 addition & 0 deletions engine/execution/state/state_storehouse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ func makeComputationResult(
completeBlock.ID(),
computationResult.AllChunks(),
flow.ServiceEventList{},
nil,
executionDataID)

computationResult.BlockAttestationResult.BlockExecutionResult.ExecutionDataRoot = &flow.BlockExecutionDataRoot{
Expand Down
1 change: 1 addition & 0 deletions engine/execution/state/unittest/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ func ComputationResultForBlockFixture(
completeBlock.ID(),
computationResult.AllChunks(),
convertedServiceEvents,
[]uint64{0, 0, 0, 0},
executionDataID)

computationResult.ExecutionReceipt = &flow.ExecutionReceipt{
Expand Down
29 changes: 23 additions & 6 deletions model/flow/execution_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,42 @@ type ExecutionResult struct {
BlockID Identifier // commit of the current block
Chunks ChunkList
ServiceEvents ServiceEventList
ExecutionDataID Identifier // hash commitment to flow.BlockExecutionDataRoot
// maps index in ServiceEvents to index in ChunkList
// Requirements:
// - len(ServiceEventChunkIndices) == len(ServiceEvents)
// - values are monotonically increasing, and in the range [0, len(Chunks)]
ServiceEventChunkIndices []uint64
ExecutionDataID Identifier // hash commitment to flow.BlockExecutionDataRoot
}

func NewExecutionResult(
previousResultID Identifier,
blockID Identifier,
chunks ChunkList,
serviceEvents ServiceEventList,
serviceEventChunkIndices []uint64,
executionDataID Identifier,
) *ExecutionResult {
return &ExecutionResult{
PreviousResultID: previousResultID,
BlockID: blockID,
Chunks: chunks,
ServiceEvents: serviceEvents,
ExecutionDataID: executionDataID,
PreviousResultID: previousResultID,
BlockID: blockID,
Chunks: chunks,
ServiceEvents: serviceEvents,
ServiceEventChunkIndices: serviceEventChunkIndices,
ExecutionDataID: executionDataID,
}
}

func (er ExecutionResult) ServiceEventsByChunk(chunk uint64) ServiceEventList {
events := make(ServiceEventList, 0)
for eventIndex, chunkIndex := range er.ServiceEventChunkIndices {
if chunkIndex == chunk {
events = append(events, er.ServiceEvents[eventIndex])
}
}
return events
}

// ID returns the hash of the execution result body
func (er ExecutionResult) ID() Identifier {
return MakeID(er)
Expand Down
1 change: 1 addition & 0 deletions model/flow/service_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const (
type ServiceEvent struct {
Type ServiceEventType
Event interface{}
//ChunkIndex int
}

// ServiceEventList is a handy container to enable comparisons
Expand Down
31 changes: 17 additions & 14 deletions model/messages/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,23 @@ import (
// Deprecated: Please update flow.ExecutionResult to use []flow.Chunk, then
// replace instances of this type with flow.ExecutionResult
type UntrustedExecutionResult struct {
PreviousResultID flow.Identifier
BlockID flow.Identifier
Chunks []flow.Chunk
ServiceEvents flow.ServiceEventList
ExecutionDataID flow.Identifier
PreviousResultID flow.Identifier
BlockID flow.Identifier
Chunks []flow.Chunk
ServiceEvents flow.ServiceEventList
ServiceEventChunkIndices []uint64
ExecutionDataID flow.Identifier
}

// ToInternal returns the internal representation of the type.
func (ur *UntrustedExecutionResult) ToInternal() *flow.ExecutionResult {
result := flow.ExecutionResult{
PreviousResultID: ur.PreviousResultID,
BlockID: ur.BlockID,
Chunks: make(flow.ChunkList, 0, len(ur.Chunks)),
ServiceEvents: ur.ServiceEvents,
ExecutionDataID: ur.ExecutionDataID,
PreviousResultID: ur.PreviousResultID,
BlockID: ur.BlockID,
Chunks: make(flow.ChunkList, 0, len(ur.Chunks)),
ServiceEvents: ur.ServiceEvents,
ServiceEventChunkIndices: ur.ServiceEventChunkIndices,
ExecutionDataID: ur.ExecutionDataID,
}
for _, chunk := range ur.Chunks {
chunk := chunk
Expand All @@ -38,10 +40,11 @@ func (ur *UntrustedExecutionResult) ToInternal() *flow.ExecutionResult {
// to the representation used in untrusted messages.
func UntrustedExecutionResultFromInternal(internal *flow.ExecutionResult) UntrustedExecutionResult {
result := UntrustedExecutionResult{
PreviousResultID: internal.PreviousResultID,
BlockID: internal.BlockID,
ServiceEvents: internal.ServiceEvents,
ExecutionDataID: internal.ExecutionDataID,
PreviousResultID: internal.PreviousResultID,
BlockID: internal.BlockID,
ServiceEvents: internal.ServiceEvents,
ServiceEventChunkIndices: internal.ServiceEventChunkIndices,
ExecutionDataID: internal.ExecutionDataID,
}
for _, chunk := range internal.Chunks {
result.Chunks = append(result.Chunks, *chunk)
Expand Down
5 changes: 3 additions & 2 deletions module/chunks/chunkVerifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,9 @@ func (fcv *ChunkVerifier) verifyTransactionsInContext(
return nil, chmodels.NewCFInvalidEventsCollection(chunk.EventCollection, eventsHash, chIndex, execResID, events)
}

if systemChunk {
equal, err := result.ServiceEvents.EqualTo(serviceEvents)
if len(result.ServiceEvents) > 0 {
serviceEventsInChunk := result.ServiceEventsByChunk(chunk.Index)
equal, err := serviceEventsInChunk.EqualTo(serviceEvents)
if err != nil {
return nil, fmt.Errorf("error while comparing service events: %w", err)
}
Expand Down
13 changes: 9 additions & 4 deletions module/chunks/chunkVerifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,10 @@ type testMetadata struct {
ledger *completeLedger.Ledger
}

func (m *testMetadata) ServiceEventChunkIndices() []uint64 {
return make([]uint64, len(m.ServiceEvents)) // all 0 - all in system chunk
}

func (m *testMetadata) RefreshChunkData(t *testing.T) *verification.VerifiableChunkData {
cedCollection := m.Collection

Expand Down Expand Up @@ -653,10 +657,11 @@ func (m *testMetadata) RefreshChunkData(t *testing.T) *verification.VerifiableCh

// ExecutionResult setup
result := &flow.ExecutionResult{
BlockID: m.Header.ID(),
Chunks: flow.ChunkList{chunk},
ServiceEvents: m.ServiceEvents,
ExecutionDataID: executionDataID,
BlockID: m.Header.ID(),
Chunks: flow.ChunkList{chunk},
ServiceEvents: m.ServiceEvents,
ServiceEventChunkIndices: m.ServiceEventChunkIndices(),
ExecutionDataID: executionDataID,
}

return &verification.VerifiableChunkData{
Expand Down
Loading