mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 18:37:26 +08:00
145 lines
3.3 KiB
Go
145 lines
3.3 KiB
Go
package app
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
|
|
"go.uber.org/zap"
|
|
"source.quilibrium.com/quilibrium/monorepo/consensus/models"
|
|
"source.quilibrium.com/quilibrium/monorepo/protobufs"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/store"
|
|
)
|
|
|
|
type AppFrameChainReader interface {
|
|
GetShardClockFrame(
|
|
filter []byte,
|
|
frameNumber uint64,
|
|
truncate bool,
|
|
) (*protobufs.AppShardFrame, error)
|
|
GetStagedShardClockFrame(
|
|
filter []byte,
|
|
frameNumber uint64,
|
|
parentSelector []byte,
|
|
truncate bool,
|
|
) (*protobufs.AppShardFrame, error)
|
|
}
|
|
|
|
type AppFrameChainChecker struct {
|
|
store AppFrameChainReader
|
|
filter []byte
|
|
logger *zap.Logger
|
|
}
|
|
|
|
func NewAppFrameChainChecker(
|
|
store store.ClockStore,
|
|
logger *zap.Logger,
|
|
filter []byte,
|
|
) *AppFrameChainChecker {
|
|
if store == nil {
|
|
return nil
|
|
}
|
|
if logger == nil {
|
|
logger = zap.NewNop()
|
|
}
|
|
return &AppFrameChainChecker{
|
|
store: appFrameChainStoreAdapter{store: store},
|
|
filter: filter, // buildutils:allow-slice-alias slice is static
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
func (c *AppFrameChainChecker) CanProcessSequentialChain(
|
|
finalized *models.State[*protobufs.AppShardFrame],
|
|
proposal *protobufs.AppShardProposal,
|
|
) bool {
|
|
if c == nil || c.store == nil || proposal == nil ||
|
|
proposal.State == nil || proposal.State.Header == nil {
|
|
return false
|
|
}
|
|
|
|
parentSelector := proposal.State.Header.ParentSelector
|
|
if len(parentSelector) == 0 {
|
|
return false
|
|
}
|
|
|
|
frameNumber := proposal.State.Header.FrameNumber
|
|
if frameNumber == 0 {
|
|
return false
|
|
}
|
|
|
|
for frameNumber > 0 && len(parentSelector) > 0 {
|
|
frameNumber--
|
|
sealed, err := c.store.GetShardClockFrame(c.filter, frameNumber, false)
|
|
if err == nil && sealed != nil &&
|
|
bytes.Equal([]byte(sealed.Identity()), parentSelector) {
|
|
c.logger.Debug(
|
|
"app frame chain linked to sealed frame",
|
|
zap.Uint64("sealed_frame_number", frameNumber),
|
|
)
|
|
return true
|
|
}
|
|
|
|
candidate, err := c.store.GetStagedShardClockFrame(
|
|
c.filter,
|
|
frameNumber,
|
|
parentSelector,
|
|
false,
|
|
)
|
|
if err == nil && candidate != nil {
|
|
parentSelector = candidate.Header.ParentSelector
|
|
// keep walking
|
|
continue
|
|
}
|
|
|
|
if finalized != nil && finalized.State != nil &&
|
|
(*finalized.State).Header != nil &&
|
|
frameNumber == (*finalized.State).Header.FrameNumber &&
|
|
bytes.Equal([]byte(finalized.Identifier), parentSelector) {
|
|
c.logger.Debug(
|
|
"app frame chain linked to finalized frame",
|
|
zap.Uint64("finalized_frame_number", frameNumber),
|
|
)
|
|
return true
|
|
}
|
|
|
|
c.logger.Debug(
|
|
"missing app ancestor frame while validating chain",
|
|
zap.Uint64("missing_frame_number", frameNumber),
|
|
zap.String(
|
|
"expected_parent_selector",
|
|
hex.EncodeToString(parentSelector),
|
|
),
|
|
)
|
|
return false
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
type appFrameChainStoreAdapter struct {
|
|
store store.ClockStore
|
|
}
|
|
|
|
func (a appFrameChainStoreAdapter) GetShardClockFrame(
|
|
filter []byte,
|
|
frameNumber uint64,
|
|
truncate bool,
|
|
) (*protobufs.AppShardFrame, error) {
|
|
frame, _, err := a.store.GetShardClockFrame(filter, frameNumber, truncate)
|
|
return frame, err
|
|
}
|
|
|
|
func (a appFrameChainStoreAdapter) GetStagedShardClockFrame(
|
|
filter []byte,
|
|
frameNumber uint64,
|
|
parentSelector []byte,
|
|
truncate bool,
|
|
) (*protobufs.AppShardFrame, error) {
|
|
return a.store.GetStagedShardClockFrame(
|
|
filter,
|
|
frameNumber,
|
|
parentSelector,
|
|
truncate,
|
|
)
|
|
}
|