-
Notifications
You must be signed in to change notification settings - Fork 32
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
Contracts/communication synapse module #2050
Contracts/communication synapse module #2050
Conversation
WalkthroughThe recent updates introduce a sophisticated framework for interchain communication, focusing on enhancing the verification process, managing verifiers, and handling gas-related calculations across different blockchains. A notable addition is the abstract contract for defining interchain events and the introduction of a gas oracle interface for cost estimation. These changes aim to streamline cross-chain interactions, improve security through verifier management, and optimize transaction cost estimations, thereby fostering a more interconnected and efficient blockchain ecosystem. Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
@coderabbitai review |
There was a problem hiding this 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: 5
Configuration used: CodeRabbit UI
Files selected for processing (16)
- packages/contracts-communication/contracts/events/InterchainModuleEvents.sol (1 hunks)
- packages/contracts-communication/contracts/events/SynapseModuleEvents.sol (1 hunks)
- packages/contracts-communication/contracts/interfaces/IGasOracle.sol (1 hunks)
- packages/contracts-communication/contracts/interfaces/IInterchainModule.sol (1 hunks)
- packages/contracts-communication/contracts/interfaces/ISynapseModule.sol (1 hunks)
- packages/contracts-communication/contracts/libs/ThresholdECDSA.sol (3 hunks)
- packages/contracts-communication/contracts/modules/InterchainModule.sol (1 hunks)
- packages/contracts-communication/contracts/modules/SynapseModule.sol (1 hunks)
- packages/contracts-communication/test/InterchainClientV1Test.t.sol (3 hunks)
- packages/contracts-communication/test/harnesses/ThresholdECDSALibHarness.sol (1 hunks)
- packages/contracts-communication/test/libs/ThresholdECDSALib.t.sol (2 hunks)
- packages/contracts-communication/test/mocks/GasOracleMock.sol (1 hunks)
- packages/contracts-communication/test/mocks/InterchainDBMock.sol (1 hunks)
- packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol (1 hunks)
- packages/contracts-communication/test/modules/SynapseModule.Management.t.sol (1 hunks)
- packages/contracts-communication/test/modules/SynapseModule.Source.t.sol (1 hunks)
Additional comments: 20
packages/contracts-communication/contracts/events/InterchainModuleEvents.sol (1)
- 6-9: The event declarations in
InterchainModuleEvents.sol
are correctly implemented, following Solidity best practices for event definitions. The use ofindexed
fordestChainId
in theVerificationRequested
event is appropriate for filtering purposes, and theEntryVerified
event correctly uses theInterchainEntry
struct to provide detailed information about verified entries.packages/contracts-communication/contracts/events/SynapseModuleEvents.sol (1)
- 5-10: The event declarations in
SynapseModuleEvents.sol
are correctly implemented, adhering to Solidity best practices. The events for managing verifiers, thresholds, fee collectors, and gas oracles are clearly defined, enhancing the contract's transparency and traceability.packages/contracts-communication/test/mocks/GasOracleMock.sol (1)
- 6-37: The
GasOracleMock
contract correctly implements theIGasOracle
interface methods as empty functions, which is appropriate for testing purposes. This mock contract fulfills the interface requirements, allowing for the simulation ofIGasOracle
interactions in tests without implementing actual logic.packages/contracts-communication/test/harnesses/ThresholdECDSALibHarness.sol (1)
- 33-33: The modification to the
verifySignedHash
function inThresholdECDSALibHarness.sol
, changing the parameter type tobytes calldata
, is a performance optimization that aligns with best practices for handling large byte arrays in Solidity. This change reduces memory copying and gas costs, making it a beneficial update.packages/contracts-communication/test/mocks/InterchainDBMock.sol (1)
- 6-44: The
InterchainDBMock
contract correctly implements theIInterchainDB
interface methods as empty functions, which is appropriate for testing purposes. This mock contract fulfills the interface requirements, allowing for the simulation ofIInterchainDB
interactions in tests without implementing actual logic.packages/contracts-communication/test/modules/SynapseModule.Source.t.sol (6)
- 55-58: The function
mockRequestVerification
is a good example of encapsulating a specific test setup action into a reusable internal function. This approach enhances test readability and maintainability.- 61-68: The function
encodeAndHashEntry
correctly encodes and hashes anInterchainEntry
for testing. However, it's important to ensure that the hash generation process aligns with the production code to avoid discrepancies in test behavior.Ensure that the hash generation process (
keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(encodedEntry)))
) matches the expected production behavior. If there's a mismatch, it could lead to false positives or negatives in testing.
- 70-75: The
test_setup
function correctly asserts the initial state of theSynapseModule
after setup. This includes ownership, interchain DB address, verifier status, and threshold settings. It's crucial for ensuring the contract is initialized correctly.- 85-87: The test
test_requestVerification_transfersFeeToCollector
correctly asserts that the fee is transferred to the fee collector upon a successful verification request. This is an important check for the economic integrity of the system.- 102-106: The test
test_requestVerification_revert_feeBelowRequired
correctly expects a revert when the fee provided is below the required amount. This is crucial for ensuring the contract enforces its fee policy correctly.- 113-120: The function
test_getModuleFee_callsGasOracle_twoSigners
demonstrates good testing practice by mocking external calls and verifying that the contract interacts with the gas oracle as expected. This is important for ensuring the contract's external dependencies are integrated correctly.packages/contracts-communication/test/InterchainClientV1Test.t.sol (2)
- 42-49: The function
mockModuleFee
is a good practice for mocking external dependencies in tests. It allows for controlled testing of the contract's behavior when interacting with the module's fee functionality.- 54-70: The test
test_generateTxId
correctly generates and asserts the transaction ID based on input parameters. This is crucial for ensuring the integrity and uniqueness of interchain transactions.packages/contracts-communication/test/modules/SynapseModule.Management.t.sol (4)
- 39-43: The
test_setup
function correctly asserts the initial state of theSynapseModule
after setup. This includes ownership and interchain DB address. It's crucial for ensuring the contract is initialized correctly.- 78-82: The test
test_addSigner_revert_notOwner
correctly expects a revert when a non-owner attempts to add a verifier. This is important for ensuring that only authorized users can modify the contract state.- 113-116: The function
test_setThreshold_setsThreshold
correctly tests the threshold setting functionality. It's important to ensure that the contract allows for dynamic adjustment of the verification threshold.- 179-187: The test
test_setGasOracle_revert_notContract
correctly expects a revert when attempting to set a non-contract address as the gas oracle. This is crucial for ensuring that only valid contracts can be set as the gas oracle, preventing potential issues.packages/contracts-communication/test/libs/ThresholdECDSALib.t.sol (2)
- 49-53: The introduction of
expectIncorrectSignaturesLengthError
function is a good practice for handling specific error expectations in tests. It enhances test readability and maintainability by abstracting the error expectation logic.- 218-218: Refactoring tests to use
bytes.concat
for signature concatenation simplifies the process of combining multiple signatures into a single byte array. This change improves code readability and reduces the complexity of test setup. However, ensure that the concatenated signatures are correctly formatted and adhere to the expected structure for signatures.Also applies to: 224-224, 230-230, 236-236, 242-242, 247-247, 252-252, 257-257, 262-262, 267-267, 272-272, 277-277, 283-283, 288-288, 293-293, 298-298, 304-304, 309-309, 311-311, 319-319, 327-327, 330-333, 335-339, 346-346
packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol (1)
- 1-321: Overall, the test suite in
SynapseModule.Destination.t.sol
is well-structured and covers a variety of scenarios for entry verification, including valid and invalid signatures, sorted and unsorted signatures, and handling of duplicate signatures. The use of helper functions likesignEntry
andverifyEntry
enhances code reuse and readability. It's important to ensure that all edge cases are covered, especially regarding signature formatting and the handling of different error conditions. Additionally, consider adding tests for any new functionality introduced in the SynapseModule contract that is not covered by the current test suite.
function setUp() public { | ||
vm.chainId(SRC_CHAIN_ID); | ||
module = new SynapseModule(interchainDB, owner); | ||
gasOracle = new GasOracleMock(); | ||
vm.startPrank(owner); | ||
module.setGasOracle(address(gasOracle)); | ||
module.setFeeCollector(feeCollector); | ||
module.addVerifier(address(1)); | ||
module.addVerifier(address(2)); | ||
module.setThreshold(2); | ||
vm.stopPrank(); | ||
// Mock: gasOracle.estimateTxCostInLocalUnits(DST_CHAIN_ID, *, *) to return FEE | ||
vm.mockCall( | ||
address(gasOracle), | ||
abi.encodeWithSelector(GasOracleMock.estimateTxCostInLocalUnits.selector, DST_CHAIN_ID), | ||
abi.encode(FEE) | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setup function setUp
correctly initializes the SynapseModule
contract, sets up a mock GasOracle
, and configures the module with necessary parameters. However, it's recommended to separate concerns by creating helper functions for each setup step to improve readability and maintainability.
Consider refactoring the setup process into smaller, more focused functions. For example, one function could handle the creation and configuration of the SynapseModule
, while another could set up the GasOracleMock
.
function test_requestVerification_emitsEvent() public { | ||
(bytes memory encodedEntry, bytes32 ethSignedHash) = encodeAndHashEntry(mockEntry); | ||
vm.expectEmit(address(module)); | ||
emit VerificationRequested(DST_CHAIN_ID, encodedEntry, ethSignedHash); | ||
mockRequestVerification(FEE, mockEntry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test test_requestVerification_emitsEvent
correctly checks if the VerificationRequested
event is emitted upon calling requestVerification
. However, it's essential to also verify the correctness of the event parameters to ensure they match the expected values.
Consider adding assertions to check the values of the event parameters against expected values. This will ensure not only that the event is emitted but also that it contains the correct information.
icClient.interchainSend{value: totalModuleFees}(receiver, DST_CHAIN_ID, message, options, srcModules); | ||
// TODO: should check the transaction ID? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment // TODO: should check the transaction ID?
in test_interchainSend
highlights an area for improvement. Verifying the transaction ID ensures that the interchain send functionality generates the expected transaction ID based on the input parameters.
Would you like me to help implement the transaction ID check in this test?
function setUp() public { | ||
module = new SynapseModule(interchainDB, owner); | ||
gasOracle = new GasOracleMock(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setUp
function correctly initializes the SynapseModule
contract and a GasOracleMock
. However, it's recommended to also perform initial assertions to verify the correct setup of the contract, such as checking initial values or configurations.
Consider adding initial assertions in the setUp
function to ensure the contract is correctly initialized before running tests.
function test_addSigner_addsSinger() public { | ||
vm.prank(owner); | ||
module.addVerifier(VERIFIER_1); | ||
assertTrue(module.isVerifier(VERIFIER_1)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test test_addSigner_addsSinger
correctly verifies that a signer can be added to the module. However, the function name contains a typo ("addsSinger" should be "addsSigner").
- function test_addSigner_addsSinger() public {
+ function test_addSigner_addsSigner() public {
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
function test_addSigner_addsSinger() public { | |
vm.prank(owner); | |
module.addVerifier(VERIFIER_1); | |
assertTrue(module.isVerifier(VERIFIER_1)); | |
} | |
function test_addSigner_addsSigner() public { | |
vm.prank(owner); | |
module.addVerifier(VERIFIER_1); | |
assertTrue(module.isVerifier(VERIFIER_1)); | |
} |
|
||
/// @inheritdoc IInterchainModule | ||
function requestVerification(uint256 destChainId, InterchainEntry memory entry) external payable { | ||
if (msg.sender != INTERCHAIN_DB) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting that if interchainDB address ever changes, all modules will need to re-deploy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the intended behavior imo, as the module should be compatible only with the latest InterchainDB contract.
In the unlikely event that InterchainDB needs to be updated and redeployed, its design shouldn't be constrained by the existing DB <> Module interaction workflow.
Description
A clear and concise description of the features you're adding in this pull request.
Additional context
Add any other context about the problem you're solving.
Metadata
Summary by CodeRabbit