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

Check round ids #15183

Merged
merged 8 commits into from
Nov 12, 2024
Merged

Check round ids #15183

merged 8 commits into from
Nov 12, 2024

Conversation

eduard-cl
Copy link

Add same epochAndRound check to the contract and _checkRounds() to the tests.

@eduard-cl eduard-cl requested a review from a team as a code owner November 11, 2024 13:03
Copy link
Contributor

I see you updated files related to contracts. Please run pnpm changeset in the contracts directory to add a changeset.

Copy link
Contributor

github-actions bot commented Nov 11, 2024

Static analysis results are available

Hey @eduard-cl, you can view Slither reports in the job summary here or download them as artifact here.
Please check them before merging and make sure you have addressed all issues.

Copy link
Contributor

github-actions bot commented Nov 11, 2024

AER Report: Operator UI CI

aer_workflow , commit , Breaking Changes GQL Check

1. Workflow conclusion is failure:[convictional/trigger-workflow-and-wait@f69fa9e]

Source of Error:
Run convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be	2024-11-12T15:14:51.9383232Z Checking conclusion [failure]
Run convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be	2024-11-12T15:14:51.9384184Z Checking status [completed]
Run convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be	2024-11-12T15:14:51.9385085Z Conclusion is not success, it's [failure].
Run convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be	2024-11-12T15:14:51.9386458Z Propagating failure to upstream job

Why: The triggered workflow did not complete successfully. The conclusion status was "failure" instead of "success," causing the upstream job to fail as well.

Suggested fix: Investigate the logs of the triggered workflow (ID: 11800155115) to identify the specific cause of failure and address the underlying issue. Ensure all dependencies and configurations are correct.

AER Report: CI Core ran successfully ✅

aer_workflow , commit

@Oozyx
Copy link

Oozyx commented Nov 11, 2024

Only checking the epochAndRound doesn't work. We can end up with a situation where the transmitter constantly resends the same transmission and it won't revert.

Comment on lines 828 to 829
// Verify signatures attached to report
_verifySignatures(reportContext, report, rs, ss, rawVs);
Copy link

Choose a reason for hiding this comment

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

Just realized we should always verify signatures. This should be placed under _validateReport

Copy link
Author

Choose a reason for hiding this comment

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

Why? To optimize gas costs it's better if we only verify the signatures one time per report.

Copy link

Choose a reason for hiding this comment

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

It's an attack vector. You can provide existing reports to the secondary feed that were not signed.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, but the existing reports have to have the same timestamp and answer than the one already validated. I thought the biggest benefit of this implementation was to not have to double check the signatures if a report has previously arrived by the other aggregator path.

}

// Lock/unlock the primary feed and pay the transmitters
s_primaryLocked = isSecondary;

Choose a reason for hiding this comment

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

This is not easy to understand, as we're only locking for a single block. Let's change this variable to something more direct, saying that the last update was from the secondary feed, and then communicate the implications of this on the reading side

Copy link
Author

Choose a reason for hiding this comment

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

That's true, renamed it to s_latestSecondary

Comment on lines 829 to 832
if (epochAndRound != s_hotVars.latestEpochAndRound || !s_latestSecondary) {
if (epochAndRound <= s_hotVars.latestEpochAndRound) {
revert StaleReport();
}
Copy link

Choose a reason for hiding this comment

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

I'm finding these conditions hard to follow. Can you include some comments explaining what different edge cases we are validating for?

Copy link
Author

Choose a reason for hiding this comment

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

Added some comments, it's true it's a bit hard to understand, because I inverted some conditionals to not have duplicated code. To help you understand the code, it's the same as this:

// In case the report is the same as the latest and it arrived throw the secondary feed,
// we have to validate it without transmitting a duplicated report
if (epochAndRound == s_hotVars.latestEpochAndRound && s_latestSecondary) {
  s_latestSecondary = isSecondary;
  _payTransmitter(s_hotVars, report_.juelsPerFeeCoin, uint32(initialGas), msg.sender);
  return;
}

// revert because it's older or already arrived throw the primary feed too (if not we would 
// have match the previous check)
if (epochAndRound <= s_hotVars.latestEpochAndRound) {
  revert StaleReport();
}

_report(s_hotVars, reportContext[0], epochAndRound, report_, isSecondary);

// Store if the latest report was secondary or not
s_latestSecondary = isSecondary;
_payTransmitter(s_hotVars, report_.juelsPerFeeCoin, uint32(initialGas), msg.sender);

The only difference is that I inverted the first conditional to not have this lines duplicated:

s_latestSecondary = isSecondary;
_payTransmitter(s_hotVars, report_.juelsPerFeeCoin, uint32(initialGas), msg.sender);

s_hotVars.latestSecondaryRoundId = roundId;
emit SecondaryRoundIdUpdated(roundId);

_payTransmitter(s_hotVars, report_.juelsPerFeeCoin, uint32(initialGas), msg.sender);
return;
}
// In case the report doesn't exist, lock the primary feed
s_primaryLocked = true;
} else {
Copy link

@Oozyx Oozyx Nov 12, 2024

Choose a reason for hiding this comment

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

suggestion: I think we could keep this else and use it for the case where the primary feed deals with receiving an existing, but latest report.

if (epochAndRound == s_hotVars.latestEpochAndRound && s_primaryLocked))

I see this if, else block as where the logic is evaluated for all edge cases where an existing report is sent to either feed. Early returns would happen here as well.

The rest of the function would be to handle and record new reports.

This is very subjective so feel free to disagree.

Copy link
Author

Choose a reason for hiding this comment

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

Could you develop more this idea? Not sure I'm following how it should be implemented.

@cl-sonarqube-production
Copy link

Quality Gate passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarQube

@Oozyx Oozyx merged commit 2a5cb74 into feeds-project-develop Nov 12, 2024
84 of 103 checks passed
@Oozyx Oozyx deleted the feeds-project-rounds-fix branch November 12, 2024 16:04
@@ -804,37 +804,46 @@ contract DualAggregator is OCR2Abstract, OwnerIsCreator, AggregatorV2V3Interface
// Validate the report data
_validateReport(reportContext, report, rs, ss);

// Verify signatures attached to report
_verifySignatures(reportContext, report, rs, ss, rawVs);
Copy link

Choose a reason for hiding this comment

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

Why it got moved? I have to be missing something, but isn't the main gas saving due to skipping this step if the report is already recorded?

@eduard-cl eduard-cl mentioned this pull request Nov 14, 2024
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