Skip to content

Commit ca65c0f

Browse files
authored
Merge branch 'master' into custom-runtime-pool-with-given-config
2 parents 99e6f4f + dcb617f commit ca65c0f

File tree

150 files changed

+5459
-3636
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+5459
-3636
lines changed

.github/workflows/bench.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ jobs:
2020
benchstat:
2121
name: Performance regression check
2222
runs-on: ubuntu-latest
23+
# Check if the event is not triggered by a fork
24+
# peter-evans/find-comment@v1 does not work on forks.
25+
# see https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#restrictions-on-repository-forks for details.
26+
# Ideally we would like to still run the benchmark on forks, but we can't do that with the current setup.
27+
if: github.event.pull_request.head.repo.full_name == github.repository
2328
continue-on-error: true
2429
steps:
2530
- name: Set benchmark repetitions

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ generate-mocks: install-mock-generators
161161
mockery --name '.*' --dir=engine/execution/computation/computer --case=underscore --output="./engine/execution/computation/computer/mock" --outpkg="mock"
162162
mockery --name '.*' --dir=engine/execution/state --case=underscore --output="./engine/execution/state/mock" --outpkg="mock"
163163
mockery --name '.*' --dir=engine/collection --case=underscore --output="./engine/collection/mock" --outpkg="mock"
164+
mockery --name 'complianceCore' --dir=engine/common/follower --exported --case=underscore --output="./engine/common/follower/mock" --outpkg="mock"
164165
mockery --name '.*' --dir=engine/common/follower/cache --case=underscore --output="./engine/common/follower/cache/mock" --outpkg="mock"
165166
mockery --name '.*' --dir=engine/consensus --case=underscore --output="./engine/consensus/mock" --outpkg="mock"
166167
mockery --name '.*' --dir=engine/consensus/approvals --case=underscore --output="./engine/consensus/approvals/mock" --outpkg="mock"

