Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CommitPlugin with RMN OffChain Blessing #17

Merged
merged 20 commits into from
Aug 15, 2024

Conversation

rstout
Copy link
Contributor

@rstout rstout commented Jul 2, 2024

Implements a new version of the Commit Plugin in /commit_rmn_ocb (ocb = off chain blessing) based on the spec. This is basically only the OCR3 function implementations (e.g. Query, Observation, Outcome, etc). No tests have been written yet. I recommend starting with the README.

@rstout rstout force-pushed the rs/commit_plugin_rmn_ocb branch 6 times, most recently from f3e3035 to 113e94e Compare July 9, 2024 21:43
@rstout rstout force-pushed the rs/commit_plugin_rmn_ocb branch 11 times, most recently from d62f0b3 to 1608eb2 Compare July 16, 2024 18:27
plugintypes/commit.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@makramkd makramkd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still combing through the PR, this is just my first pass

Comment on lines 312 to 313
// GetOnRampMaxSeqNums returns the maximum sequence number that this oracle finds on the OnRamp for each given chain
// (for the configured dest chain)
GetOnRampMaxSeqNums() ([]plugintypes.SeqNumChain, error)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be a bit more precise here in terms of what we want from this method and try to match existing terminology in the ramp contracts so we don't get confused.

The onramp has this method: getExpectedNextSequenceNumber which returns the next sequence number that is going to be used by the onramp. Is this what we want?

Or do we want the last-used sequence number, which would be getExpectedNextSequenceNumber() - 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getExpectedNextSequenceNumber is a method on the OffRamp, not the OnRamp right? I've renamed the OffRamp seq nums to OffRampNextSeqNums and kept OnRampMaxSeqNums, we can discuss changing the names further.

Comment on lines 316 to 317
// GetOffRampMaxSeqNums returns the maximum sequence number that this oracle finds on the OffRamp for each given
// chain (for the configured dest chain)
GetOffRampMaxSeqNums() ([]plugintypes.SeqNumChain, error)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another piece of terminology / consistency in order to avoid confusion: these have been called "max committed sequence numbers" so maybe call this GetMaxCommittedSeqNums

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed this to OffRampNextSeqNums, but happy to discuss clearer names

commit_rmn_ocb/types.go Outdated Show resolved Hide resolved
commit_rmn_ocb/types.go Outdated Show resolved Hide resolved
Comment on lines 270 to 235
case ReportIntervalsSelected:
return BuildingReport
case ReportGenerated:
return WaitingForReportTransmission
case ReportEmpty:
return SelectingRangesForReport
case ReportNotYetTransmitted:
return WaitingForReportTransmission
case ReportTransmitted:
return SelectingRangesForReport
case ReportNotTransmitted:
return SelectingRangesForReport
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This would be more readable if the transitions that lead to the same state are grouped together, e.g

switch o.OutcomeType {
    case ReportIntervalsSelected:
		return BuildingReport

    case ReportGenerated:
        fallthrough
    case ReportNotYetTransmitted:
        return WaitingForReportTransmission

    case ReportEmpty:
        fallthrough
    case ReportTransmitted:
        fallthrough
    case ReportNotTransmitted:
        fallthrough
    default:
        return SelectingRangesForReport

}

Feels like this might be better as a pure func rather than tied to the Outcome, but I'm not too opinionated about that. Also needs a set of tests to cover all the transitions.

commit_rmn_ocb/types.go Outdated Show resolved Hide resolved

