1.1.3 – Rewinding heads and obvious fork comparison, additional bugfixes

This commit is contained in:
Cassandra Heart 2023-10-13 23:05:44 -05:00
parent 045fec34fa
commit 59c550db0f
No known key found for this signature in database
GPG Key ID: 6352152859385958
15 changed files with 150 additions and 29 deletions

View File

@ -212,6 +212,13 @@ func (e *CeremonyDataClockConsensusEngine) handleCeremonyPeerListAnnounce(
zap.String("announced_peer", peer.ID(pr.peerId).String()), zap.String("announced_peer", peer.ID(pr.peerId).String()),
zap.Int64("frame_distance", dst), zap.Int64("frame_distance", dst),
) )
e.peerMap[string(p.PeerId)] = &peerInfo{
peerId: p.PeerId,
multiaddr: p.Multiaddr,
maxFrame: p.MaxFrame,
direct: false,
lastSeen: time.Now().Unix(),
}
} else if dst < -4 { } else if dst < -4 {
e.logger.Debug( e.logger.Debug(
"peer sent announcement with lower frame index for peer", "peer sent announcement with lower frame index for peer",

View File

@ -87,7 +87,6 @@ type CeremonyDataClockConsensusEngine struct {
peerAnnounceMap map[string]*protobufs.CeremonyPeerListAnnounce peerAnnounceMap map[string]*protobufs.CeremonyPeerListAnnounce
peerMap map[string]*peerInfo peerMap map[string]*peerInfo
uncooperativePeersMap map[string]*peerInfo uncooperativePeersMap map[string]*peerInfo
fullResync bool
} }
var _ consensus.DataConsensusEngine = (*CeremonyDataClockConsensusEngine)(nil) var _ consensus.DataConsensusEngine = (*CeremonyDataClockConsensusEngine)(nil)
@ -265,16 +264,19 @@ func (e *CeremonyDataClockConsensusEngine) Start(
case consensus.EngineStateCollecting: case consensus.EngineStateCollecting:
if latestFrame, err = e.collect(latestFrame); err != nil { if latestFrame, err = e.collect(latestFrame); err != nil {
e.logger.Error("could not collect", zap.Error(err)) e.logger.Error("could not collect", zap.Error(err))
e.state = consensus.EngineStateCollecting
errChan <- err errChan <- err
} }
case consensus.EngineStateProving: case consensus.EngineStateProving:
if latestFrame, err = e.prove(latestFrame); err != nil { if latestFrame, err = e.prove(latestFrame); err != nil {
e.logger.Error("could not prove", zap.Error(err)) e.logger.Error("could not prove", zap.Error(err))
e.state = consensus.EngineStateCollecting
errChan <- err errChan <- err
} }
case consensus.EngineStatePublishing: case consensus.EngineStatePublishing:
if err = e.publishProof(latestFrame); err != nil { if err = e.publishProof(latestFrame); err != nil {
e.logger.Error("could not publish", zap.Error(err)) e.logger.Error("could not publish", zap.Error(err))
e.state = consensus.EngineStateCollecting
errChan <- err errChan <- err
} }
} }

View File

@ -688,6 +688,7 @@ func (e *CeremonyDataClockConsensusEngine) commitLongestPath(
) )
for _, s := range runningFrames[0][1:] { for _, s := range runningFrames[0][1:] {
s := s
txn, err := e.clockStore.NewTransaction() txn, err := e.clockStore.NewTransaction()
if err != nil { if err != nil {
return nil, errors.Wrap(err, "commit longest path") return nil, errors.Wrap(err, "commit longest path")
@ -728,12 +729,14 @@ func (e *CeremonyDataClockConsensusEngine) commitLongestPath(
) )
for _, p := range s.AggregateProofs { for _, p := range s.AggregateProofs {
p := p
e.logger.Debug( e.logger.Debug(
"committing inclusions", "committing inclusions",
zap.Int("inclusions_count", len(p.InclusionCommitments)), zap.Int("inclusions_count", len(p.InclusionCommitments)),
) )
for _, c := range p.InclusionCommitments { for _, c := range p.InclusionCommitments {
c := c
switch c.TypeUrl { switch c.TypeUrl {
case protobufs.ProvingKeyAnnouncementType: case protobufs.ProvingKeyAnnouncementType:
provingKey := &protobufs.ProvingKeyAnnouncement{} provingKey := &protobufs.ProvingKeyAnnouncement{}
@ -885,7 +888,6 @@ func (e *CeremonyDataClockConsensusEngine) collect(
zap.String("peer_id", peer.ID(peerId).String()), zap.String("peer_id", peer.ID(peerId).String()),
) )
willPerformFullResync := false
cc, err := e.pubSub.GetDirectChannel(peerId) cc, err := e.pubSub.GetDirectChannel(peerId)
if err != nil { if err != nil {
e.logger.Error( e.logger.Error(
@ -898,9 +900,11 @@ func (e *CeremonyDataClockConsensusEngine) collect(
e.peerMapMx.Unlock() e.peerMapMx.Unlock()
} else { } else {
from := latest.FrameNumber from := latest.FrameNumber
originalFrom := from
originalLatest := latest
if from == 0 { if from == 0 {
from = 1 from = 1
} else if maxFrame-from > 32 && !e.fullResync { } else if maxFrame-from > 32 {
// divergence is high, we need to confirm we're not in a fork // divergence is high, we need to confirm we're not in a fork
from = 1 from = 1
latest, _, err = e.clockStore.GetDataClockFrame(e.filter, 0) latest, _, err = e.clockStore.GetDataClockFrame(e.filter, 0)
@ -912,7 +916,6 @@ func (e *CeremonyDataClockConsensusEngine) collect(
) )
panic(err) panic(err)
} }
willPerformFullResync = true
} }
client := protobufs.NewCeremonyServiceClient(cc) client := protobufs.NewCeremonyServiceClient(cc)
@ -922,6 +925,7 @@ func (e *CeremonyDataClockConsensusEngine) collect(
Filter: e.filter, Filter: e.filter,
FromFrameNumber: from, FromFrameNumber: from,
ToFrameNumber: maxFrame, ToFrameNumber: maxFrame,
ParentSelector: latest.ParentSelector,
}, },
grpc.MaxCallRecvMsgSize(400*1024*1024), grpc.MaxCallRecvMsgSize(400*1024*1024),
) )
@ -930,13 +934,19 @@ func (e *CeremonyDataClockConsensusEngine) collect(
"error while retrieving sync", "error while retrieving sync",
zap.Error(err), zap.Error(err),
) )
latest = originalLatest
e.peerMapMx.Lock() e.peerMapMx.Lock()
e.uncooperativePeersMap[string(peerId)] = e.peerMap[string(peerId)] e.uncooperativePeersMap[string(peerId)] = e.peerMap[string(peerId)]
delete(e.peerMap, string(peerId)) delete(e.peerMap, string(peerId))
e.peerMapMx.Unlock() e.peerMapMx.Unlock()
} else { } else {
var syncMsg *protobufs.CeremonyCompressedSync var syncMsg *protobufs.CeremonyCompressedSync
askedFrom := from
for syncMsg, err = s.Recv(); err == nil; syncMsg, err = s.Recv() { for syncMsg, err = s.Recv(); err == nil; syncMsg, err = s.Recv() {
if syncMsg.FromFrameNumber < askedFrom {
askedFrom = syncMsg.FromFrameNumber
}
e.logger.Info( e.logger.Info(
"received compressed sync frame", "received compressed sync frame",
zap.Uint64("from", syncMsg.FromFrameNumber), zap.Uint64("from", syncMsg.FromFrameNumber),
@ -945,21 +955,42 @@ func (e *CeremonyDataClockConsensusEngine) collect(
zap.Int("proofs", len(syncMsg.Proofs)), zap.Int("proofs", len(syncMsg.Proofs)),
) )
if err = e.decompressAndStoreCandidates(syncMsg); err != nil { if err = e.decompressAndStoreCandidates(syncMsg); err != nil {
e.logger.Error(
"could not decompress and store candidate",
zap.Error(err),
)
from = originalFrom
latest = originalLatest
break break
} }
} }
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
e.logger.Error("error while receiving sync", zap.Error(err)) e.logger.Error("error while receiving sync", zap.Error(err))
from = originalFrom
latest = originalLatest
askedFrom = from
}
if askedFrom < from {
e.logger.Info(
"peer provided deeper history due to fork, rewinding consensus " +
"head",
)
askedLatest, _, err := e.clockStore.GetDataClockFrame(
e.filter,
askedFrom-1,
)
if err != nil {
e.logger.Error("error while receiving sync", zap.Error(err))
} else {
latest = askedLatest
}
} }
} }
if err := cc.Close(); err != nil { if err := cc.Close(); err != nil {
e.logger.Error("error while closing connection", zap.Error(err)) e.logger.Error("error while closing connection", zap.Error(err))
} }
if willPerformFullResync {
e.fullResync = true
}
} }
} }