cmd/access/node_builder/access_node_builder.go

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/onflow/flow-go/consensus"
2929
"github.com/onflow/flow-go/consensus/hotstuff"
3030
"github.com/onflow/flow-go/consensus/hotstuff/committees"
31+
"github.com/onflow/flow-go/consensus/hotstuff/notifications"
3132
consensuspubsub "github.com/onflow/flow-go/consensus/hotstuff/notifications/pubsub"
3233
"github.com/onflow/flow-go/consensus/hotstuff/signature"
3334
hotstuffvalidator "github.com/onflow/flow-go/consensus/hotstuff/validator"
@@ -39,17 +40,15 @@ import (
3940
"github.com/onflow/flow-go/engine/access/rpc"
4041
"github.com/onflow/flow-go/engine/access/rpc/backend"
4142
"github.com/onflow/flow-go/engine/access/state_stream"
42-
"github.com/onflow/flow-go/engine/common/follower"
4343
followereng "github.com/onflow/flow-go/engine/common/follower"
4444
"github.com/onflow/flow-go/engine/common/requester"
4545
synceng "github.com/onflow/flow-go/engine/common/synchronization"
4646
"github.com/onflow/flow-go/model/flow"
4747
"github.com/onflow/flow-go/model/flow/filter"
4848
"github.com/onflow/flow-go/module"
4949
"github.com/onflow/flow-go/module/blobs"
50-
"github.com/onflow/flow-go/module/buffer"
5150
"github.com/onflow/flow-go/module/chainsync"
52-
"github.com/onflow/flow-go/module/compliance"
51+
modulecompliance "github.com/onflow/flow-go/module/compliance"
5352
"github.com/onflow/flow-go/module/executiondatasync/execution_data"
5453
finalizer "github.com/onflow/flow-go/module/finalizer/consensus"
5554
"github.com/onflow/flow-go/module/id"
@@ -69,6 +68,7 @@ import (
6968
"github.com/onflow/flow-go/network/p2p/dht"
7069
"github.com/onflow/flow-go/network/p2p/middleware"
7170
"github.com/onflow/flow-go/network/p2p/p2pbuilder"
71+
"github.com/onflow/flow-go/network/p2p/p2pbuilder/inspector"
7272
"github.com/onflow/flow-go/network/p2p/subscription"
7373
"github.com/onflow/flow-go/network/p2p/tracer"
7474
"github.com/onflow/flow-go/network/p2p/translator"
@@ -223,7 +223,7 @@ type FlowAccessNodeBuilder struct {
223223
// engines
224224
IngestEng *ingestion.Engine
225225
RequestEng *requester.Engine
226-
FollowerEng *followereng.Engine
226+
FollowerEng *followereng.ComplianceEngine
227227
SyncEng *synceng.Engine
228228
StateStreamEng *state_stream.Engine
229229
}
@@ -237,7 +237,15 @@ func (builder *FlowAccessNodeBuilder) buildFollowerState() *FlowAccessNodeBuilde
237237
return fmt.Errorf("only implementations of type badger.State are currently supported but read-only state has type %T", node.State)
238238
}
239239

240-
followerState, err := badgerState.NewFollowerState(state, node.Storage.Index, node.Storage.Payloads, node.Tracer, node.ProtocolEvents, blocktimer.DefaultBlockTimer)
240+
followerState, err := badgerState.NewFollowerState(
241+
node.Logger,
242+
node.Tracer,
243+
node.ProtocolEvents,
244+
state,
245+
node.Storage.Index,
246+
node.Storage.Payloads,
247+
blocktimer.DefaultBlockTimer,
248+
)
241249
builder.FollowerState = followerState
242250

243251
return err
@@ -319,31 +327,39 @@ func (builder *FlowAccessNodeBuilder) buildFollowerCore() *FlowAccessNodeBuilder
319327

320328
func (builder *FlowAccessNodeBuilder) buildFollowerEngine() *FlowAccessNodeBuilder {
321329
builder.Component("follower engine", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
322-
// initialize cleaner for DB
323-
cleaner := bstorage.NewCleaner(node.Logger, node.DB, builder.Metrics.CleanCollector, flow.DefaultValueLogGCFrequency)
324-
conCache := buffer.NewPendingBlocks()
330+
var heroCacheCollector module.HeroCacheMetrics = metrics.NewNoopCollector()
331+
if node.HeroCacheMetricsEnable {
332+
heroCacheCollector = metrics.FollowerCacheMetrics(node.MetricsRegisterer)
333+
}
325334

326-
followerEng, err := follower.New(
335+
core, err := followereng.NewComplianceCore(
327336
node.Logger,
328-
node.Network,
329-
node.Me,
330-
node.Metrics.Engine,
331337
node.Metrics.Mempool,
332-
cleaner,
333-
node.Storage.Headers,
334-
node.Storage.Payloads,
338+
heroCacheCollector,
339+
builder.FinalizationDistributor,
335340
builder.FollowerState,
336-
conCache,
337341
builder.FollowerCore,
338342
builder.Validator,
339343
builder.SyncCore,
340344
node.Tracer,
341-
follower.WithComplianceOptions(compliance.WithSkipNewProposalsThreshold(builder.ComplianceConfig.SkipNewProposalsThreshold)),
345+
)
346+
if err != nil {
347+
return nil, fmt.Errorf("could not create follower core: %w", err)
348+
}
349+
350+
builder.FollowerEng, err = followereng.NewComplianceLayer(
351+
node.Logger,
352+
node.Network,
353+
node.Me,
354+
node.Metrics.Engine,
355+
node.Storage.Headers,
356+
builder.Finalized,
357+
core,
358+
followereng.WithComplianceConfigOpt(modulecompliance.WithSkipNewProposalsThreshold(node.ComplianceConfig.SkipNewProposalsThreshold)),
342359
)
343360
if err != nil {
344361
return nil, fmt.Errorf("could not create follower engine: %w", err)
345362
}
346-
builder.FollowerEng = followerEng
347363

348364
return builder.FollowerEng, nil
349365
})
@@ -560,10 +576,12 @@ func (builder *FlowAccessNodeBuilder) BuildExecutionDataRequester() *FlowAccessN
560576
}
561577

562578
func FlowAccessNode(nodeBuilder *cmd.FlowNodeBuilder) *FlowAccessNodeBuilder {
579+
dist := consensuspubsub.NewFinalizationDistributor()
580+
dist.AddConsumer(notifications.NewSlashingViolationsConsumer(nodeBuilder.Logger))
563581
return &FlowAccessNodeBuilder{
564582
AccessNodeConfig: DefaultAccessNodeConfig(),
565583
FlowNodeBuilder: nodeBuilder,
566-
FinalizationDistributor: consensuspubsub.NewFinalizationDistributor(),
584+
FinalizationDistributor: dist,
567585
}
568586
}
569587

@@ -1011,7 +1029,7 @@ func (builder *FlowAccessNodeBuilder) enqueuePublicNetworkInit() {
10111029
}).
10121030
Component("public libp2p node", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
10131031

1014-
libP2PFactory := builder.initLibP2PFactory(builder.NodeConfig.NetworkKey, builder.PublicNetworkConfig.BindAddress, builder.PublicNetworkConfig.Metrics)
1032+
libP2PFactory := builder.initPublicLibP2PFactory(builder.NodeConfig.NetworkKey, builder.PublicNetworkConfig.BindAddress, builder.PublicNetworkConfig.Metrics)
10151033

10161034
var err error
10171035
libp2pNode, err = libP2PFactory()
@@ -1057,15 +1075,15 @@ func (builder *FlowAccessNodeBuilder) enqueuePublicNetworkInit() {
10571075
})
10581076
}
10591077