func validateFChain(fChain map[cciptypes.ChainSelector]int) error {
for _, f := range fChain {
if f < 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be f <= 0 since f is never 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f can be 0 for chains that are not RMN enabled

commit_rmn_ocb/types.go Outdated Show resolved Hide resolved
commit_rmn_ocb/types.go Outdated Show resolved Hide resolved
return nil
}

func (p *Plugin) decodeOutcome(outcome ocr3types.Outcome) (CommitPluginOutcome, CommitPluginState) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like this should return an error instead of just returning SelectingRangesForReport if there is an error decoding

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My logic is: if there's an issue decoding, just go to the "select interval" state instead of erroring-out

@rstout rstout force-pushed the rs/commit_plugin_rmn_ocb branch 6 times, most recently from f37494d to e245649 Compare August 9, 2024 17:53
@rstout rstout force-pushed the rs/commit_plugin_rmn_ocb branch 4 times, most recently from af41868 to 4506323 Compare August 12, 2024 21:30
commit_rmn_ocb/observation.go Outdated Show resolved Hide resolved
@@ -0,0 +1 @@
package commitrmnocb
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intention of this file to house some prometheus metrics?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Comment on lines +134 to +174
// Assert there are no sequence number gaps in msgs
if i > 0 {
if msg.Header.SequenceNumber != msgs[i-1].Header.SequenceNumber+1 {
return [32]byte{}, fmt.Errorf("found non-consecutive sequence numbers when computing merkle root, "+
"gap between sequence nums %d and %d, messages: %v", msgs[i-1].Header.SequenceNumber,
msg.Header.SequenceNumber, msgs)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: would this be useful as a separate helper that is unit tested?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See ConstructMerkleTree in execute/report/report.go. Not a drop-in helper since it uses exec specific types.

commitrmnocb/observation.go Outdated Show resolved Hide resolved
commitrmnocb/observation.go Outdated Show resolved Hide resolved
Comment on lines +22 to +25
if outcome.OutcomeType != ReportGenerated {
return []ocr3types.ReportWithInfo[[]byte]{}, nil
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding a log for this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the happy path (e.g. in the round when intervals are chosen), so I think logging here would just be verbose.

commitrmnocb/report.go Show resolved Hide resolved
commitrmnocb/types.go Show resolved Hide resolved
commitrmnocb/types.go Outdated Show resolved Hide resolved
Comment on lines +25 to +26
// The maximum number of times to check if the previous report has been transmitted
MaxReportTransmissionCheckAttempts uint
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something we want all plugin instances in the DON to have in common? If so, it should go in the OffchainConfig struct below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between CommitPluginConfig and CommitOffchainConfig?

@makramkd
Copy link
Collaborator

Looks good overall, mostly minor comments above 😄

Copy link
Contributor

@winder winder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly nits and questions. Looks great overall.

I did have some confusion around the transient nature of states and the outcome type -- especially in the Reports function where it would have been nice to check for a BuildingReport state rather than a ReportGenerated outcome.

commitrmnocb/factory.go Outdated Show resolved Hide resolved
commitrmnocb/types.go Outdated Show resolved Hide resolved
commitrmnocb/observation.go Outdated Show resolved Hide resolved
commitrmnocb/observation.go Outdated Show resolved Hide resolved
commitrmnocb/observation.go Outdated Show resolved Hide resolved
commitrmnocb/outcome.go Outdated Show resolved Hide resolved
commitrmnocb/outcome.go Outdated Show resolved Hide resolved
commitrmnocb/outcome.go Outdated Show resolved Hide resolved

const (
ReportIntervalsSelected OutcomeType = iota + 1
ReportGenerated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the report doesn't generate until after the outcome. I'd also consider removing the Report prefix from all of these.

Suggested change
ReportGenerated
ReportGeneration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer past tense, as in practice these are the states of the previous outcome. I think dropping "Report" might lose some clarity imo.

commitrmnocb/report.go Show resolved Hide resolved
Copy link
Contributor

@winder winder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think most/all of the feedback I left can wait until a followup PR. Feel free to merge at your discretion.

Copy link

Test Coverage

Branch Coverage
rs/commit_plugin_rmn_ocb 66.4%
ccip-develop 76.2%

@rstout rstout merged commit 7bdc5fd into ccip-develop Aug 15, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants