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

Fix: ToB-11 (dispute collusion) #1519

Merged
merged 14 commits into from
Oct 31, 2023
Merged

Conversation

ChiTimesChi
Copy link
Collaborator

@ChiTimesChi ChiTimesChi commented Oct 30, 2023

Description

  • Fixes ToB-11 by introducing the concept of "post dispute timeout" for Notaries.
  • Once a Notary wins a Dispute, they are put into the post-dispute timeout (currently set to 12 hours). During this period a Notary is considered active, but their signed statements could not used:
    • Summit
      • New Notary snapshots are not accepted.
      • Attestations formed from the previously submitted Notary snapshots could not be used to award the tips.
      • New Notary receipts are not accepted.
      • Previously submitted receipts could not be used to award the tips.
    • Destination
      • New Notary attestations are not accepted.
      • Previously submitted Notary attestations could not be used to prove and execute the message.
      • Gas data from the previously submitted Notary attestation could not be used.
      • Agent Merkle Root from the previously submitted Notary attestation could not be passed to LightManager

Summary by CodeRabbit

New Features:

  • Introduced a dispute timeout mechanism for notaries, enhancing the fairness and robustness of the system.
  • Added a function to retrieve the latest dispute status of an agent, improving transparency and traceability.

Refactor:

  • Updated conditions in various functions to check if a notary is in dispute and if the dispute timeout is over, enhancing system security.

Tests:

  • Added numerous tests to verify the correct functioning of the new dispute timeout mechanism and its integration with existing features.

Chores:

  • Updated import statements across multiple files to accommodate new libraries and structures.

Bug Fixes:

  • Fixed potential issues with notary dispute handling by introducing a dispute timeout mechanism.

@ChiTimesChi ChiTimesChi requested a review from trajan0x as a code owner October 30, 2023 12:28
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2023

Walkthrough

The changes primarily focus on enhancing the dispute resolution mechanism in the contracts. They introduce a new DisputeStatus struct, a DisputeTimeoutNotOver error, and a DISPUTE_TIMEOUT_NOTARY constant. The changes also modify several functions to check if a notary is in dispute and if the dispute timeout is over. New test functions have been added to validate these changes.

Changes

File(s) Summary
packages/contracts-core/contracts/Destination.sol
packages/contracts-core/contracts/Summit.sol
packages/contracts-core/contracts/hubs/ExecutionHub.sol
Added DisputeTimeoutNotOver error and modified conditions in functions to check if a notary is in dispute and if the dispute timeout is over.
packages/contracts-core/contracts/base/AgentSecured.sol
packages/contracts-core/contracts/interfaces/IAgentSecured.sol
packages/contracts-core/contracts/libs/Structures.sol
Introduced DisputeStatus struct and updated functions and mappings to handle dispute status of agents. Added latestDisputeStatus function.
packages/contracts-core/contracts/libs/Constants.sol
packages/contracts-core/contracts/libs/Errors.sol
Added DISPUTE_TIMEOUT_NOTARY constant and DisputeTimeoutNotOver error.
packages/contracts-core/test/mocks/base/AgentSecuredMock.t.sol Added latestDisputeStatus function to the mock contract.
packages/contracts-core/test/suite/Destination.t.sol
packages/contracts-core/test/suite/DestinationSynapse.t.sol
packages/contracts-core/test/suite/Summit.t.sol
packages/contracts-core/test/suite/SummitTips.t.sol
packages/contracts-core/test/suite/base/AgentSecured.t.sol
packages/contracts-core/test/suite/hubs/ExecutionHub.t.sol
Added new test functions to validate the changes related to dispute status and timeout.