View File

@ -76,7 +76,7 @@ func (e *CeremonyDataClockConsensusEngine) GetCompressedSyncFrames(
from := request.FromFrameNumber from := request.FromFrameNumber
_, _, err := e.clockStore.GetDataClockFrame( frame, _, err := e.clockStore.GetDataClockFrame(
request.Filter, request.Filter,
from, from,
) )
@ -108,6 +108,43 @@ func (e *CeremonyDataClockConsensusEngine) GetCompressedSyncFrames(
} }
} }
parent := request.ParentSelector
if parent != nil {
if !bytes.Equal(frame.ParentSelector, parent) {
e.logger.Info(
"peer specified out of consensus head, seeking backwards for fork",
)
}
for !bytes.Equal(frame.ParentSelector, parent) {
ours, err := e.clockStore.GetParentDataClockFrame(
e.filter,
frame.FrameNumber-1,
frame.ParentSelector,
)
if err != nil {
from = 1
e.logger.Info("peer fully out of sync, rewinding sync head to start")
break
}
theirs, err := e.clockStore.GetParentDataClockFrame(
e.filter,
frame.FrameNumber-1,
parent,
)
if err != nil {
from = 1
e.logger.Info("peer fully out of sync, rewinding sync head to start")
break
}
from--
frame = ours
parent = theirs.ParentSelector
}
}
max := e.frame max := e.frame
to := request.ToFrameNumber to := request.ToFrameNumber
@ -151,7 +188,14 @@ func (e *CeremonyDataClockConsensusEngine) GetCompressedSyncFrames(
func (e *CeremonyDataClockConsensusEngine) decompressAndStoreCandidates( func (e *CeremonyDataClockConsensusEngine) decompressAndStoreCandidates(
syncMsg *protobufs.CeremonyCompressedSync, syncMsg *protobufs.CeremonyCompressedSync,
) error { ) error {
if len(syncMsg.TruncatedClockFrames) != int(
syncMsg.ToFrameNumber-syncMsg.FromFrameNumber+1,
) {
return errors.New("invalid continuity for compressed sync response")
}
for _, frame := range syncMsg.TruncatedClockFrames { for _, frame := range syncMsg.TruncatedClockFrames {
frame := frame
commits := (len(frame.Input) - 516) / 74 commits := (len(frame.Input) - 516) / 74
e.logger.Info( e.logger.Info(
"processing frame", "processing frame",
@ -167,6 +211,7 @@ func (e *CeremonyDataClockConsensusEngine) decompressAndStoreCandidates(
commit := frame.Input[516+(j*74) : 516+((j+1)*74)] commit := frame.Input[516+(j*74) : 516+((j+1)*74)]
var aggregateProof *protobufs.InclusionProofsMap var aggregateProof *protobufs.InclusionProofsMap
for _, a := range syncMsg.Proofs { for _, a := range syncMsg.Proofs {
a := a
if bytes.Equal(a.FrameCommit, commit) { if bytes.Equal(a.FrameCommit, commit) {
e.logger.Info( e.logger.Info(
"found matching proof", "found matching proof",
@ -197,6 +242,8 @@ func (e *CeremonyDataClockConsensusEngine) decompressAndStoreCandidates(
} }
for k, c := range aggregateProof.Commitments { for k, c := range aggregateProof.Commitments {
k := k
c := c
e.logger.Info( e.logger.Info(
"adding inclusion commitment", "adding inclusion commitment",
zap.Uint64("frame_number", frame.FrameNumber), zap.Uint64("frame_number", frame.FrameNumber),
@ -217,7 +264,12 @@ func (e *CeremonyDataClockConsensusEngine) decompressAndStoreCandidates(
output = &protobufs.IntrinsicExecutionOutput{} output = &protobufs.IntrinsicExecutionOutput{}
} }
for l, h := range c.SegmentHashes { for l, h := range c.SegmentHashes {
l := l
h := h
for _, s := range syncMsg.Segments { for _, s := range syncMsg.Segments {
s := s
if bytes.Equal(s.Hash, h) { if bytes.Equal(s.Hash, h) {
if output != nil { if output != nil {
if l == 0 { if l == 0 {

View File

@ -54,6 +54,7 @@ func (e *MasterClockConsensusEngine) handleMessage(message *pb.Message) error {
} }
for _, m := range messages { for _, m := range messages {
m := m
if err := e.publishMessage(m.Address, m); err != nil { if err := e.publishMessage(m.Address, m); err != nil {
e.logger.Error( e.logger.Error(
"could not publish message for engine", "could not publish message for engine",

View File

@ -240,6 +240,7 @@ func (
} }
for _, frame := range committedSet { for _, frame := range committedSet {
frame := frame
if err = e.clockStore.PutMasterClockFrame(frame, txn); err != nil { if err = e.clockStore.PutMasterClockFrame(frame, txn); err != nil {
e.logger.Error("error while committing frame", zap.Error(err)) e.logger.Error("error while committing frame", zap.Error(err))
return nil, errors.Wrap(err, "confirm latest frame") return nil, errors.Wrap(err, "confirm latest frame")

View File

@ -50,6 +50,7 @@ func (e *MasterClockConsensusEngine) handleSync(message *pb.Message) error {
} }
for _, m := range messages { for _, m := range messages {
m := m
if err := e.publishMessage(e.filter, m); err != nil { if err := e.publishMessage(e.filter, m); err != nil {
e.logger.Error( e.logger.Error(
"could not publish message for engine", "could not publish message for engine",
@ -128,6 +129,7 @@ func (e *MasterClockConsensusEngine) handleClockFramesResponse(
} }
for _, frame := range response.ClockFrames { for _, frame := range response.ClockFrames {
frame := frame
e.logger.Debug( e.logger.Debug(
"processing clock frame", "processing clock frame",
zap.Binary("sender", peerID), zap.Binary("sender", peerID),

View File

@ -855,6 +855,7 @@ func (a *CeremonyApplication) ApplyTransition(
a.StateCount = 0 a.StateCount = 0
a.RoundCount = 0 a.RoundCount = 0
for _, p := range a.ActiveParticipants { for _, p := range a.ActiveParticipants {
p := p
if _, ok := droppedProversMap[string(p.KeyValue)]; !ok { if _, ok := droppedProversMap[string(p.KeyValue)]; !ok {
a.NextRoundPreferredParticipants = append( a.NextRoundPreferredParticipants = append(
append( append(
@ -974,6 +975,7 @@ func (a *CeremonyApplication) ApplyTransition(
a.StateCount = 0 a.StateCount = 0
a.RoundCount = 0 a.RoundCount = 0
for _, p := range a.ActiveParticipants { for _, p := range a.ActiveParticipants {
p := p
if _, ok := droppedProversMap[string(p.KeyValue)]; !ok { if _, ok := droppedProversMap[string(p.KeyValue)]; !ok {
a.NextRoundPreferredParticipants = append( a.NextRoundPreferredParticipants = append(
append( append(

View File

@ -54,6 +54,7 @@ func (a *CeremonyApplication) applySeenProverAttestation(
replaced := false replaced := false
for i, att := range a.LatestSeenProverAttestations { for i, att := range a.LatestSeenProverAttestations {
att := att
if bytes.Equal( if bytes.Equal(
att.SeenProverKey.KeyValue, att.SeenProverKey.KeyValue,
seenProverAttestation.SeenProverKey.KeyValue, seenProverAttestation.SeenProverKey.KeyValue,
@ -126,6 +127,7 @@ func (a *CeremonyApplication) applyDroppedProverAttestation(
replaced := false replaced := false
for i, att := range a.DroppedParticipantAttestations { for i, att := range a.DroppedParticipantAttestations {
att := att
if bytes.Equal( if bytes.Equal(
att.DroppedProverKey.KeyValue, att.DroppedProverKey.KeyValue,
droppedProverAttestation.DroppedProverKey.KeyValue, droppedProverAttestation.DroppedProverKey.KeyValue,

View File

@ -51,6 +51,7 @@ func (a *CeremonyApplication) applyLobbyJoin(
prepend := false prepend := false
nextRoundPreferredParticipants := []*protobufs.Ed448PublicKey{} nextRoundPreferredParticipants := []*protobufs.Ed448PublicKey{}
for _, p := range a.NextRoundPreferredParticipants { for _, p := range a.NextRoundPreferredParticipants {
p := p
if !bytes.Equal(p.KeyValue, signature.PublicKey.KeyValue) { if !bytes.Equal(p.KeyValue, signature.PublicKey.KeyValue) {
nextRoundPreferredParticipants = append( nextRoundPreferredParticipants = append(
nextRoundPreferredParticipants, nextRoundPreferredParticipants,

View File

@ -1,3 +1,5 @@
//go:build !js && !wasm
package main package main
import ( import (
@ -228,5 +230,5 @@ func printLogo() {
func printVersion() { func printVersion() {
fmt.Println(" ") fmt.Println(" ")
fmt.Println(" Quilibrium Node - v1.1.2 Dawn") fmt.Println(" Quilibrium Node - v1.1.3 Dawn")
} }

View File

@ -449,6 +449,7 @@ func discoverPeers(
} }
for peer := range peerChan { for peer := range peerChan {
peer := peer
if peer.ID == h.ID() { if peer.ID == h.ID() {
continue continue
} }

View File

@ -206,6 +206,9 @@ type ClockFramesRequest struct {
// The latest frame in the range requested, if provided. Capped to a maximum // The latest frame in the range requested, if provided. Capped to a maximum
// size of 128 frames. // size of 128 frames.
ToFrameNumber uint64 `protobuf:"varint,3,opt,name=to_frame_number,json=toFrameNumber,proto3" json:"to_frame_number,omitempty"` ToFrameNumber uint64 `protobuf:"varint,3,opt,name=to_frame_number,json=toFrameNumber,proto3" json:"to_frame_number,omitempty"`
// The optional parent selector. If provided, will perform a check to confirm
// continuity, otherwise, will rewind the sync head to the beginning.
ParentSelector []byte `protobuf:"bytes,4,opt,name=parent_selector,json=parentSelector,proto3" json:"parent_selector,omitempty"`
} }
func (x *ClockFramesRequest) Reset() { func (x *ClockFramesRequest) Reset() {
@ -261,6 +264,13 @@ func (x *ClockFramesRequest) GetToFrameNumber() uint64 {
return 0 return 0
} }
func (x *ClockFramesRequest) GetParentSelector() []byte {
if x != nil {
return x.ParentSelector
}
return nil
}
// Represents a response for a range of clock frames. Used to stay synchronized // Represents a response for a range of clock frames. Used to stay synchronized
// to the latest state. // to the latest state.
type ClockFramesResponse struct { type ClockFramesResponse struct {
@ -374,7 +384,7 @@ var file_clock_proto_rawDesc = []byte{
0x52, 0x17, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x52, 0x17, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x45, 0x64, 0x34, 0x34, 0x38, 0x42, 0x16, 0x0a, 0x14, 0x70, 0x75, 0x62, 0x74, 0x75, 0x72, 0x65, 0x45, 0x64, 0x34, 0x34, 0x38, 0x42, 0x16, 0x0a, 0x14, 0x70, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x22, 0x80, 0x01, 0x0a, 0x12, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x65, 0x22, 0xa9, 0x01, 0x0a, 0x12, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74,
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
0x12, 0x2a, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e,
@ -382,24 +392,26 @@ var file_clock_proto_rawDesc = []byte{
0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f,
0x74, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x74, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18,
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75,
0x6d, 0x62, 0x65, 0x72, 0x22, 0xca, 0x01, 0x0a, 0x13, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73,
0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70,
0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0xca, 0x01,
0x6c, 0x74, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x72, 0x61, 0x0a, 0x13, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73,
0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18,
0x0f, 0x66, 0x72, 0x6f, 0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2a, 0x0a,
0x12, 0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62,
0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x46, 0x72, 0x61, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x66, 0x72, 0x6f, 0x6d, 0x46, 0x72,
0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x6c, 0x6f, 0x63, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x5f,
0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65,
0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65,
0x72, 0x61, 0x6d, 0x65, 0x52, 0x0b, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62,
0x73, 0x42, 0x3a, 0x5a, 0x38, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e,
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x0b, 0x63,
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x6d, 0x6f, 0x6e, 0x6f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x42, 0x3a, 0x5a, 0x38, 0x73, 0x6f,
0x6f, 0x64, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x73, 0x62, 0x06, 0x70, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e,
0x72, 0x6f, 0x74, 0x6f, 0x33, 0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x6d,
0x6f, 0x6e, 0x6f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (

View File

@ -71,6 +71,9 @@ message ClockFramesRequest {
// The latest frame in the range requested, if provided. Capped to a maximum // The latest frame in the range requested, if provided. Capped to a maximum
// size of 128 frames. // size of 128 frames.
uint64 to_frame_number = 3; uint64 to_frame_number = 3;
// The optional parent selector. If provided, will perform a check to confirm
// continuity, otherwise, will rewind the sync head to the beginning.
bytes parent_selector = 4;
} }
// Represents a response for a range of clock frames. Used to stay synchronized // Represents a response for a range of clock frames. Used to stay synchronized

View File

@ -1341,6 +1341,8 @@ func (p *PebbleClockStore) GetCompressedDataClockFrames(
} }
for k, v := range proofs { for k, v := range proofs {
k := k
v := v
value, closer, err := p.db.Get(dataProofMetadataKey(filter, []byte(k))) value, closer, err := p.db.Get(dataProofMetadataKey(filter, []byte(k)))
if err != nil { if err != nil {
if errors.Is(err, pebble.ErrNotFound) { if errors.Is(err, pebble.ErrNotFound) {