Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ func (o Observation) GoEthereumValue() *big.Int { return o.v }

func (o Observation) Deviates(old Observation, thresholdPPB uint64) bool {
if old.v.Cmp(i(0)) == 0 {
//nolint:gosimple
if o.v.Cmp(i(0)) == 0 {
return false // Both values are zero; no deviation
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ func finalToProtoMessage(v protocol.MessageFinal) *protobuf.MessageFinal {
Signatures: make([][]byte, len(v.Report.Signatures)),
},
}
for i, sig := range v.Report.Signatures { //nolint:gosimple
for i, sig := range v.Report.Signatures { //nolint:staticcheck
pm.Report.Signatures[i] = sig
}
return pm
Expand Down
2 changes: 1 addition & 1 deletion offchainreporting2/reportingplugin/median/median.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func (fac NumericalMedianFactory) NewReportingPlugin(ctx context.Context, config

func DefaultDeviationFunc(_ context.Context, thresholdPPB uint64, old *big.Int, new *big.Int) (bool, error) {
if old.Cmp(i(0)) == 0 {
if new.Cmp(i(0)) == 0 { //nolint:gosimple
if new.Cmp(i(0)) == 0 {
return false, nil // Both values are zero; no deviation
}
return true, nil // Any deviation from 0 is significant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import (
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"
)

// PublicConfig is the configuration disseminated through the smart contract
// It's public, because anybody can read it from the blockchain
// PublicConfig is the configuration disseminated through the smart contract.
// It's public, because anybody can read it from the blockchain.
// The various parameters (e.g. Delta*, MaxDuration*) have some dependencies
// on each other, so be sure to consider the holistic impact of changes to them.
type PublicConfig struct {
// If an epoch (driven by a leader) fails to achieve progress (generate a
// report) after DeltaProgress, we enter a new epoch. This parameter must be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import (
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"
)

// PublicConfig is the configuration disseminated through the smart contract
// It's public, because anybody can read it from the blockchain
// PublicConfig is the configuration disseminated through the smart contract.
// It's public, because anybody can read it from the blockchain.
// The various parameters (e.g. Delta*, MaxDuration*) have some dependencies
// on each other, so be sure to consider the holistic impact of changes to them.
type PublicConfig struct {
// If an epoch (driven by a leader) fails to achieve progress (generate a
// report) after DeltaProgress, we enter a new epoch. This parameter must be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ func ocr3limits(cfg ocr3config.PublicConfig, pluginLimits ocr3types.ReportingPlu
maxLenMsgNewEpoch := overhead
maxLenMsgEpochStartRequest := add(maxLenCertifiedPrepareOrCommit, overhead)
maxLenMsgEpochStart := add(maxLenCertifiedPrepareOrCommit, mul(2*(ed25519.SignatureSize+sigOverhead), cfg.ByzQuorumSize()), overhead)
maxLenMsgRoundStart := add(pluginLimits.MaxQueryLength, overhead)
maxLenMsgRoundStart := add(pluginLimits.MaxQueryLength, ed25519.SignatureSize+sigOverhead, overhead)
maxLenMsgObservation := add(pluginLimits.MaxObservationLength, overhead)
maxLenMsgProposal := add(mul(add(pluginLimits.MaxObservationLength, ed25519.SignatureSize+sigOverhead), cfg.N()), overhead)
maxLenMsgProposal := add(mul(add(pluginLimits.MaxObservationLength, ed25519.SignatureSize+sigOverhead), cfg.N()), ed25519.SignatureSize+sigOverhead, overhead)
maxLenMsgPrepare := overhead
maxLenMsgCommit := overhead
maxLenMsgReportSignatures := add(mul(add(maxSigLen, sigOverhead), pluginLimits.MaxReportCount), overhead)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func RunManagedMercuryOracle(
offchainKeyring,
ocr3OnchainKeyring,
shim.LimitCheckOCR3ReportingPlugin[mercuryshim.MercuryReportInfo]{reportingPlugin, reportingPluginLimits},
shim.NewOCR3TelemetrySender(chTelemetrySend, childLogger),
shim.NewOCR3TelemetrySender(chTelemetrySend, childLogger, localConfig.EnableTransmissionTelemetry),
)

return nil, false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func RunManagedOCR2Oracle(
onchainKeyring,
shim.LimitCheckReportingPlugin{reportingPlugin, reportingPluginInfo.Limits},
reportQuorum,
shim.NewOCR2TelemetrySender(chTelemetrySend, childLogger),
shim.NewOCR2TelemetrySender(chTelemetrySend, childLogger, localConfig.EnableTransmissionTelemetry),
)

return nil, false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func RunManagedOCR3Oracle[RI any](
offchainKeyring,
onchainKeyring,
shim.LimitCheckOCR3ReportingPlugin[RI]{reportingPlugin, reportingPluginInfo.Limits},
shim.NewOCR3TelemetrySender(chTelemetrySend, childLogger),
shim.NewOCR3TelemetrySender(chTelemetrySend, childLogger, localConfig.EnableTransmissionTelemetry),
)

return nil, false
Expand Down
1 change: 1 addition & 0 deletions offchainreporting2plus/internal/ocr2/protocol/oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ func (o *oracleState) run() {
o.localConfig,
o.logger,
o.reportingPlugin,
o.telemetrySender,
o.contractTransmitter,
)
})
Expand Down
2 changes: 2 additions & 0 deletions offchainreporting2plus/internal/ocr2/protocol/pacemaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ func (pace *pacemakerState) messageNewepoch(msg MessageNewEpoch, sender commonty
pace.metrics.leader.Set(float64(pace.l))
pace.persist()

pace.telemetrySender.EpochStarted(pace.config.ConfigDigest, pace.e, pace.l)

// abort instance [...], initialize instance (e,l) of report generation
pace.spawnReportGeneration()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,7 @@ func (repgen *reportGenerationState) messageObserveReq(msg MessageObserveReq, se
repgen.followerState.sentReport = false
repgen.followerState.completedRound = false

repgen.telemetrySender.RoundStarted(
repgen.config.ConfigDigest,
repgen.e,
repgen.followerState.r,
repgen.l,
)
repgen.telemetrySender.RoundStarted(repgen.followerReportTimestamp(), repgen.l)

var o types.Observation
{
Expand Down
28 changes: 26 additions & 2 deletions offchainreporting2plus/internal/ocr2/protocol/telemetry.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
package protocol

import (
"time"

"github.com/smartcontractkit/libocr/commontypes"
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"
)

type TelemetrySender interface {
RoundStarted(
EpochStarted(
configDigest types.ConfigDigest,
epoch uint32,
round uint8,
leader commontypes.OracleID,
)

RoundStarted(
reportTimestamp types.ReportTimestamp,
leader commontypes.OracleID,
)

TransmissionScheduleComputed(
reportTimestamp types.ReportTimestamp,
now time.Time,
schedule map[commontypes.OracleID]time.Duration,
)

TransmissionShouldAcceptFinalizedReportComputed(
reportTimestamp types.ReportTimestamp,
result bool,
ok bool,
)

TransmissionShouldTransmitAcceptedReportComputed(
reportTimestamp types.ReportTimestamp,
result bool,
ok bool,
)
}
61 changes: 48 additions & 13 deletions offchainreporting2plus/internal/ocr2/protocol/transmission.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func RunTransmission(
localConfig types.LocalConfig,
logger loghelper.LoggerWithContext,
reportingPlugin types.ReportingPlugin,
telemetrySender TelemetrySender,
transmitter types.ContractTransmitter,
) {
t := transmissionState{
Expand All @@ -50,6 +51,7 @@ func RunTransmission(
localConfig: localConfig,
logger: logger,
reportingPlugin: reportingPlugin,
telemetrySender: telemetrySender,
transmitter: transmitter,
}
t.run()
Expand All @@ -66,6 +68,7 @@ type transmissionState struct {
localConfig types.LocalConfig
logger loghelper.LoggerWithContext
reportingPlugin types.ReportingPlugin
telemetrySender TelemetrySender
transmitter types.ContractTransmitter

chPersist chan<- persist.TransmissionDBUpdate
Expand Down Expand Up @@ -173,6 +176,7 @@ func (t *transmissionState) eventTransmit(ev EventTransmit) {
"epoch": ev.Epoch,
"round": ev.Round,
})
t.telemetrySender.TransmissionShouldAcceptFinalizedReportComputed(ts, false, false)
return
}

Expand All @@ -181,16 +185,20 @@ func (t *transmissionState) eventTransmit(ev EventTransmit) {
"epoch": ev.Epoch,
"round": ev.Round,
})
t.telemetrySender.TransmissionShouldAcceptFinalizedReportComputed(ts, false, true)
return
}
}

t.telemetrySender.TransmissionShouldAcceptFinalizedReportComputed(ts, true, true)

now := time.Now()
delayMaybe := t.transmitDelay(ev.Epoch, ev.Round)
if delayMaybe == nil {
delays := t.transmitDelays(ev.Epoch, ev.Round)
t.telemetrySender.TransmissionScheduleComputed(ts, now, delays)
delay, ok := delays[t.id]
if !ok {
return
}
delay := *delayMaybe

transmission := types.PendingTransmission{
now.Add(delay),
Expand Down Expand Up @@ -266,11 +274,13 @@ func (t *transmissionState) eventTTransmitTimeout() {

if err != nil {
t.logger.Error("eventTTransmitTimeout: ReportingPlugin.ShouldTransmitAcceptedReport error", commontypes.LogFields{"error": err})
t.telemetrySender.TransmissionShouldTransmitAcceptedReportComputed(item.ReportTimestamp, false, false)
return
}

if !shouldTransmit {
t.logger.Info("eventTTransmitTimeout: ReportingPlugin.ShouldTransmitAcceptedReport returned false", nil)
t.telemetrySender.TransmissionShouldTransmitAcceptedReportComputed(item.ReportTimestamp, false, true)
return
}
}
Expand All @@ -279,6 +289,7 @@ func (t *transmissionState) eventTTransmitTimeout() {
"epoch": item.Epoch,
"round": item.Round,
})
t.telemetrySender.TransmissionShouldTransmitAcceptedReportComputed(item.ReportTimestamp, true, true)

{
ctx, cancel := context.WithTimeout(
Expand Down Expand Up @@ -321,7 +332,10 @@ func (t *transmissionState) eventTTransmitTimeout() {
})
}

func (t *transmissionState) transmitDelay(epoch uint32, round uint8) *time.Duration {
// Computes a map from oracle ids to to transmission delays. This is
// deterministic across all oracles. The result is derived pseudorandomly
// uniformly and independently per epoch and round.
func (t *transmissionState) transmitDelays(epoch uint32, round uint8) map[commontypes.OracleID]time.Duration {
// No need for HMAC. Since we use Keccak256, prepending
// with key gives us a PRF already.
hash := sha3.NewLegacyKeccak256()
Expand All @@ -336,15 +350,36 @@ func (t *transmissionState) transmitDelay(epoch uint32, round uint8) *time.Durat

var key [16]byte
copy(key[:], hash.Sum(nil))
pi := permutation.Permutation(t.config.N(), key)

sum := 0
for i, s := range t.config.S {
sum += s
if pi[t.id] < sum {
result := time.Duration(i) * t.config.DeltaStage
return &result

// Permutation from transmission order index to oracle id
piInv := make([]int, t.config.N())
{
// Permutation from oracle id to transmission order index. The
// permutations are structured in this "inverted" way for historical
// compatibility
pi := permutation.Permutation(t.config.N(), key)
for i := range pi {
piInv[pi[i]] = i
}
}

result := make(map[commontypes.OracleID]time.Duration, t.config.N())

accumulatedStageSize := 0
for stageIdx, stageSize := range t.config.S {
// i is the index of the oracle sorted by transmission order
for i := accumulatedStageSize; i < accumulatedStageSize+stageSize; i++ {
if i >= len(piInv) {
// Index is larger than index of the last oracle. This happens
// when sum(S) > N.
break
}
oracleId := commontypes.OracleID(piInv[i])
result[oracleId] = time.Duration(stageIdx) * t.config.DeltaStage
}

accumulatedStageSize += stageSize
}
return nil

return result
}
Loading