🐇🍂 "As autumn leaves fall, we code with joy,
Disputes resolved, no longer a ploy.
With timeouts in place, fairness restored,
In the world of contracts, harmony is scored.
Celebrate the changes, for they bring light,
To the blockchain world, oh what a sight!
So here's to the coders, working day and night,
Making the blockchain world, incredibly bright!" 🎃🌕


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • If you reply to a review comment from CodeRabbit, the bot will automatically respond.
  • To engage with CodeRabbit bot directly around the specific lines of code in the PR, mention @coderabbitai in your review comment
  • Note: Review comments are made on code diffs or files, not on the PR overview.
  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai help to get help.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.

Note: For conversation with the bot, please use the review comments on code diffs or files.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.json

@github-actions github-actions bot added the M-contracts Module: Contracts label Oct 30, 2023
@codecov
Copy link

codecov bot commented Oct 30, 2023

Codecov Report

Attention: 2 lines in your changes are missing coverage. Please review.

Comparison is base (00e4cff) 50.76253% compared to head (fb00b44) 50.81212%.
Report is 1 commits behind head on master.

Additional details and impacted files
@@                 Coverage Diff                 @@
##              master       #1519         +/-   ##
===================================================
+ Coverage   50.76253%   50.81212%   +0.04959%     
===================================================
  Files            357         357                 
  Lines          23868       23888         +20     
  Branches         273         280          +7     
===================================================
+ Hits           12116       12138         +22     
+ Misses         10598       10596          -2     
  Partials        1154        1154                 
