ceremonyclient/node/consensus/app/factory.go
Cassandra Heart ce4f77b140
v2.1.0.19 (#515)
* v2.1.0.19

* enhanced error logging, fix seniority marker join blocker, fix sync message size limit defaults

* resolve signature failure

* additional error logging for merge-related signatures

* fix: one-shot sync message size, app shard TC signature size, collector/hotstuff race condition, expired joins blocking new joins due to pruning disable

* remove compat with old 2.0.0 blossomsub

* fix: resolve abandoned prover joins

* reload prover registry

* fix stale worker proposal edge

* add full sanity check on join before submitting to identify bug

* resolve non-fallthrough condition that should be fallthrough

* fix: resolve rare SIGFPE, fix orphan expired joins blocking workers from reallocating

* add reconnect fallback if no peers are found with variable reconnect time (#511)

Co-authored-by: Tyler Sturos <55340199+tjsturos@users.noreply.github.com>

* update base peer count to 1 (#513)

* fix: expired prover join frames, starting port ranges, proposer getting stuck, and seniority on joins

* fix: panic on shutdown, libp2p discovery picking inaccessible peers, coverage event check not in shutdown logic, amend app shard worker behavior to mirror global for prover root reconciliation

* fix: shutdown scenario quirks, reload hanging

* fix: do not bailout early on shutdown of coverage check

* fix: force registry refresh on worker waiting for registration

* add more logging to wait for prover

* fix: worker manager refreshes the filter on allocation, snapshots blocking close on shutdown

* tweak: force shutdown after five seconds for app worker

* fix: don't loop when shutting down

* fix: slight reordering, also added named workers to trace hanging shutdowns

* use deterministic key for peer id of workers to stop flagging workers as sybil attacks

* fix: remove pubsub stop from app consensus engine as it shouldn't manage pubsub lifecycle, integrate shutdown context to PerformSync to prevent stuck syncs from halting respawn

* fix: blossomsub pubsub interface does not properly track subscription status

* fix: subscribe order to avoid nil panic

* switch from dnsaddr to dns4

* add missing quic-v1

* additional logging to isolate respawn quirks

* fix: dnsaddr -> dns4 for blossomsub

* sort-of fix: apply sledgehammer to restart logic

* fix: restore proper respawn logic, fix frozen hypergraph post respawn, unsubscribe from bitmask previously missing

---------

Co-authored-by: winged-pegasus <55340199+winged-pegasus@users.noreply.github.com>
Co-authored-by: Tyler Sturos <55340199+tjsturos@users.noreply.github.com>
2026-02-26 04:20:13 -06:00

204 lines
6.5 KiB
Go

package app
import (
"github.com/pkg/errors"
"go.uber.org/zap"
"google.golang.org/grpc"
"source.quilibrium.com/quilibrium/monorepo/config"
qconsensus "source.quilibrium.com/quilibrium/monorepo/consensus"
"source.quilibrium.com/quilibrium/monorepo/node/consensus/events"
"source.quilibrium.com/quilibrium/monorepo/node/consensus/time"
"source.quilibrium.com/quilibrium/monorepo/protobufs"
"source.quilibrium.com/quilibrium/monorepo/types/channel"
"source.quilibrium.com/quilibrium/monorepo/types/compiler"
"source.quilibrium.com/quilibrium/monorepo/types/consensus"
"source.quilibrium.com/quilibrium/monorepo/types/crypto"
"source.quilibrium.com/quilibrium/monorepo/types/hypergraph"
"source.quilibrium.com/quilibrium/monorepo/types/keys"
"source.quilibrium.com/quilibrium/monorepo/types/p2p"
"source.quilibrium.com/quilibrium/monorepo/types/store"
)
// AppConsensusEngineFactory provides a factory method for creating properly
// wired AppConsensusEngine instances with time reels and event distributors.
type AppConsensusEngineFactory struct {
logger *zap.Logger
config *config.Config
pubsub p2p.PubSub
hypergraph hypergraph.Hypergraph
keyManager keys.KeyManager
keyStore store.KeyStore
clockStore store.ClockStore
inboxStore store.InboxStore
shardsStore store.ShardsStore
hypergraphStore store.HypergraphStore
consensusStore qconsensus.ConsensusStore[*protobufs.ProposalVote]
frameProver crypto.FrameProver
inclusionProver crypto.InclusionProver
bulletproofProver crypto.BulletproofProver
verEnc crypto.VerifiableEncryptor
decafConstructor crypto.DecafConstructor
compiler compiler.CircuitCompiler
signerRegistry consensus.SignerRegistry
proverRegistry consensus.ProverRegistry
peerInfoManager p2p.PeerInfoManager
dynamicFeeManager consensus.DynamicFeeManager
frameValidator consensus.AppFrameValidator
globalFrameValidator consensus.GlobalFrameValidator
difficultyAdjuster consensus.DifficultyAdjuster
rewardIssuance consensus.RewardIssuance
blsConstructor crypto.BlsConstructor
encryptedChannel channel.EncryptedChannel
}
// NewAppConsensusEngineFactory creates a new factory for consensus engines.
func NewAppConsensusEngineFactory(
logger *zap.Logger,
config *config.Config,
pubsub p2p.PubSub,
hypergraph hypergraph.Hypergraph,
keyManager keys.KeyManager,
keyStore store.KeyStore,
clockStore store.ClockStore,
inboxStore store.InboxStore,
shardsStore store.ShardsStore,
hypergraphStore store.HypergraphStore,
consensusStore qconsensus.ConsensusStore[*protobufs.ProposalVote],
frameProver crypto.FrameProver,
inclusionProver crypto.InclusionProver,
bulletproofProver crypto.BulletproofProver,
verEnc crypto.VerifiableEncryptor,
decafConstructor crypto.DecafConstructor,
compiler compiler.CircuitCompiler,
signerRegistry consensus.SignerRegistry,
proverRegistry consensus.ProverRegistry,
peerInfoManager p2p.PeerInfoManager,
dynamicFeeManager consensus.DynamicFeeManager,
frameValidator consensus.AppFrameValidator,
globalFrameValidator consensus.GlobalFrameValidator,
difficultyAdjuster consensus.DifficultyAdjuster,
rewardIssuance consensus.RewardIssuance,
blsConstructor crypto.BlsConstructor,
encryptedChannel channel.EncryptedChannel,
) *AppConsensusEngineFactory {
return &AppConsensusEngineFactory{
logger: logger,
config: config,
pubsub: pubsub,
hypergraph: hypergraph,
keyManager: keyManager,
keyStore: keyStore,
clockStore: clockStore,
inboxStore: inboxStore,
shardsStore: shardsStore,
hypergraphStore: hypergraphStore,
consensusStore: consensusStore,
frameProver: frameProver,
inclusionProver: inclusionProver,
bulletproofProver: bulletproofProver,
verEnc: verEnc,
decafConstructor: decafConstructor,
compiler: compiler,
signerRegistry: signerRegistry,
proverRegistry: proverRegistry,
dynamicFeeManager: dynamicFeeManager,
frameValidator: frameValidator,
globalFrameValidator: globalFrameValidator,
difficultyAdjuster: difficultyAdjuster,
rewardIssuance: rewardIssuance,
blsConstructor: blsConstructor,
encryptedChannel: encryptedChannel,
peerInfoManager: peerInfoManager,
}
}
// CloseSnapshots synchronously closes the hypergraph snapshot manager. Call
// this before closing the underlying database to ensure no Pebble snapshots
// remain open.
func (f *AppConsensusEngineFactory) CloseSnapshots() {
if closer, ok := f.hypergraph.(interface{ CloseSnapshots() }); ok {
closer.CloseSnapshots()
}
}
// CreateAppConsensusEngine creates a new AppConsensusEngine
func (f *AppConsensusEngineFactory) CreateAppConsensusEngine(
appAddress []byte,
coreId uint,
globalTimeReel *time.GlobalTimeReel,
grpcServer *grpc.Server,
) (*AppConsensusEngine, error) {
// Create the app time reel for this shard
appTimeReel, err := time.NewAppTimeReel(
f.logger,
appAddress,
f.proverRegistry,
f.clockStore,
f.config.Engine.ArchiveMode,
)
if err != nil {
return nil, errors.Wrap(err, "create app time reel")
}
// Create the event distributor with channels from both time reels
eventDistributor := events.NewAppEventDistributor(
globalTimeReel.GetEventCh(),
appTimeReel.GetEventCh(),
)
// Create the consensus engine with the wired event distributor and time reel
engine, err := NewAppConsensusEngine(
f.logger,
f.config,
coreId,
appAddress,
f.pubsub,
f.hypergraph,
f.keyManager,
f.keyStore,
f.clockStore,
f.inboxStore,
f.shardsStore,
f.hypergraphStore,
f.consensusStore,
f.frameProver,
f.inclusionProver,
f.bulletproofProver,
f.verEnc,
f.decafConstructor,
f.compiler,
f.signerRegistry,
f.proverRegistry,
f.dynamicFeeManager,
f.frameValidator,
f.globalFrameValidator,
f.difficultyAdjuster,
f.rewardIssuance,
eventDistributor,
f.peerInfoManager,
appTimeReel,
globalTimeReel,
f.blsConstructor,
f.encryptedChannel,
grpcServer,
)
if err != nil {
return nil, errors.Wrap(err, "create app consensus engine")
}
return engine, nil
}
// CreateGlobalTimeReel creates a new global time reel
func (
f *AppConsensusEngineFactory,
) CreateGlobalTimeReel() (*time.GlobalTimeReel, error) {
return time.NewGlobalTimeReel(
f.logger,
f.proverRegistry,
f.clockStore,
f.config.P2P.Network,
f.config.Engine.ArchiveMode,
)
}