github.com/koko1123/flow-go-1@v0.29.6/engine/collection/epochmgr/factories/hotstuff.go (about) 1 package factories 2 3 import ( 4 "fmt" 5 6 "github.com/dgraph-io/badger/v3" 7 "github.com/rs/zerolog" 8 9 "github.com/koko1123/flow-go-1/consensus" 10 "github.com/koko1123/flow-go-1/consensus/hotstuff" 11 "github.com/koko1123/flow-go-1/consensus/hotstuff/blockproducer" 12 "github.com/koko1123/flow-go-1/consensus/hotstuff/committees" 13 "github.com/koko1123/flow-go-1/consensus/hotstuff/notifications" 14 "github.com/koko1123/flow-go-1/consensus/hotstuff/notifications/pubsub" 15 "github.com/koko1123/flow-go-1/consensus/hotstuff/persister" 16 validatorImpl "github.com/koko1123/flow-go-1/consensus/hotstuff/validator" 17 "github.com/koko1123/flow-go-1/consensus/hotstuff/verification" 18 "github.com/koko1123/flow-go-1/consensus/hotstuff/votecollector" 19 recovery "github.com/koko1123/flow-go-1/consensus/recovery/cluster" 20 "github.com/koko1123/flow-go-1/model/flow" 21 "github.com/koko1123/flow-go-1/module" 22 hotmetrics "github.com/koko1123/flow-go-1/module/metrics/hotstuff" 23 "github.com/koko1123/flow-go-1/state/cluster" 24 "github.com/koko1123/flow-go-1/state/protocol" 25 "github.com/koko1123/flow-go-1/storage" 26 ) 27 28 type HotStuffMetricsFunc func(chainID flow.ChainID) module.HotstuffMetrics 29 30 type HotStuffFactory struct { 31 log zerolog.Logger 32 me module.Local 33 db *badger.DB 34 protoState protocol.State 35 createMetrics HotStuffMetricsFunc 36 opts []consensus.Option 37 } 38 39 func NewHotStuffFactory( 40 log zerolog.Logger, 41 me module.Local, 42 db *badger.DB, 43 protoState protocol.State, 44 createMetrics HotStuffMetricsFunc, 45 opts ...consensus.Option, 46 ) (*HotStuffFactory, error) { 47 48 factory := &HotStuffFactory{ 49 log: log, 50 me: me, 51 db: db, 52 protoState: protoState, 53 createMetrics: createMetrics, 54 opts: opts, 55 } 56 return factory, nil 57 } 58 59 func (f *HotStuffFactory) CreateModules( 60 epoch protocol.Epoch, 61 cluster protocol.Cluster, 62 clusterState cluster.State, 63 headers storage.Headers, 64 payloads storage.ClusterPayloads, 65 updater module.Finalizer, 66 ) (*consensus.HotstuffModules, module.HotstuffMetrics, error) { 67 68 // setup metrics/logging with the new chain ID 69 metrics := f.createMetrics(cluster.ChainID()) 70 notifier := pubsub.NewDistributor() 71 finalizationDistributor := pubsub.NewFinalizationDistributor() 72 notifier.AddConsumer(finalizationDistributor) 73 notifier.AddConsumer(notifications.NewLogConsumer(f.log)) 74 notifier.AddConsumer(hotmetrics.NewMetricsConsumer(metrics)) 75 notifier.AddConsumer(notifications.NewTelemetryConsumer(f.log, cluster.ChainID())) 76 77 var ( 78 err error 79 committee hotstuff.Committee 80 ) 81 committee, err = committees.NewClusterCommittee(f.protoState, payloads, cluster, epoch, f.me.NodeID()) 82 if err != nil { 83 return nil, nil, fmt.Errorf("could not create cluster committee: %w", err) 84 } 85 committee = committees.NewMetricsWrapper(committee, metrics) // wrapper for measuring time spent determining consensus committee relations 86 87 // create a signing provider 88 var signer hotstuff.Signer = verification.NewStakingSigner(f.me) 89 signer = verification.NewMetricsWrapper(signer, metrics) // wrapper for measuring time spent with crypto-related operations 90 91 finalizedBlock, err := clusterState.Final().Head() 92 if err != nil { 93 return nil, nil, fmt.Errorf("could not get cluster finalized block: %w", err) 94 } 95 96 forks, err := consensus.NewForks( 97 finalizedBlock, 98 headers, 99 updater, 100 notifier, 101 cluster.RootBlock().Header, 102 cluster.RootQC(), 103 ) 104 if err != nil { 105 return nil, nil, err 106 } 107 108 qcDistributor := pubsub.NewQCCreatedDistributor() 109 110 verifier := verification.NewStakingVerifier() 111 validator := validatorImpl.NewMetricsWrapper(validatorImpl.New(committee, forks, verifier), metrics) 112 voteProcessorFactory := votecollector.NewStakingVoteProcessorFactory(committee, qcDistributor.OnQcConstructedFromVotes) 113 aggregator, err := consensus.NewVoteAggregator( 114 f.log, 115 // since we don't want to aggregate votes for finalized view, 116 // the lowest retained view starts with the next view of the last finalized view. 117 finalizedBlock.View+1, 118 notifier, 119 voteProcessorFactory, 120 finalizationDistributor, 121 ) 122 if err != nil { 123 return nil, nil, err 124 } 125 126 return &consensus.HotstuffModules{ 127 Forks: forks, 128 Validator: validator, 129 Notifier: notifier, 130 Committee: committee, 131 Signer: signer, 132 Persist: persister.New(f.db, cluster.ChainID()), 133 Aggregator: aggregator, 134 QCCreatedDistributor: qcDistributor, 135 FinalizationDistributor: finalizationDistributor, 136 }, metrics, nil 137 } 138 139 func (f *HotStuffFactory) Create( 140 clusterState cluster.State, 141 metrics module.HotstuffMetrics, 142 builder module.Builder, 143 headers storage.Headers, 144 communicator hotstuff.Communicator, 145 hotstuffModules *consensus.HotstuffModules, 146 ) (module.HotStuff, error) { 147 148 // setup metrics/logging with the new chain ID 149 builder = blockproducer.NewMetricsWrapper(builder, metrics) // wrapper for measuring time spent building block payload component 150 151 finalizedBlock, pendingBlocks, err := recovery.FindLatest(clusterState, headers) 152 if err != nil { 153 return nil, err 154 } 155 156 participant, err := consensus.NewParticipant( 157 f.log, 158 metrics, 159 builder, 160 communicator, 161 finalizedBlock, 162 pendingBlocks, 163 hotstuffModules, 164 f.opts..., 165 ) 166 return participant, err 167 }