Flag Coverage Δ
packages 90.62003% <ø> (ø)
solidity 93.64207% <93.93939%> (+0.26089%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
packages/contracts-core/contracts/Destination.sol 93.84615% <100.00000%> (+5.71056%) ⬆️
packages/contracts-core/contracts/Summit.sol 96.73913% <100.00000%> (+0.07246%) ⬆️
...ges/contracts-core/contracts/hubs/ExecutionHub.sol 97.61905% <100.00000%> (+0.02868%) ⬆️
...ges/contracts-core/contracts/base/AgentSecured.sol 85.00000% <87.50000%> (+7.22221%) ⬆️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between f75a32b and 34d666a.
Files selected for processing (15)
  • packages/contracts-core/contracts/Destination.sol (4 hunks)
  • packages/contracts-core/contracts/Summit.sol (4 hunks)
  • packages/contracts-core/contracts/base/AgentSecured.sol (5 hunks)
  • packages/contracts-core/contracts/hubs/ExecutionHub.sol (2 hunks)
  • packages/contracts-core/contracts/interfaces/IAgentSecured.sol (2 hunks)
  • packages/contracts-core/contracts/libs/Constants.sol (1 hunks)
  • packages/contracts-core/contracts/libs/Errors.sol (1 hunks)
  • packages/contracts-core/contracts/libs/Structures.sol (1 hunks)
  • packages/contracts-core/test/mocks/base/AgentSecuredMock.t.sol (2 hunks)
  • packages/contracts-core/test/suite/Destination.t.sol (5 hunks)
  • packages/contracts-core/test/suite/DestinationSynapse.t.sol (3 hunks)
  • packages/contracts-core/test/suite/Summit.t.sol (2 hunks)
  • packages/contracts-core/test/suite/SummitTips.t.sol (5 hunks)
  • packages/contracts-core/test/suite/base/AgentSecured.t.sol (2 hunks)
  • packages/contracts-core/test/suite/hubs/ExecutionHub.t.sol (2 hunks)
Files skipped from review due to trivial changes (4)
  • packages/contracts-core/contracts/libs/Constants.sol
  • packages/contracts-core/contracts/libs/Errors.sol
  • packages/contracts-core/contracts/libs/Structures.sol
  • packages/contracts-core/test/mocks/base/AgentSecuredMock.t.sol
Additional comments: 44
packages/contracts-core/contracts/interfaces/IAgentSecured.sol (2)
  • 1-4: The import statement for DisputeStatus from Structures.sol is added correctly. Ensure that the Structures.sol file is in the correct path and that the DisputeStatus struct is defined in it.

  • 57-64: The latestDisputeStatus function is added to the IAgentSecured interface. This function is expected to return the latest dispute status for an agent given its index in the Agent Merkle Tree. Ensure that this function is implemented in the contract that uses this interface.

packages/contracts-core/test/suite/Summit.t.sol (2)
  • 1-11: The import statements look fine and are importing necessary contracts and libraries. Ensure that the imported contracts and libraries are up-to-date and compatible with the current version of solidity (0.8.17).

  • 403-448: The newly added test cases test_submitSnapshot_revert_notaryWonDisputeTimeout and test_submitSnapshot_afterNotaryDisputeTimeout are checking the functionality of the dispute timeout for Notaries. The tests seem to be well-structured and cover the necessary scenarios. However, ensure that these tests are passing and providing the expected results.

packages/contracts-core/contracts/hubs/ExecutionHub.sol (2)
  • 9-15: The new exception DisputeTimeoutNotOver has been imported. This is used to handle the case where a notary is still in the post-dispute timeout period.

  • 368-374: The function _proveAttestation has been updated to check if a notary is in post-dispute timeout using the function _notaryDisputeTimeout. If the notary is in post-dispute timeout, the function reverts with the DisputeTimeoutNotOver error. This is a good practice as it ensures that notaries who have recently been in a dispute cannot submit attestations until the timeout period is over, which can help prevent malicious behavior.

+        // Check that Notary who submitted the attestation isn't in post-dispute timeout
+        if (_notaryDisputeTimeout(rootData.notaryIndex)) revert DisputeTimeoutNotOver();
packages/contracts-core/test/suite/DestinationSynapse.t.sol (6)
  • 1-8: The import statements look fine. Ensure that the DISPUTE_TIMEOUT_NOTARY constant and DisputeTimeoutNotOver error are correctly defined in their respective files.

  • 194-225: The prepareGasDataDisputeTest function seems to be setting up a test scenario for a dispute. It's important to ensure that the openTestDispute function correctly simulates a dispute scenario.

  • 227-231: The prepareNotaryWonDisputeTest function seems to be setting up a test scenario where a notary wins a dispute. It's important to ensure that the resolveTestDispute function correctly simulates a dispute resolution scenario.

  • 194-238: > Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [233-243]

The test_getGasData_notaryInDispute function tests the getGasData function when a notary is in dispute. It's important to ensure that the getGasData function correctly handles the case when a notary is in dispute.

  • 245-256: The test_getGasData_notaryWonDisputeTimeout function tests the getGasData function when a notary has won a dispute but is still within the dispute timeout period. It's important to ensure that the getGasData function correctly handles the case when a notary is in the dispute timeout period.

  • 259-271: The test_getGasData_afterNotaryDisputeTimeout function tests the getGasData function after the dispute timeout period for a notary has passed. It's important to ensure that the getGasData function correctly handles the case when the dispute timeout period for a notary has passed.

packages/contracts-core/contracts/Summit.sol (4)
  • 5-17: The import statements are well organized and the new error DisputeTimeoutNotOver is imported correctly.

  • 118-123: The function acceptReceipt now checks if a notary is in dispute or if the dispute timeout is over before proceeding. This is a good security measure to ensure that only trusted notaries can submit receipts.

+ if (_notaryDisputeExists(rcptNotaryIndex)) revert NotaryInDispute();
+ if (_notaryDisputeTimeout(rcptNotaryIndex)) revert DisputeTimeoutNotOver();
  • 146-151: The function acceptNotarySnapshot now checks if a notary is in dispute or if the dispute timeout is over before proceeding. This is a good security measure to ensure that only trusted notaries can submit snapshots.
+ if (_notaryDisputeExists(notaryIndex)) revert NotaryInDispute();
+ if (_notaryDisputeTimeout(notaryIndex)) revert DisputeTimeoutNotOver();
  • 221-237: The function _checkNotaryDisputed has been updated to handle the case where a notary has recently won a dispute and is in the post-dispute timeout period. This is a good way to ensure that the notary's statements are not accepted during the timeout period.
+ } else if (flag == DisputeFlag.Pending || _notaryDisputeTimeout(notaryIndex)) {
+     // Notary is in the ongoing Dispute, or has recently won one. We postpone the receipt handling.
+     // To keep the tips flow going we add the receipt to the back of the queue,
+     // hoping that by the next interaction the dispute will have been resolved.
+     _moveToBack();
+     queuePopped = true;
+ }
packages/contracts-core/test/suite/base/AgentSecured.t.sol (9)
  • 1-13: The import statements and the updateOrigin function look fine. No issues found.

  • 22-25: The openTestDispute function is a helper function for testing. It impersonates the localAgentManager and opens a dispute. This is a good practice for testing purposes.

  • 27-30: The resolveTestDispute function is another helper function for testing. It impersonates the localAgentManager and resolves a dispute. This is a good practice for testing purposes.

  • 32-37: The checkLatestDisputeStatus function checks if the latest dispute status matches the expected status. This is a good practice for testing purposes.

  • 39-45: The test_openDispute function tests the openDispute function. It sets the expected dispute status, opens a dispute, and checks if the dispute status matches the expected status. This is a good practice for testing purposes.

  • 47-52: The test_openDispute_revert_onlyAgentManager function tests if the openDispute function reverts when called by someone other than the localAgentManager. This is a good practice for testing purposes.

  • 56-63: The test_resolveDispute function tests the resolveDispute function. It opens a dispute, resolves it, and checks if the dispute status matches the expected status. This is a good practice for testing purposes.

  • 65-71: The test_resolveDispute_revert_onlyAgentManager function tests if the resolveDispute function reverts when called by someone other than the localAgentManager. This is a good practice for testing purposes.

  • 75-78: The localAgentSecured function returns the tested contract as IAgentSecured. This is a good practice for testing purposes.