1060-
// initLibP2PFactory creates the LibP2P factory function for the given node ID and network key.
1078+
// initPublicLibP2PFactory creates the LibP2P factory function for the given node ID and network key.
10611079
// The factory function is later passed into the initMiddleware function to eventually instantiate the p2p.LibP2PNode instance
10621080
// The LibP2P host is created with the following options:
10631081
// - DHT as server
10641082
// - The address from the node config or the specified bind address as the listen address
10651083
// - The passed in private key as the libp2p key
10661084
// - No connection gater
10671085
// - Default Flow libp2p pubsub options
1068-
func (builder *FlowAccessNodeBuilder) initLibP2PFactory(networkKey crypto.PrivateKey, bindAddress string, networkMetrics module.LibP2PMetrics) p2p.LibP2PFactoryFunc {
1086+
func (builder *FlowAccessNodeBuilder) initPublicLibP2PFactory(networkKey crypto.PrivateKey, bindAddress string, networkMetrics module.LibP2PMetrics) p2p.LibP2PFactoryFunc {
10691087
return func() (p2p.LibP2PNode, error) {
10701088
connManager, err := connection.NewConnManager(builder.Logger, networkMetrics, builder.ConnectionManagerConfig)
10711089
if err != nil {
@@ -1078,6 +1096,16 @@ func (builder *FlowAccessNodeBuilder) initLibP2PFactory(networkKey crypto.Privat
10781096
builder.IdentityProvider,
10791097
builder.GossipSubConfig.LocalMeshLogInterval)
10801098

1099+
// setup RPC inspectors
1100+
rpcInspectorBuilder := inspector.NewGossipSubInspectorBuilder(builder.Logger, builder.SporkID, builder.GossipSubRPCInspectorsConfig, builder.GossipSubInspectorNotifDistributor)
1101+
rpcInspectors, err := rpcInspectorBuilder.
1102+
SetPublicNetwork(p2p.PublicNetworkEnabled).
1103+
SetMetrics(builder.Metrics.Network, builder.MetricsRegisterer).
1104+
SetMetricsEnabled(builder.MetricsEnabled).Build()
1105+
if err != nil {
1106+
return nil, fmt.Errorf("failed to create gossipsub rpc inspectors: %w", err)
1107+
}
1108+
10811109
libp2pNode, err := p2pbuilder.NewNodeBuilder(
10821110
builder.Logger,
10831111
networkMetrics,
@@ -1107,6 +1135,7 @@ func (builder *FlowAccessNodeBuilder) initLibP2PFactory(networkKey crypto.Privat
11071135
SetStreamCreationRetryInterval(builder.UnicastCreateStreamRetryDelay).
11081136
SetGossipSubTracer(meshTracer).
11091137
SetGossipSubScoreTracerInterval(builder.GossipSubConfig.ScoreTracerInterval).
1138+
SetGossipSubRPCInspectors(rpcInspectors...).
11101139
Build()
11111140

11121141
if err != nil {

cmd/bootstrap/run/execution_state.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ func GenerateServiceAccountPrivateKey(seed []byte) (flow.AccountPrivateKey, erro
3232
}, nil
3333
}
3434

35-
// NOTE: this is now unused and should become part of another tool.
3635
func GenerateExecutionState(
3736
dbDir string,
3837
accountKey flow.AccountPublicKey,

cmd/collection/main.go

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/onflow/flow-go/consensus"
2121
"github.com/onflow/flow-go/consensus/hotstuff"
2222
"github.com/onflow/flow-go/consensus/hotstuff/committees"
23+
"github.com/onflow/flow-go/consensus/hotstuff/notifications"
2324
"github.com/onflow/flow-go/consensus/hotstuff/notifications/pubsub"
2425
"github.com/onflow/flow-go/consensus/hotstuff/pacemaker/timeout"
2526
hotsignature "github.com/onflow/flow-go/consensus/hotstuff/signature"
@@ -37,7 +38,6 @@ import (
3738
"github.com/onflow/flow-go/model/flow"
3839
"github.com/onflow/flow-go/model/flow/filter"
3940
"github.com/onflow/flow-go/module"
40-
"github.com/onflow/flow-go/module/buffer"
4141
builder "github.com/onflow/flow-go/module/builder/collection"
4242
"github.com/onflow/flow-go/module/chainsync"
4343
"github.com/onflow/flow-go/module/epochs"
@@ -50,7 +50,6 @@ import (
5050
badgerState "github.com/onflow/flow-go/state/protocol/badger"
5151
"github.com/onflow/flow-go/state/protocol/blocktimer"
5252
"github.com/onflow/flow-go/state/protocol/events/gadgets"
53-
storagekv "github.com/onflow/flow-go/storage/badger"
5453
)
5554

5655
func main() {
@@ -80,15 +79,14 @@ func main() {
8079
clusterComplianceConfig modulecompliance.Config
8180

8281
pools *epochpool.TransactionPools // epoch-scoped transaction pools
83-
followerBuffer *buffer.PendingBlocks // pending block cache for follower
8482
finalizationDistributor *pubsub.FinalizationDistributor
8583
finalizedHeader *consync.FinalizedHeaderCache
8684

8785
push *pusher.Engine
8886
ing *ingest.Engine
8987
mainChainSyncCore *chainsync.Core
9088
followerCore *hotstuff.FollowerLoop // follower hotstuff logic
91-
followerEng *followereng.Engine
89+
followerEng *followereng.ComplianceEngine
9290
colMetrics module.CollectionMetrics
9391
err error
9492

@@ -173,14 +171,27 @@ func main() {
173171

174172
nodeBuilder.
175173
PreInit(cmd.DynamicStartPreInit).
174+
Module("finalization distributor", func(node *cmd.NodeConfig) error {
175+
finalizationDistributor = pubsub.NewFinalizationDistributor()
176+
finalizationDistributor.AddConsumer(notifications.NewSlashingViolationsConsumer(node.Logger))
177+
return nil
178+
}).
176179
Module("mutable follower state", func(node *cmd.NodeConfig) error {
177180
// For now, we only support state implementations from package badger.
178181
// If we ever support different implementations, the following can be replaced by a type-aware factory
179182
state, ok := node.State.(*badgerState.State)
180183
if !ok {
181184
return fmt.Errorf("only implementations of type badger.State are currently supported but read-only state has type %T", node.State)
182185
}
183-
followerState, err = badgerState.NewFollowerState(state, node.Storage.Index, node.Storage.Payloads, node.Tracer, node.ProtocolEvents, blocktimer.DefaultBlockTimer)
186+
followerState, err = badgerState.NewFollowerState(
187+
node.Logger,
188+
node.Tracer,
189+
node.ProtocolEvents,
190+
state,
191+
node.Storage.Index,
192+
node.Storage.Payloads,
193+
blocktimer.DefaultBlockTimer,
194+
)
184195
return err
185196
}).
186197
Module("transactions mempool", func(node *cmd.NodeConfig) error {
@@ -199,10 +210,6 @@ func main() {
199210
err := node.Metrics.Mempool.Register(metrics.ResourceTransaction, pools.CombinedSize)
200211
return err
201212
}).
202-
Module("pending block cache", func(node *cmd.NodeConfig) error {
203-
followerBuffer = buffer.NewPendingBlocks()
204-
return nil
205-
}).
206213
Module("metrics", func(node *cmd.NodeConfig) error {
207214
colMetrics = metrics.NewCollectionCollector(node.Tracer)
208215
return nil
@@ -230,7 +237,7 @@ func main() {
230237
return nil
231238
}).
232239
Component("machine account config validator", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
233-
//@TODO use fallback logic for flowClient similar to DKG/QC contract clients
240+
// @TODO use fallback logic for flowClient similar to DKG/QC contract clients
234241
flowClient, err := common.FlowClient(flowClientConfigs[0])
235242
if err != nil {
236243
return nil, fmt.Errorf("failed to get flow client connection option for access node (0): %s %w", flowClientConfigs[0].AccessAddress, err)
@@ -251,6 +258,14 @@ func main() {
251258

252259
return validator, err
253260
}).
261+
Component("finalized snapshot", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
262+
finalizedHeader, err = consync.NewFinalizedHeaderCache(node.Logger, node.State, finalizationDistributor)
263+
if err != nil {
264+
return nil, fmt.Errorf("could not create finalized snapshot cache: %w", err)
265+
}
266+
267+
return finalizedHeader, nil
268+
}).
254269
Component("consensus committee", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
255270
// initialize consensus committee's membership state
256271
// This committee state is for the HotStuff follower, which follows the MAIN CONSENSUS Committee
@@ -270,7 +285,6 @@ func main() {
270285
packer := hotsignature.NewConsensusSigDataPacker(mainConsensusCommittee)
271286
// initialize the verifier for the protocol consensus
272287
verifier := verification.NewCombinedVerifier(mainConsensusCommittee, packer)
273-
finalizationDistributor = pubsub.NewFinalizationDistributor()
274288
// creates a consensus follower with noop consumer as the notifier
275289
followerCore, err = consensus.NewFollower(
276290
node.Logger,
@@ -290,45 +304,47 @@ func main() {
290304
return followerCore, nil
291305
}).
292306
Component("follower engine", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
293-
// initialize cleaner for DB
294-
cleaner := storagekv.NewCleaner(node.Logger, node.DB, node.Metrics.CleanCollector, flow.DefaultValueLogGCFrequency)
295-
296307
packer := hotsignature.NewConsensusSigDataPacker(mainConsensusCommittee)
297308
// initialize the verifier for the protocol consensus
298309
verifier := verification.NewCombinedVerifier(mainConsensusCommittee, packer)
299310

300311
validator := validator.New(mainConsensusCommittee, verifier)
301312

302-
followerEng, err = followereng.New(
313+
var heroCacheCollector module.HeroCacheMetrics = metrics.NewNoopCollector()
314+
if node.HeroCacheMetricsEnable {
315+
heroCacheCollector = metrics.FollowerCacheMetrics(node.MetricsRegisterer)
316+
}
317+
318+
core, err := followereng.NewComplianceCore(
303319
node.Logger,
304-
node.Network,
305-
node.Me,
306-
node.Metrics.Engine,
307320
node.Metrics.Mempool,
308-
cleaner,
309-
node.Storage.Headers,
310-
node.Storage.Payloads,
321+
heroCacheCollector,
322+
finalizationDistributor,
311323
followerState,
312-
followerBuffer,
313324
followerCore,
314325
validator,
315326
mainChainSyncCore,
316327
node.Tracer,
317-
followereng.WithComplianceOptions(modulecompliance.WithSkipNewProposalsThreshold(node.ComplianceConfig.SkipNewProposalsThreshold)),
318328
)
319329
if err != nil {
320-
return nil, fmt.Errorf("could not create follower engine: %w", err)
330+
return nil, fmt.Errorf("could not create follower core: %w", err)
321331
}
322332

323-
return followerEng, nil
324-
}).
325-
Component("finalized snapshot", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
326-
finalizedHeader, err = consync.NewFinalizedHeaderCache(node.Logger, node.State, finalizationDistributor)
333+
followerEng, err = followereng.NewComplianceLayer(
334+
node.Logger,
335+
node.Network,
336+
node.Me,
337+
node.Metrics.Engine,
338+
node.Storage.Headers,
339+
finalizedHeader.Get(),
340+
core,
341+
followereng.WithComplianceConfigOpt(modulecompliance.WithSkipNewProposalsThreshold(node.ComplianceConfig.SkipNewProposalsThreshold)),
342+
)
327343
if err != nil {
328-
return nil, fmt.Errorf("could not create finalized snapshot cache: %w", err)
344+
return nil, fmt.Errorf("could not create follower engine: %w", err)
329345
}
330346

331-
return finalizedHeader, nil
347+
return followerEng, nil
332348
}).
333349
Component("main chain sync engine", func(node *cmd.NodeConfig) (module.ReadyDoneAware, error) {
334350

0 commit comments

Comments
 (0)