From 9c10352b229b48b8247a97230f5320453e0facd5 Mon Sep 17 00:00:00 2001 From: Janez Podhostnik Date: Mon, 13 Jan 2025 20:23:25 +0100 Subject: [PATCH] cleanup --- .../node_builder/access_node_builder.go | 4 +-- cmd/observer/node_builder/observer_builder.go | 4 +-- .../computation/computer/computer.go | 4 +-- engine/execution/computation/manager.go | 2 +- .../execution/computation/query/executor.go | 4 +-- .../computation/snapshot_provider.go | 17 +++++++--- engine/execution/testutil/fixtures.go | 10 +++--- fvm/context.go | 11 ++---- model/flow/snapshot_subset.go | 34 ++++++++++++++++--- model/verification/convert/convert.go | 2 +- model/verification/verifiableChunkData.go | 16 ++++----- module/execution/scripts.go | 2 +- 12 files changed, 68 insertions(+), 42 deletions(-) diff --git a/cmd/access/node_builder/access_node_builder.go b/cmd/access/node_builder/access_node_builder.go index 416deccaeee..4c209b15693 100644 --- a/cmd/access/node_builder/access_node_builder.go +++ b/cmd/access/node_builder/access_node_builder.go @@ -63,7 +63,7 @@ import ( "github.com/onflow/flow-go/engine/common/stop" synceng "github.com/onflow/flow-go/engine/common/synchronization" "github.com/onflow/flow-go/engine/common/version" - fvmExecution "github.com/onflow/flow-go/engine/execution/computation" + "github.com/onflow/flow-go/engine/execution/computation" "github.com/onflow/flow-go/engine/execution/computation/query" "github.com/onflow/flow-go/fvm/storage/derived" "github.com/onflow/flow-go/ledger" @@ -992,7 +992,7 @@ func (builder *FlowAccessNodeBuilder) BuildExecutionSyncComponents() *FlowAccess builder.Logger, metrics.NewExecutionCollector(builder.Tracer), builder.RootChainID, - fvmExecution.NewProtocolStateWrapper(builder.State), + computation.NewProtocolStateWrapper(builder.State), builder.Storage.Headers, builder.ExecutionIndexerCore.RegisterValue, builder.scriptExecutorConfig, diff --git a/cmd/observer/node_builder/observer_builder.go b/cmd/observer/node_builder/observer_builder.go index 051dc21ded9..6829b115060 100644 --- a/cmd/observer/node_builder/observer_builder.go +++ b/cmd/observer/node_builder/observer_builder.go @@ -57,7 +57,7 @@ import ( "github.com/onflow/flow-go/engine/common/stop" synceng "github.com/onflow/flow-go/engine/common/synchronization" "github.com/onflow/flow-go/engine/common/version" - fvmExecution "github.com/onflow/flow-go/engine/execution/computation" + "github.com/onflow/flow-go/engine/execution/computation" "github.com/onflow/flow-go/engine/execution/computation/query" "github.com/onflow/flow-go/fvm/storage/derived" "github.com/onflow/flow-go/ledger" @@ -1455,7 +1455,7 @@ func (builder *ObserverServiceBuilder) BuildExecutionSyncComponents() *ObserverS builder.Logger, metrics.NewExecutionCollector(builder.Tracer), builder.RootChainID, - fvmExecution.NewProtocolStateWrapper(builder.State), + computation.NewProtocolStateWrapper(builder.State), builder.Storage.Headers, builder.ExecutionIndexerCore.RegisterValue, builder.scriptExecutorConfig, diff --git a/engine/execution/computation/computer/computer.go b/engine/execution/computation/computer/computer.go index a857335f4f3..c3d79c11e56 100644 --- a/engine/execution/computation/computer/computer.go +++ b/engine/execution/computation/computer/computer.go @@ -114,7 +114,7 @@ type blockComputer struct { spockHasher hash.Hasher receiptHasher hash.Hasher colResCons []result.ExecutedCollectionConsumer - protocolState flow.ProtocolStateSnapshotProvider + protocolState flow.ProtocolSnapshotExecutionSubsetProvider maxConcurrency int } @@ -145,7 +145,7 @@ func NewBlockComputer( signer module.Local, executionDataProvider provider.Provider, colResCons []result.ExecutedCollectionConsumer, - state flow.ProtocolStateSnapshotProvider, + state flow.ProtocolSnapshotExecutionSubsetProvider, maxConcurrency int, ) (BlockComputer, error) { if maxConcurrency < 1 { diff --git a/engine/execution/computation/manager.go b/engine/execution/computation/manager.go index 470ebbf60b2..a2fa056e017 100644 --- a/engine/execution/computation/manager.go +++ b/engine/execution/computation/manager.go @@ -90,7 +90,7 @@ func New( metrics module.ExecutionMetrics, tracer module.Tracer, me module.Local, - protoState flow.ProtocolStateSnapshotProvider, + protoState flow.ProtocolSnapshotExecutionSubsetProvider, vmCtx fvm.Context, committer computer.ViewCommitter, executionDataProvider provider.Provider, diff --git a/engine/execution/computation/query/executor.go b/engine/execution/computation/query/executor.go index c22923c0744..c4dcd016059 100644 --- a/engine/execution/computation/query/executor.go +++ b/engine/execution/computation/query/executor.go @@ -117,7 +117,7 @@ type QueryExecutor struct { vmCtx fvm.Context derivedChainData *derived.DerivedChainData rngLock *sync.Mutex - protocolStateSnapshot flow.ProtocolStateSnapshotProvider + protocolStateSnapshot flow.ProtocolSnapshotExecutionSubsetProvider } var _ Executor = &QueryExecutor{} @@ -129,7 +129,7 @@ func NewQueryExecutor( vm fvm.VM, vmCtx fvm.Context, derivedChainData *derived.DerivedChainData, - protocolStateSnapshot flow.ProtocolStateSnapshotProvider, + protocolStateSnapshot flow.ProtocolSnapshotExecutionSubsetProvider, ) *QueryExecutor { if config.ComputationLimit > 0 { vmCtx = fvm.NewContextFromParent(vmCtx, fvm.WithComputationLimit(config.ComputationLimit)) diff --git a/engine/execution/computation/snapshot_provider.go b/engine/execution/computation/snapshot_provider.go index 49091b5eb2a..5b95a050a25 100644 --- a/engine/execution/computation/snapshot_provider.go +++ b/engine/execution/computation/snapshot_provider.go @@ -5,18 +5,25 @@ import ( "github.com/onflow/flow-go/state/protocol" ) -// protocolStateWrapper implements `EntropyProviderPerBlock` -var _ flow.ProtocolStateSnapshotProvider = (*protocolStateWrapper)(nil) +// ProtocolSnapshotExecutionSubset is a subset of the protocol state snapshot that is needed by the FVM +var _ flow.ProtocolSnapshotExecutionSubset = (protocol.Snapshot)(nil) +// protocolStateWrapper just wraps the protocol.State and returns a ProtocolSnapshotExecutionSubset +// from the AtBlockID method instead of the protocol.Snapshot interface. type protocolStateWrapper struct { protocol.State } -func (p protocolStateWrapper) AtBlockID(blockID flow.Identifier) flow.SnapshotSubset { +// protocolStateWrapper implements `EntropyProviderPerBlock` +var _ flow.ProtocolSnapshotExecutionSubsetProvider = (*protocolStateWrapper)(nil) + +func (p protocolStateWrapper) AtBlockID(blockID flow.Identifier) flow.ProtocolSnapshotExecutionSubset { return p.State.AtBlockID(blockID) } -// NewProtocolStateWrapper wraps a protocol.State input as an `EntropyProviderPerBlock` -func NewProtocolStateWrapper(s protocol.State) flow.ProtocolStateSnapshotProvider { +// NewProtocolStateWrapper wraps the protocol.State input so that the AtBlockID method returns a +// ProtocolSnapshotExecutionSubset instead of the protocol.Snapshot interface. +// This is used in the FVM for execution. +func NewProtocolStateWrapper(s protocol.State) flow.ProtocolSnapshotExecutionSubsetProvider { return protocolStateWrapper{s} } diff --git a/engine/execution/testutil/fixtures.go b/engine/execution/testutil/fixtures.go index c93b251dc13..ffb44274488 100644 --- a/engine/execution/testutil/fixtures.go +++ b/engine/execution/testutil/fixtures.go @@ -656,7 +656,7 @@ func EntropyProviderFixture(source []byte) environment.EntropyProvider { // supports AtBlockID to return a snapshot mock. // The snapshot mock only supports RandomSource(). // If input is nil, a random source fixture is generated. -func ProtocolStateWithSourceFixture(source []byte) flow.ProtocolStateSnapshotProvider { +func ProtocolStateWithSourceFixture(source []byte) flow.ProtocolSnapshotExecutionSubsetProvider { if source == nil { source = unittest.SignatureFixture() } @@ -670,7 +670,7 @@ func ProtocolStateWithSourceFixture(source []byte) flow.ProtocolStateSnapshotPro } provider := mockProtocolStateSnapshotProvider{ - snapshotFunc: func(blockID flow.Identifier) flow.SnapshotSubset { + snapshotFunc: func(blockID flow.Identifier) flow.ProtocolSnapshotExecutionSubset { return snapshot }, } @@ -678,10 +678,10 @@ func ProtocolStateWithSourceFixture(source []byte) flow.ProtocolStateSnapshotPro } type mockProtocolStateSnapshotProvider struct { - snapshotFunc func(blockID flow.Identifier) flow.SnapshotSubset + snapshotFunc func(blockID flow.Identifier) flow.ProtocolSnapshotExecutionSubset } -func (m mockProtocolStateSnapshotProvider) AtBlockID(blockID flow.Identifier) flow.SnapshotSubset { +func (m mockProtocolStateSnapshotProvider) AtBlockID(blockID flow.Identifier) flow.ProtocolSnapshotExecutionSubset { return m.snapshotFunc(blockID) } @@ -704,4 +704,4 @@ func (m mockSnapshotSubset) VersionBeacon() (*flow.SealedVersionBeacon, error) { return m.versionBeaconFunc() } -var _ flow.SnapshotSubset = (*mockSnapshotSubset)(nil) +var _ flow.ProtocolSnapshotExecutionSubset = (*mockSnapshotSubset)(nil) diff --git a/fvm/context.go b/fvm/context.go index 4b9f5174c45..5f25616800b 100644 --- a/fvm/context.go +++ b/fvm/context.go @@ -405,14 +405,9 @@ func WithExecutionVersionProvider(provider environment.ExecutionVersionProvider) // WithProtocolStateSnapshot sets all the necessary components from a subset of the protocol state // to the virtual machine context. -func WithProtocolStateSnapshot(snapshot flow.SnapshotSubset) Option { - return func(ctx Context) Context { - // `protocol.SnapshotSubset` implements `EntropyProvider` interface - // Note that `SnapshotSubset` possible errors for RandomSource() are: - // - storage.ErrNotFound if the QC is unknown. - // - state.ErrUnknownSnapshotReference if the snapshot reference block is unknown - // However, at this stage, snapshot reference block should be known and the QC should also be known, - // so no error is expected in normal operations, as required by `EntropyProvider`. +func WithProtocolStateSnapshot(snapshot flow.ProtocolSnapshotExecutionSubset) Option { + return func(ctx Context) Context { + ctx = WithEntropyProvider(snapshot)(ctx) ctx = WithExecutionVersionProvider(environment.NewVersionBeaconExecutionVersionProvider(snapshot.VersionBeacon))(ctx) diff --git a/model/flow/snapshot_subset.go b/model/flow/snapshot_subset.go index 31c31322dd1..613c82f16d5 100644 --- a/model/flow/snapshot_subset.go +++ b/model/flow/snapshot_subset.go @@ -1,14 +1,38 @@ package flow -// SnapshotSubset is a subset of the protocol state snapshot that is needed by the FVM +// ProtocolSnapshotExecutionSubset is a subset of the protocol state snapshot that is needed by the FVM // for execution. -type SnapshotSubset interface { +type ProtocolSnapshotExecutionSubset interface { + // RandomSource provides a source of entropy that can be + // expanded into randoms (using a pseudo-random generator). + // The returned slice should have at least 128 bits of entropy. + // The function doesn't error in normal operations, any + // error should be treated as an exception. + // + // `protocol.ProtocolSnapshotExecutionSubset` implements `EntropyProvider` interface + // Note that `ProtocolSnapshotExecutionSubset` possible errors for RandomSource() are: + // - storage.ErrNotFound if the QC is unknown. + // - state.ErrUnknownSnapshotReference if the snapshot reference block is unknown + // However, at this stage, snapshot reference block should be known and the QC should also be known, + // so no error is expected in normal operations, as required by `EntropyProvider`. RandomSource() ([]byte, error) + + // VersionBeacon returns the latest sealed version beacon. + // If no version beacon has been sealed so far during the current spork, returns nil. + // The latest VersionBeacon is only updated for finalized blocks. This means that, when + // querying an un-finalized fork, `VersionBeacon` will have the same value as querying + // the snapshot for the latest finalized block, even if a newer version beacon is included + // in a seal along the un-finalized fork. + // + // The SealedVersionBeacon must contain at least one entry. The first entry is for a past block height. + // The remaining entries are for all future block heights. Future version boundaries + // can be removed, in which case the emitted event will not contain the removed version + // boundaries. VersionBeacon() (*SealedVersionBeacon, error) } -// ProtocolStateSnapshotProvider is an interface that provides a subset of the protocol state +// ProtocolSnapshotExecutionSubsetProvider is an interface that provides a subset of the protocol state // at a specific block. -type ProtocolStateSnapshotProvider interface { - AtBlockID(blockID Identifier) SnapshotSubset +type ProtocolSnapshotExecutionSubsetProvider interface { + AtBlockID(blockID Identifier) ProtocolSnapshotExecutionSubset } diff --git a/model/verification/convert/convert.go b/model/verification/convert/convert.go index 3b4a26a45d1..109f69667de 100644 --- a/model/verification/convert/convert.go +++ b/model/verification/convert/convert.go @@ -11,7 +11,7 @@ func FromChunkDataPack( chunk *flow.Chunk, chunkDataPack *flow.ChunkDataPack, header *flow.Header, - snapshot flow.SnapshotSubset, + snapshot flow.ProtocolSnapshotExecutionSubset, result *flow.ExecutionResult, ) (*verification.VerifiableChunkData, error) { diff --git a/model/verification/verifiableChunkData.go b/model/verification/verifiableChunkData.go index 7e3d32a8cee..510c207881b 100644 --- a/model/verification/verifiableChunkData.go +++ b/model/verification/verifiableChunkData.go @@ -7,12 +7,12 @@ import ( // VerifiableChunkData represents a ready-to-verify chunk // It contains the execution result as well as all resources needed to verify it type VerifiableChunkData struct { - IsSystemChunk bool // indicates whether this is a system chunk - Chunk *flow.Chunk // the chunk to be verified - Header *flow.Header // BlockHeader that contains this chunk - Snapshot flow.SnapshotSubset // state snapshot at the chunk's block - Result *flow.ExecutionResult // execution result of this block - ChunkDataPack *flow.ChunkDataPack // chunk data package needed to verify this chunk - EndState flow.StateCommitment // state commitment at the end of this chunk - TransactionOffset uint32 // index of the first transaction in a chunk within a block + IsSystemChunk bool // indicates whether this is a system chunk + Chunk *flow.Chunk // the chunk to be verified + Header *flow.Header // BlockHeader that contains this chunk + Snapshot flow.ProtocolSnapshotExecutionSubset // state snapshot at the chunk's block + Result *flow.ExecutionResult // execution result of this block + ChunkDataPack *flow.ChunkDataPack // chunk data package needed to verify this chunk + EndState flow.StateCommitment // state commitment at the end of this chunk + TransactionOffset uint32 // index of the first transaction in a chunk within a block } diff --git a/module/execution/scripts.go b/module/execution/scripts.go index 7f8047e07d4..968de301f58 100644 --- a/module/execution/scripts.go +++ b/module/execution/scripts.go @@ -75,7 +75,7 @@ func NewScripts( log zerolog.Logger, metrics module.ExecutionMetrics, chainID flow.ChainID, - protocolSnapshotProvider flow.ProtocolStateSnapshotProvider, + protocolSnapshotProvider flow.ProtocolSnapshotExecutionSubsetProvider, header storage.Headers, registerAtHeight RegisterAtHeight, queryConf query.QueryConfig,