packages/contracts-core/contracts/base/AgentSecured.sol (7)
  • 2-11: The import statements look good and are importing the necessary libraries and interfaces for the contract.

  • 34-38: The _disputes mapping is correctly defined to store the dispute status of agents. The DisputeStatus struct is used to store the flag, openedAt timestamp, and resolvedAt timestamp for each agent.

  • 58-65: The openDispute function correctly sets the dispute status for the specified guard and notary agents. It uses the ChainContext.blockTimestamp() function to get the current timestamp and sets the DisputeFlag to Pending.

  • 68-78: The resolveDispute function correctly resolves the dispute for the slashed agent and, if specified, marks the rival agent as not disputed. It uses the ChainContext.blockTimestamp() function to get the current timestamp and sets the DisputeFlag to Slashed for the slashed agent and None for the rival agent.

  • 92-95: The latestDisputeStatus function correctly retrieves the dispute status of an agent from the _disputes mapping.

  • 109-116: The _notaryDisputeExists function correctly checks if a notary agent is in an ongoing dispute or has been slashed by checking if the DisputeFlag is not None.

  • 118-131: The _notaryDisputeTimeout function correctly checks if a notary agent is in the post-dispute timeout period. It first checks if the notary is in an ongoing dispute or has been slashed, then checks if the notary has been in any dispute at all, and finally checks if the dispute timeout is still active by comparing the current timestamp with the sum of the resolvedAt timestamp and DISPUTE_TIMEOUT_NOTARY.

