Skip to content

Commit 96e7860

Browse files
committed
exec
1 parent 310e250 commit 96e7860

8 files changed

Lines changed: 31 additions & 37 deletions

File tree

chains/evm/contracts/executor/Executor.sol

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ pragma solidity ^0.8.24;
44
import {IExecutor} from "../interfaces/IExecutor.sol";
55

66
import {FeeTokenHandler} from "../libraries/FeeTokenHandler.sol";
7-
import {Ownable2StepMsgSender} from "@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol";
7+
import {FinalityCodec} from "../libraries/FinalityCodec.sol";
88

9+
import {Ownable2StepMsgSender} from "@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol";
910
import {IERC20} from "@openzeppelin/contracts@5.3.0/token/ERC20/IERC20.sol";
1011
import {SafeERC20} from "@openzeppelin/contracts@5.3.0/token/ERC20/utils/SafeERC20.sol";
1112
import {EnumerableSet} from "@openzeppelin/contracts@5.3.0/utils/structs/EnumerableSet.sol";
@@ -19,7 +20,6 @@ contract Executor is IExecutor, Ownable2StepMsgSender {
1920
error ExceedsMaxCCVs(uint256 provided, uint256 max);
2021
error InvalidCCV(address ccv);
2122
error InvalidDestChain(uint64 destChainSelector);
22-
error Executor__RequestedBlockDepthTooLow(uint16 blockConfirmationsRequested, uint16 minBlockConfirmations);
2323
error InvalidMaxPossibleCCVsPerMsg(uint256 maxPossibleCCVsPerMsg);
2424

2525
event CCVAllowlistUpdated(bool enabled);
@@ -41,7 +41,7 @@ contract Executor is IExecutor, Ownable2StepMsgSender {
4141

4242
struct DynamicConfig {
4343
address feeAggregator; // ───────╮ Address to send withdrawn fees to.
44-
uint16 minBlockConfirmations; // │ Minimum number of block confirmations allowed (0 = finality).
44+
bytes2 allowedFinalityConfig; // │ The allowed finality config according to the `FinalityCodec` encoding.
4545
bool ccvAllowlistEnabled; // ────╯ Whether the CCV allowlist is enabled.
4646
}
4747

@@ -142,15 +142,14 @@ contract Executor is IExecutor, Ownable2StepMsgSender {
142142
function _setDynamicConfig(
143143
DynamicConfig memory dynamicConfig
144144
) internal {
145-
// Zero is a valid value for minBlockConfirmations, indicating that finality is requested.
146145
s_dynamicConfig = dynamicConfig;
147146

148147
emit ConfigSet(dynamicConfig);
149148
}
150149

151150
/// @inheritdoc IExecutor
152-
function getMinBlockConfirmations() external view virtual returns (uint16) {
153-
return s_dynamicConfig.minBlockConfirmations;
151+
function getAllowedFinalityConfig() external view virtual returns (bytes2) {
152+
return s_dynamicConfig.allowedFinalityConfig;
154153
}
155154

156155
/// @notice Returns the list of CCVs that the executor supports.
@@ -196,12 +195,12 @@ contract Executor is IExecutor, Ownable2StepMsgSender {
196195

197196
/// @notice Validates whether or not the executor can process the message and returns the fee required to do so.
198197
/// @param destChainSelector The destination chain selector.
199-
/// @param finalityConfig The requested finality encoding for the message. `bytes2(0)` indicates waiting for finality.
198+
/// @param requestedFinality The requested finality encoding for the message. `bytes2(0)` indicates waiting for finality.
200199
/// @param ccvs The CCVs that are requested on source.
201200
/// @return usdCentsFee The USD denominated fee for the executor.
202201
function getFee(
203202
uint64 destChainSelector,
204-
bytes2 finalityConfig,
203+
bytes2 requestedFinality,
205204
address[] calldata ccvs,
206205
bytes calldata, // extraArgs
207206
address // feeToken
@@ -210,10 +209,7 @@ contract Executor is IExecutor, Ownable2StepMsgSender {
210209
if (!remoteChainConfig.enabled) {
211210
revert InvalidDestChain(destChainSelector);
212211
}
213-
uint16 requested = uint16(finalityConfig);
214-
if (requested != 0 && requested < s_dynamicConfig.minBlockConfirmations) {
215-
revert Executor__RequestedBlockDepthTooLow(requested, s_dynamicConfig.minBlockConfirmations);
216-
}
212+
FinalityCodec._ensureRequestedFinalityAllowed(requestedFinality, s_dynamicConfig.allowedFinalityConfig);
217213

218214
if (s_dynamicConfig.ccvAllowlistEnabled) {
219215
for (uint256 i = 0; i < ccvs.length; ++i) {

chains/evm/contracts/interfaces/IExecutor.sol

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
pragma solidity ^0.8.0;
33

44
interface IExecutor {
5-
/// @notice Returns the minimum number of block confirmations that's allowed to be requested. The actual waiting for
6-
/// the block confirmations is handled by the CCVs. This value is only here to gate the value a user can request from
7-
/// a verifier.
8-
function getMinBlockConfirmations() external view returns (uint16);
5+
/// @notice Returns the allowed finality config according to the FinalityCodec encoding.
6+
function getAllowedFinalityConfig() external view returns (bytes2);
97

108
/// @notice Validates whether or not the executor can process the message and returns the fee required to do so.
119
/// @param destChainSelector The destination chain selector.

chains/evm/contracts/test/e2e/e2e.feeWithdraw.t.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ contract e2e_feeWithdrawal is OnRampSetup {
3636
uint256 tokenPoolBalance;
3737
uint256 feeAggregatorBalance;
3838
}
39-
uint16 internal constant MIN_BLOCK_CONFIRMATIONS = 50;
39+
bytes2 internal constant MIN_FINALITY_CONFIG = bytes2(uint16(50));
4040

4141
OffRampHelper internal s_offRamp;
4242
address internal s_destVerifier;
@@ -137,7 +137,7 @@ contract e2e_feeWithdrawal is OnRampSetup {
137137
s_executorImpl = new Executor(
138138
10, // maxCCVsPerMsg
139139
Executor.DynamicConfig({
140-
feeAggregator: s_feeAggregator, minBlockConfirmations: MIN_BLOCK_CONFIRMATIONS, ccvAllowlistEnabled: false
140+
feeAggregator: s_feeAggregator, allowedFinalityConfig: MIN_FINALITY_CONFIG, ccvAllowlistEnabled: false
141141
})
142142
);
143143

chains/evm/contracts/test/executor/Executor/Executor.getFee.t.sol

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
pragma solidity ^0.8.24;
33

44
import {Executor} from "../../../executor/Executor.sol";
5+
import {FinalityCodec} from "../../../libraries/FinalityCodec.sol";
56
import {ExecutorSetup} from "./ExecutorSetup.t.sol";
67

78
contract Executor_getFee is ExecutorSetup {
@@ -14,17 +15,13 @@ contract Executor_getFee is ExecutorSetup {
1415
assertEq(DEFAULT_EXEC_FEE_USD_CENTS, fee);
1516
}
1617

17-
function test_getFee_RevertWhen_Executor__RequestedBlockDepthTooLow() public {
18-
uint16 blockConfirmationsRequested = MIN_BLOCK_CONFIRMATIONS - 1;
18+
function test_getFee_RevertWhen_InvalidRequestedFinality() public {
19+
bytes2 requestedFinality = bytes2(uint16(MIN_FINALITY_CONFIG) - 1);
1920

2021
vm.expectRevert(
21-
abi.encodeWithSelector(
22-
Executor.Executor__RequestedBlockDepthTooLow.selector, blockConfirmationsRequested, MIN_BLOCK_CONFIRMATIONS
23-
)
24-
);
25-
s_executor.getFee(
26-
DEST_CHAIN_SELECTOR, bytes2(uint16(blockConfirmationsRequested)), new address[](1), "", s_sourceFeeToken
22+
abi.encodeWithSelector(FinalityCodec.InvalidRequestedFinality.selector, requestedFinality, MIN_FINALITY_CONFIG)
2723
);
24+
s_executor.getFee(DEST_CHAIN_SELECTOR, requestedFinality, new address[](1), "", s_sourceFeeToken);
2825
}
2926

3027
function test_getFee_RevertWhen_InvalidDestChain() public {

chains/evm/contracts/test/executor/Executor/Executor.getMaxCCVsPerMessage.t.sol

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ contract Executor_getMaxCCVsPerMessage is ExecutorSetup {
1111

1212
uint8 newMaxCCVs = INITIAL_MAX_CCVS + 5;
1313
Executor.DynamicConfig memory dynamicConfig = Executor.DynamicConfig({
14-
feeAggregator: FEE_AGGREGATOR, minBlockConfirmations: MIN_BLOCK_CONFIRMATIONS, ccvAllowlistEnabled: false
14+
feeAggregator: FEE_AGGREGATOR, allowedFinalityConfig: MIN_FINALITY_CONFIG, ccvAllowlistEnabled: false
1515
});
1616
s_executor = new Executor(newMaxCCVs, dynamicConfig);
1717
maxCCVs = s_executor.getMaxCCVsPerMessage();
1818
assertEq(newMaxCCVs, maxCCVs);
1919
}
2020

2121
function test_constructor_RevertWhen_InvalidMaxPossibleCCVsPerMsg() public {
22-
Executor.DynamicConfig memory dynamicConfig =
23-
Executor.DynamicConfig({feeAggregator: FEE_AGGREGATOR, minBlockConfirmations: 0, ccvAllowlistEnabled: false});
22+
Executor.DynamicConfig memory dynamicConfig = Executor.DynamicConfig({
23+
feeAggregator: FEE_AGGREGATOR, allowedFinalityConfig: bytes2(0), ccvAllowlistEnabled: false
24+
});
2425

2526
vm.expectRevert(abi.encodeWithSelector(Executor.InvalidMaxPossibleCCVsPerMsg.selector, 0));
2627
new Executor(0, dynamicConfig);

chains/evm/contracts/test/executor/Executor/Executor.setDynamicConfig.t.sol

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import {Ownable2Step} from "@chainlink/contracts/src/v0.8/shared/access/Ownable2
88
contract Executor_setDynamicConfig is ExecutorSetup {
99
function test_setDynamicConfig() public {
1010
Executor.DynamicConfig memory newConfig = Executor.DynamicConfig({
11-
feeAggregator: makeAddr("newFeeAggregator"), minBlockConfirmations: 123, ccvAllowlistEnabled: false
11+
feeAggregator: makeAddr("newFeeAggregator"),
12+
allowedFinalityConfig: bytes2(uint16(123)),
13+
ccvAllowlistEnabled: false
1214
});
1315

1416
vm.expectEmit();
@@ -17,11 +19,11 @@ contract Executor_setDynamicConfig is ExecutorSetup {
1719

1820
Executor.DynamicConfig memory config = s_executor.getDynamicConfig();
1921
assertEq(newConfig.feeAggregator, config.feeAggregator);
20-
assertEq(newConfig.minBlockConfirmations, config.minBlockConfirmations);
22+
assertEq(newConfig.allowedFinalityConfig, config.allowedFinalityConfig);
2123
assertEq(newConfig.ccvAllowlistEnabled, config.ccvAllowlistEnabled);
2224

23-
// Verify getter for minBlockConfirmations still works
24-
assertEq(s_executor.getMinBlockConfirmations(), newConfig.minBlockConfirmations);
25+
// Verify getAllowedFinalityConfig getter works
26+
assertEq(s_executor.getAllowedFinalityConfig(), newConfig.allowedFinalityConfig);
2527
}
2628

2729
function test_setDynamicConfig_RevertWhen_OnlyCallableByOwner() public {

chains/evm/contracts/test/executor/Executor/ExecutorSetup.t.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ contract ExecutorSetup is BaseTest {
1111
address internal constant FEE_AGGREGATOR = address(999999);
1212
uint8 internal constant INITIAL_MAX_CCVS = 1;
1313
uint16 internal constant DEFAULT_EXEC_FEE_USD_CENTS = 89;
14-
uint16 internal constant MIN_BLOCK_CONFIRMATIONS = 50;
14+
bytes2 internal constant MIN_FINALITY_CONFIG = bytes2(uint16(50));
1515

1616
uint8 internal constant EVM_ADDRESS_LENGTH = 20;
1717

@@ -22,7 +22,7 @@ contract ExecutorSetup is BaseTest {
2222
super.setUp();
2323

2424
Executor.DynamicConfig memory dynamicConfig = Executor.DynamicConfig({
25-
feeAggregator: FEE_AGGREGATOR, minBlockConfirmations: MIN_BLOCK_CONFIRMATIONS, ccvAllowlistEnabled: true
25+
feeAggregator: FEE_AGGREGATOR, allowedFinalityConfig: MIN_FINALITY_CONFIG, ccvAllowlistEnabled: true
2626
});
2727

2828
s_executor = new Executor(INITIAL_MAX_CCVS, dynamicConfig);

chains/evm/contracts/test/mocks/MockExecutor.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ pragma solidity ^0.8.24;
44
import {IExecutor} from "../../interfaces/IExecutor.sol";
55

66
contract MockExecutor is IExecutor {
7-
function getMinBlockConfirmations() external view virtual returns (uint16) {
8-
return 0;
7+
function getAllowedFinalityConfig() external view virtual returns (bytes2) {
8+
return bytes2(0);
99
}
1010

1111
function getFee(

0 commit comments

Comments
 (0)