diff --git a/internal/singlewriter/overlay_transaction.go b/internal/singlewriter/overlay_transaction.go index d32f82eb..ede70ef4 100644 --- a/internal/singlewriter/overlay_transaction.go +++ b/internal/singlewriter/overlay_transaction.go @@ -108,6 +108,7 @@ func (oi *overlayIterator) advanceBase() { } oi.baseNext = true + oi.baseKey = bytes.Clone(k) } diff --git a/offchainreporting2plus/internal/config/ocr3_1config/metrics.go b/offchainreporting2plus/internal/config/ocr3_1config/metrics.go index 3ad92d7c..3c947e9c 100644 --- a/offchainreporting2plus/internal/config/ocr3_1config/metrics.go +++ b/offchainreporting2plus/internal/config/ocr3_1config/metrics.go @@ -57,6 +57,8 @@ type PublicConfigMetrics struct { maxDurationShouldAcceptAttestedReport prometheus.Gauge maxDurationShouldTransmitAcceptedReport prometheus.Gauge + prevSeqNr prometheus.Gauge + n prometheus.Gauge f prometheus.Gauge @@ -319,6 +321,17 @@ func NewPublicConfigMetrics( maxDurationShouldTransmitAcceptedReport.Set(publicConfig.MaxDurationShouldTransmitAcceptedReport.Seconds()) metricshelper.RegisterOrLogError(logger, registerer, maxDurationShouldTransmitAcceptedReport, "ocr3_1_config_max_duration_should_transmit_accepted_report_seconds") + prevSeqNr := prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "ocr3_1_config_prev_seq_nr", + Help: "See https://pkg.go.dev/github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config/ocr3_1config#PublicConfig for details", + }) + if publicConfig.PrevSeqNr != nil { + prevSeqNr.Set(float64(*publicConfig.PrevSeqNr)) + } else { + prevSeqNr.Set(0) + } + metricshelper.RegisterOrLogError(logger, registerer, prevSeqNr, "ocr3_1_config_prev_seq_nr") + n := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "ocr3_1_config_n", Help: "The number of oracles participating in this protocol instance", @@ -391,6 +404,8 @@ func NewPublicConfigMetrics( maxDurationShouldAcceptAttestedReport, maxDurationShouldTransmitAcceptedReport, + prevSeqNr, + n, f, minRoundInterval, @@ -446,6 +461,8 @@ func (pm *PublicConfigMetrics) Close() { pm.registerer.Unregister(pm.maxDurationShouldAcceptAttestedReport) pm.registerer.Unregister(pm.maxDurationShouldTransmitAcceptedReport) + pm.registerer.Unregister(pm.prevSeqNr) + pm.registerer.Unregister(pm.n) pm.registerer.Unregister(pm.f) pm.registerer.Unregister(pm.minRoundInterval) diff --git a/offchainreporting2plus/internal/config/ocr3_1config/offchainreporting3_1_offchain_config.pb.go b/offchainreporting2plus/internal/config/ocr3_1config/offchainreporting3_1_offchain_config.pb.go index bb7fb22a..d1e88201 100644 --- a/offchainreporting2plus/internal/config/ocr3_1config/offchainreporting3_1_offchain_config.pb.go +++ b/offchainreporting2plus/internal/config/ocr3_1config/offchainreporting3_1_offchain_config.pb.go @@ -64,6 +64,9 @@ type OffchainConfigProto struct { WarnDurationCommittedNanoseconds uint64 `protobuf:"varint,87,opt,name=warn_duration_committed_nanoseconds,json=warnDurationCommittedNanoseconds,proto3" json:"warn_duration_committed_nanoseconds,omitempty"` MaxDurationShouldAcceptAttestedReportNanoseconds uint64 `protobuf:"varint,88,opt,name=max_duration_should_accept_attested_report_nanoseconds,json=maxDurationShouldAcceptAttestedReportNanoseconds,proto3" json:"max_duration_should_accept_attested_report_nanoseconds,omitempty"` MaxDurationShouldTransmitAcceptedReportNanoseconds uint64 `protobuf:"varint,89,opt,name=max_duration_should_transmit_accepted_report_nanoseconds,json=maxDurationShouldTransmitAcceptedReportNanoseconds,proto3" json:"max_duration_should_transmit_accepted_report_nanoseconds,omitempty"` + PrevConfigDigest []byte `protobuf:"bytes,91,opt,name=prev_config_digest,json=prevConfigDigest,proto3,oneof" json:"prev_config_digest,omitempty"` + PrevSeqNr *uint64 `protobuf:"varint,92,opt,name=prev_seq_nr,json=prevSeqNr,proto3,oneof" json:"prev_seq_nr,omitempty"` + PrevHistoryDigest []byte `protobuf:"bytes,93,opt,name=prev_history_digest,json=prevHistoryDigest,proto3,oneof" json:"prev_history_digest,omitempty"` SharedSecretEncryptions *SharedSecretEncryptionsProto `protobuf:"bytes,90,opt,name=shared_secret_encryptions,json=sharedSecretEncryptions,proto3" json:"shared_secret_encryptions,omitempty"` } @@ -372,6 +375,27 @@ func (x *OffchainConfigProto) GetMaxDurationShouldTransmitAcceptedReportNanoseco return 0 } +func (x *OffchainConfigProto) GetPrevConfigDigest() []byte { + if x != nil { + return x.PrevConfigDigest + } + return nil +} + +func (x *OffchainConfigProto) GetPrevSeqNr() uint64 { + if x != nil && x.PrevSeqNr != nil { + return *x.PrevSeqNr + } + return 0 +} + +func (x *OffchainConfigProto) GetPrevHistoryDigest() []byte { + if x != nil { + return x.PrevHistoryDigest + } + return nil +} + func (x *OffchainConfigProto) GetSharedSecretEncryptions() *SharedSecretEncryptionsProto { if x != nil { return x.SharedSecretEncryptions @@ -449,7 +473,7 @@ var file_offchainreporting3_1_offchain_config_proto_rawDesc = []byte{ 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x5f, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, - 0x5f, 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xbf, 0x21, 0x0a, 0x13, 0x4f, 0x66, + 0x5f, 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x8b, 0x23, 0x0a, 0x13, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x3c, 0x0a, 0x1a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, @@ -650,86 +674,98 @@ var file_offchainreporting3_1_offchain_config_proto_rawDesc = []byte{ 0x6d, 0x61, 0x78, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x12, 0x75, 0x0a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x5f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x5a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x52, 0x17, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x45, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x64, 0x65, - 0x6c, 0x74, 0x61, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x1c, 0x0a, 0x1a, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, - 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x33, 0x0a, 0x31, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, - 0x75, 0x72, 0x73, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x61, - 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x30, 0x0a, 0x2e, 0x5f, 0x64, 0x65, - 0x6c, 0x74, 0x61, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x73, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, - 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x43, 0x0a, 0x41, 0x5f, - 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x79, 0x6e, 0x63, - 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x5f, - 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, - 0x42, 0x30, 0x0a, 0x2e, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x42, 0x25, 0x0a, 0x23, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x79, 0x6e, 0x63, - 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x20, 0x0a, 0x1e, 0x5f, 0x6d, 0x61, - 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x42, 0x0a, 0x40, 0x5f, - 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, - 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, - 0x2f, 0x0a, 0x2d, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, - 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, - 0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x79, - 0x6e, 0x63, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x42, 0x2d, 0x0a, - 0x2b, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x42, 0x27, 0x0a, 0x25, - 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x5f, 0x74, 0x72, - 0x65, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x66, 0x65, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x24, 0x0a, 0x22, 0x5f, - 0x6d, 0x61, 0x78, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x73, - 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x64, 0x42, 0x43, 0x0a, 0x41, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, - 0x5f, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, - 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, + 0x64, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x15, + 0x52, 0x10, 0x70, 0x72, 0x65, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x73, 0x65, + 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x04, 0x48, 0x16, 0x52, 0x09, 0x70, 0x72, + 0x65, 0x76, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x13, 0x70, 0x72, + 0x65, 0x76, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x17, 0x52, 0x11, 0x70, 0x72, 0x65, 0x76, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x88, 0x01, 0x01, 0x12, + 0x75, 0x0a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x5f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x5a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x45, 0x6e, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x17, 0x73, + 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x73, 0x42, 0x1c, 0x0a, 0x1a, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x42, 0x33, 0x0a, 0x31, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, + 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x30, 0x0a, 0x2e, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, - 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x61, 0x6e, - 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x29, 0x0a, 0x27, 0x5f, 0x64, 0x65, 0x6c, - 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x5f, 0x67, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x73, 0x42, 0x43, 0x0a, 0x41, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, - 0x6f, 0x62, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x72, 0x61, - 0x63, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, - 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x30, 0x0a, 0x2e, 0x5f, 0x64, 0x65, 0x6c, - 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, - 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x62, - 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x4a, - 0x04, 0x08, 0x01, 0x10, 0x2b, 0x4a, 0x04, 0x08, 0x2b, 0x10, 0x33, 0x22, 0x9c, 0x01, 0x0a, 0x1c, - 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2e, 0x0a, 0x12, - 0x64, 0x69, 0x66, 0x66, 0x69, 0x65, 0x48, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x50, 0x6f, 0x69, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x64, 0x69, 0x66, 0x66, 0x69, 0x65, - 0x48, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x10, - 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x48, 0x61, 0x73, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x65, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x3b, - 0x6f, 0x63, 0x72, 0x33, 0x5f, 0x31, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, + 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x43, 0x0a, 0x41, 0x5f, 0x64, 0x65, 0x6c, + 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x69, + 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x61, 0x6d, + 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x30, 0x0a, + 0x2e, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x79, + 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, + 0x25, 0x0a, 0x23, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x70, + 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x20, 0x0a, 0x1e, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x42, 0x0a, 0x40, 0x5f, 0x64, 0x65, 0x6c, + 0x74, 0x61, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x69, 0x6e, + 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x61, 0x6d, 0x65, + 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x2f, 0x0a, 0x2d, + 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, + 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x1b, 0x0a, + 0x19, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, + 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x42, 0x2d, 0x0a, 0x2b, 0x5f, 0x6d, + 0x61, 0x78, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x68, 0x75, + 0x6e, 0x6b, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x42, 0x27, 0x0a, 0x25, 0x5f, 0x6d, 0x61, + 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, + 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, + 0x65, 0x73, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x24, 0x0a, 0x22, 0x5f, 0x6d, 0x61, 0x78, + 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x42, 0x43, + 0x0a, 0x41, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x6f, 0x66, + 0x66, 0x65, 0x72, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x74, 0x6f, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x73, 0x42, 0x30, 0x0a, 0x2e, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, + 0x6f, 0x62, 0x5f, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x29, 0x0a, 0x27, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, + 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x67, + 0x72, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x42, 0x43, 0x0a, 0x41, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, + 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, + 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x30, 0x0a, 0x2e, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, + 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x62, 0x6c, 0x6f, 0x62, + 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x42, 0x15, 0x0a, 0x13, + 0x5f, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x73, 0x65, 0x71, + 0x5f, 0x6e, 0x72, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x68, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10, + 0x2b, 0x4a, 0x04, 0x08, 0x2b, 0x10, 0x33, 0x22, 0x9c, 0x01, 0x0a, 0x1c, 0x53, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2e, 0x0a, 0x12, 0x64, 0x69, 0x66, 0x66, + 0x69, 0x65, 0x48, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x64, 0x69, 0x66, 0x66, 0x69, 0x65, 0x48, 0x65, 0x6c, 0x6c, + 0x6d, 0x61, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x10, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x3b, 0x6f, 0x63, 0x72, 0x33, + 0x5f, 0x31, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/offchainreporting2plus/internal/config/ocr3_1config/public_config.go b/offchainreporting2plus/internal/config/ocr3_1config/public_config.go index 7b63929d..8cc62eb3 100644 --- a/offchainreporting2plus/internal/config/ocr3_1config/public_config.go +++ b/offchainreporting2plus/internal/config/ocr3_1config/public_config.go @@ -190,6 +190,47 @@ type PublicConfig struct { MaxDurationShouldAcceptAttestedReport time.Duration // Context deadline passed to ShouldAcceptAttestedReport. MaxDurationShouldTransmitAcceptedReport time.Duration // Context deadline passed to ShouldTransmitAcceptedReport. + // PrevConfigDigest is the config digest of the previous instance that this + // next instance is a continuation of. The previous instance must overlap in + // at least one oracle with the next instance, though larger overlaps are + // highly encouraged and will improve the initial synchronization + // performance. + // + // WARNING! This is an advanced feature and should only be used if you + // *really* know what you are doing. Failure to set this or any of the other + // Prev fields correctly will result in the instance not making any + // progress or data loss. + PrevConfigDigest *types.ConfigDigest + // PrevSeqNr is the sequence number of the previous instance that this next + // instance will continue from. Sequence numbers in the next instance will + // continue from PrevSeqNr. This must be a snapshot sequence number for the + // previous instance, i.e., PrevSeqNr % PrevInstanceConfig.SnapshotInterval + // == 0. The overlapping oracle must have locally committed the state as of + // PrevSeqNr and the snapshot associated with PrevSeqNr must be in the + // retention window implied by + // PrevInstanceConfig.MaxHistoricalSnapshotsRetained and + // PrevInstanceConfig.SnapshotInterval. (For instances whose previous + // instance already has a PrevSeqNr, this imples PrevSeqNr > + // PrevInstanceConfig.PrevSeqNr.) + // + // Be aware that any state transitions committed after PrevSeqNr in the + // previous instance will not be available in the next instance (and + // typically be lost forever). + // + // WARNING! This is an advanced feature and should only be used if you + // *really* know what you are doing. Failure to set this or any of the other + // Prev fields correctly will result in the instance not making any + // progress or data loss. + PrevSeqNr *uint64 + // PrevHistoryDigest is the history digest of the previous instance at + // PrevSeqNr. + // + // WARNING! This is an advanced feature and should only be used if you + // *really* know what you are doing. Failure to set this or any of the other + // Prev fields correctly will result in the instance not making any + // progress or data loss. + PrevHistoryDigest *types.HistoryDigest + // The maximum number of oracles that are assumed to be faulty while the // protocol can retain liveness and safety. Unless you really know what // you’re doing, be sure to set this to floor((n-1)/3) where n is the total @@ -297,6 +338,23 @@ func (c *PublicConfig) GetBlobChunkBytes() int { return util.NilCoalesce(c.BlobChunkBytes, DefaultBlobChunkBytes) } +type PublicConfigPrevFields struct { + PrevConfigDigest types.ConfigDigest + PrevSeqNr uint64 + PrevHistoryDigest types.HistoryDigest +} + +func (c *PublicConfig) GetPrevFields() (PublicConfigPrevFields, bool) { + if c.PrevConfigDigest == nil || c.PrevSeqNr == nil || c.PrevHistoryDigest == nil { + return PublicConfigPrevFields{}, false + } + return PublicConfigPrevFields{ + *c.PrevConfigDigest, + *c.PrevSeqNr, + *c.PrevHistoryDigest, + }, true +} + // The minimum interval between round starts. // This is not a guaranteed lower bound. For example, a malicious leader could // violate this bound. @@ -400,6 +458,10 @@ func publicConfigFromContractConfig(skipInsaneForProductionChecks bool, change t oc.MaxDurationShouldAcceptAttestedReport, oc.MaxDurationShouldTransmitAcceptedReport, + oc.PrevConfigDigest, + oc.PrevSeqNr, + oc.PrevHistoryDigest, + int(change.F), change.OnchainConfig, change.ConfigDigest, @@ -554,6 +616,13 @@ func checkPublicConfigParameters(cfg PublicConfig) error { // be made when you change this function! ///////////////////////////////////////////////////////////////// + if !((cfg.PrevConfigDigest == nil) == (cfg.PrevSeqNr == nil) && (cfg.PrevSeqNr == nil) == (cfg.PrevHistoryDigest == nil)) { + return fmt.Errorf("PrevConfigDigest, PrevSeqNr, and PrevHistoryDigest must all be set or all be nil") + } + if cfg.PrevSeqNr != nil && !(0 < *cfg.PrevSeqNr) { + return fmt.Errorf("PrevSeqNr (%v) must be positive if non-nil", *cfg.PrevSeqNr) + } + if !(0 <= cfg.F && cfg.F*3 < cfg.N()) { return fmt.Errorf("F (%v) must be non-negative and less than N/3 (N = %v)", cfg.F, cfg.N()) diff --git a/offchainreporting2plus/internal/config/ocr3_1config/serialize.go b/offchainreporting2plus/internal/config/ocr3_1config/serialize.go index 382517b7..7f84134a 100644 --- a/offchainreporting2plus/internal/config/ocr3_1config/serialize.go +++ b/offchainreporting2plus/internal/config/ocr3_1config/serialize.go @@ -70,6 +70,9 @@ type offchainConfig struct { WarnDurationCommitted time.Duration MaxDurationShouldAcceptAttestedReport time.Duration MaxDurationShouldTransmitAcceptedReport time.Duration + PrevConfigDigest *types.ConfigDigest + PrevSeqNr *uint64 + PrevHistoryDigest *types.HistoryDigest SharedSecretEncryptions config.SharedSecretEncryptions } @@ -135,6 +138,24 @@ func deprotoOffchainConfig( return offchainConfig{}, fmt.Errorf("could not unmarshal shared protobuf: %w", err) } + var prevConfigDigest *types.ConfigDigest + if len(offchainConfigProto.PrevConfigDigest) != 0 { + d, err := types.BytesToConfigDigest(offchainConfigProto.PrevConfigDigest) + if err != nil { + return offchainConfig{}, fmt.Errorf("invalid PrevConfigDigest: %w", err) + } + prevConfigDigest = &d + } + + var prevHistoryDigest *types.HistoryDigest + if len(offchainConfigProto.PrevHistoryDigest) != 0 { + d, err := types.BytesToHistoryDigest(offchainConfigProto.PrevHistoryDigest) + if err != nil { + return offchainConfig{}, fmt.Errorf("invalid PrevHistoryDigest: %w", err) + } + prevHistoryDigest = &d + } + return offchainConfig{ time.Duration(offchainConfigProto.GetDeltaProgressNanoseconds()), util.PointerIntegerCast[time.Duration](offchainConfigProto.DeltaResendNanoseconds), @@ -186,6 +207,9 @@ func deprotoOffchainConfig( time.Duration(offchainConfigProto.GetWarnDurationCommittedNanoseconds()), time.Duration(offchainConfigProto.GetMaxDurationShouldAcceptAttestedReportNanoseconds()), time.Duration(offchainConfigProto.GetMaxDurationShouldTransmitAcceptedReportNanoseconds()), + prevConfigDigest, + offchainConfigProto.PrevSeqNr, + prevHistoryDigest, sharedSecretEncryptions, }, nil } @@ -230,6 +254,16 @@ func enprotoOffchainConfig(o offchainConfig) OffchainConfigProto { offchainPublicKeys = append(offchainPublicKeys, k[:]) } sharedSecretEncryptions := enprotoSharedSecretEncryptions(o.SharedSecretEncryptions) + + var prevConfigDigestBytes []byte + if o.PrevConfigDigest != nil { + prevConfigDigestBytes = o.PrevConfigDigest[:] + } + var prevHistoryDigestBytes []byte + if o.PrevHistoryDigest != nil { + prevHistoryDigestBytes = o.PrevHistoryDigest[:] + } + return OffchainConfigProto{ // zero-initialize protobuf built-ins protoimpl.MessageState{}, @@ -275,6 +309,9 @@ func enprotoOffchainConfig(o offchainConfig) OffchainConfigProto { uint64(o.WarnDurationCommitted), uint64(o.MaxDurationShouldAcceptAttestedReport), uint64(o.MaxDurationShouldTransmitAcceptedReport), + prevConfigDigestBytes, + o.PrevSeqNr, + prevHistoryDigestBytes, &sharedSecretEncryptions, } } diff --git a/offchainreporting2plus/internal/config/ocr3_1config/shared_config.go b/offchainreporting2plus/internal/config/ocr3_1config/shared_config.go index 8fbe6285..62644c24 100644 --- a/offchainreporting2plus/internal/config/ocr3_1config/shared_config.go +++ b/offchainreporting2plus/internal/config/ocr3_1config/shared_config.go @@ -186,6 +186,9 @@ func ContractSetConfigArgsFromSharedConfigDeterministic( c.WarnDurationCommitted, c.MaxDurationShouldAcceptAttestedReport, c.MaxDurationShouldTransmitAcceptedReport, + c.PrevConfigDigest, + c.PrevSeqNr, + c.PrevHistoryDigest, sharedSecretEncryptions, }).serialize() return signers, transmitters, uint8(c.F), c.OnchainConfig, config.OCR3_1OffchainConfigVersion, offchainConfig_, nil diff --git a/offchainreporting2plus/internal/managed/managed_ocr3_1_oracle.go b/offchainreporting2plus/internal/managed/managed_ocr3_1_oracle.go index 1c49a160..28fb93f4 100644 --- a/offchainreporting2plus/internal/managed/managed_ocr3_1_oracle.go +++ b/offchainreporting2plus/internal/managed/managed_ocr3_1_oracle.go @@ -9,8 +9,10 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/internal/jmt" "github.com/smartcontractkit/libocr/internal/loghelper" "github.com/smartcontractkit/libocr/internal/metricshelper" + "github.com/smartcontractkit/libocr/internal/util" "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config/ocr3_1config" "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/managed/limits" "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3_1/protocol" @@ -154,7 +156,7 @@ func RunManagedOCR3_1Oracle[RI any]( "error": err, "reportingPluginInfo": reportingPluginInfo, }) - return fmt.Errorf("ManagedOCR3_1Oracle: invalid MercuryPluginInfo"), false + return fmt.Errorf("ManagedOCR3_1Oracle: invalid ReportingPluginInfo"), false } maxSigLen := onchainKeyring.MaxSignatureLength() @@ -222,24 +224,42 @@ func RunManagedOCR3_1Oracle[RI any]( "ManagedOCR3_1Oracle: error during netEndpoint.Close()", ) + if prev, ok := sharedConfig.PublicConfig.GetPrevFields(); ok { + err := tryCopyFromPrevInstance( + ctx, + sharedConfig.PublicConfig, + logger, + &devNullRegisterer{}, + registerer, + reportingPluginInfo.Limits, + keyValueDatabaseFactory, + prev.PrevConfigDigest, + prev.PrevSeqNr, + sharedConfig.ConfigDigest, + ) + if err != nil { + return fmt.Errorf("ManagedOCR3_1Oracle: error during tryCopyFromPrevInstance: %w", err), true + } + } + keyValueDatabase, err := keyValueDatabaseFactory.NewKeyValueDatabase(sharedConfig.ConfigDigest) if err != nil { - return fmt.Errorf("ManagedOCR3_1Oracle: error during NewKeyValueDatabase: %w", err), false + return fmt.Errorf("ManagedOCR3_1Oracle: error during NewKeyValueDatabase: %w", err), true } defer loghelper.CloseLogError( keyValueDatabase, logger, "ManagedOCR3_1Oracle: error during keyValueDatabase.Close()", ) - keyValueDatabaseWithMetrics := shim.NewKeyValueDatabaseWithMetrics(keyValueDatabase, metricsRegisterer, logger) + keyValueDatabaseWithMetrics := shim.NewKeyValueDatabaseWithMetrics(keyValueDatabase, registerer, logger) defer loghelper.CloseLogError( keyValueDatabaseWithMetrics, logger, "ManagedOCR3_1Oracle: error during keyValueDatabaseWithMetrics.Close()", ) - semanticOCR3_1KeyValueDatabase, err := shim.NewSemanticOCR3_1KeyValueDatabase(keyValueDatabaseWithMetrics, reportingPluginInfo.Limits, sharedConfig.PublicConfig, logger, metricsRegisterer) + semanticOCR3_1KeyValueDatabase, err := shim.NewSemanticOCR3_1KeyValueDatabase(keyValueDatabaseWithMetrics, reportingPluginInfo.Limits, sharedConfig.PublicConfig, logger, registerer) if err != nil { - return fmt.Errorf("ManagedOCR3_1Oracle: error during NewSemanticOCR3_1KeyValueDatabase: %w", err), false + return fmt.Errorf("ManagedOCR3_1Oracle: error during NewSemanticOCR3_1KeyValueDatabase: %w", err), true } defer loghelper.CloseLogError( semanticOCR3_1KeyValueDatabase, @@ -304,3 +324,341 @@ func validateOCR3_1ReportingPluginLimits(limits ocr3_1types.ReportingPluginLimit } return err } + +func tryCopyFromPrevInstance( + ctx context.Context, + publicConfig ocr3_1config.PublicConfig, + logger loghelper.LoggerWithContext, + prevRegisterer prometheus.Registerer, + nextRegisterer prometheus.Registerer, + reportingPluginLimits ocr3_1types.ReportingPluginLimits, + keyValueDatabaseFactory ocr3_1types.KeyValueDatabaseFactory, + prevConfigDigest types.ConfigDigest, + prevSeqNr uint64, + nextConfigDigest types.ConfigDigest, +) error { + nextKeyValueDatabase, err := keyValueDatabaseFactory.NewKeyValueDatabase(nextConfigDigest) + if err != nil { + return fmt.Errorf("error during NewKeyValueDatabase: %w", err) + } + defer nextKeyValueDatabase.Close() + + nextSemanticKeyValueDatabase, err := shim.NewSemanticOCR3_1KeyValueDatabase( + nextKeyValueDatabase, + reportingPluginLimits, + publicConfig, + logger, + nextRegisterer, + ) + if err != nil { + return fmt.Errorf("error during NewSemanticOCR3_1KeyValueDatabase: %w", err) + } + defer nextSemanticKeyValueDatabase.Close() + + nextHighestCommittedSeqNr, nextTreeSyncPhase, err := readHighestCommittedSeqNrAndTreeSyncPhase(nextSemanticKeyValueDatabase) + if err != nil { + return fmt.Errorf("error during readHighestCommittedSeqNrAndTreeSyncPhase: %w", err) + } + + if nextHighestCommittedSeqNr >= prevSeqNr { + logger.Info("⚙️ tryCopyFromPrevInstance: next instance kvdb is already synced, nothing to do", commontypes.LogFields{ + "nextHighestCommittedSeqNr": nextHighestCommittedSeqNr, + "prevSeqNr": prevSeqNr, + }) + return nil + } + + err = ensureKeyValueDatabaseIsPristine(nextHighestCommittedSeqNr, nextTreeSyncPhase) + if err != nil { + logger.Warn("⚙️ tryCopyFromPrevInstance: next instance kvdb is not pristine, we won't copy from prev instance."+ + " If you would like to copy from prev instance, you should delete the next instance kvdb and restart.", commontypes.LogFields{ + "error": err, + }) + return nil + } + + prevKeyValueDatabase, err := keyValueDatabaseFactory.NewKeyValueDatabaseIfExists(prevConfigDigest) + if err != nil { + if errors.Is(err, ocr3_1types.ErrKeyValueDatabaseDoesNotExist) { + logger.Warn("⚙️ tryCopyFromPrevInstance: prev instance kvdb does not exist, nothing to do", commontypes.LogFields{ + "prevConfigDigest": prevConfigDigest, + }) + return nil + } + return fmt.Errorf("error during prev keyValueDatabaseFactory.NewKeyValueDatabaseIfExists: %w", err) + } + defer prevKeyValueDatabase.Close() + + // We do not have access to the public config of the prev instance, so we + // reconstruct a good-enough public config for opening the semantic kvdb of + // the prev instance and reading the tree sync chunks. + prevPublicConfig := ocr3_1config.PublicConfig{ + // We do not know the snapshot interval of the prev instance, but + // PrevSeqNr is guaranteed to be a snapshot sequence number in the prev + // instance, and we will call ReadTreeSyncChunk with it. + SnapshotInterval: util.PointerTo(uint64(1)), + ConfigDigest: prevConfigDigest, + // Set all tree sync chunking parameters to be the same as the next + // instance. They are guaranteed to fit a maximally sized key-value due + // to checkPublicConfigParameters. + MaxTreeSyncChunkKeys: publicConfig.MaxTreeSyncChunkKeys, + MaxTreeSyncChunkKeysPlusValuesBytes: publicConfig.MaxTreeSyncChunkKeysPlusValuesBytes, + } + prevSemanticKeyValueDatabase, err := shim.NewSemanticOCR3_1KeyValueDatabase( + prevKeyValueDatabase, + reportingPluginLimits, + prevPublicConfig, + logger, + prevRegisterer, + ) + if err != nil { + return fmt.Errorf("error during NewSemanticOCR3_1KeyValueDatabase: %w", err) + } + defer prevSemanticKeyValueDatabase.Close() + + prevTxn, err := prevSemanticKeyValueDatabase.NewReadTransactionUnchecked() + if err != nil { + return fmt.Errorf("error during NewReadTransactionUnchecked: %w", err) + } + defer prevTxn.Discard() + + genesisBlock, err := findGenesisBlockInPrevKeyValueDatabase(logger, publicConfig, prevTxn, prevSeqNr) + if err != nil { + return fmt.Errorf("error during findGenesisBlockInPrevKeyValueDatabase: %w", err) + } + if genesisBlock == nil { + logger.Warn("⚙️ tryCopyFromPrevInstance: prev seqnr block does not exist, nothing to do", commontypes.LogFields{ + "prevSeqNr": prevSeqNr, + "prevConfigDigest": prevConfigDigest, + }) + return nil + } + + startIndex := jmt.Digest{} + for { + logger.Info("⚙️ tryCopyFromPrevInstance: copying chunk from prev instance to next instance", commontypes.LogFields{ + "startIndex": fmt.Sprintf("%x", startIndex), + "prevSeqNr": prevSeqNr, + }) + endInclIndex, done, err := copyChunkFromPrevInstance( + publicConfig, + prevSeqNr, + genesisBlock.StateRootDigest, + startIndex, + prevTxn, + nextSemanticKeyValueDatabase, + ) + if err != nil { + return fmt.Errorf("error during copyChunkFromPrevInstance: %w", err) + } + + if done { + break + } + + var ok bool + startIndex, ok = jmt.IncrementDigest(endInclIndex) + if !ok { + return fmt.Errorf("failed to increment endInclIndex even though we are not done copying chunks") + } + + if ctx.Err() != nil { + return ctx.Err() + } + } + + nextTxn, err := nextSemanticKeyValueDatabase.NewSerializedReadWriteTransactionUnchecked() + if err != nil { + return fmt.Errorf("error during NewSerializedReadWriteTransactionUnchecked: %w", err) + } + defer nextTxn.Discard() + + err = nextTxn.WritePrevInstanceGenesisStateTransitionBlock(*genesisBlock) + if err != nil { + return fmt.Errorf("error during WritePrevInstanceGenesisStateTransitionBlock: %w", err) + } + + err = nextTxn.WriteHighestCommittedSeqNr(prevSeqNr) + if err != nil { + return fmt.Errorf("error during WriteHighestCommittedSeqNr: %w", err) + } + + err = nextTxn.WriteLowestPersistedSeqNr(prevSeqNr) + if err != nil { + return fmt.Errorf("error during WriteLowestPersistedSeqNr: %w", err) + } + + err = nextTxn.Commit() + if err != nil { + return fmt.Errorf("error during Commit: %w", err) + } + + return nil +} + +func readHighestCommittedSeqNrAndTreeSyncPhase(semanticKeyValueDatabase protocol.KeyValueDatabase) (uint64, protocol.TreeSyncPhase, error) { + txn, err := semanticKeyValueDatabase.NewReadTransactionUnchecked() + if err != nil { + return 0, protocol.TreeSyncPhaseInactive, fmt.Errorf("error during NewReadTransactionUnchecked: %w", err) + } + defer txn.Discard() + + highestCommittedSeqNr, err := txn.ReadHighestCommittedSeqNr() + if err != nil { + return 0, protocol.TreeSyncPhaseInactive, fmt.Errorf("error during ReadHighestCommittedSeqNr: %w", err) + } + + treeSyncStatus, err := txn.ReadTreeSyncStatus() + if err != nil { + return 0, protocol.TreeSyncPhaseInactive, fmt.Errorf("error during ReadTreeSyncStatus: %w", err) + } + + return highestCommittedSeqNr, treeSyncStatus.Phase, nil +} + +func ensureKeyValueDatabaseIsPristine(highestCommittedSeqNr uint64, treeSyncPhase protocol.TreeSyncPhase) error { + if highestCommittedSeqNr != 0 { + return fmt.Errorf("highest committed sequence number is not 0") + } + if treeSyncPhase != protocol.TreeSyncPhaseInactive { + return fmt.Errorf("tree sync phase is not inactive, it is %v", treeSyncPhase) + } + return nil +} + +func findGenesisBlockInPrevKeyValueDatabase( + logger commontypes.Logger, + publicConfig ocr3_1config.PublicConfig, + prevTxn protocol.KeyValueDatabaseReadTransaction, + prevSeqNr uint64, +) (*protocol.GenesisStateTransitionBlock, error) { + prev, ok := publicConfig.GetPrevFields() + if !ok { + return nil, fmt.Errorf("previous instance is not specified in PublicConfig") + } + + // ensure prevSeqNr is in range [lowest, highest] + prevLowestPersistedSeqNr, err := prevTxn.ReadLowestPersistedSeqNr() + if err != nil { + return nil, fmt.Errorf("error during ReadLowestPersistedSeqNr: %w", err) + } + if prevSeqNr < prevLowestPersistedSeqNr { + logger.Warn("⚙️ findGenesisBlockInPrevKeyValueDatabase: prevSeqNr is less than prevLowestPersistedSeqNr", commontypes.LogFields{ + "prevSeqNr": prevSeqNr, + "prevLowestPersistedSeqNr": prevLowestPersistedSeqNr, + }) + return nil, nil + } + + prevHighestCommittedSeqNr, err := prevTxn.ReadHighestCommittedSeqNr() + if err != nil { + return nil, fmt.Errorf("error during ReadHighestCommittedSeqNr: %w", err) + } + if prevSeqNr > prevHighestCommittedSeqNr { + logger.Warn("⚙️ findGenesisBlockInPrevKeyValueDatabase: prevSeqNr is greater than prevHighestCommittedSeqNr", commontypes.LogFields{ + "prevSeqNr": prevSeqNr, + "prevHighestCommittedSeqNr": prevHighestCommittedSeqNr, + }) + return nil, nil + } + + treeSyncStatus, err := prevTxn.ReadTreeSyncStatus() + if err != nil { + return nil, fmt.Errorf("error during ReadTreeSyncStatus: %w", err) + } + if treeSyncStatus.Phase != protocol.TreeSyncPhaseInactive { + logger.Warn("⚙️ findGenesisBlockInPrevKeyValueDatabase: tree sync phase is not inactive, can't read from prev kvdb", commontypes.LogFields{ + "treeSyncStatus": treeSyncStatus, + }) + return nil, nil + } + + // check that history digest matches the block at prevSeqNr + prevAstb, err := prevTxn.ReadAttestedStateTransitionBlock(prevSeqNr) + if err != nil { + return nil, fmt.Errorf("error during ReadAttestedStateTransitionBlock: %w", err) + } + if prevAstb.StateTransitionBlock.BlockSeqNr != prevSeqNr { + // block does not exist + return nil, nil + } + + gstb := protocol.AttestedToGenesisStateTransitionBlock(prev.PrevConfigDigest, prevAstb) + err = protocol.VerifyGenesisStateTransitionBlockFromPrevInstance(publicConfig, gstb) + if err != nil { + return nil, fmt.Errorf("error during VerifyGenesisStateTransitionBlockFromPrevInstance: %w", err) + } + return &gstb, nil +} + +func copyChunkFromPrevInstance( + publicConfig ocr3_1config.PublicConfig, // non essential + prevSeqNr uint64, + prevStateRootDigest protocol.StateRootDigest, + startIndex jmt.Digest, + prevTxn protocol.KeyValueDatabaseReadTransaction, + nextSemanticKeyValueDatabase protocol.KeyValueDatabase, +) (endInclIndex jmt.Digest, done bool, err error) { + nextTxn, err := nextSemanticKeyValueDatabase.NewSerializedReadWriteTransactionUnchecked() + if err != nil { + return jmt.Digest{}, false, fmt.Errorf("error during NewSerializedReadWriteTransactionUnchecked: %w", err) + } + defer nextTxn.Discard() + + requestEndInclIndex := jmt.MaxDigest + endInclIndex, boundingLeaves, keyValues, err := prevTxn.ReadTreeSyncChunk( + prevSeqNr, + startIndex, + requestEndInclIndex, + publicConfig.GetMaxTreeSyncChunkKeysPlusValuesBytes(), + ) + if err != nil { + return jmt.Digest{}, false, fmt.Errorf("error during ReadTreeSyncChunk: %w", err) + } + + writeAndVerifyTreeSyncChunkResult, err := nextTxn.VerifyAndWriteTreeSyncChunk( + prevStateRootDigest, + prevSeqNr, + startIndex, + requestEndInclIndex, + endInclIndex, + boundingLeaves, + keyValues, + ) + if err != nil { + return jmt.Digest{}, false, fmt.Errorf("error during VerifyAndWriteTreeSyncChunk: %w", err) + } + + switch writeAndVerifyTreeSyncChunkResult { + case protocol.VerifyAndWriteTreeSyncChunkResultOkComplete: + done = true + case protocol.VerifyAndWriteTreeSyncChunkResultOkNeedMore: + done = false + case protocol.VerifyAndWriteTreeSyncChunkResultByzantine: + return jmt.Digest{}, false, fmt.Errorf("byzantine error during VerifyAndWriteTreeSyncChunk") + case protocol.VerifyAndWriteTreeSyncChunkResultUnrelatedError: + return jmt.Digest{}, false, fmt.Errorf("unrelated error during VerifyAndWriteTreeSyncChunk") + } + + err = nextTxn.Commit() + if err != nil { + return jmt.Digest{}, false, fmt.Errorf("error during Commit: %w", err) + } + + return endInclIndex, done, nil +} + +type devNullRegisterer struct{} + +var _ prometheus.Registerer = (*devNullRegisterer)(nil) + +func (d *devNullRegisterer) Register(collector prometheus.Collector) error { + return nil +} + +func (d *devNullRegisterer) MustRegister(collectors ...prometheus.Collector) { +} + +func (d *devNullRegisterer) Unregister(collector prometheus.Collector) bool { + return false +} diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go b/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go index 4f444a0a..23962167 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go @@ -3,6 +3,7 @@ package protocol import ( "context" "fmt" + "iter" "slices" "time" @@ -380,8 +381,29 @@ type blobChunkId struct { chunkIndex uint64 } -func numChunks(payloadLength uint64, blobChunkSize int) uint64 { - return (payloadLength + uint64(blobChunkSize) - 1) / uint64(blobChunkSize) +func numChunks(payloadLength uint64, cfgBlobChunkSize int) uint64 { + return (payloadLength + uint64(cfgBlobChunkSize) - 1) / uint64(cfgBlobChunkSize) +} + +func chunkBytes(payloadLength uint64, chunkIndex uint64, cfgBlobChunkSize int) (uint64, bool) { + if !(0 <= chunkIndex && chunkIndex < numChunks(payloadLength, cfgBlobChunkSize)) { + return 0, false + } + cfgBlobChunkSizeU64 := uint64(cfgBlobChunkSize) + remainingAfterPreviousChunks := payloadLength - (chunkIndex * cfgBlobChunkSizeU64) + return min(remainingAfterPreviousChunks, cfgBlobChunkSizeU64), true +} + +func chunkPayload(payload []byte, cfgBlobChunkSize int) iter.Seq2[uint64, []byte] { + return func(yield func(uint64, []byte) bool) { + chunkIdx := uint64(0) + for chunk := range slices.Chunk(payload, cfgBlobChunkSize) { + if !yield(chunkIdx, chunk) { + return + } + chunkIdx++ + } + } } type blobFetchMeta struct { @@ -483,7 +505,11 @@ func (b *blob) weOweOfferResponse() bool { } func (b *blob) haveAllChunks() bool { - return !slices.Contains(b.chunkHaves, false) + return haveAllChunks(b.chunkHaves, b.chunkDigests, b.chunkDigestsRoot) +} + +func haveAllChunks(chunkHaves []bool, chunkDigests []BlobChunkDigest, chunkDigestsRoot mt.Digest) bool { + return !slices.Contains(chunkHaves, false) && blobtypes.MakeBlobChunkDigestsRoot(chunkDigests) == chunkDigestsRoot } func (b *blob) prunable() bool { @@ -709,7 +735,7 @@ func (bex *blobExchangeState[RI]) messageBlobOffer(msg MessageBlobOffer[RI], sen } // check if we maybe already have this blob in full - if !slices.Contains(chunkHaves, false) { + if haveAllChunks(chunkHaves, chunkDigests, msg.ChunkDigestsRoot) { bex.logger.Debug("received MessageBlobOffer for which we already have the payload", commontypes.LogFields{ "blobDigest": blobDigest, "sender": sender, @@ -1230,6 +1256,22 @@ func (bex *blobExchangeState[RI]) messageBlobChunkResponse(msg MessageBlobChunkR return } + expectedChunkBytes, ok := chunkBytes(blob.payloadLength, chunkIndex, bex.config.GetBlobChunkBytes()) + + if !ok || uint64(len(msg.Chunk)) != expectedChunkBytes { + bex.logger.Warn("dropping MessageBlobChunkResponse, incorrectly sized chunk", commontypes.LogFields{ + "blobDigest": msg.BlobDigest, + "sender": sender, + "chunkIndex": chunkIndex, + "chunkCount": len(blob.chunkDigests), + "payloadLength": blob.payloadLength, + "expectedChunkBytes": expectedChunkBytes, + "actualChunkBytes": len(msg.Chunk), + }) + bex.chunkRequesterGadget.MarkBadResponse(bcid, sender) + return + } + if blob.chunkHaves[chunkIndex] { bex.logger.Debug("dropping MessageBlobChunkResponse, already have chunk", commontypes.LogFields{ "blobDigest": msg.BlobDigest, @@ -1364,9 +1406,7 @@ func (bex *blobExchangeState[RI]) processBlobBroadcastRequest(req blobBroadcastR chunkDigests := make([]BlobChunkDigest, 0, numChunks(payloadLength, cfgBlobChunkSize)) chunkHaves := make([]bool, 0, numChunks(payloadLength, cfgBlobChunkSize)) - for i, chunkIdx := 0, 0; i < len(payload); i, chunkIdx = i+cfgBlobChunkSize, chunkIdx+1 { - payloadChunk := payload[i:min(i+cfgBlobChunkSize, len(payload))] - + for _, payloadChunk := range chunkPayload(payload, cfgBlobChunkSize) { // prepare for offer chunkDigest := blobtypes.MakeBlobChunkDigest(payloadChunk) chunkDigests = append(chunkDigests, chunkDigest) @@ -1531,8 +1571,7 @@ func (bex *blobExchangeState[RI]) writeBlobBeforeBroadcast(blobDigest BlobDigest chunkHaves := make([]bool, numChunks) chunkDigests := make([]BlobChunkDigest, numChunks) - for i, chunkIdx := 0, uint64(0); i < len(payload); i, chunkIdx = i+cfgBlobChunkSize, chunkIdx+1 { - payloadChunk := payload[i:min(i+cfgBlobChunkSize, len(payload))] + for chunkIdx, payloadChunk := range chunkPayload(payload, cfgBlobChunkSize) { if err := tx.WriteBlobChunk(blobDigest, chunkIdx, payloadChunk); err != nil { return fmt.Errorf("failed to write local blob chunk: %w", err) } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/kvdb.go b/offchainreporting2plus/internal/ocr3_1/protocol/kvdb.go index 943d732f..354e3086 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/kvdb.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/kvdb.go @@ -61,6 +61,8 @@ type KeyValueDatabaseSemanticRead interface { jmt.RootReader jmt.NodeReader + + ReadPrevInstanceGenesisStateTransitionBlock() (*GenesisStateTransitionBlock, error) } type KeyValueDatabaseReadWriteTransaction interface { @@ -114,12 +116,15 @@ type KeyValueDatabaseSemanticWrite interface { WriteLowestPersistedSeqNr(seqNr uint64) error // VerifyAndWriteTreeSyncChunk first verifies that the keyValues are fully // and without omissions included in the key digest range of [startIndex, - // endInclIndex]. Only after doing so, it writes all keyValues into the tree - // and flat representation. + // endInclIndex]. It also verifies that endInclIndex is in the range of + // [startIndex, requestEndInclIndex], and that keyValues is non-empty unless + // requestEndInclIndex == endInclIndex. Only after doing all the above, it + // writes all keyValues into the tree and flat representation. VerifyAndWriteTreeSyncChunk( targetRootDigest StateRootDigest, targetSeqNr uint64, startIndex jmt.Digest, + requestEndInclIndex jmt.Digest, endInclIndex jmt.Digest, boundingLeaves []jmt.BoundingLeaf, keyValues []KeyValuePair, @@ -145,6 +150,8 @@ type KeyValueDatabaseSemanticWrite interface { DeleteStaleNodes(maxStaleSinceVersion jmt.Version, maxItems int) (done bool, err error) DestructiveDestroyForTreeSync(n int) (done bool, err error) + + WritePrevInstanceGenesisStateTransitionBlock(genesisStateTransitionBlock GenesisStateTransitionBlock) error } type BlobMeta struct { diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/message.go b/offchainreporting2plus/internal/ocr3_1/protocol/message.go index 0026e5fa..6f2840cb 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/message.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/message.go @@ -443,6 +443,7 @@ type MessageBlockSyncResponse[RI any] struct { RequestStartSeqNr uint64 RequestEndExclSeqNr uint64 AttestedStateTransitionBlocks []AttestedStateTransitionBlock // must be contiguous and (if non-empty) starting at RequestStartSeqNr + GenesisStateTransitionBlock *GenesisStateTransitionBlock // optional genesis block info when syncing from prev instance } var _ MessageToStateSync[struct{}] = MessageBlockSyncResponse[struct{}]{} diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go b/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go index f8b20d06..72da6327 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go @@ -426,7 +426,7 @@ func (o *oracleState[RI]) restoreFromDatabase() (PacemakerState, CertifiedPrepar }) } else { o.logger.Info("restoreFromDatabase: did not find cert, starting at genesis", nil) - cert = &CertifiedCommit{} + cert = GenesisCertifiedPrepareOrCommit(o.config.PublicConfig) } return paceState, cert, nil diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go index 92557ea2..dfa595d2 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go @@ -200,12 +200,15 @@ func (outgen *outcomeGenerationState[RI]) run(restoredCert CertifiedPrepareOrCom var restoredCommitedSeqNr uint64 var restoredCommitedHistoryDigest HistoryDigest if restoredCert == nil { - restoredCert = &CertifiedCommit{} // genesis + // must not be nil per restoreFromDatabase + panic("restoredCert is nil") } - if commitQC, ok := restoredCert.(*CertifiedCommit); ok { - restoredCommitedSeqNr = commitQC.SeqNr() - restoredCommitedHistoryDigest = commitQC.HistoryDigest(outgen.config.ConfigDigest) - } else if prepareQc, ok := restoredCert.(*CertifiedPrepare); ok { + switch cpoc := restoredCert.(type) { + case *GenesisFromScratch, *GenesisFromPrevInstance, *CertifiedCommit: + restoredCommitedSeqNr = cpoc.SeqNr() + restoredCommitedHistoryDigest = cpoc.HistoryDigest(outgen.config.ConfigDigest) + case *CertifiedPrepare: + prepareQc := cpoc if prepareQc.SeqNr() >= 1 { restoredCommitedSeqNr = prepareQc.SeqNr() - 1 restoredCommitedHistoryDigest = prepareQc.PrevHistoryDigest @@ -473,6 +476,10 @@ func callPluginFromOutcomeGenerationBackground[T any]( func (outgen *outcomeGenerationState[RI]) sendStateSyncRequestFromCertifiedPrepareOrCommit(cert CertifiedPrepareOrCommit) { var seqNr uint64 switch cert := cert.(type) { + case *GenesisFromScratch: + seqNr = cert.SeqNr() + case *GenesisFromPrevInstance: + seqNr = cert.PrevSeqNr case *CertifiedPrepare: seqNr = cert.PrepareSeqNr - 1 case *CertifiedCommit: @@ -592,11 +599,7 @@ func (outgen *outcomeGenerationState[RI]) tryToMoveCertAndKVStateToCommitQC(comm commitQC.CommitQuorumCertificate, } - if err := commitQCAttestedStateTransitionBlock.Verify( - outgen.config.ConfigDigest, - outgen.config.OracleIdentities, - outgen.config.ByzQuorumSize(), - ); err != nil { + if err := commitQCAttestedStateTransitionBlock.Verify(outgen.config.PublicConfig); err != nil { outgen.logger.Critical("commitQCAttestedStateTransitionBlock is invalid, very surprising!", commontypes.LogFields{ "commitQCSeqNr": commitQC.CommitSeqNr, "commitQC": commitQC, diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go index c9707e7b..ef7ffd8c 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go @@ -74,8 +74,7 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar { err := msg.EpochStartProof.Verify( outgen.ID(), - outgen.config.OracleIdentities, - outgen.config.ByzQuorumSize(), + outgen.config.PublicConfig, ) if err != nil { outgen.logger.Warn("dropping MessageEpochStart containing invalid StartRoundQuorumCertificate", commontypes.LogFields{ @@ -91,10 +90,12 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar outgen.refreshCommittedSeqNrAndCert() // call in case stasy has made progress in the meanwhile outgen.sendStateSyncRequestFromCertifiedPrepareOrCommit(msg.EpochStartProof.HighestCertified) - if msg.EpochStartProof.HighestCertified.IsGenesis() { + switch cpoc := msg.EpochStartProof.HighestCertified.(type) { + case *GenesisFromScratch, *GenesisFromPrevInstance: outgen.sharedState.firstSeqNrOfEpoch = outgen.sharedState.committedSeqNr + 1 outgen.startSubsequentFollowerRound() - } else if commitQC, ok := msg.EpochStartProof.HighestCertified.(*CertifiedCommit); ok { + case *CertifiedCommit: + commitQC := cpoc outgen.tryToMoveCertAndKVStateToCommitQC(commitQC) if outgen.sharedState.committedSeqNr != commitQC.CommitSeqNr { outgen.logger.Warn("cannot process MessageEpochStart, mismatching committedSeqNr, will not be able to participate in epoch", commontypes.LogFields{ @@ -109,15 +110,9 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar return } outgen.startSubsequentFollowerRound() - } else { + case *CertifiedPrepare: // We're dealing with a re-proposal from a failed epoch - prepareQc, ok := msg.EpochStartProof.HighestCertified.(*CertifiedPrepare) - if !ok { - outgen.logger.Critical("cast to CertifiedPrepare failed while processing MessageEpochStart", commontypes.LogFields{ - "seqNr": outgen.sharedState.seqNr, - }) - return - } + prepareQc := cpoc if prepareQc.SeqNr() < outgen.sharedState.committedSeqNr { outgen.logger.Warn("cannot process MessageEpochStart, prepareQC seqNr is less than committedSeqNr, will not be able to participate in epoch", commontypes.LogFields{ @@ -920,7 +915,7 @@ func (outgen *outcomeGenerationState[RI]) tryProcessCommitPool() { } if outgen.followerState.openKVTxn == nil { - outgen.logger.Error("no open kv transaction, unexpected", commontypes.LogFields{ + outgen.logger.Error("no open kv transaction, we likely already failed to commit to kvdb in a prior call to tryProcessCommitPool", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "phase": outgen.followerState.phase, }) @@ -930,7 +925,7 @@ func (outgen *outcomeGenerationState[RI]) tryProcessCommitPool() { // Write attested state transition block { stb := StateTransitionBlock{ - stid.PrevHistoryDigest, + sti.PrevHistoryDigest, commitQC.CommitEpoch, commitQC.CommitSeqNr, sti.InputsDigest, @@ -984,7 +979,7 @@ func (outgen *outcomeGenerationState[RI]) tryProcessCommitPool() { } if outgen.sharedState.committedSeqNr != commitQC.CommitSeqNr { - outgen.logger.Warn("could not move committed seq nr to commit qc, abandoning epoch", commontypes.LogFields{ + outgen.logger.Warn("could not move committed seq nr to commit qc, will retry if another MessageCommit is received", commontypes.LogFields{ "commitSeqNr": commitQC.CommitSeqNr, "committedSeqNr": outgen.sharedState.committedSeqNr, }) @@ -1143,7 +1138,8 @@ func (outgen *outcomeGenerationState[RI]) commit(commit CertifiedCommit) bool { outgen.metrics.committedSeqNr.Set(float64(commit.SeqNr())) outgen.logger.Debug("✅ committed", commontypes.LogFields{ - "seqNr": commit.SeqNr(), + "seqNr": commit.SeqNr(), + "historyDigest": outgen.sharedState.committedHistoryDigest, }) select { diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go index 05fcb501..8862bf1f 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go @@ -117,11 +117,7 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp return } - if err := maxRequest.message.HighestCertified.Verify( - outgen.config.ConfigDigest, - outgen.config.OracleIdentities, - outgen.config.ByzQuorumSize(), - ); err != nil { + if err := maxRequest.message.HighestCertified.Verify(outgen.config.PublicConfig); err != nil { maxRequest.bad = true outgen.logger.Warn("MessageEpochStartRequest.HighestCertified is invalid", commontypes.LogFields{ "sender": *maxSender, @@ -154,7 +150,7 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp // This is a sanity check to ensure that we only construct epochStartProofs that are actually valid. // This should never fail. - if err := epochStartProof.Verify(outgen.ID(), outgen.config.OracleIdentities, outgen.config.ByzQuorumSize()); err != nil { + if err := epochStartProof.Verify(outgen.ID(), outgen.config.PublicConfig); err != nil { outgen.logger.Critical("EpochStartProof is invalid, very surprising!", commontypes.LogFields{ "proof": epochStartProof, "error": err, @@ -189,10 +185,12 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp return } - if epochStartProof.HighestCertified.IsGenesis() { + switch cpoc := epochStartProof.HighestCertified.(type) { + case *GenesisFromScratch, *GenesisFromPrevInstance: outgen.sharedState.firstSeqNrOfEpoch = outgen.sharedState.committedSeqNr + 1 outgen.startSubsequentLeaderRound() - } else if commitQC, ok := epochStartProof.HighestCertified.(*CertifiedCommit); ok { + case *CertifiedCommit: + commitQC := cpoc // Try to commit the block corresponding to the commitQC if (1) we have // not done so and (2) if we have all available information present, // i.e. the StateTransitionBlock corresponding to the commitQC is @@ -209,12 +207,8 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp } outgen.sharedState.firstSeqNrOfEpoch = outgen.sharedState.committedSeqNr + 1 outgen.startSubsequentLeaderRound() - } else { - prepareQc, ok := epochStartProof.HighestCertified.(*CertifiedPrepare) - if !ok { - outgen.logger.Critical("cast to CertifiedPrepare failed while processing MessageEpochStartRequest", nil) - return - } + case *CertifiedPrepare: + prepareQc := cpoc if prepareQc.SeqNr() < outgen.sharedState.committedSeqNr { @@ -240,6 +234,10 @@ func (outgen *outcomeGenerationState[RI]) couldLeaderCreateProposalInEpoch(highe ) switch cpoc := highestCertified.(type) { + case *GenesisFromScratch, *GenesisFromPrevInstance: + highestCertifiedSeqNr = cpoc.SeqNr() + + highestCertifiedStateTransitionInputsDigest = StateTransitionInputsDigest{} case *CertifiedCommit: highestCertifiedSeqNr = cpoc.CommitSeqNr highestCertifiedStateTransitionInputsDigest = cpoc.StateTransitionInputsDigest diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/prev_instance.go b/offchainreporting2plus/internal/ocr3_1/protocol/prev_instance.go new file mode 100644 index 00000000..07caeb9f --- /dev/null +++ b/offchainreporting2plus/internal/ocr3_1/protocol/prev_instance.go @@ -0,0 +1,49 @@ +package protocol + +import ( + "fmt" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config/ocr3_1config" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +func AttestedToGenesisStateTransitionBlock(prevConfigDigest types.ConfigDigest, astb AttestedStateTransitionBlock) GenesisStateTransitionBlock { + stb := astb.StateTransitionBlock + stateWriteSetDigest := MakeStateWriteSetDigest( + prevConfigDigest, + stb.BlockSeqNr, + stb.StateWriteSet.Entries, + ) + return GenesisStateTransitionBlock{ + stb.PrevHistoryDigest, + stb.BlockSeqNr, + stb.StateTransitionInputsDigest, + stateWriteSetDigest, + stb.StateRootDigest, + stb.ReportsPlusPrecursorDigest, + } +} + +func VerifyGenesisStateTransitionBlockFromPrevInstance(cfg ocr3_1config.PublicConfig, gstb GenesisStateTransitionBlock) error { + prev, ok := cfg.GetPrevFields() + if !ok { + return fmt.Errorf("previous instance is not specified in PublicConfig") + } + if gstb.SeqNr != prev.PrevSeqNr { + return fmt.Errorf("genesis state transition block seqNr mismatch, expected PrevSeqNr %d but got %d", prev.PrevSeqNr, gstb.SeqNr) + } + + actualPrevHistoryDigest := MakeHistoryDigest( + prev.PrevConfigDigest, + gstb.PrevHistoryDigest, + gstb.SeqNr, + gstb.StateTransitionInputsDigest, + gstb.StateWriteSetDigest, + gstb.StateRootDigest, + gstb.ReportsPlusPrecursorDigest, + ) + if actualPrevHistoryDigest != prev.PrevHistoryDigest { + return fmt.Errorf("history digest mismatch, expected PrevHistoryDigest %s but got %s", prev.PrevHistoryDigest, actualPrevHistoryDigest) + } + return nil +} diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/signed_data.go b/offchainreporting2plus/internal/ocr3_1/protocol/signed_data.go index a14f20f3..05e2885c 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/signed_data.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/signed_data.go @@ -9,7 +9,7 @@ import ( "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/internal/byzquorum" - "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config" + "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config/ocr3_1config" "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3_1/blobtypes" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3_1types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -291,7 +291,7 @@ func (sig CommitSignature) Verify( return nil } -type HistoryDigest [32]byte +type HistoryDigest = types.HistoryDigest const historyDigestDomainSeparator = "ocr3.1/HistoryDigest/" @@ -450,9 +450,10 @@ type EpochStartProof struct { func (qc *EpochStartProof) Verify( ogid OutcomeGenerationID, - oracleIdentities []config.OracleIdentity, - byzQuorumSize int, + config ocr3_1config.PublicConfig, ) error { + oracleIdentities := config.OracleIdentities + byzQuorumSize := config.ByzQuorumSize() if byzQuorumSize != len(qc.HighestCertifiedProof) { return fmt.Errorf("wrong length of HighestCertifiedProof, expected %v for byz. quorum and got %v", byzQuorumSize, len(qc.HighestCertifiedProof)) } @@ -481,7 +482,7 @@ func (qc *EpochStartProof) Verify( return fmt.Errorf("mismatch between timestamp of HighestCertified (%v) and the max from HighestCertifiedProof (%v)", qc.HighestCertified.Timestamp(), maximumTimestamp) } - if err := qc.HighestCertified.Verify(ogid.ConfigDigest, oracleIdentities, byzQuorumSize); err != nil { + if err := qc.HighestCertified.Verify(config); err != nil { return fmt.Errorf("failed to verify HighestCertified: %w", err) } @@ -495,12 +496,8 @@ type CertifiedPrepareOrCommit interface { Epoch() uint64 SeqNr() uint64 Timestamp() HighestCertifiedTimestamp - IsGenesis() bool - Verify( - _ types.ConfigDigest, - _ []config.OracleIdentity, - byzQuorumSize int, - ) error + HistoryDigest(_ types.ConfigDigest) HistoryDigest + Verify(_ ocr3_1config.PublicConfig) error CheckSize(n int, f int, limits ocr3_1types.ReportingPluginLimits, maxReportSigLen int) bool } @@ -535,15 +532,22 @@ func (hc *CertifiedPrepare) Timestamp() HighestCertifiedTimestamp { } } -func (hc *CertifiedPrepare) IsGenesis() bool { - return false +func (hc *CertifiedPrepare) HistoryDigest(configDigest types.ConfigDigest) HistoryDigest { + return MakeHistoryDigest( + configDigest, + hc.PrevHistoryDigest, + hc.PrepareSeqNr, + hc.StateTransitionInputsDigest, + hc.StateWriteSetDigest, + hc.StateRootDigest, + hc.ReportsPlusPrecursorDigest, + ) } -func (hc *CertifiedPrepare) Verify( - configDigest types.ConfigDigest, - oracleIdentities []config.OracleIdentity, - byzQuorumSize int, -) error { +func (hc *CertifiedPrepare) Verify(config ocr3_1config.PublicConfig) error { + configDigest := config.ConfigDigest + oracleIdentities := config.OracleIdentities + byzQuorumSize := config.ByzQuorumSize() if byzQuorumSize != len(hc.PrepareQuorumCertificate) { return fmt.Errorf("wrong number of signatures, expected %v for byz. quorum and got %v", byzQuorumSize, len(hc.PrepareQuorumCertificate)) } @@ -585,7 +589,6 @@ func (hc *CertifiedPrepare) CheckSize(n int, f int, limits ocr3_1types.Reporting var _ CertifiedPrepareOrCommit = &CertifiedCommit{} -// The empty CertifiedCommit{} is the genesis value type CertifiedCommit struct { PrevHistoryDigest HistoryDigest CommitEpoch uint64 @@ -615,28 +618,10 @@ func (hc *CertifiedCommit) Timestamp() HighestCertifiedTimestamp { } } -func (hc *CertifiedCommit) IsGenesis() bool { - // We intentionally don't just compare with CertifiedCommit{}, because after - // protobuf deserialization, we might end up with hc.Outcome = []byte{} - return hc.PrevHistoryDigest == HistoryDigest{} && - hc.CommitEpoch == uint64(0) && - hc.CommitSeqNr == uint64(0) && - hc.StateTransitionInputsDigest == StateTransitionInputsDigest{} && - hc.StateWriteSetDigest == StateWriteSetDigest{} && - hc.StateRootDigest == StateRootDigest{} && - hc.ReportsPlusPrecursorDigest == ReportsPlusPrecursorDigest{} && - len(hc.CommitQuorumCertificate) == 0 -} - -func (hc *CertifiedCommit) Verify( - configDigest types.ConfigDigest, - oracleIdentities []config.OracleIdentity, - byzQuorumSize int, -) error { - if hc.IsGenesis() { - return nil - } - +func (hc *CertifiedCommit) Verify(config ocr3_1config.PublicConfig) error { + configDigest := config.ConfigDigest + oracleIdentities := config.OracleIdentities + byzQuorumSize := config.ByzQuorumSize() if byzQuorumSize != len(hc.CommitQuorumCertificate) { return fmt.Errorf("wrong number of signatures, expected %d for byz. quorum but got %d", byzQuorumSize, len(hc.CommitQuorumCertificate)) } @@ -671,10 +656,6 @@ func (hc *CertifiedCommit) Verify( } func (hc *CertifiedCommit) CheckSize(n int, f int, limits ocr3_1types.ReportingPluginLimits, maxReportSigLen int) bool { - if hc.IsGenesis() { - return true - } - if len(hc.CommitQuorumCertificate) != byzquorum.Size(n, f) { return false } @@ -698,6 +679,117 @@ func (hc *CertifiedCommit) HistoryDigest(configDigest types.ConfigDigest) Histor ) } +type GenesisFromScratch struct{} + +var _ CertifiedPrepareOrCommit = &GenesisFromScratch{} + +func (gscratch *GenesisFromScratch) CheckSize(_ int, _ int, _ ocr3_1types.ReportingPluginLimits, _ int) bool { + return true +} + +func (gscratch *GenesisFromScratch) Epoch() uint64 { + return 0 +} + +func (gscratch *GenesisFromScratch) SeqNr() uint64 { + return 0 +} + +func (gscratch *GenesisFromScratch) Timestamp() HighestCertifiedTimestamp { + return HighestCertifiedTimestamp{ + 0, + true, + 0, + } +} + +func (gscratch *GenesisFromScratch) Verify(config ocr3_1config.PublicConfig) error { + if _, ok := config.GetPrevFields(); ok { + return fmt.Errorf("GenesisFromScratch is invalid when previous instance is specified in PublicConfig") + } + return nil +} + +func (gscratch *GenesisFromScratch) HistoryDigest(configDigest types.ConfigDigest) HistoryDigest { + return MakeHistoryDigest( + configDigest, + HistoryDigest{}, + 0, + StateTransitionInputsDigest{}, + StateWriteSetDigest{}, + StateRootDigest{}, + ReportsPlusPrecursorDigest{}, + ) +} + +func (gscratch *GenesisFromScratch) isCertifiedPrepareOrCommit() {} + +type GenesisFromPrevInstance struct { + PrevHistoryDigest HistoryDigest + PrevSeqNr uint64 +} + +var _ CertifiedPrepareOrCommit = &GenesisFromPrevInstance{} + +func (gprev *GenesisFromPrevInstance) CheckSize(_ int, _ int, _ ocr3_1types.ReportingPluginLimits, _ int) bool { + return true +} + +func (gprev *GenesisFromPrevInstance) Epoch() uint64 { + return 0 +} + +func (gprev *GenesisFromPrevInstance) SeqNr() uint64 { + return gprev.PrevSeqNr +} + +func (gprev *GenesisFromPrevInstance) Timestamp() HighestCertifiedTimestamp { + return HighestCertifiedTimestamp{ + gprev.SeqNr(), + true, + gprev.Epoch(), + } +} + +func (gprev *GenesisFromPrevInstance) Verify(config ocr3_1config.PublicConfig) error { + prev, ok := config.GetPrevFields() + if !ok { + return fmt.Errorf("GenesisFromPrevInstance is invalid when previous instance is not specified in PublicConfig") + } + if gprev.PrevHistoryDigest != prev.PrevHistoryDigest { + return fmt.Errorf("GenesisFromPrevInstance.PrevHistoryDigest (%x) does not match config.PrevHistoryDigest (%x)", gprev.PrevHistoryDigest, prev.PrevHistoryDigest) + } + if gprev.PrevSeqNr != prev.PrevSeqNr { + return fmt.Errorf("GenesisFromPrevInstance.PrevSeqNr (%d) does not match config.PrevSeqNr (%d)", gprev.PrevSeqNr, prev.PrevSeqNr) + } + return nil +} + +func (gprev *GenesisFromPrevInstance) HistoryDigest(configDigest types.ConfigDigest) HistoryDigest { + return MakeHistoryDigest( + configDigest, + gprev.PrevHistoryDigest, + gprev.SeqNr(), + StateTransitionInputsDigest{}, + StateWriteSetDigest{}, + StateRootDigest{}, + ReportsPlusPrecursorDigest{}, + ) +} + +func (gprev *GenesisFromPrevInstance) isCertifiedPrepareOrCommit() {} + +func GenesisCertifiedPrepareOrCommit(cfg ocr3_1config.PublicConfig) CertifiedPrepareOrCommit { + prev, ok := cfg.GetPrevFields() + if !ok { + return &GenesisFromScratch{} + } + return &GenesisFromPrevInstance{ + prev.PrevHistoryDigest, + prev.PrevSeqNr, + } +} + type StateTransitionBlock struct { PrevHistoryDigest HistoryDigest Epoch uint64 @@ -760,13 +852,9 @@ func (astb *AttestedStateTransitionBlock) CheckSize(n int, f int, limits ocr3_1t return astb.StateTransitionBlock.CheckSize(limits) } -func (astb *AttestedStateTransitionBlock) Verify( - configDigest types.ConfigDigest, - oracleIdentities []config.OracleIdentity, - byzQuorumSize int, -) error { - certifiedCommit := astb.ToCertifiedCommit(configDigest) - return certifiedCommit.Verify(configDigest, oracleIdentities, byzQuorumSize) +func (astb *AttestedStateTransitionBlock) Verify(config ocr3_1config.PublicConfig) error { + certifiedCommit := astb.ToCertifiedCommit(config.ConfigDigest) + return certifiedCommit.Verify(config) } func (astb *AttestedStateTransitionBlock) ToCertifiedCommit(configDigest types.ConfigDigest) CertifiedCommit { @@ -788,6 +876,39 @@ func (astb *AttestedStateTransitionBlock) ToCertifiedCommit(configDigest types.C } } +type GenesisStateTransitionBlock struct { + PrevHistoryDigest HistoryDigest + SeqNr uint64 + StateTransitionInputsDigest StateTransitionInputsDigest + StateWriteSetDigest StateWriteSetDigest + StateRootDigest StateRootDigest + ReportsPlusPrecursorDigest ReportsPlusPrecursorDigest +} + +//go-sumtype:decl AttestedOrGenesisStateTransitionBlock + +type AttestedOrGenesisStateTransitionBlock interface { + isAttestedOrGenesisStateTransitionBlock() + seqNr() uint64 + stateRootDigest() StateRootDigest +} + +func (astb *AttestedStateTransitionBlock) isAttestedOrGenesisStateTransitionBlock() {} +func (astb *AttestedStateTransitionBlock) seqNr() uint64 { + return astb.StateTransitionBlock.SeqNr() +} +func (astb *AttestedStateTransitionBlock) stateRootDigest() StateRootDigest { + return astb.StateTransitionBlock.StateRootDigest +} + +func (gstb *GenesisStateTransitionBlock) isAttestedOrGenesisStateTransitionBlock() {} +func (gstb *GenesisStateTransitionBlock) seqNr() uint64 { + return gstb.SeqNr +} +func (gstb *GenesisStateTransitionBlock) stateRootDigest() StateRootDigest { + return gstb.StateRootDigest +} + type BlobDigest = blobtypes.BlobDigest type BlobChunkDigest = blobtypes.BlobChunkDigest type BlobChunkDigestsRoot = blobtypes.BlobChunkDigestsRoot diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go index 3d67ee11..268356aa 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go @@ -2,7 +2,6 @@ package protocol import ( "context" - "math" "slices" "time" @@ -29,11 +28,15 @@ func RunStateSync[RI any]( netSender NetworkSender[RI], reportingPlugin ocr3_1types.ReportingPlugin[RI], ) { + subs := subprocesses.Subprocesses{} + defer subs.Wait() + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + chNotificationToStateBlockReplay := make(chan struct{}) chNotificationToStateDestroyIfNeeded := make(chan struct{}) - subs := subprocesses.Subprocesses{} - defer subs.Wait() subs.Go(func() { RunStateSyncDestroyIfNeeded(ctx, logger, kvDb, chNotificationToStateDestroyIfNeeded) }) @@ -77,6 +80,8 @@ type stateSyncState[RI any] struct { logger loghelper.LoggerWithContext netSender NetworkSender[RI] + genesisSeqNr uint64 + highestPersistedStateTransitionBlockSeqNr uint64 lowestPersistedStateTransitionBlockSeqNr uint64 highestCommittedSeqNr uint64 @@ -228,7 +233,8 @@ func (stasy *stateSyncState[RI]) eventTSendSummaryTimeout() { if stasy.treeSyncState.treeSyncPhase != TreeSyncPhaseInactive { stasy.netSender.Broadcast(MessageStateSyncSummary[RI]{ - math.MaxUint64, + + 0, 0, }) return @@ -348,19 +354,16 @@ func (stasy *stateSyncState[RI]) decideBlockSyncOrTreeSyncBasedOnSummariesAndHig } func (stasy *stateSyncState[RI]) pickSomeTreeSyncTarget() (uint64, bool) { - if snapshotSeqNr(stasy.highestHeardSeqNr, stasy.config.PublicConfig) == stasy.highestHeardSeqNr { - return stasy.highestHeardSeqNr, true - } else { - snapshotIndex := snapshotIndexFromSeqNr(stasy.highestHeardSeqNr, stasy.config.PublicConfig) - if snapshotIndex > 0 { - return maxSeqNrWithSnapshotIndex(snapshotIndex-1, stasy.config.PublicConfig), true - } else { - return 0, false - } - } + return highestCompleteSnapshotSeqNrNotAbove(stasy.highestHeardSeqNr, stasy.config.PublicConfig) } func (stasy *stateSyncState[RI]) needToRetargetTreeSync() bool { + + newTargetSeqNr, found := stasy.pickSomeTreeSyncTarget() + if found && newTargetSeqNr == stasy.treeSyncState.targetSeqNr { + return false + } + switch stasy.findSomeHonestOraclePruneStatus(stasy.treeSyncState.targetSeqNr) { case honestOraclePruneStatusWouldNotPrune: return false @@ -413,7 +416,12 @@ func (stasy *stateSyncState[RI]) tryToKickStartSync() { return } - decision := stasy.decideBlockSyncOrTreeSyncBasedOnSummariesAndHighestHeard() + var decision blockSyncOrTreeSyncDecision + if stasy.mustTreeSyncToPrevInstance() { + decision = blockSyncOrTreeSyncDecisionTreeSync + } else { + decision = stasy.decideBlockSyncOrTreeSyncBasedOnSummariesAndHighestHeard() + } if decision == blockSyncOrTreeSyncDecisionCannotDecideYet { stasy.logger.Debug("cannot decide whether to block-sync or tree-sync, yet", nil) @@ -436,6 +444,10 @@ func (stasy *stateSyncState[RI]) tryToKickStartSync() { } } +func (stasy *stateSyncState[RI]) mustTreeSyncToPrevInstance() bool { + return stasy.highestCommittedSeqNr < stasy.genesisSeqNr +} + func newStateSyncState[RI any]( ctx context.Context, chNetToStateSync <-chan MessageToStateSyncWithSender[RI], @@ -459,6 +471,8 @@ func newStateSyncState[RI any]( }) } + genesisSeqNr := genesisSeqNr(config.PublicConfig) + stasy := &stateSyncState[RI]{ ctx, @@ -473,12 +487,15 @@ func newStateSyncState[RI any]( kvDb, logger.MakeUpdated(commontypes.LogFields{"proto": "stasy"}), netSender, + + genesisSeqNr, + 0, 0, 0, oracles, - 0, + genesisSeqNr, blockSyncState[RI]{ logger.MakeUpdated(commontypes.LogFields{"proto": "stasy/block"}), diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go index 57b875e3..19b5c36b 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go @@ -1,6 +1,7 @@ package protocol import ( + "fmt" "time" "github.com/google/btree" @@ -170,18 +171,36 @@ func (stasy *stateSyncState[RI]) messageBlockSyncRequest(msg MessageBlockSyncReq } defer tx.Discard() - astbs, _, err := tx.ReadAttestedStateTransitionBlocks(msg.StartSeqNr, maxBlocksInResponse) - if err != nil { - stasy.blockSyncState.logger.Error("failed to read attested state transition blocks", commontypes.LogFields{ - "error": err, - }) - return + var astbs []AttestedStateTransitionBlock + var gstb *GenesisStateTransitionBlock + + // Special case: If someone requests the genesis block, they're looking for + // the genesis state transition block from the prev instance. + if msg.StartSeqNr == stasy.genesisSeqNr && msg.EndExclSeqNr == stasy.genesisSeqNr+1 { + prevInstanceGenesisStateTransitionBlock, err := tx.ReadPrevInstanceGenesisStateTransitionBlock() + if err != nil { + stasy.blockSyncState.logger.Error("error reading prev instance genesis state transition block", commontypes.LogFields{ + "error": err, + }) + return + } + gstb = prevInstanceGenesisStateTransitionBlock + } else { + var err error + astbs, _, err = tx.ReadAttestedStateTransitionBlocks(msg.StartSeqNr, maxBlocksInResponse) + if err != nil { + stasy.blockSyncState.logger.Error("failed to read attested state transition blocks", commontypes.LogFields{ + "error": err, + }) + return + } } maxCumulativeWriteSetBytes := min(msg.MaxCumulativeWriteSetBytes, maxMaxCumulativeWriteSetBytes) // trim suffix of astbs to fit in maxCumulativeWriteSetBytes and avoid seq nr gaps cumulativeWriteSetBytes := 0 + validPrefixCount := 0 for i, astb := range astbs { // check if block has the expected sequence number, if not break seqNr := astb.StateTransitionBlock.SeqNr() @@ -202,17 +221,21 @@ func (stasy *stateSyncState[RI]) messageBlockSyncRequest(msg MessageBlockSyncReq break } cumulativeWriteSetBytes += thisBlockWriteSetBytes + validPrefixCount++ } + astbs = astbs[:validPrefixCount] + goAway := len(astbs) == 0 && gstb == nil stasy.blockSyncState.logger.Debug("sending MessageBlockSyncResponse", commontypes.LogFields{ "highestPersisted": stasy.highestPersistedStateTransitionBlockSeqNr, "lowestPersisted": stasy.lowestPersistedStateTransitionBlockSeqNr, "requestStartSeqNr": msg.StartSeqNr, "requestEndExclSeqNr": msg.EndExclSeqNr, "blocks": len(astbs), + "hasGenesisBlock": gstb != nil, "cumulativeWriteSetBytes": cumulativeWriteSetBytes, "maxCumulativeWriteSetBytes": maxCumulativeWriteSetBytes, - "goAway": len(astbs) == 0, + "goAway": goAway, "to": sender, }) stasy.netSender.SendTo(MessageBlockSyncResponse[RI]{ @@ -220,6 +243,7 @@ func (stasy *stateSyncState[RI]) messageBlockSyncRequest(msg MessageBlockSyncReq msg.StartSeqNr, msg.EndExclSeqNr, astbs, + gstb, }, sender) } @@ -234,17 +258,52 @@ func (stasy *stateSyncState[RI]) messageBlockSyncResponse(msg MessageBlockSyncRe return } - if len(msg.AttestedStateTransitionBlocks) == 0 { - stasy.blockSyncState.logger.Debug("dropping MessageBlockSyncResponse, go-away", commontypes.LogFields{ - "sender": sender, - "requestSeqNrRange": requestSeqNrRange, - }) - stasy.blockSyncState.blockRequesterGadget.MarkGoAwayResponse(requestSeqNrRange, sender) - return + requestedGenesis := msg.RequestStartSeqNr == stasy.genesisSeqNr && msg.RequestEndExclSeqNr == stasy.genesisSeqNr+1 + + // Validate response structure based on what was requested + if requestedGenesis { + // Genesis request: must have GenesisStateTransitionBlock, must NOT have AttestedStateTransitionBlocks + if len(msg.AttestedStateTransitionBlocks) > 0 { + stasy.blockSyncState.logger.Warn("dropping MessageBlockSyncResponse for genesis with unexpected attested blocks", commontypes.LogFields{ + "sender": sender, + "requestSeqNrRange": requestSeqNrRange, + "numBlocks": len(msg.AttestedStateTransitionBlocks), + }) + stasy.blockSyncState.blockRequesterGadget.MarkBadResponse(requestSeqNrRange, sender) + return + } + if msg.GenesisStateTransitionBlock == nil { + stasy.blockSyncState.logger.Debug("dropping MessageBlockSyncResponse for genesis, go-away", commontypes.LogFields{ + "sender": sender, + "requestSeqNrRange": requestSeqNrRange, + }) + stasy.blockSyncState.blockRequesterGadget.MarkGoAwayResponse(requestSeqNrRange, sender) + return + } + } else { + // Non-genesis request: must NOT have GenesisStateTransitionBlock + if msg.GenesisStateTransitionBlock != nil { + stasy.blockSyncState.logger.Warn("dropping MessageBlockSyncResponse for non-genesis with unexpected genesis block", commontypes.LogFields{ + "sender": sender, + "requestSeqNrRange": requestSeqNrRange, + }) + stasy.blockSyncState.blockRequesterGadget.MarkBadResponse(requestSeqNrRange, sender) + return + } + if len(msg.AttestedStateTransitionBlocks) == 0 { + stasy.blockSyncState.logger.Debug("dropping MessageBlockSyncResponse, go-away", commontypes.LogFields{ + "sender": sender, + "requestSeqNrRange": requestSeqNrRange, + }) + stasy.blockSyncState.blockRequesterGadget.MarkGoAwayResponse(requestSeqNrRange, sender) + return + } } stasy.blockSyncState.logger.Debug("received MessageBlockSyncResponse", commontypes.LogFields{ - "sender": sender, + "sender": sender, + "blocks": len(msg.AttestedStateTransitionBlocks), + "hasGenesisBlock": msg.GenesisStateTransitionBlock != nil, }) switch stasy.syncMode { @@ -258,6 +317,21 @@ func (stasy *stateSyncState[RI]) messageBlockSyncResponse(msg MessageBlockSyncRe return } + // Verify genesis state transition block if present + if msg.GenesisStateTransitionBlock != nil { + if err := stasy.verifyGenesisStateTransitionBlock(*msg.GenesisStateTransitionBlock); err != nil { + stasy.blockSyncState.logger.Warn("dropping MessageBlockSyncResponse with genesis block that does not verify", commontypes.LogFields{ + "sender": sender, + "requestStartSeqNr": msg.RequestStartSeqNr, + "requestEndExclSeqNr": msg.RequestEndExclSeqNr, + "genesisBlockSeqNr": msg.GenesisStateTransitionBlock.SeqNr, + "error": err, + }) + stasy.blockSyncState.blockRequesterGadget.MarkBadResponse(requestSeqNrRange, sender) + return + } + } + for i, astb := range msg.AttestedStateTransitionBlocks { if astb.StateTransitionBlock.SeqNr() != msg.RequestStartSeqNr+uint64(i) { stasy.blockSyncState.logger.Warn("dropping MessageBlockSyncResponse with out of order state transition blocks", commontypes.LogFields{ @@ -281,8 +355,8 @@ func (stasy *stateSyncState[RI]) messageBlockSyncResponse(msg MessageBlockSyncRe return } - if err := astb.Verify(stasy.config.ConfigDigest, stasy.config.OracleIdentities, stasy.config.ByzQuorumSize()); err != nil { - stasy.blockSyncState.logger.Warn("dropping MessageBlockSyncResponse with invalid attestation", commontypes.LogFields{ + if err := stasy.verifyAttestedStateTransitionBlock(astb); err != nil { + stasy.blockSyncState.logger.Warn("dropping MessageBlockSyncResponse with block that does not verify", commontypes.LogFields{ "sender": sender, "requestStartSeqNr": msg.RequestStartSeqNr, "requestEndExclSeqNr": msg.RequestEndExclSeqNr, @@ -297,9 +371,16 @@ func (stasy *stateSyncState[RI]) messageBlockSyncResponse(msg MessageBlockSyncRe stasy.blockSyncState.blockRequesterGadget.MarkGoodResponse(requestSeqNrRange, sender) if stasy.syncMode == syncModeFetchSnapshotBlock { - err := stasy.acceptTreeSyncTargetBlockFromBlockSync(msg.AttestedStateTransitionBlocks[0]) - if err != nil { - stasy.blockSyncState.logger.Error("error accepting tree-sync target block from block sync, will try again", commontypes.LogFields{ + var block AttestedOrGenesisStateTransitionBlock + if msg.GenesisStateTransitionBlock != nil { + block = msg.GenesisStateTransitionBlock + } else if len(msg.AttestedStateTransitionBlocks) > 0 { + block = &msg.AttestedStateTransitionBlocks[0] + } + if block == nil { + stasy.blockSyncState.logger.Critical("unexpected: no block in response after validation passed", nil) + } else if err := stasy.acceptTreeSyncTargetBlockFromBlockSync(block); err != nil { + stasy.blockSyncState.logger.Error("error accepting tree-sync target block, will try again", commontypes.LogFields{ "error": err, }) } @@ -316,6 +397,17 @@ func (stasy *stateSyncState[RI]) messageBlockSyncResponse(msg MessageBlockSyncRe stasy.tryCompleteBlockSync() } +func (stasy *stateSyncState[RI]) verifyAttestedStateTransitionBlock(astb AttestedStateTransitionBlock) error { + return astb.Verify(stasy.config.PublicConfig) +} + +func (stasy *stateSyncState[RI]) verifyGenesisStateTransitionBlock(gstb GenesisStateTransitionBlock) error { + if gstb.SeqNr != stasy.genesisSeqNr { + return fmt.Errorf("genesis state transition block seqNr %d does not match expected genesis seqNr %d", gstb.SeqNr, stasy.genesisSeqNr) + } + return VerifyGenesisStateTransitionBlockFromPrevInstance(stasy.config.PublicConfig, gstb) +} + func (stasy *stateSyncState[RI]) tryCompleteBlockSync() { stasy.refreshStateSyncState() diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_reap.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_reap.go index b849bc33..d7ce7301 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_reap.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_reap.go @@ -11,8 +11,9 @@ import ( ) const ( - stateReapInterval = 10 * time.Second - stateReapFastFollowOnError = 120 * time.Millisecond + stateReapInterval = 10 * time.Second + initialStateReapFastFollowOnError = 120 * time.Millisecond + maxStateReapFastFollowOnError = stateReapInterval maxBlocksToReapInOneGo = 100_000 maxTreeNodesToReapInOneGo = 10_000 @@ -192,6 +193,8 @@ func RunStateSyncReap( chDone := ctx.Done() chTick := time.After(0) + stateReapFastFollowOnError := initialStateReapFastFollowOnError + for { select { case <-chTick: @@ -202,15 +205,22 @@ func RunStateSyncReap( logger.Info("RunStateSyncReap: calling reapState", nil) done, err := reapState(ctx, kvDb, logger, config.PublicConfig) if err != nil { + stateReapFastFollowOnError *= 2 + if stateReapFastFollowOnError > maxStateReapFastFollowOnError { + stateReapFastFollowOnError = maxStateReapFastFollowOnError + } logger.Warn("RunStateSyncReap: failed to reap state. Will retry soon.", commontypes.LogFields{ "error": err, "waitBeforeRetry": stateReapFastFollowOnError.String(), }) chTick = time.After(stateReapFastFollowOnError) - } else if !done { - chTick = time.After(0) } else { - chTick = time.After(stateReapInterval) + stateReapFastFollowOnError = initialStateReapFastFollowOnError + if !done { + chTick = time.After(0) + } else { + chTick = time.After(stateReapInterval) + } } } } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_snapshot.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_snapshot.go index b6cb799c..210f1463 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_snapshot.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_snapshot.go @@ -4,22 +4,59 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config/ocr3_1config" ) -func snapshotIndexFromSeqNr(seqNr uint64, config ocr3_1config.PublicConfig) uint64 { +func genesisSeqNr(config ocr3_1config.PublicConfig) uint64 { + if prev, ok := config.GetPrevFields(); ok { + return prev.PrevSeqNr + } + return 0 +} + +func snapshotIndexFromSeqNrAssumingZeroGenesis(seqNr uint64, config ocr3_1config.PublicConfig) uint64 { if seqNr == 0 { return 0 } return (seqNr + config.GetSnapshotInterval() - 1) / config.GetSnapshotInterval() } -func maxSeqNrWithSnapshotIndex(snapshotIndex uint64, config ocr3_1config.PublicConfig) uint64 { - if snapshotIndex == 0 { - return 0 - } +func maxSeqNrWithSnapshotIndexAssumingZeroGenesis(snapshotIndex uint64, config ocr3_1config.PublicConfig) uint64 { return snapshotIndex * config.GetSnapshotInterval() } +func highestCompleteSnapshotSeqNrNotAbove(seqNr uint64, config ocr3_1config.PublicConfig) (uint64, bool) { + if isCompleteSnapshotSeqNr(seqNr, config) { + return seqNr, true + } + snapshotIndex := snapshotIndexFromSeqNrAssumingZeroGenesis(seqNr, config) + if snapshotIndex > 0 { + prevSnapshotMaxSeqNr := maxSeqNrWithSnapshotIndexAssumingZeroGenesis(snapshotIndex-1, config) + prevSnapshotMaxSeqNrConsideringGenesis := max(genesisSeqNr(config), prevSnapshotMaxSeqNr) + if prevSnapshotMaxSeqNrConsideringGenesis == 0 || prevSnapshotMaxSeqNrConsideringGenesis > seqNr { + return 0, false + } else { + return prevSnapshotMaxSeqNrConsideringGenesis, true + } + } + return 0, false +} + +func isCompleteSnapshotSeqNr(seqNr uint64, config ocr3_1config.PublicConfig) bool { + if seqNr == 0 { + return false + } + gen := genesisSeqNr(config) + if seqNr < gen { + return false + } + return RootVersion(seqNr, config) == seqNr +} + func desiredLowestPersistedSeqNr(highestCommittedSeqNr uint64, config ocr3_1config.PublicConfig) uint64 { - highestSnapshotIndex := snapshotIndexFromSeqNr(highestCommittedSeqNr, config) + gen := genesisSeqNr(config) + if highestCommittedSeqNr < gen { + return 0 // ensures that lowest <= highest + } + + highestSnapshotIndex := snapshotIndexFromSeqNrAssumingZeroGenesis(highestCommittedSeqNr, config) var lowestDesiredSnapshotIndex uint64 cfgMaxHistoricalSnapshotsRetained := config.GetMaxHistoricalSnapshotsRetained() if highestSnapshotIndex > cfgMaxHistoricalSnapshotsRetained { @@ -27,11 +64,20 @@ func desiredLowestPersistedSeqNr(highestCommittedSeqNr uint64, config ocr3_1conf } else { lowestDesiredSnapshotIndex = 0 } - return maxSeqNrWithSnapshotIndex(lowestDesiredSnapshotIndex, config) + + lowestDesiredSeqNrAssumingZeroGenesis := maxSeqNrWithSnapshotIndexAssumingZeroGenesis(lowestDesiredSnapshotIndex, config) + return max(gen, lowestDesiredSeqNrAssumingZeroGenesis) } func snapshotSeqNr(seqNr uint64, config ocr3_1config.PublicConfig) uint64 { - return maxSeqNrWithSnapshotIndex(snapshotIndexFromSeqNr(seqNr, config), config) + gen := genesisSeqNr(config) + if seqNr < gen { + return 0 + } + if seqNr <= gen { + return gen + } + return maxSeqNrWithSnapshotIndexAssumingZeroGenesis(snapshotIndexFromSeqNrAssumingZeroGenesis(seqNr, config), config) } // prevRootVersion returns the version number of the JMT root referring to the @@ -39,6 +85,9 @@ func snapshotSeqNr(seqNr uint64, config ocr3_1config.PublicConfig) uint64 { // modifications of seqNr. We only maintain trees with versions that are // multiples of SnapshotInterval. func PrevRootVersion(seqNr uint64, config ocr3_1config.PublicConfig) uint64 { + if seqNr <= 0 { + return 0 + } return snapshotSeqNr(seqNr-1, config) } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go index 90d9b8f4..e766096f 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go @@ -7,7 +7,6 @@ import ( "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/internal/jmt" - "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config/ocr3_1config" "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3_1/protocol/requestergadget" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) @@ -64,6 +63,7 @@ func (stasy *stateSyncState[RI]) sendTreeSyncChunkRequest(item treeSyncChunkRequ item.targetSeqNr, item.keyDigestRange.StartIndex, item.keyDigestRange.EndInclIndex, + stasy.config.GetMaxTreeSyncChunkKeysPlusValuesBytes(), } stasy.netSender.SendTo(msg, target) @@ -143,6 +143,7 @@ func (stasy *stateSyncState[RI]) evolveTreeSyncPhase() { return } stasy.refreshStateSyncState() + stasy.pleaseDestroyStateIfNeeded() return case TreeSyncPhaseWaiting: stasy.treeSyncState.logger.Debug("tree-sync waiting for key-value store cleanup 🧹", nil) @@ -190,6 +191,7 @@ func (stasy *stateSyncState[RI]) evolveTreeSyncPhase() { return } stasy.refreshStateSyncState() + stasy.pleaseDestroyStateIfNeeded() return } else { // our target seq nr is fine, and we are active @@ -206,7 +208,7 @@ func (stasy *stateSyncState[RI]) evolveTreeSyncPhase() { } } -func (stasy *stateSyncState[RI]) acceptTreeSyncTargetBlockFromBlockSync(block AttestedStateTransitionBlock) error { +func (stasy *stateSyncState[RI]) acceptTreeSyncTargetBlockFromBlockSync(block AttestedOrGenesisStateTransitionBlock) error { if stasy.syncMode != syncModeFetchSnapshotBlock { return fmt.Errorf("not in fetch snapshot block mode") } @@ -219,12 +221,12 @@ func (stasy *stateSyncState[RI]) acceptTreeSyncTargetBlockFromBlockSync(block At return fmt.Errorf("not accepting block in unexpected tree-sync phase %v", stasy.treeSyncState.treeSyncPhase) } - seqNr := block.StateTransitionBlock.SeqNr() + seqNr := block.seqNr() if seqNr != stasy.treeSyncState.targetSeqNr { - return fmt.Errorf("tree-sync target block sequence number does not match expected target sequence number") + return fmt.Errorf("tree-sync target block sequence number %d does not match expected target sequence number %d", seqNr, stasy.treeSyncState.targetSeqNr) } - stateRootDigest := block.StateTransitionBlock.StateRootDigest + stateRootDigest := block.stateRootDigest() kvReadWriteTxn, err := stasy.kvDb.NewSerializedReadWriteTransactionUnchecked() if err != nil { @@ -240,8 +242,18 @@ func (stasy *stateSyncState[RI]) acceptTreeSyncTargetBlockFromBlockSync(block At return fmt.Errorf("failed to write tree-sync status: %w", err) } - if err = kvReadWriteTxn.WriteAttestedStateTransitionBlock(seqNr, block); err != nil { - return fmt.Errorf("failed to write attested state transition block: %w", err) + var isGenesis bool + switch b := block.(type) { + case *AttestedStateTransitionBlock: + isGenesis = false + if err = kvReadWriteTxn.WriteAttestedStateTransitionBlock(seqNr, *b); err != nil { + return fmt.Errorf("failed to write attested state transition block: %w", err) + } + case *GenesisStateTransitionBlock: + isGenesis = true + if err = kvReadWriteTxn.WritePrevInstanceGenesisStateTransitionBlock(*b); err != nil { + return fmt.Errorf("failed to write genesis state transition block: %w", err) + } } if err = kvReadWriteTxn.Commit(); err != nil { @@ -249,8 +261,9 @@ func (stasy *stateSyncState[RI]) acceptTreeSyncTargetBlockFromBlockSync(block At } stasy.treeSyncState.logger.Debug("tree-sync accepted verified state root digest", commontypes.LogFields{ - "targetSeqNr": seqNr, - "rootDigest": stateRootDigest, + "targetSeqNr": seqNr, + "rootDigest": stateRootDigest, + "isGenesisBlock": isGenesis, }) stasy.syncMode = syncModeTree @@ -266,7 +279,7 @@ func (stasy *stateSyncState[RI]) messageTreeSyncChunkRequest(msg MessageTreeSync "startIndex": msg.StartIndex, }) - if !mustTakeSnapshot(msg.ToSeqNr, stasy.config.PublicConfig) { + if !stasy.mustTakeSnapshot(msg.ToSeqNr) { stasy.treeSyncState.logger.Warn("dropping MessageTreeSyncChunkRequest with invalid SeqNr", commontypes.LogFields{ "toSeqNr": msg.ToSeqNr, }) @@ -474,6 +487,7 @@ func (stasy *stateSyncState[RI]) messageTreeSyncChunkResponse(msg MessageTreeSyn stasy.treeSyncState.targetStateRootDigest, stasy.treeSyncState.targetSeqNr, msg.StartIndex, + msg.RequestEndInclIndex, msg.EndInclIndex, msg.BoundingLeaves, msg.KeyValues, @@ -577,6 +591,6 @@ func (stasy *stateSyncState[RI]) messageTreeSyncChunkResponse(msg MessageTreeSyn panic("unreachable") } -func mustTakeSnapshot(seqNr uint64, config ocr3_1config.PublicConfig) bool { - return seqNr%config.GetSnapshotInterval() == 0 +func (stasy *stateSyncState[RI]) mustTakeSnapshot(seqNr uint64) bool { + return isCompleteSnapshotSeqNr(seqNr, stasy.config.PublicConfig) } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/types.go b/offchainreporting2plus/internal/ocr3_1/protocol/types.go index 786a5ef7..bfa002d3 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/types.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/types.go @@ -1,6 +1,8 @@ package protocol import ( + "fmt" + "github.com/smartcontractkit/libocr/internal/jmt" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -38,6 +40,18 @@ const ( TreeSyncPhaseActive ) +func (tsp TreeSyncPhase) String() string { + switch tsp { + case TreeSyncPhaseInactive: + return "inactive" + case TreeSyncPhaseWaiting: + return "waiting" + case TreeSyncPhaseActive: + return "active" + } + return fmt.Sprintf("unknown tree sync phase: %d", tsp) +} + type TreeSyncStatus struct { Phase TreeSyncPhase TargetSeqNr uint64 diff --git a/offchainreporting2plus/internal/ocr3_1/serialization/offchainreporting3_1_messages.pb.go b/offchainreporting2plus/internal/ocr3_1/serialization/offchainreporting3_1_messages.pb.go index 88fa2500..b4aebb84 100644 --- a/offchainreporting2plus/internal/ocr3_1/serialization/offchainreporting3_1_messages.pb.go +++ b/offchainreporting2plus/internal/ocr3_1/serialization/offchainreporting3_1_messages.pb.go @@ -1077,6 +1077,7 @@ type MessageBlockSyncResponse struct { RequestStartSeqNr uint64 `protobuf:"varint,1,opt,name=request_start_seq_nr,json=requestStartSeqNr,proto3" json:"request_start_seq_nr,omitempty"` RequestEndExclSeqNr uint64 `protobuf:"varint,2,opt,name=request_end_excl_seq_nr,json=requestEndExclSeqNr,proto3" json:"request_end_excl_seq_nr,omitempty"` AttestedStateTransitionBlocks []*AttestedStateTransitionBlock `protobuf:"bytes,3,rep,name=attested_state_transition_blocks,json=attestedStateTransitionBlocks,proto3" json:"attested_state_transition_blocks,omitempty"` + GenesisStateTransitionBlock *GenesisStateTransitionBlock `protobuf:"bytes,4,opt,name=genesis_state_transition_block,json=genesisStateTransitionBlock,proto3" json:"genesis_state_transition_block,omitempty"` } func (x *MessageBlockSyncResponse) Reset() { @@ -1132,6 +1133,13 @@ func (x *MessageBlockSyncResponse) GetAttestedStateTransitionBlocks() []*Atteste return nil } +func (x *MessageBlockSyncResponse) GetGenesisStateTransitionBlock() *GenesisStateTransitionBlock { + if x != nil { + return x.GenesisStateTransitionBlock + } + return nil +} + type MessageStateSyncSummary struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1582,6 +1590,8 @@ type CertifiedPrepareOrCommit struct { // // *CertifiedPrepareOrCommit_Prepare // *CertifiedPrepareOrCommit_Commit + // *CertifiedPrepareOrCommit_GenesisFromScratch + // *CertifiedPrepareOrCommit_GenesisFromPrevInstance PrepareOrCommit isCertifiedPrepareOrCommit_PrepareOrCommit `protobuf_oneof:"prepare_or_commit"` } @@ -1638,6 +1648,20 @@ func (x *CertifiedPrepareOrCommit) GetCommit() *CertifiedCommit { return nil } +func (x *CertifiedPrepareOrCommit) GetGenesisFromScratch() *GenesisFromScratch { + if x, ok := x.GetPrepareOrCommit().(*CertifiedPrepareOrCommit_GenesisFromScratch); ok { + return x.GenesisFromScratch + } + return nil +} + +func (x *CertifiedPrepareOrCommit) GetGenesisFromPrevInstance() *GenesisFromPrevInstance { + if x, ok := x.GetPrepareOrCommit().(*CertifiedPrepareOrCommit_GenesisFromPrevInstance); ok { + return x.GenesisFromPrevInstance + } + return nil +} + type isCertifiedPrepareOrCommit_PrepareOrCommit interface { isCertifiedPrepareOrCommit_PrepareOrCommit() } @@ -1650,10 +1674,23 @@ type CertifiedPrepareOrCommit_Commit struct { Commit *CertifiedCommit `protobuf:"bytes,2,opt,name=commit,proto3,oneof"` } +type CertifiedPrepareOrCommit_GenesisFromScratch struct { + GenesisFromScratch *GenesisFromScratch `protobuf:"bytes,3,opt,name=genesis_from_scratch,json=genesisFromScratch,proto3,oneof"` +} + +type CertifiedPrepareOrCommit_GenesisFromPrevInstance struct { + GenesisFromPrevInstance *GenesisFromPrevInstance `protobuf:"bytes,4,opt,name=genesis_from_prev_instance,json=genesisFromPrevInstance,proto3,oneof"` +} + func (*CertifiedPrepareOrCommit_Prepare) isCertifiedPrepareOrCommit_PrepareOrCommit() {} func (*CertifiedPrepareOrCommit_Commit) isCertifiedPrepareOrCommit_PrepareOrCommit() {} +func (*CertifiedPrepareOrCommit_GenesisFromScratch) isCertifiedPrepareOrCommit_PrepareOrCommit() {} + +func (*CertifiedPrepareOrCommit_GenesisFromPrevInstance) isCertifiedPrepareOrCommit_PrepareOrCommit() { +} + type CertifiedPrepare struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1860,6 +1897,99 @@ func (x *CertifiedCommit) GetCommitQuorumCertificate() []*AttributedCommitSignat return nil } +type GenesisFromScratch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GenesisFromScratch) Reset() { + *x = GenesisFromScratch{} + if protoimpl.UnsafeEnabled { + mi := &file_offchainreporting3_1_messages_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisFromScratch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisFromScratch) ProtoMessage() {} + +func (x *GenesisFromScratch) ProtoReflect() protoreflect.Message { + mi := &file_offchainreporting3_1_messages_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenesisFromScratch.ProtoReflect.Descriptor instead. +func (*GenesisFromScratch) Descriptor() ([]byte, []int) { + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{24} +} + +type GenesisFromPrevInstance struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PrevHistoryDigest []byte `protobuf:"bytes,1,opt,name=prev_history_digest,json=prevHistoryDigest,proto3" json:"prev_history_digest,omitempty"` + PrevSeqNr uint64 `protobuf:"varint,2,opt,name=prev_seq_nr,json=prevSeqNr,proto3" json:"prev_seq_nr,omitempty"` +} + +func (x *GenesisFromPrevInstance) Reset() { + *x = GenesisFromPrevInstance{} + if protoimpl.UnsafeEnabled { + mi := &file_offchainreporting3_1_messages_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisFromPrevInstance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisFromPrevInstance) ProtoMessage() {} + +func (x *GenesisFromPrevInstance) ProtoReflect() protoreflect.Message { + mi := &file_offchainreporting3_1_messages_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenesisFromPrevInstance.ProtoReflect.Descriptor instead. +func (*GenesisFromPrevInstance) Descriptor() ([]byte, []int) { + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{25} +} + +func (x *GenesisFromPrevInstance) GetPrevHistoryDigest() []byte { + if x != nil { + return x.PrevHistoryDigest + } + return nil +} + +func (x *GenesisFromPrevInstance) GetPrevSeqNr() uint64 { + if x != nil { + return x.PrevSeqNr + } + return 0 +} + type HighestCertifiedTimestamp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1873,7 +2003,7 @@ type HighestCertifiedTimestamp struct { func (x *HighestCertifiedTimestamp) Reset() { *x = HighestCertifiedTimestamp{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[24] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1886,7 +2016,7 @@ func (x *HighestCertifiedTimestamp) String() string { func (*HighestCertifiedTimestamp) ProtoMessage() {} func (x *HighestCertifiedTimestamp) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[24] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1899,7 +2029,7 @@ func (x *HighestCertifiedTimestamp) ProtoReflect() protoreflect.Message { // Deprecated: Use HighestCertifiedTimestamp.ProtoReflect.Descriptor instead. func (*HighestCertifiedTimestamp) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{24} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{26} } func (x *HighestCertifiedTimestamp) GetSeqNr() uint64 { @@ -1935,7 +2065,7 @@ type AttributedSignedHighestCertifiedTimestamp struct { func (x *AttributedSignedHighestCertifiedTimestamp) Reset() { *x = AttributedSignedHighestCertifiedTimestamp{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[25] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1948,7 +2078,7 @@ func (x *AttributedSignedHighestCertifiedTimestamp) String() string { func (*AttributedSignedHighestCertifiedTimestamp) ProtoMessage() {} func (x *AttributedSignedHighestCertifiedTimestamp) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[25] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1961,7 +2091,7 @@ func (x *AttributedSignedHighestCertifiedTimestamp) ProtoReflect() protoreflect. // Deprecated: Use AttributedSignedHighestCertifiedTimestamp.ProtoReflect.Descriptor instead. func (*AttributedSignedHighestCertifiedTimestamp) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{25} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{27} } func (x *AttributedSignedHighestCertifiedTimestamp) GetSignedHighestCertifiedTimestamp() *SignedHighestCertifiedTimestamp { @@ -1990,7 +2120,7 @@ type SignedHighestCertifiedTimestamp struct { func (x *SignedHighestCertifiedTimestamp) Reset() { *x = SignedHighestCertifiedTimestamp{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[26] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2003,7 +2133,7 @@ func (x *SignedHighestCertifiedTimestamp) String() string { func (*SignedHighestCertifiedTimestamp) ProtoMessage() {} func (x *SignedHighestCertifiedTimestamp) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[26] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2016,7 +2146,7 @@ func (x *SignedHighestCertifiedTimestamp) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedHighestCertifiedTimestamp.ProtoReflect.Descriptor instead. func (*SignedHighestCertifiedTimestamp) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{26} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{28} } func (x *SignedHighestCertifiedTimestamp) GetHighestCertifiedTimestamp() *HighestCertifiedTimestamp { @@ -2045,7 +2175,7 @@ type AttributedObservation struct { func (x *AttributedObservation) Reset() { *x = AttributedObservation{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[27] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2058,7 +2188,7 @@ func (x *AttributedObservation) String() string { func (*AttributedObservation) ProtoMessage() {} func (x *AttributedObservation) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[27] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2071,7 +2201,7 @@ func (x *AttributedObservation) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributedObservation.ProtoReflect.Descriptor instead. func (*AttributedObservation) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{27} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{29} } func (x *AttributedObservation) GetObservation() []byte { @@ -2100,7 +2230,7 @@ type AttributedSignedObservation struct { func (x *AttributedSignedObservation) Reset() { *x = AttributedSignedObservation{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[28] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2113,7 +2243,7 @@ func (x *AttributedSignedObservation) String() string { func (*AttributedSignedObservation) ProtoMessage() {} func (x *AttributedSignedObservation) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[28] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2126,7 +2256,7 @@ func (x *AttributedSignedObservation) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributedSignedObservation.ProtoReflect.Descriptor instead. func (*AttributedSignedObservation) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{28} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{30} } func (x *AttributedSignedObservation) GetSignedObservation() *SignedObservation { @@ -2155,7 +2285,7 @@ type SignedObservation struct { func (x *SignedObservation) Reset() { *x = SignedObservation{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[29] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2168,7 +2298,7 @@ func (x *SignedObservation) String() string { func (*SignedObservation) ProtoMessage() {} func (x *SignedObservation) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[29] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2181,7 +2311,7 @@ func (x *SignedObservation) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedObservation.ProtoReflect.Descriptor instead. func (*SignedObservation) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{29} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{31} } func (x *SignedObservation) GetObservation() []byte { @@ -2210,7 +2340,7 @@ type AttributedPrepareSignature struct { func (x *AttributedPrepareSignature) Reset() { *x = AttributedPrepareSignature{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[30] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2223,7 +2353,7 @@ func (x *AttributedPrepareSignature) String() string { func (*AttributedPrepareSignature) ProtoMessage() {} func (x *AttributedPrepareSignature) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[30] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2236,7 +2366,7 @@ func (x *AttributedPrepareSignature) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributedPrepareSignature.ProtoReflect.Descriptor instead. func (*AttributedPrepareSignature) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{30} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{32} } func (x *AttributedPrepareSignature) GetSignature() []byte { @@ -2265,7 +2395,7 @@ type AttributedCommitSignature struct { func (x *AttributedCommitSignature) Reset() { *x = AttributedCommitSignature{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[31] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2278,7 +2408,7 @@ func (x *AttributedCommitSignature) String() string { func (*AttributedCommitSignature) ProtoMessage() {} func (x *AttributedCommitSignature) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[31] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2291,7 +2421,7 @@ func (x *AttributedCommitSignature) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributedCommitSignature.ProtoReflect.Descriptor instead. func (*AttributedCommitSignature) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{31} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{33} } func (x *AttributedCommitSignature) GetSignature() []byte { @@ -2320,7 +2450,7 @@ type AttestedStateTransitionBlock struct { func (x *AttestedStateTransitionBlock) Reset() { *x = AttestedStateTransitionBlock{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[32] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2333,7 +2463,7 @@ func (x *AttestedStateTransitionBlock) String() string { func (*AttestedStateTransitionBlock) ProtoMessage() {} func (x *AttestedStateTransitionBlock) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[32] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2346,7 +2476,7 @@ func (x *AttestedStateTransitionBlock) ProtoReflect() protoreflect.Message { // Deprecated: Use AttestedStateTransitionBlock.ProtoReflect.Descriptor instead. func (*AttestedStateTransitionBlock) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{32} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{34} } func (x *AttestedStateTransitionBlock) GetStateTransitionBlock() *StateTransitionBlock { @@ -2363,6 +2493,93 @@ func (x *AttestedStateTransitionBlock) GetAttributedSignatures() []*AttributedCo return nil } +type GenesisStateTransitionBlock struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PrevHistoryDigest []byte `protobuf:"bytes,1,opt,name=prev_history_digest,json=prevHistoryDigest,proto3" json:"prev_history_digest,omitempty"` + SeqNr uint64 `protobuf:"varint,2,opt,name=seq_nr,json=seqNr,proto3" json:"seq_nr,omitempty"` + StateTransitionInputsDigest []byte `protobuf:"bytes,3,opt,name=state_transition_inputs_digest,json=stateTransitionInputsDigest,proto3" json:"state_transition_inputs_digest,omitempty"` + StateWriteSetDigest []byte `protobuf:"bytes,4,opt,name=state_write_set_digest,json=stateWriteSetDigest,proto3" json:"state_write_set_digest,omitempty"` + StateRootDigest []byte `protobuf:"bytes,5,opt,name=state_root_digest,json=stateRootDigest,proto3" json:"state_root_digest,omitempty"` + ReportsPlusPrecursorDigest []byte `protobuf:"bytes,6,opt,name=reports_plus_precursor_digest,json=reportsPlusPrecursorDigest,proto3" json:"reports_plus_precursor_digest,omitempty"` +} + +func (x *GenesisStateTransitionBlock) Reset() { + *x = GenesisStateTransitionBlock{} + if protoimpl.UnsafeEnabled { + mi := &file_offchainreporting3_1_messages_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisStateTransitionBlock) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisStateTransitionBlock) ProtoMessage() {} + +func (x *GenesisStateTransitionBlock) ProtoReflect() protoreflect.Message { + mi := &file_offchainreporting3_1_messages_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenesisStateTransitionBlock.ProtoReflect.Descriptor instead. +func (*GenesisStateTransitionBlock) Descriptor() ([]byte, []int) { + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{35} +} + +func (x *GenesisStateTransitionBlock) GetPrevHistoryDigest() []byte { + if x != nil { + return x.PrevHistoryDigest + } + return nil +} + +func (x *GenesisStateTransitionBlock) GetSeqNr() uint64 { + if x != nil { + return x.SeqNr + } + return 0 +} + +func (x *GenesisStateTransitionBlock) GetStateTransitionInputsDigest() []byte { + if x != nil { + return x.StateTransitionInputsDigest + } + return nil +} + +func (x *GenesisStateTransitionBlock) GetStateWriteSetDigest() []byte { + if x != nil { + return x.StateWriteSetDigest + } + return nil +} + +func (x *GenesisStateTransitionBlock) GetStateRootDigest() []byte { + if x != nil { + return x.StateRootDigest + } + return nil +} + +func (x *GenesisStateTransitionBlock) GetReportsPlusPrecursorDigest() []byte { + if x != nil { + return x.ReportsPlusPrecursorDigest + } + return nil +} + type StateTransitionBlock struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2380,7 +2597,7 @@ type StateTransitionBlock struct { func (x *StateTransitionBlock) Reset() { *x = StateTransitionBlock{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[33] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2393,7 +2610,7 @@ func (x *StateTransitionBlock) String() string { func (*StateTransitionBlock) ProtoMessage() {} func (x *StateTransitionBlock) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[33] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2406,7 +2623,7 @@ func (x *StateTransitionBlock) ProtoReflect() protoreflect.Message { // Deprecated: Use StateTransitionBlock.ProtoReflect.Descriptor instead. func (*StateTransitionBlock) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{33} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{36} } func (x *StateTransitionBlock) GetPrevHistoryDigest() []byte { @@ -2469,7 +2686,7 @@ type StateWriteSet struct { func (x *StateWriteSet) Reset() { *x = StateWriteSet{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[34] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2482,7 +2699,7 @@ func (x *StateWriteSet) String() string { func (*StateWriteSet) ProtoMessage() {} func (x *StateWriteSet) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[34] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2495,7 +2712,7 @@ func (x *StateWriteSet) ProtoReflect() protoreflect.Message { // Deprecated: Use StateWriteSet.ProtoReflect.Descriptor instead. func (*StateWriteSet) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{34} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{37} } func (x *StateWriteSet) GetEntries() []*KeyValueModification { @@ -2518,7 +2735,7 @@ type KeyValueModification struct { func (x *KeyValueModification) Reset() { *x = KeyValueModification{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[35] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2531,7 +2748,7 @@ func (x *KeyValueModification) String() string { func (*KeyValueModification) ProtoMessage() {} func (x *KeyValueModification) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[35] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2544,7 +2761,7 @@ func (x *KeyValueModification) ProtoReflect() protoreflect.Message { // Deprecated: Use KeyValueModification.ProtoReflect.Descriptor instead. func (*KeyValueModification) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{35} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{38} } func (x *KeyValueModification) GetKey() []byte { @@ -2583,7 +2800,7 @@ type StateTransitionInputs struct { func (x *StateTransitionInputs) Reset() { *x = StateTransitionInputs{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[36] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2596,7 +2813,7 @@ func (x *StateTransitionInputs) String() string { func (*StateTransitionInputs) ProtoMessage() {} func (x *StateTransitionInputs) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[36] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2609,7 +2826,7 @@ func (x *StateTransitionInputs) ProtoReflect() protoreflect.Message { // Deprecated: Use StateTransitionInputs.ProtoReflect.Descriptor instead. func (*StateTransitionInputs) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{36} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{39} } func (x *StateTransitionInputs) GetSeqNr() uint64 { @@ -2660,7 +2877,7 @@ type MessageBlobOffer struct { func (x *MessageBlobOffer) Reset() { *x = MessageBlobOffer{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[37] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2673,7 +2890,7 @@ func (x *MessageBlobOffer) String() string { func (*MessageBlobOffer) ProtoMessage() {} func (x *MessageBlobOffer) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[37] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2686,7 +2903,7 @@ func (x *MessageBlobOffer) ProtoReflect() protoreflect.Message { // Deprecated: Use MessageBlobOffer.ProtoReflect.Descriptor instead. func (*MessageBlobOffer) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{37} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{40} } func (x *MessageBlobOffer) GetChunkDigestsRoot() []byte { @@ -2722,7 +2939,7 @@ type MessageBlobChunkRequest struct { func (x *MessageBlobChunkRequest) Reset() { *x = MessageBlobChunkRequest{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[38] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2735,7 +2952,7 @@ func (x *MessageBlobChunkRequest) String() string { func (*MessageBlobChunkRequest) ProtoMessage() {} func (x *MessageBlobChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[38] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2748,7 +2965,7 @@ func (x *MessageBlobChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MessageBlobChunkRequest.ProtoReflect.Descriptor instead. func (*MessageBlobChunkRequest) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{38} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{41} } func (x *MessageBlobChunkRequest) GetBlobDigest() []byte { @@ -2780,7 +2997,7 @@ type MessageBlobChunkResponse struct { func (x *MessageBlobChunkResponse) Reset() { *x = MessageBlobChunkResponse{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[39] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2793,7 +3010,7 @@ func (x *MessageBlobChunkResponse) String() string { func (*MessageBlobChunkResponse) ProtoMessage() {} func (x *MessageBlobChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[39] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2806,7 +3023,7 @@ func (x *MessageBlobChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MessageBlobChunkResponse.ProtoReflect.Descriptor instead. func (*MessageBlobChunkResponse) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{39} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{42} } func (x *MessageBlobChunkResponse) GetBlobDigest() []byte { @@ -2857,7 +3074,7 @@ type MessageBlobOfferResponse struct { func (x *MessageBlobOfferResponse) Reset() { *x = MessageBlobOfferResponse{} if protoimpl.UnsafeEnabled { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[40] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2870,7 +3087,7 @@ func (x *MessageBlobOfferResponse) String() string { func (*MessageBlobOfferResponse) ProtoMessage() {} func (x *MessageBlobOfferResponse) ProtoReflect() protoreflect.Message { - mi := &file_offchainreporting3_1_messages_proto_msgTypes[40] + mi := &file_offchainreporting3_1_messages_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2883,7 +3100,7 @@ func (x *MessageBlobOfferResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MessageBlobOfferResponse.ProtoReflect.Descriptor instead. func (*MessageBlobOfferResponse) Descriptor() ([]byte, []int) { - return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{40} + return file_offchainreporting3_1_messages_proto_rawDescGZIP(), []int{43} } func (x *MessageBlobOfferResponse) GetBlobDigest() []byte { @@ -3147,7 +3364,7 @@ var file_offchainreporting3_1_messages_proto_rawDesc = []byte{ 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1a, 0x6d, 0x61, 0x78, 0x43, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x53, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x18, 0x4d, 0x65, + 0x65, 0x53, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xf6, 0x02, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, @@ -3163,310 +3380,359 @@ var file_offchainreporting3_1_messages_proto_rawDesc = []byte{ 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x1d, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x35, 0x0a, 0x17, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, - 0x5f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x50, - 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x37, 0x0a, - 0x18, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, - 0x65, 0x64, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x15, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, - 0x64, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x22, 0xd1, 0x01, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x54, 0x72, 0x65, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x74, 0x6f, 0x5f, 0x73, 0x65, 0x71, - 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x6f, 0x53, 0x65, 0x71, - 0x4e, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x5f, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x6e, 0x64, - 0x49, 0x6e, 0x63, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4f, 0x0a, 0x25, 0x6d, 0x61, 0x78, - 0x5f, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x20, 0x6d, 0x61, 0x78, 0x43, 0x75, 0x6d, - 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x36, 0x0a, 0x0c, 0x4b, 0x65, - 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x5a, 0x0a, 0x16, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x41, 0x6e, 0x64, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, - 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x6b, 0x65, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x6c, - 0x0a, 0x0c, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x61, 0x66, 0x12, 0x40, - 0x0a, 0x04, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, - 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, - 0x33, 0x5f, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x41, 0x6e, 0x64, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x52, 0x04, 0x6c, 0x65, 0x61, 0x66, - 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x08, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xdf, 0x02, 0x0a, - 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x72, 0x65, 0x65, 0x53, 0x79, 0x6e, 0x63, - 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, - 0x09, 0x74, 0x6f, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x74, 0x6f, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x33, 0x0a, 0x16, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x45, 0x6e, 0x64, 0x49, 0x6e, 0x63, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x17, 0x0a, 0x07, 0x67, 0x6f, 0x5f, 0x61, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x67, 0x6f, 0x41, 0x77, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x5f, - 0x69, 0x6e, 0x63, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x63, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x41, - 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x65, - 0x61, 0x76, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x66, 0x66, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x76, 0x0a, 0x1e, 0x67, 0x65, + 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x1b, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x35, + 0x0a, 0x17, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, + 0x65, 0x64, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x14, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, + 0x53, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x37, 0x0a, 0x18, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x22, 0xd1, + 0x01, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x72, 0x65, 0x65, 0x53, 0x79, + 0x6e, 0x63, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x09, 0x74, 0x6f, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x07, 0x74, 0x6f, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0e, 0x65, + 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x63, 0x6c, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x12, 0x4f, 0x0a, 0x25, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x20, 0x6d, 0x61, 0x78, 0x43, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x22, 0x36, 0x0a, 0x0c, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, + 0x69, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5a, 0x0a, 0x16, 0x4c, 0x65, + 0x61, 0x66, 0x4b, 0x65, 0x79, 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x44, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x64, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x6c, 0x0a, 0x0c, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x4c, 0x65, 0x61, 0x66, 0x12, 0x40, 0x0a, 0x04, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x66, + 0x4b, 0x65, 0x79, 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x73, 0x52, 0x04, 0x6c, 0x65, 0x61, 0x66, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x69, 0x62, 0x6c, + 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x69, 0x62, 0x6c, + 0x69, 0x6e, 0x67, 0x73, 0x22, 0xdf, 0x02, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x72, 0x65, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x09, 0x74, 0x6f, 0x5f, 0x73, 0x65, 0x71, 0x5f, + 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x6f, 0x53, 0x65, 0x71, 0x4e, + 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x12, 0x33, 0x0a, 0x16, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x65, 0x6e, + 0x64, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x64, 0x49, 0x6e, + 0x63, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x17, 0x0a, 0x07, 0x67, 0x6f, 0x5f, 0x61, 0x77, + 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x67, 0x6f, 0x41, 0x77, 0x61, 0x79, + 0x12, 0x24, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x63, + 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x41, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, - 0x31, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x0e, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x22, 0xe7, - 0x01, 0x0a, 0x0f, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, - 0x6f, 0x66, 0x12, 0x5b, 0x0a, 0x11, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, - 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x4f, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x10, 0x68, - 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, - 0x77, 0x0a, 0x17, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x3f, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x15, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xb4, 0x01, 0x0a, 0x18, 0x43, 0x65, 0x72, + 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x09, + 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x0e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x0f, 0x45, 0x70, 0x6f, 0x63, 0x68, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x5b, 0x0a, 0x11, 0x68, 0x69, + 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4f, 0x72, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x48, 0x00, - 0x52, 0x07, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x66, 0x66, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, - 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x48, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x13, 0x0a, 0x11, 0x70, 0x72, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, - 0xc8, 0x03, 0x0a, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x68, 0x69, 0x73, - 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x11, 0x70, 0x72, 0x65, 0x76, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, - 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, - 0x72, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x64, 0x69, 0x67, - 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1b, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, - 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, - 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x53, 0x65, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, - 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, - 0x72, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1a, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x50, 0x72, 0x65, 0x63, 0x75, - 0x72, 0x73, 0x6f, 0x72, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x1a, 0x70, 0x72, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, - 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, - 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x52, 0x18, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0xc4, 0x03, 0x0a, 0x0f, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x2e, - 0x0a, 0x13, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x70, 0x72, 0x65, - 0x76, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, - 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x43, 0x0a, 0x1e, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x1b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, - 0x12, 0x33, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, - 0x73, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x44, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, - 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, - 0x74, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x70, 0x6c, 0x75, - 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x5f, 0x64, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x50, 0x6c, 0x75, 0x73, 0x50, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x44, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x12, 0x6b, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x71, - 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x22, 0x80, 0x01, 0x0a, 0x19, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6c, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, - 0x65, 0x64, 0x45, 0x6c, 0x73, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, - 0x70, 0x6f, 0x63, 0x68, 0x22, 0xc8, 0x01, 0x0a, 0x29, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x82, 0x01, 0x0a, 0x22, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x68, 0x69, - 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x35, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, - 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x1f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, - 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, - 0xb0, 0x01, 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, - 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x6f, 0x0a, 0x1b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x10, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x77, 0x0a, 0x17, 0x68, 0x69, 0x67, 0x68, 0x65, + 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, + 0x6f, 0x66, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x19, 0x68, 0x69, 0x67, 0x68, 0x65, - 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x22, 0x55, 0x0a, 0x15, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, - 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, - 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x91, 0x01, 0x0a, 0x1b, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x12, 0x73, 0x69, 0x67, - 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x53, 0x69, 0x67, - 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, - 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x53, 0x0a, - 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x22, 0x52, 0x0a, 0x1a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, - 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, - 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x19, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0xe6, 0x01, 0x0a, 0x1c, 0x41, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x60, 0x0a, 0x16, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6f, 0x66, 0x66, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, - 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x64, 0x0a, 0x15, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x66, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x15, 0x68, 0x69, 0x67, 0x68, 0x65, + 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0x22, 0x80, 0x03, 0x0a, 0x18, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x4f, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x42, 0x0a, + 0x07, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, + 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x48, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x12, 0x5c, 0x0a, 0x14, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x66, 0x72, + 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x72, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x46, + 0x72, 0x6f, 0x6d, 0x53, 0x63, 0x72, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x12, 0x67, 0x65, + 0x6e, 0x65, 0x73, 0x69, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x63, 0x72, 0x61, 0x74, 0x63, 0x68, + 0x12, 0x6c, 0x0a, 0x1a, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, + 0x5f, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, + 0x73, 0x69, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x65, 0x76, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x46, 0x72, + 0x6f, 0x6d, 0x50, 0x72, 0x65, 0x76, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x13, + 0x0a, 0x11, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x22, 0xc8, 0x03, 0x0a, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x76, + 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x70, 0x72, 0x65, 0x76, 0x48, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, + 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, + 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1b, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x73, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x16, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x64, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, + 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x1d, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x1a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x50, + 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x6e, + 0x0a, 0x1a, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x52, 0x18, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x51, 0x75, 0x6f, + 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0xc4, + 0x03, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x11, 0x70, 0x72, 0x65, 0x76, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, + 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, + 0x43, 0x0a, 0x1e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x44, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x53, 0x65, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x44, + 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x5f, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1a, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x50, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, + 0x6f, 0x72, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x6b, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x14, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x22, 0xf4, 0x02, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x13, 0x70, - 0x72, 0x65, 0x76, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x70, 0x72, 0x65, 0x76, 0x48, 0x69, - 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, - 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x70, - 0x75, 0x74, 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x1b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, - 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x52, 0x0d, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, - 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, - 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1a, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x50, 0x72, 0x65, 0x63, 0x75, 0x72, - 0x73, 0x6f, 0x72, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x55, 0x0a, 0x0d, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x12, 0x44, 0x0a, 0x07, 0x65, 0x6e, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6f, 0x66, + 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x17, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x63, 0x72, 0x61, 0x74, 0x63, 0x68, 0x22, 0x69, 0x0a, 0x17, 0x47, + 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x65, 0x76, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x11, 0x70, 0x72, 0x65, 0x76, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x73, + 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, 0x72, 0x65, + 0x76, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x22, 0x80, 0x01, 0x0a, 0x19, 0x48, 0x69, 0x67, 0x68, 0x65, + 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6c, 0x73, 0x65, 0x5f, 0x70, 0x72, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x45, 0x6c, 0x73, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, + 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x22, 0xc8, 0x01, 0x0a, 0x29, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, + 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x82, 0x01, 0x0a, 0x22, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x5f, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x1f, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x72, 0x22, 0xb0, 0x01, 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, + 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x6f, 0x0a, 0x1b, 0x68, 0x69, 0x67, 0x68, + 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, + 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, + 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x19, + 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x55, 0x0a, 0x15, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x91, + 0x01, 0x0a, 0x1b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, + 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x66, 0x66, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, + 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x22, 0x53, 0x0a, 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x52, 0x0a, 0x1a, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x19, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0xe6, + 0x01, 0x0a, 0x1c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x60, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2a, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x14, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x64, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x5f, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x14, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0xcd, 0x02, 0x0a, 0x1b, 0x47, 0x65, 0x6e, 0x65, + 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x76, 0x5f, + 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x70, 0x72, 0x65, 0x76, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x43, + 0x0a, 0x1e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x44, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, + 0x65, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x44, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, + 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x5f, 0x64, + 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1a, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x50, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, + 0x72, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0xf4, 0x02, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x70, + 0x72, 0x65, 0x76, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x43, 0x0a, + 0x1e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x44, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, - 0x5f, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4d, 0x6f, 0x64, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, - 0x22, 0x58, 0x0a, 0x14, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4d, 0x6f, 0x64, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0xd6, 0x01, 0x0a, 0x15, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, - 0x70, 0x75, 0x74, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x70, 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, - 0x68, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x64, 0x0a, - 0x17, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, 0x65, - 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, - 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, - 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x16, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x10, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, - 0x6c, 0x6f, 0x62, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x68, 0x75, 0x6e, - 0x6b, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x44, 0x69, 0x67, 0x65, 0x73, - 0x74, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x22, 0x0a, - 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x53, 0x65, 0x71, 0x4e, - 0x72, 0x22, 0x5b, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x62, - 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, - 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xa1, - 0x01, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x68, - 0x75, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x62, - 0x6c, 0x6f, 0x62, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, - 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x17, 0x0a, - 0x07, 0x67, 0x6f, 0x5f, 0x61, 0x77, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x67, 0x6f, 0x41, 0x77, 0x61, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, - 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, - 0x6f, 0x66, 0x22, 0x7c, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, - 0x62, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x66, 0x66, - 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x42, 0x11, 0x5a, 0x0f, 0x2e, 0x3b, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5f, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, + 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x12, + 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x1d, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x1a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x50, + 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x55, + 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x12, + 0x44, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x58, 0x0a, 0x14, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, + 0xd6, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, + 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x64, 0x0a, 0x17, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, + 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x5f, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x16, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x10, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x2c, 0x0a, + 0x12, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x63, 0x68, 0x75, 0x6e, 0x6b, + 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x70, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0d, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x12, 0x22, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x71, + 0x5f, 0x6e, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x79, 0x53, 0x65, 0x71, 0x4e, 0x72, 0x22, 0x5b, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x44, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x22, 0xa1, 0x01, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, + 0x6c, 0x6f, 0x62, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x44, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x12, 0x17, 0x0a, 0x07, 0x67, 0x6f, 0x5f, 0x61, 0x77, 0x61, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x67, 0x6f, 0x41, 0x77, 0x61, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, + 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x68, 0x75, 0x6e, + 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x7c, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x64, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x44, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6f, + 0x66, 0x66, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, 0x6a, 0x65, + 0x63, 0x74, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x11, 0x5a, 0x0f, 0x2e, 0x3b, 0x73, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3481,7 +3747,7 @@ func file_offchainreporting3_1_messages_proto_rawDescGZIP() []byte { return file_offchainreporting3_1_messages_proto_rawDescData } -var file_offchainreporting3_1_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_offchainreporting3_1_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 44) var file_offchainreporting3_1_messages_proto_goTypes = []interface{}{ (*MessageWrapper)(nil), // 0: offchainreporting3_1.MessageWrapper (*MessageNewEpochWish)(nil), // 1: offchainreporting3_1.MessageNewEpochWish @@ -3507,23 +3773,26 @@ var file_offchainreporting3_1_messages_proto_goTypes = []interface{}{ (*CertifiedPrepareOrCommit)(nil), // 21: offchainreporting3_1.CertifiedPrepareOrCommit (*CertifiedPrepare)(nil), // 22: offchainreporting3_1.CertifiedPrepare (*CertifiedCommit)(nil), // 23: offchainreporting3_1.CertifiedCommit - (*HighestCertifiedTimestamp)(nil), // 24: offchainreporting3_1.HighestCertifiedTimestamp - (*AttributedSignedHighestCertifiedTimestamp)(nil), // 25: offchainreporting3_1.AttributedSignedHighestCertifiedTimestamp - (*SignedHighestCertifiedTimestamp)(nil), // 26: offchainreporting3_1.SignedHighestCertifiedTimestamp - (*AttributedObservation)(nil), // 27: offchainreporting3_1.AttributedObservation - (*AttributedSignedObservation)(nil), // 28: offchainreporting3_1.AttributedSignedObservation - (*SignedObservation)(nil), // 29: offchainreporting3_1.SignedObservation - (*AttributedPrepareSignature)(nil), // 30: offchainreporting3_1.AttributedPrepareSignature - (*AttributedCommitSignature)(nil), // 31: offchainreporting3_1.AttributedCommitSignature - (*AttestedStateTransitionBlock)(nil), // 32: offchainreporting3_1.AttestedStateTransitionBlock - (*StateTransitionBlock)(nil), // 33: offchainreporting3_1.StateTransitionBlock - (*StateWriteSet)(nil), // 34: offchainreporting3_1.StateWriteSet - (*KeyValueModification)(nil), // 35: offchainreporting3_1.KeyValueModification - (*StateTransitionInputs)(nil), // 36: offchainreporting3_1.StateTransitionInputs - (*MessageBlobOffer)(nil), // 37: offchainreporting3_1.MessageBlobOffer - (*MessageBlobChunkRequest)(nil), // 38: offchainreporting3_1.MessageBlobChunkRequest - (*MessageBlobChunkResponse)(nil), // 39: offchainreporting3_1.MessageBlobChunkResponse - (*MessageBlobOfferResponse)(nil), // 40: offchainreporting3_1.MessageBlobOfferResponse + (*GenesisFromScratch)(nil), // 24: offchainreporting3_1.GenesisFromScratch + (*GenesisFromPrevInstance)(nil), // 25: offchainreporting3_1.GenesisFromPrevInstance + (*HighestCertifiedTimestamp)(nil), // 26: offchainreporting3_1.HighestCertifiedTimestamp + (*AttributedSignedHighestCertifiedTimestamp)(nil), // 27: offchainreporting3_1.AttributedSignedHighestCertifiedTimestamp + (*SignedHighestCertifiedTimestamp)(nil), // 28: offchainreporting3_1.SignedHighestCertifiedTimestamp + (*AttributedObservation)(nil), // 29: offchainreporting3_1.AttributedObservation + (*AttributedSignedObservation)(nil), // 30: offchainreporting3_1.AttributedSignedObservation + (*SignedObservation)(nil), // 31: offchainreporting3_1.SignedObservation + (*AttributedPrepareSignature)(nil), // 32: offchainreporting3_1.AttributedPrepareSignature + (*AttributedCommitSignature)(nil), // 33: offchainreporting3_1.AttributedCommitSignature + (*AttestedStateTransitionBlock)(nil), // 34: offchainreporting3_1.AttestedStateTransitionBlock + (*GenesisStateTransitionBlock)(nil), // 35: offchainreporting3_1.GenesisStateTransitionBlock + (*StateTransitionBlock)(nil), // 36: offchainreporting3_1.StateTransitionBlock + (*StateWriteSet)(nil), // 37: offchainreporting3_1.StateWriteSet + (*KeyValueModification)(nil), // 38: offchainreporting3_1.KeyValueModification + (*StateTransitionInputs)(nil), // 39: offchainreporting3_1.StateTransitionInputs + (*MessageBlobOffer)(nil), // 40: offchainreporting3_1.MessageBlobOffer + (*MessageBlobChunkRequest)(nil), // 41: offchainreporting3_1.MessageBlobChunkRequest + (*MessageBlobChunkResponse)(nil), // 42: offchainreporting3_1.MessageBlobChunkResponse + (*MessageBlobOfferResponse)(nil), // 43: offchainreporting3_1.MessageBlobOfferResponse } var file_offchainreporting3_1_messages_proto_depIdxs = []int32{ 1, // 0: offchainreporting3_1.MessageWrapper.message_new_epoch_wish:type_name -> offchainreporting3_1.MessageNewEpochWish @@ -3542,38 +3811,41 @@ var file_offchainreporting3_1_messages_proto_depIdxs = []int32{ 14, // 13: offchainreporting3_1.MessageWrapper.message_state_sync_summary:type_name -> offchainreporting3_1.MessageStateSyncSummary 15, // 14: offchainreporting3_1.MessageWrapper.message_tree_sync_chunk_request:type_name -> offchainreporting3_1.MessageTreeSyncChunkRequest 19, // 15: offchainreporting3_1.MessageWrapper.message_tree_sync_chunk_response:type_name -> offchainreporting3_1.MessageTreeSyncChunkResponse - 37, // 16: offchainreporting3_1.MessageWrapper.message_blob_offer:type_name -> offchainreporting3_1.MessageBlobOffer - 40, // 17: offchainreporting3_1.MessageWrapper.message_blob_offer_response:type_name -> offchainreporting3_1.MessageBlobOfferResponse - 38, // 18: offchainreporting3_1.MessageWrapper.message_blob_chunk_request:type_name -> offchainreporting3_1.MessageBlobChunkRequest - 39, // 19: offchainreporting3_1.MessageWrapper.message_blob_chunk_response:type_name -> offchainreporting3_1.MessageBlobChunkResponse + 40, // 16: offchainreporting3_1.MessageWrapper.message_blob_offer:type_name -> offchainreporting3_1.MessageBlobOffer + 43, // 17: offchainreporting3_1.MessageWrapper.message_blob_offer_response:type_name -> offchainreporting3_1.MessageBlobOfferResponse + 41, // 18: offchainreporting3_1.MessageWrapper.message_blob_chunk_request:type_name -> offchainreporting3_1.MessageBlobChunkRequest + 42, // 19: offchainreporting3_1.MessageWrapper.message_blob_chunk_response:type_name -> offchainreporting3_1.MessageBlobChunkResponse 21, // 20: offchainreporting3_1.MessageEpochStartRequest.highest_certified:type_name -> offchainreporting3_1.CertifiedPrepareOrCommit - 26, // 21: offchainreporting3_1.MessageEpochStartRequest.signed_highest_certified_timestamp:type_name -> offchainreporting3_1.SignedHighestCertifiedTimestamp + 28, // 21: offchainreporting3_1.MessageEpochStartRequest.signed_highest_certified_timestamp:type_name -> offchainreporting3_1.SignedHighestCertifiedTimestamp 20, // 22: offchainreporting3_1.MessageEpochStart.epoch_start_proof:type_name -> offchainreporting3_1.EpochStartProof - 29, // 23: offchainreporting3_1.MessageObservation.signed_observation:type_name -> offchainreporting3_1.SignedObservation - 28, // 24: offchainreporting3_1.MessageProposal.attributed_signed_observations:type_name -> offchainreporting3_1.AttributedSignedObservation - 32, // 25: offchainreporting3_1.MessageBlockSyncResponse.attested_state_transition_blocks:type_name -> offchainreporting3_1.AttestedStateTransitionBlock - 17, // 26: offchainreporting3_1.BoundingLeaf.leaf:type_name -> offchainreporting3_1.LeafKeyAndValueDigests - 16, // 27: offchainreporting3_1.MessageTreeSyncChunkResponse.key_values:type_name -> offchainreporting3_1.KeyValuePair - 18, // 28: offchainreporting3_1.MessageTreeSyncChunkResponse.bounding_leaves:type_name -> offchainreporting3_1.BoundingLeaf - 21, // 29: offchainreporting3_1.EpochStartProof.highest_certified:type_name -> offchainreporting3_1.CertifiedPrepareOrCommit - 25, // 30: offchainreporting3_1.EpochStartProof.highest_certified_proof:type_name -> offchainreporting3_1.AttributedSignedHighestCertifiedTimestamp - 22, // 31: offchainreporting3_1.CertifiedPrepareOrCommit.prepare:type_name -> offchainreporting3_1.CertifiedPrepare - 23, // 32: offchainreporting3_1.CertifiedPrepareOrCommit.commit:type_name -> offchainreporting3_1.CertifiedCommit - 30, // 33: offchainreporting3_1.CertifiedPrepare.prepare_quorum_certificate:type_name -> offchainreporting3_1.AttributedPrepareSignature - 31, // 34: offchainreporting3_1.CertifiedCommit.commit_quorum_certificate:type_name -> offchainreporting3_1.AttributedCommitSignature - 26, // 35: offchainreporting3_1.AttributedSignedHighestCertifiedTimestamp.signed_highest_certified_timestamp:type_name -> offchainreporting3_1.SignedHighestCertifiedTimestamp - 24, // 36: offchainreporting3_1.SignedHighestCertifiedTimestamp.highest_certified_timestamp:type_name -> offchainreporting3_1.HighestCertifiedTimestamp - 29, // 37: offchainreporting3_1.AttributedSignedObservation.signed_observation:type_name -> offchainreporting3_1.SignedObservation - 33, // 38: offchainreporting3_1.AttestedStateTransitionBlock.state_transition_block:type_name -> offchainreporting3_1.StateTransitionBlock - 31, // 39: offchainreporting3_1.AttestedStateTransitionBlock.attributed_signatures:type_name -> offchainreporting3_1.AttributedCommitSignature - 34, // 40: offchainreporting3_1.StateTransitionBlock.state_write_set:type_name -> offchainreporting3_1.StateWriteSet - 35, // 41: offchainreporting3_1.StateWriteSet.entries:type_name -> offchainreporting3_1.KeyValueModification - 27, // 42: offchainreporting3_1.StateTransitionInputs.attributed_observations:type_name -> offchainreporting3_1.AttributedObservation - 43, // [43:43] is the sub-list for method output_type - 43, // [43:43] is the sub-list for method input_type - 43, // [43:43] is the sub-list for extension type_name - 43, // [43:43] is the sub-list for extension extendee - 0, // [0:43] is the sub-list for field type_name + 31, // 23: offchainreporting3_1.MessageObservation.signed_observation:type_name -> offchainreporting3_1.SignedObservation + 30, // 24: offchainreporting3_1.MessageProposal.attributed_signed_observations:type_name -> offchainreporting3_1.AttributedSignedObservation + 34, // 25: offchainreporting3_1.MessageBlockSyncResponse.attested_state_transition_blocks:type_name -> offchainreporting3_1.AttestedStateTransitionBlock + 35, // 26: offchainreporting3_1.MessageBlockSyncResponse.genesis_state_transition_block:type_name -> offchainreporting3_1.GenesisStateTransitionBlock + 17, // 27: offchainreporting3_1.BoundingLeaf.leaf:type_name -> offchainreporting3_1.LeafKeyAndValueDigests + 16, // 28: offchainreporting3_1.MessageTreeSyncChunkResponse.key_values:type_name -> offchainreporting3_1.KeyValuePair + 18, // 29: offchainreporting3_1.MessageTreeSyncChunkResponse.bounding_leaves:type_name -> offchainreporting3_1.BoundingLeaf + 21, // 30: offchainreporting3_1.EpochStartProof.highest_certified:type_name -> offchainreporting3_1.CertifiedPrepareOrCommit + 27, // 31: offchainreporting3_1.EpochStartProof.highest_certified_proof:type_name -> offchainreporting3_1.AttributedSignedHighestCertifiedTimestamp + 22, // 32: offchainreporting3_1.CertifiedPrepareOrCommit.prepare:type_name -> offchainreporting3_1.CertifiedPrepare + 23, // 33: offchainreporting3_1.CertifiedPrepareOrCommit.commit:type_name -> offchainreporting3_1.CertifiedCommit + 24, // 34: offchainreporting3_1.CertifiedPrepareOrCommit.genesis_from_scratch:type_name -> offchainreporting3_1.GenesisFromScratch + 25, // 35: offchainreporting3_1.CertifiedPrepareOrCommit.genesis_from_prev_instance:type_name -> offchainreporting3_1.GenesisFromPrevInstance + 32, // 36: offchainreporting3_1.CertifiedPrepare.prepare_quorum_certificate:type_name -> offchainreporting3_1.AttributedPrepareSignature + 33, // 37: offchainreporting3_1.CertifiedCommit.commit_quorum_certificate:type_name -> offchainreporting3_1.AttributedCommitSignature + 28, // 38: offchainreporting3_1.AttributedSignedHighestCertifiedTimestamp.signed_highest_certified_timestamp:type_name -> offchainreporting3_1.SignedHighestCertifiedTimestamp + 26, // 39: offchainreporting3_1.SignedHighestCertifiedTimestamp.highest_certified_timestamp:type_name -> offchainreporting3_1.HighestCertifiedTimestamp + 31, // 40: offchainreporting3_1.AttributedSignedObservation.signed_observation:type_name -> offchainreporting3_1.SignedObservation + 36, // 41: offchainreporting3_1.AttestedStateTransitionBlock.state_transition_block:type_name -> offchainreporting3_1.StateTransitionBlock + 33, // 42: offchainreporting3_1.AttestedStateTransitionBlock.attributed_signatures:type_name -> offchainreporting3_1.AttributedCommitSignature + 37, // 43: offchainreporting3_1.StateTransitionBlock.state_write_set:type_name -> offchainreporting3_1.StateWriteSet + 38, // 44: offchainreporting3_1.StateWriteSet.entries:type_name -> offchainreporting3_1.KeyValueModification + 29, // 45: offchainreporting3_1.StateTransitionInputs.attributed_observations:type_name -> offchainreporting3_1.AttributedObservation + 46, // [46:46] is the sub-list for method output_type + 46, // [46:46] is the sub-list for method input_type + 46, // [46:46] is the sub-list for extension type_name + 46, // [46:46] is the sub-list for extension extendee + 0, // [0:46] is the sub-list for field type_name } func init() { file_offchainreporting3_1_messages_proto_init() } @@ -3871,7 +4143,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HighestCertifiedTimestamp); i { + switch v := v.(*GenesisFromScratch); i { case 0: return &v.state case 1: @@ -3883,7 +4155,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributedSignedHighestCertifiedTimestamp); i { + switch v := v.(*GenesisFromPrevInstance); i { case 0: return &v.state case 1: @@ -3895,7 +4167,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SignedHighestCertifiedTimestamp); i { + switch v := v.(*HighestCertifiedTimestamp); i { case 0: return &v.state case 1: @@ -3907,7 +4179,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributedObservation); i { + switch v := v.(*AttributedSignedHighestCertifiedTimestamp); i { case 0: return &v.state case 1: @@ -3919,7 +4191,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributedSignedObservation); i { + switch v := v.(*SignedHighestCertifiedTimestamp); i { case 0: return &v.state case 1: @@ -3931,7 +4203,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SignedObservation); i { + switch v := v.(*AttributedObservation); i { case 0: return &v.state case 1: @@ -3943,7 +4215,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributedPrepareSignature); i { + switch v := v.(*AttributedSignedObservation); i { case 0: return &v.state case 1: @@ -3955,7 +4227,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributedCommitSignature); i { + switch v := v.(*SignedObservation); i { case 0: return &v.state case 1: @@ -3967,7 +4239,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttestedStateTransitionBlock); i { + switch v := v.(*AttributedPrepareSignature); i { case 0: return &v.state case 1: @@ -3979,7 +4251,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StateTransitionBlock); i { + switch v := v.(*AttributedCommitSignature); i { case 0: return &v.state case 1: @@ -3991,7 +4263,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StateWriteSet); i { + switch v := v.(*AttestedStateTransitionBlock); i { case 0: return &v.state case 1: @@ -4003,7 +4275,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyValueModification); i { + switch v := v.(*GenesisStateTransitionBlock); i { case 0: return &v.state case 1: @@ -4015,7 +4287,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StateTransitionInputs); i { + switch v := v.(*StateTransitionBlock); i { case 0: return &v.state case 1: @@ -4027,7 +4299,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MessageBlobOffer); i { + switch v := v.(*StateWriteSet); i { case 0: return &v.state case 1: @@ -4039,7 +4311,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MessageBlobChunkRequest); i { + switch v := v.(*KeyValueModification); i { case 0: return &v.state case 1: @@ -4051,7 +4323,7 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MessageBlobChunkResponse); i { + switch v := v.(*StateTransitionInputs); i { case 0: return &v.state case 1: @@ -4063,6 +4335,42 @@ func file_offchainreporting3_1_messages_proto_init() { } } file_offchainreporting3_1_messages_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageBlobOffer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_offchainreporting3_1_messages_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageBlobChunkRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_offchainreporting3_1_messages_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageBlobChunkResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_offchainreporting3_1_messages_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MessageBlobOfferResponse); i { case 0: return &v.state @@ -4100,6 +4408,8 @@ func file_offchainreporting3_1_messages_proto_init() { file_offchainreporting3_1_messages_proto_msgTypes[21].OneofWrappers = []interface{}{ (*CertifiedPrepareOrCommit_Prepare)(nil), (*CertifiedPrepareOrCommit_Commit)(nil), + (*CertifiedPrepareOrCommit_GenesisFromScratch)(nil), + (*CertifiedPrepareOrCommit_GenesisFromPrevInstance)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -4107,7 +4417,7 @@ func file_offchainreporting3_1_messages_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_offchainreporting3_1_messages_proto_rawDesc, NumEnums: 0, - NumMessages: 41, + NumMessages: 44, NumExtensions: 0, NumServices: 0, }, diff --git a/offchainreporting2plus/internal/ocr3_1/serialization/serialization.go b/offchainreporting2plus/internal/ocr3_1/serialization/serialization.go index 8a03be8e..0c8c80d0 100644 --- a/offchainreporting2plus/internal/ocr3_1/serialization/serialization.go +++ b/offchainreporting2plus/internal/ocr3_1/serialization/serialization.go @@ -109,6 +109,12 @@ func SerializeStateTransitionBlock(stb protocol.StateTransitionBlock) ([]byte, e return proto.Marshal(tpm.stateTransitionBlock(stb)) } +func SerializeGenesisStateTransitionBlock(gstb protocol.GenesisStateTransitionBlock) ([]byte, error) { + tpm := toProtoMessage[struct{}]{} + + return proto.Marshal(tpm.genesisStateTransitionBlock(&gstb)) +} + // Deserialize decodes a binary payload into a protocol.Message func Deserialize[RI any](n int, b []byte, requestHandle types.RequestHandle) (protocol.Message[RI], *MessageWrapper, error) { pb := &MessageWrapper{} @@ -227,6 +233,23 @@ func DeserializeStateTransitionBlock(b []byte) (protocol.StateTransitionBlock, e return fpm.stateTransitionBlock(&pb) } +func DeserializeGenesisStateTransitionBlock(b []byte) (protocol.GenesisStateTransitionBlock, error) { + pb := GenesisStateTransitionBlock{} + if err := proto.Unmarshal(b, &pb); err != nil { + return protocol.GenesisStateTransitionBlock{}, err + } + + fpm := fromProtoMessage[struct{}]{} + gstb, err := fpm.genesisStateTransitionBlock(&pb) + if err != nil { + return protocol.GenesisStateTransitionBlock{}, err + } + if gstb == nil { + return protocol.GenesisStateTransitionBlock{}, fmt.Errorf("unexpectedly got nil genesis state transition block") + } + return *gstb, nil +} + // // *toProtoMessage // @@ -394,6 +417,7 @@ func (tpm *toProtoMessage[RI]) messageWrapper(m protocol.Message[RI]) (*MessageW v.RequestStartSeqNr, v.RequestEndExclSeqNr, astbs, + tpm.genesisStateTransitionBlock(v.GenesisStateTransitionBlock), } msgWrapper.Msg = &MessageWrapper_MessageBlockSyncResponse{pm} case protocol.MessageStateSyncSummary[RI]: @@ -550,6 +574,33 @@ func (tpm *toProtoMessage[RI]) certifiedPrepareOrCommit(cpoc protocol.CertifiedP // fields &CertifiedPrepareOrCommit_Commit{tpm.CertifiedCommit(*v)}, } + case *protocol.GenesisFromScratch: + return &CertifiedPrepareOrCommit{ + // zero-initialize protobuf built-ins + protoimpl.MessageState{}, + 0, + nil, + // fields + &CertifiedPrepareOrCommit_GenesisFromScratch{&GenesisFromScratch{}}, + } + case *protocol.GenesisFromPrevInstance: + return &CertifiedPrepareOrCommit{ + // zero-initialize protobuf built-ins + protoimpl.MessageState{}, + 0, + nil, + // fields + &CertifiedPrepareOrCommit_GenesisFromPrevInstance{ + &GenesisFromPrevInstance{ + // zero-initialize protobuf built-ins + protoimpl.MessageState{}, + 0, + nil, + // fields + v.PrevHistoryDigest[:], + v.PrevSeqNr, + }}, + } default: // It's safe to crash here since the "protocol.*" versions of these values // come from the trusted, local environment. @@ -705,6 +756,25 @@ func (tpm *toProtoMessage[RI]) stateTransitionBlock(stb protocol.StateTransition } } +func (tpm *toProtoMessage[RI]) genesisStateTransitionBlock(gstb *protocol.GenesisStateTransitionBlock) *GenesisStateTransitionBlock { + if gstb == nil { + return nil + } + return &GenesisStateTransitionBlock{ + // zero-initialize protobuf built-ins + protoimpl.MessageState{}, + 0, + nil, + // fields + gstb.PrevHistoryDigest[:], + gstb.SeqNr, + gstb.StateTransitionInputsDigest[:], + gstb.StateWriteSetDigest[:], + gstb.StateRootDigest[:], + gstb.ReportsPlusPrecursorDigest[:], + } +} + func (tpm *toProtoMessage[RI]) stateWriteSet(sto protocol.StateWriteSet) *StateWriteSet { pbWriteSet := make([]*KeyValueModification, 0, len(sto.Entries)) for _, kvmod := range sto.Entries { @@ -952,11 +1022,31 @@ func (fpm *fromProtoMessage[RI]) certifiedPrepareOrCommit(m *CertifiedPrepareOrC return nil, err } return &cpocc, nil + case *CertifiedPrepareOrCommit_GenesisFromScratch: + return &protocol.GenesisFromScratch{}, nil + case *CertifiedPrepareOrCommit_GenesisFromPrevInstance: + gfpi, err := fpm.genesisFromPrevInstance(poc.GenesisFromPrevInstance) + if err != nil { + return nil, err + } + return &gfpi, nil default: return nil, fmt.Errorf("unknown case of CertifiedPrepareOrCommit") } } +func (fpm *fromProtoMessage[RI]) genesisFromPrevInstance(m *GenesisFromPrevInstance) (protocol.GenesisFromPrevInstance, error) { + if m == nil { + return protocol.GenesisFromPrevInstance{}, fmt.Errorf("unable to extract a GenesisFromPrevInstance value") + } + var prevHistoryDigest protocol.HistoryDigest + copy(prevHistoryDigest[:], m.PrevHistoryDigest) + return protocol.GenesisFromPrevInstance{ + prevHistoryDigest, + m.PrevSeqNr, + }, nil +} + func (fpm *fromProtoMessage[RI]) certifiedPrepare(m *CertifiedPrepare) (protocol.CertifiedPrepare, error) { if m == nil { return protocol.CertifiedPrepare{}, fmt.Errorf("unable to extract a CertifiedPrepare value") @@ -1229,11 +1319,16 @@ func (fpm *fromProtoMessage[RI]) messageBlockSyncResponse(m *MessageBlockSyncRes if err != nil { return protocol.MessageBlockSyncResponse[RI]{}, err } + gstb, err := fpm.genesisStateTransitionBlock(m.GenesisStateTransitionBlock) + if err != nil { + return protocol.MessageBlockSyncResponse[RI]{}, err + } return protocol.MessageBlockSyncResponse[RI]{ types.EmptyRequestHandleForInboundResponse, m.RequestStartSeqNr, m.RequestEndExclSeqNr, astbs, + gstb, }, nil } @@ -1303,6 +1398,30 @@ func (fpm *fromProtoMessage[RI]) stateTransitionBlock(m *StateTransitionBlock) ( }, nil } +func (fpm *fromProtoMessage[RI]) genesisStateTransitionBlock(m *GenesisStateTransitionBlock) (*protocol.GenesisStateTransitionBlock, error) { + if m == nil { + return nil, nil + } + var prevHistoryDigest protocol.HistoryDigest + copy(prevHistoryDigest[:], m.PrevHistoryDigest) + var inputsDigest protocol.StateTransitionInputsDigest + copy(inputsDigest[:], m.StateTransitionInputsDigest) + var writeSetDigest protocol.StateWriteSetDigest + copy(writeSetDigest[:], m.StateWriteSetDigest) + var stateRootDigest protocol.StateRootDigest + copy(stateRootDigest[:], m.StateRootDigest) + var reportsPlusPrecursorDigest protocol.ReportsPlusPrecursorDigest + copy(reportsPlusPrecursorDigest[:], m.ReportsPlusPrecursorDigest) + return &protocol.GenesisStateTransitionBlock{ + prevHistoryDigest, + m.SeqNr, + inputsDigest, + writeSetDigest, + stateRootDigest, + reportsPlusPrecursorDigest, + }, nil +} + func (fpm *fromProtoMessage[RI]) attributedCommitSignatures(pbasigs []*AttributedCommitSignature) ([]protocol.AttributedCommitSignature, error) { asigs := make([]protocol.AttributedCommitSignature, 0, len(pbasigs)) for _, pbasig := range pbasigs { @@ -1329,6 +1448,18 @@ func (fpm *fromProtoMessage[RI]) attributedCommitSignature(m *AttributedCommitSi }, nil } +func (fpm *fromProtoMessage[RI]) keyValuePairWithDeletions(pbkvmod *KeyValueModification) (protocol.KeyValuePairWithDeletions, error) { + if pbkvmod == nil { + return protocol.KeyValuePairWithDeletions{}, fmt.Errorf("unable to extract a KeyValuePairWithDeletions value") + } + + return protocol.KeyValuePairWithDeletions{ + pbkvmod.Key, + pbkvmod.Value, + pbkvmod.Deleted, + }, nil +} + func (fpm *fromProtoMessage[RI]) stateWriteSet(m *StateWriteSet) (protocol.StateWriteSet, error) { if m == nil { return protocol.StateWriteSet{}, fmt.Errorf("unable to extract an StateWriteSet value") @@ -1336,11 +1467,11 @@ func (fpm *fromProtoMessage[RI]) stateWriteSet(m *StateWriteSet) (protocol.State writeSet := make([]protocol.KeyValuePairWithDeletions, 0, len(m.Entries)) for _, pbkvmod := range m.Entries { - writeSet = append(writeSet, protocol.KeyValuePairWithDeletions{ - pbkvmod.Key, - pbkvmod.Value, - pbkvmod.Deleted, - }) + kvwd, err := fpm.keyValuePairWithDeletions(pbkvmod) + if err != nil { + return protocol.StateWriteSet{}, err + } + writeSet = append(writeSet, kvwd) } return protocol.StateWriteSet{writeSet}, nil @@ -1464,13 +1595,25 @@ func (fpm *fromProtoMessage[RI]) treeSyncChunkProof(pbpns [][]byte) ([]jmt.Diges return proof, nil } +func (fpm *fromProtoMessage[RI]) keyValuePair(pbkvp *KeyValuePair) (protocol.KeyValuePair, error) { + if pbkvp == nil { + return protocol.KeyValuePair{}, fmt.Errorf("unable to extract a KeyValuePair value") + } + + return protocol.KeyValuePair{ + pbkvp.Key, + pbkvp.Value, + }, nil +} + func (fpm *fromProtoMessage[RI]) treeSyncChunkKeyValues(pbkvps []*KeyValuePair) ([]protocol.KeyValuePair, error) { kvps := make([]protocol.KeyValuePair, 0, len(pbkvps)) for _, pbkvp := range pbkvps { - kvps = append(kvps, protocol.KeyValuePair{ - pbkvp.Key, - pbkvp.Value, - }) + kv, err := fpm.keyValuePair(pbkvp) + if err != nil { + return nil, err + } + kvps = append(kvps, kv) } return kvps, nil } @@ -1485,6 +1628,9 @@ func (fpm *fromProtoMessage[RI]) digest(pbdigest []byte) (jmt.Digest, error) { } func (fpm *fromProtoMessage[RI]) leafKeyAndValueDigests(pblkd *LeafKeyAndValueDigests) (jmt.LeafKeyAndValueDigests, error) { + if pblkd == nil { + return jmt.LeafKeyAndValueDigests{}, fmt.Errorf("unable to extract a LeafKeyAndValueDigests value") + } keyDigest, err := fpm.digest(pblkd.KeyDigest) if err != nil { return jmt.LeafKeyAndValueDigests{}, err @@ -1499,21 +1645,32 @@ func (fpm *fromProtoMessage[RI]) leafKeyAndValueDigests(pblkd *LeafKeyAndValueDi }, nil } +func (fpm *fromProtoMessage[RI]) boundingLeaf(pbbl *BoundingLeaf) (jmt.BoundingLeaf, error) { + if pbbl == nil { + return jmt.BoundingLeaf{}, fmt.Errorf("unable to extract a BoundingLeaf value") + } + leafKeyAndValueDigests, err := fpm.leafKeyAndValueDigests(pbbl.Leaf) + if err != nil { + return jmt.BoundingLeaf{}, err + } + siblings, err := fpm.treeSyncChunkProof(pbbl.Siblings) + if err != nil { + return jmt.BoundingLeaf{}, err + } + return jmt.BoundingLeaf{ + leafKeyAndValueDigests, + siblings, + }, nil +} + func (fpm *fromProtoMessage[RI]) treeSyncChunkBoundingLeaves(pbbls []*BoundingLeaf) ([]jmt.BoundingLeaf, error) { boundingLeaves := make([]jmt.BoundingLeaf, 0, len(pbbls)) - for _, pbbbl := range pbbls { - leafKeyAndValueDigests, err := fpm.leafKeyAndValueDigests(pbbbl.Leaf) + for _, pbbl := range pbbls { + bl, err := fpm.boundingLeaf(pbbl) if err != nil { return nil, err } - siblings, err := fpm.treeSyncChunkProof(pbbbl.Siblings) - if err != nil { - return nil, err - } - boundingLeaves = append(boundingLeaves, jmt.BoundingLeaf{ - leafKeyAndValueDigests, - siblings, - }) + boundingLeaves = append(boundingLeaves, bl) } return boundingLeaves, nil } @@ -1554,18 +1711,29 @@ func (fpm *fromProtoMessage[RI]) messageTreeSyncChunkResponse(m *MessageTreeSync }, nil } +func (fpm *fromProtoMessage[RI]) keyDigestRange(pbr *KeyDigestRange) (protocol.KeyDigestRange, error) { + if pbr == nil { + return protocol.KeyDigestRange{}, fmt.Errorf("unable to extract a KeyDigestRange value") + } + startIndex, err := fpm.digest(pbr.StartIndex) + if err != nil { + return protocol.KeyDigestRange{}, err + } + endInclIndex, err := fpm.digest(pbr.EndInclIndex) + if err != nil { + return protocol.KeyDigestRange{}, err + } + return protocol.KeyDigestRange{startIndex, endInclIndex}, nil +} + func (fpm *fromProtoMessage[RI]) pendingKeyDigestRanges(pbRanges []*KeyDigestRange) (protocol.PendingKeyDigestRanges, error) { ranges := make([]protocol.KeyDigestRange, 0, len(pbRanges)) for _, pbr := range pbRanges { - startIndex, err := fpm.digest(pbr.StartIndex) - if err != nil { - return protocol.PendingKeyDigestRanges{}, err - } - endInclIndex, err := fpm.digest(pbr.EndInclIndex) + kr, err := fpm.keyDigestRange(pbr) if err != nil { return protocol.PendingKeyDigestRanges{}, err } - ranges = append(ranges, protocol.KeyDigestRange{startIndex, endInclIndex}) + ranges = append(ranges, kr) } return protocol.NewPendingKeyDigestRanges(ranges), nil } diff --git a/offchainreporting2plus/internal/shim/ocr3_1_key_value_store.go b/offchainreporting2plus/internal/shim/ocr3_1_key_value_store.go index 37a6860c..5bdaa439 100644 --- a/offchainreporting2plus/internal/shim/ocr3_1_key_value_store.go +++ b/offchainreporting2plus/internal/shim/ocr3_1_key_value_store.go @@ -680,10 +680,24 @@ func (s *SemanticOCR3_1KeyValueDatabaseReadWriteTransaction) VerifyAndWriteTreeS targetRootDigest protocol.StateRootDigest, targetSeqNr uint64, startIndex jmt.Digest, + requestEndInclIndex jmt.Digest, endInclIndex jmt.Digest, boundingLeaves []jmt.BoundingLeaf, keyValues []protocol.KeyValuePair, ) (protocol.VerifyAndWriteTreeSyncChunkResult, error) { + if !(bytes.Compare(startIndex[:], endInclIndex[:]) <= 0) { + return protocol.VerifyAndWriteTreeSyncChunkResultByzantine, fmt.Errorf("start index %x is not less than or equal to end incl index %x", startIndex, endInclIndex) + } + if !(bytes.Compare(endInclIndex[:], requestEndInclIndex[:]) <= 0) { + return protocol.VerifyAndWriteTreeSyncChunkResultByzantine, fmt.Errorf("end incl index %x is not less than or equal to request end incl index %x", endInclIndex, requestEndInclIndex) + } + if len(keyValues) == 0 && !bytes.Equal(endInclIndex[:], requestEndInclIndex[:]) { + + return protocol.VerifyAndWriteTreeSyncChunkResultByzantine, + fmt.Errorf("no leaves in chunk and endInclIndex != requestEndInclIndex, the seeder is stalling us: "+ + "startIndex:%x endInclIndex:%x requestEndInclIndex:%x", startIndex, endInclIndex, requestEndInclIndex) + } + if len(keyValues) > s.config.GetMaxTreeSyncChunkKeys() { return protocol.VerifyAndWriteTreeSyncChunkResultByzantine, fmt.Errorf("too many leaves: %d > %d", len(keyValues), s.config.GetMaxTreeSyncChunkKeys()) @@ -1094,6 +1108,29 @@ func (s *SemanticOCR3_1KeyValueDatabaseReadWriteTransaction) DeleteUnattestedSta return !more, err } +func (s *SemanticOCR3_1KeyValueDatabaseReadTransaction) ReadPrevInstanceGenesisStateTransitionBlock() (*protocol.GenesisStateTransitionBlock, error) { + genesisStateTransitionBlockRaw, err := s.rawTransaction.Read([]byte(prevInstanceGenesisStateTransitionBlockKey)) + if err != nil { + return nil, fmt.Errorf("error reading prev instance genesis state transition block: %w", err) + } + if genesisStateTransitionBlockRaw == nil { + return nil, nil + } + genesisStateTransitionBlock, err := serialization.DeserializeGenesisStateTransitionBlock(genesisStateTransitionBlockRaw) + if err != nil { + return nil, fmt.Errorf("failed to deserialize prev instance genesis state transition block: %w", err) + } + return &genesisStateTransitionBlock, nil +} + +func (s *SemanticOCR3_1KeyValueDatabaseReadWriteTransaction) WritePrevInstanceGenesisStateTransitionBlock(genesisStateTransitionBlock protocol.GenesisStateTransitionBlock) error { + genesisStateTransitionBlockRaw, err := serialization.SerializeGenesisStateTransitionBlock(genesisStateTransitionBlock) + if err != nil { + return fmt.Errorf("failed to serialize genesis state transition block: %w", err) + } + return s.rawTransaction.Write([]byte(prevInstanceGenesisStateTransitionBlockKey), genesisStateTransitionBlockRaw) +} + var destructiveDestroyForTreeSyncPrefixesToDelete = [][]byte{ []byte(pluginPrefix), []byte(treeNodePrefix), @@ -1121,6 +1158,8 @@ const ( treeSyncStatusKey = "TSS" highestCommittedSeqNrKey = "HCS" lowestPersistedSeqNrKey = "LPS" + + prevInstanceGenesisStateTransitionBlockKey = "PIGSTB" ) func initializeSchema(keyValueDatabase ocr3_1types.KeyValueDatabase) error { diff --git a/offchainreporting2plus/keyvaluedatabase/pebble_key_value_database.go b/offchainreporting2plus/keyvaluedatabase/pebble_key_value_database.go index 61148c32..ba90e654 100644 --- a/offchainreporting2plus/keyvaluedatabase/pebble_key_value_database.go +++ b/offchainreporting2plus/keyvaluedatabase/pebble_key_value_database.go @@ -4,7 +4,7 @@ import ( "bytes" "errors" "fmt" - "path" + "path/filepath" "sync" "github.com/cockroachdb/pebble" @@ -30,10 +30,23 @@ type pebbleKeyValueDatabaseFactory struct{ baseDir string } var _ ocr3_1types.KeyValueDatabaseFactory = &pebbleKeyValueDatabaseFactory{} func (p *pebbleKeyValueDatabaseFactory) NewKeyValueDatabase(configDigest types.ConfigDigest) (ocr3_1types.KeyValueDatabase, error) { - dbPath := path.Join(p.baseDir, fmt.Sprintf("%s.db", configDigest.String())) + return p.newKeyValueDatabase(configDigest, true) +} + +func (p *pebbleKeyValueDatabaseFactory) NewKeyValueDatabaseIfExists(configDigest types.ConfigDigest) (ocr3_1types.KeyValueDatabase, error) { + return p.newKeyValueDatabase(configDigest, false) +} - db, err := pebble.Open(dbPath, nil) +func (p *pebbleKeyValueDatabaseFactory) newKeyValueDatabase(configDigest types.ConfigDigest, createIfNotExists bool) (ocr3_1types.KeyValueDatabase, error) { + dbPath := p.pathForConfigDigest(configDigest) + opts := pebble.Options{} + errorIfNotExists := !createIfNotExists + opts.ErrorIfNotExists = errorIfNotExists + db, err := pebble.Open(dbPath, &opts) if err != nil { + if errorIfNotExists && errors.Is(err, pebble.ErrDBDoesNotExist) { + return nil, ocr3_1types.ErrKeyValueDatabaseDoesNotExist + } return nil, err } @@ -44,6 +57,10 @@ func (p *pebbleKeyValueDatabaseFactory) NewKeyValueDatabase(configDigest types.C }, nil } +func (p *pebbleKeyValueDatabaseFactory) pathForConfigDigest(configDigest types.ConfigDigest) string { + return filepath.Join(p.baseDir, fmt.Sprintf("%s.db", configDigest.String())) +} + type pebbleKeyValueDatabase struct { db *pebble.DB diff --git a/offchainreporting2plus/ocr3_1confighelper/ocr3_1confighelper.go b/offchainreporting2plus/ocr3_1confighelper/ocr3_1confighelper.go index ddf20ec2..f904da47 100644 --- a/offchainreporting2plus/ocr3_1confighelper/ocr3_1confighelper.go +++ b/offchainreporting2plus/ocr3_1confighelper/ocr3_1confighelper.go @@ -88,6 +88,10 @@ type PublicConfig struct { MaxDurationShouldAcceptAttestedReport time.Duration MaxDurationShouldTransmitAcceptedReport time.Duration + PrevConfigDigest *types.ConfigDigest + PrevSeqNr *uint64 + PrevHistoryDigest *types.HistoryDigest + ConfigDigest types.ConfigDigest } @@ -196,6 +200,11 @@ func PublicConfigFromContractConfig(checkPublicConfigLevel CheckPublicConfigLeve internalPublicConfig.WarnDurationCommitted, internalPublicConfig.MaxDurationShouldAcceptAttestedReport, internalPublicConfig.MaxDurationShouldTransmitAcceptedReport, + + internalPublicConfig.PrevConfigDigest, + internalPublicConfig.PrevSeqNr, + internalPublicConfig.PrevHistoryDigest, + internalPublicConfig.ConfigDigest, }, nil } @@ -306,6 +315,10 @@ type ContractSetConfigArgsOptionalConfig struct { DeltaBlobChunkMinRequestToSameOracleInterval *time.Duration DeltaBlobChunkResponseTimeout *time.Duration BlobChunkBytes *int + + PrevConfigDigest *types.ConfigDigest + PrevSeqNr *uint64 + PrevHistoryDigest *types.HistoryDigest } // This function may be used in production. If you use this as part of multisig @@ -415,6 +428,11 @@ func ContractSetConfigArgsDeterministic( warnDurationCommitted, maxDurationShouldAcceptAttestedReport, maxDurationShouldTransmitAcceptedReport, + + optionalConfig.PrevConfigDigest, + optionalConfig.PrevSeqNr, + optionalConfig.PrevHistoryDigest, + f, onchainConfig, types.ConfigDigest{}, diff --git a/offchainreporting2plus/ocr3_1types/kvdb.go b/offchainreporting2plus/ocr3_1types/kvdb.go index 7ff7ecce..ada3c715 100644 --- a/offchainreporting2plus/ocr3_1types/kvdb.go +++ b/offchainreporting2plus/ocr3_1types/kvdb.go @@ -1,6 +1,8 @@ package ocr3_1types import ( + "fmt" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) @@ -87,6 +89,9 @@ type KeyValueDatabase interface { Close() error } +var ErrKeyValueDatabaseDoesNotExist = fmt.Errorf("key value database does not exist") + type KeyValueDatabaseFactory interface { NewKeyValueDatabase(configDigest types.ConfigDigest) (KeyValueDatabase, error) + NewKeyValueDatabaseIfExists(configDigest types.ConfigDigest) (KeyValueDatabase, error) } diff --git a/offchainreporting2plus/types/history_digest.go b/offchainreporting2plus/types/history_digest.go new file mode 100644 index 00000000..acf1436e --- /dev/null +++ b/offchainreporting2plus/types/history_digest.go @@ -0,0 +1,26 @@ +package types + +import "fmt" + +type HistoryDigest [32]byte + +var _ fmt.Stringer = HistoryDigest{} + +func (h HistoryDigest) String() string { + return fmt.Sprintf("%x", h[:]) +} + +func BytesToHistoryDigest(b []byte) (HistoryDigest, error) { + historyDigest := HistoryDigest{} + + if len(b) != len(historyDigest) { + return HistoryDigest{}, fmt.Errorf("cannot convert bytes to HistoryDigest. bytes have wrong length %v", len(b)) + } + + if len(historyDigest) != copy(historyDigest[:], b) { + // assertion + panic("copy returned wrong length") + } + + return historyDigest, nil +}