packages/contracts-core/test/suite/Destination.t.sol (7)
  • 4-5: The import statements have been updated to include DISPUTE_TIMEOUT_NOTARY from Constants.sol and DisputeTimeoutNotOver from Errors.sol. Ensure that these new constants and errors are correctly defined in their respective files.

  • 198-214: The test_acceptAttestation_revert_notaryWonDisputeTimeout function tests the scenario where a notary has won a dispute but the dispute timeout is not over. It checks that the submitAttestation function reverts with the DisputeTimeoutNotOver error. This is a good test case to ensure that the dispute timeout is being enforced correctly.

  • 216-236: The test_acceptAttestation_afterNotaryDisputeTimeout function tests the scenario where a notary has won a dispute and the dispute timeout is over. It checks that the submitAttestation function does not revert and that the attestation nonce is updated. This is a good test case to ensure that attestations are accepted after the dispute timeout.

  • 340-356: The prepareAgentRootDisputeTest helper function prepares a mock attestation and opens a dispute for the Notary that signed it. This is a useful helper function for setting up test scenarios involving disputes.

  • 358-363: The prepareNotaryWonDisputeTest helper function resolves a test dispute in favor of the Notary. This is a useful helper function for setting up test scenarios where the Notary has won a dispute.

  • 365-456: These test functions test the passAgentRoot function under various scenarios involving disputes and dispute timeouts. They check that the agent root is passed or not passed correctly depending on the dispute status and timeout. These are good test cases to ensure that the passAgentRoot function behaves correctly in these scenarios.

  • 546-595: > Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [549-614]

These test functions test the getGasData function under various scenarios involving disputes and dispute timeouts. They check that the gas data is returned or not returned correctly depending on the dispute status and timeout. These are good test cases to ensure that the getGasData function behaves correctly in these scenarios.

packages/contracts-core/test/suite/SummitTips.t.sol (5)
  • 4-11: The import of DISPUTE_TIMEOUT_NOTARY and DisputeTimeoutNotOver indicates that the dispute timeout functionality is being tested in this suite.

  • 130-141: The prepareNotaryInDisputeTest and prepareNotaryWonDisputeTest functions are helper functions that simulate a notary being in a dispute and a notary winning a dispute, respectively. These will be useful for testing the new dispute timeout functionality.

  • 201-216: The test_submitReceipt_revert_signedByGuard and test_submitReceipt_revert_notaryInDispute functions are testing that the submitReceipt function correctly rejects receipts signed by a guard or a notary in dispute. This is good for ensuring the security and correctness of the submitReceipt function.

  • 344-367: The test_distributeTips_attestationNotary_wonDisputeTimeout and test_distributeTips_attestationNotary_afterNotaryDisputeTimeout functions are testing the new dispute timeout functionality. They ensure that a notary who has won a dispute cannot distribute tips until the dispute timeout period is over. This is good for ensuring the correctness of the dispute timeout functionality.

  • 409-432: The test_distributeTips_receiptNotary_wonDisputeTimeout and test_distributeTips_receiptNotary_afterNotaryDisputeTimeout functions are also testing the new dispute timeout functionality. They ensure that a notary who has won a dispute cannot distribute tips until the dispute timeout period is over. This is good for ensuring the correctness of the dispute timeout functionality.

Copy link
Contributor

@mikeyrf mikeyrf left a comment

Choose a reason for hiding this comment

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

lgtm as is.

would say tob 11 in point 2 of recommendations suggested a new status for agents becoming active after dispute resolution (in post dispute timeout), so you may want to add that as well. but current checks in this PR effectively implement that functionality so your call.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 34d666a and fb00b44.
Files selected for processing (2)
  • packages/contracts-core/contracts/libs/Constants.sol (1 hunks)
  • packages/contracts-core/contracts/libs/Errors.sol (1 hunks)
Files skipped from review due to trivial changes (2)
  • packages/contracts-core/contracts/libs/Constants.sol
  • packages/contracts-core/contracts/libs/Errors.sol

@ChiTimesChi ChiTimesChi merged commit d175290 into master Oct 31, 2023
65 checks passed
@ChiTimesChi ChiTimesChi deleted the fix/tob/11-dispute-collusion branch October 31, 2023 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2-reviewers C-Protocol-Critical PRs that modify protocol-critical code. M-contracts Module: Contracts size/m
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants