diff --git a/contracts/base/AppGatewayBase.sol b/contracts/base/AppGatewayBase.sol index 2b509aab..b0dd03fb 100644 --- a/contracts/base/AppGatewayBase.sol +++ b/contracts/base/AppGatewayBase.sol @@ -344,13 +344,6 @@ abstract contract AppGatewayBase is AddressResolverUtil, IAppGateway, FeesPlugin } } - function callFromChain( - uint32 chainSlug_, - address plug_, - bytes32 params_, - bytes calldata payload_ - ) external virtual onlyWatcherPrecompile {} - /// @notice Initializes the contract /// @param chainSlug_ The chain slug function initialize(uint32 chainSlug_) public virtual {} diff --git a/contracts/base/PlugBase.sol b/contracts/base/PlugBase.sol index 4707cff4..64dff39d 100644 --- a/contracts/base/PlugBase.sol +++ b/contracts/base/PlugBase.sol @@ -11,6 +11,7 @@ abstract contract PlugBase is IPlug { ISocket public socket__; address public appGateway; uint256 public isSocketInitialized; + bytes public overrides; error SocketAlreadyInitialized(); event ConnectorPlugDisconnected(); @@ -52,8 +53,10 @@ abstract contract PlugBase is IPlug { socket__ = ISocket(socket_); } - function _callAppGateway(bytes memory payload_, bytes32 params_) internal returns (bytes32) { - return socket__.callAppGateway(payload_, params_); + /// @notice Sets the overrides needed for the trigger + /// @param overrides_ The overrides + function _setOverrides(bytes memory overrides_) internal { + overrides = overrides_; } function initSocket( diff --git a/contracts/interfaces/IAppGateway.sol b/contracts/interfaces/IAppGateway.sol index 9bd9a649..21200d0e 100644 --- a/contracts/interfaces/IAppGateway.sol +++ b/contracts/interfaces/IAppGateway.sol @@ -13,13 +13,6 @@ interface IAppGateway { function onRequestComplete(uint40 requestCount_, bytes calldata onCompleteData_) external; - function callFromChain( - uint32 chainSlug_, - address plug_, - bytes32 params_, - bytes calldata payload_ - ) external; - function handleRevert(uint40 requestCount_, bytes32 payloadId_) external; /// @notice initialize the contracts on chain diff --git a/contracts/interfaces/IPlug.sol b/contracts/interfaces/IPlug.sol index 1e738f09..552ae8f0 100644 --- a/contracts/interfaces/IPlug.sol +++ b/contracts/interfaces/IPlug.sol @@ -7,4 +7,6 @@ pragma solidity ^0.8.21; */ interface IPlug { function initSocket(address appGateway_, address socket_, address switchboard_) external; + + function overrides() external view returns (bytes memory); } diff --git a/contracts/interfaces/ISocket.sol b/contracts/interfaces/ISocket.sol index 1d7e1a1e..42713610 100644 --- a/contracts/interfaces/ISocket.sol +++ b/contracts/interfaces/ISocket.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.21; import {ExecuteParams} from "../protocol/utils/common/Structs.sol"; + /** * @title ISocket * @notice An interface for a Chain Abstraction contract @@ -33,32 +34,20 @@ interface ISocket { /** * @notice emits the message details when a new message arrives at outbound - * @param callId call id + * @param triggerId call id * @param chainSlug local chain slug * @param plug local plug address - * @param appGateway appGateway address to trigger the call - * @param params params, for specifying details like fee pool chain, fee pool token and max fees if required + * @param overrides params, for specifying details like fee pool chain, fee pool token and max fees if required * @param payload the data which will be used by contracts on chain */ event AppGatewayCallRequested( - bytes32 callId, + bytes32 triggerId, uint32 chainSlug, address plug, - address appGateway, - bytes32 params, + bytes overrides, bytes payload ); - /** - * @notice To call the appGateway on EVMx. Should only be called by a plug. - * @param payload_ bytes to be delivered to the Plug on EVMx - * @param params_ a 32 bytes param to add details for execution. - */ - function callAppGateway( - bytes calldata payload_, - bytes32 params_ - ) external returns (bytes32 callId); - /** * @notice executes a payload */ diff --git a/contracts/interfaces/IWatcherPrecompile.sol b/contracts/interfaces/IWatcherPrecompile.sol index 5ce28d64..54a1b25f 100644 --- a/contracts/interfaces/IWatcherPrecompile.sol +++ b/contracts/interfaces/IWatcherPrecompile.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Unlicense pragma solidity ^0.8.21; -import {DigestParams, ResolvedPromises, PayloadParams, CallFromChainParams, PayloadSubmitParams, RequestParams} from "../protocol/utils/common/Structs.sol"; +import {DigestParams, ResolvedPromises, PayloadParams, TriggerParams, PayloadSubmitParams, RequestParams} from "../protocol/utils/common/Structs.sol"; import {IWatcherPrecompileLimits} from "./IWatcherPrecompileLimits.sol"; import {IWatcherPrecompileConfig} from "./IWatcherPrecompileConfig.sol"; @@ -9,14 +9,9 @@ import {IWatcherPrecompileConfig} from "./IWatcherPrecompileConfig.sol"; /// @notice Interface for the Watcher Precompile system that handles payload verification and execution /// @dev Defines core functionality for payload processing and promise resolution interface IWatcherPrecompile { - event CalledAppGateway( - bytes32 callId, - uint32 chainSlug, - address plug, - address appGateway, - bytes32 params, - bytes payload - ); + event CalledAppGateway(bytes32 triggerId); + + event AppGatewayCallFailed(bytes32 triggerId); /// @notice Emitted when a new query is requested event QueryRequested(PayloadParams params); @@ -146,7 +141,7 @@ interface IWatcherPrecompile { function setMaxTimeoutDelayInSeconds(uint256 maxTimeoutDelayInSeconds_) external; function callAppGateways( - CallFromChainParams[] calldata params_, + TriggerParams[] calldata params_, uint256 signatureNonce_, bytes calldata signature_ ) external; diff --git a/contracts/interfaces/IWatcherPrecompileConfig.sol b/contracts/interfaces/IWatcherPrecompileConfig.sol index d42c7294..85831eca 100644 --- a/contracts/interfaces/IWatcherPrecompileConfig.sol +++ b/contracts/interfaces/IWatcherPrecompileConfig.sol @@ -36,6 +36,7 @@ interface IWatcherPrecompileConfig { function setSwitchboard(uint32 chainSlug_, bytes32 sbType_, address switchboard_) external; /// @notice Sets valid plugs for each chain slug + /// @dev This function is used to verify if a plug deployed on a chain slug is valid connection to the app gateway function setIsValidPlug(uint32 chainSlug_, address plug_, bool isValid_) external; /// @notice Retrieves the configuration for a specific plug on a network diff --git a/contracts/protocol/socket/Socket.sol b/contracts/protocol/socket/Socket.sol index 84b588af..4f19540e 100644 --- a/contracts/protocol/socket/Socket.sol +++ b/contracts/protocol/socket/Socket.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.21; import "./SocketUtils.sol"; + +import {IPlug} from "../../interfaces/IPlug.sol"; import {PlugDisconnected, InvalidAppGateway} from "../utils/common/Errors.sol"; /** @@ -38,35 +40,6 @@ contract Socket is SocketUtils { string memory version_ ) SocketUtils(chainSlug_, owner_, version_) {} - //////////////////////////////////////////////////////// - ////////////////////// OPERATIONS ////////////////////////// - //////////////////////////////////////////////////////// - /** - * @notice To send message to a connected remote chain. Should only be called by a plug. - * @param payload bytes to be delivered to the Plug on the siblingChainSlug_ - * @param params a 32 bytes param to add details for execution, for eg: fees to be paid for execution - */ - function callAppGateway( - bytes calldata payload, - bytes32 params - ) external returns (bytes32 callId) { - PlugConfig memory plugConfig = _plugConfigs[msg.sender]; - - // if no sibling plug is found for the given chain slug, revert - if (plugConfig.appGateway == address(0)) revert PlugDisconnected(); - - // creates a unique ID for the message - callId = _encodeCallId(plugConfig.appGateway); - emit AppGatewayCallRequested( - callId, - chainSlug, - msg.sender, - plugConfig.appGateway, - params, - payload - ); - } - /** * @notice Executes a payload that has been delivered by transmitters and authenticated by switchboards */ @@ -137,4 +110,34 @@ contract Socket is SocketUtils { revert PayloadAlreadyExecuted(payloadExecuted[payloadId_]); payloadExecuted[payloadId_] = ExecutionStatus.Executed; } + + //////////////////////////////////////////////////////// + ////////////////////// OPERATIONS ////////////////////////// + //////////////////////////////////////////////////////// + /** + * @notice To send message to a connected remote chain. Should only be called by a plug. + * @param payload_ bytes to be delivered on EVMx + * @param overrides_ a bytes param to add details for execution, for eg: fees to be paid for execution + */ + function _callAppGateway( + address plug_, + bytes memory overrides_, + bytes memory payload_ + ) internal returns (bytes32 triggerId) { + PlugConfig memory plugConfig = _plugConfigs[plug_]; + + // if no sibling plug is found for the given chain slug, revert + if (plugConfig.appGateway == address(0)) revert PlugDisconnected(); + + // creates a unique ID for the message + triggerId = _encodeTriggerId(plugConfig.appGateway); + emit AppGatewayCallRequested(triggerId, chainSlug, plug_, overrides_, payload_); + } + + /// @notice Fallback function that forwards all calls to Socket's callAppGateway + /// @dev The calldata is passed as-is to the gateways + fallback(bytes calldata) external returns (bytes memory) { + bytes memory overrides = IPlug(msg.sender).overrides(); + return abi.encode(_callAppGateway(msg.sender, overrides, msg.data)); + } } diff --git a/contracts/protocol/socket/SocketUtils.sol b/contracts/protocol/socket/SocketUtils.sol index 97aa46ba..32f5cfe1 100644 --- a/contracts/protocol/socket/SocketUtils.sol +++ b/contracts/protocol/socket/SocketUtils.sol @@ -20,7 +20,7 @@ abstract contract SocketUtils is SocketConfig { // ChainSlug for this deployed socket instance uint32 public immutable chainSlug; - uint64 public callCounter; + uint64 public triggerCounter; /** * @dev keeps track of whether a payload has been executed or not using payload id @@ -113,12 +113,14 @@ abstract contract SocketUtils is SocketConfig { } // Packs the local plug, local chain slug, remote chain slug and nonce - // callCount++ will take care of call id overflow as well - // callId(256) = localChainSlug(32) | appGateway_(160) | nonce(64) - function _encodeCallId(address appGateway_) internal returns (bytes32) { + // triggerCounter++ will take care of call id overflow as well + // triggerId(256) = localChainSlug(32) | appGateway_(160) | nonce(64) + function _encodeTriggerId(address appGateway_) internal returns (bytes32) { return bytes32( - (uint256(chainSlug) << 224) | (uint256(uint160(appGateway_)) << 64) | callCounter++ + (uint256(chainSlug) << 224) | + (uint256(uint160(appGateway_)) << 64) | + triggerCounter++ ); } diff --git a/contracts/protocol/utils/common/Errors.sol b/contracts/protocol/utils/common/Errors.sol index bdebefd1..da0a0764 100644 --- a/contracts/protocol/utils/common/Errors.sol +++ b/contracts/protocol/utils/common/Errors.sol @@ -22,7 +22,7 @@ error CallFailed(); error PlugDisconnected(); error InvalidAppGateway(); error AppGatewayAlreadyCalled(); -error InvalidInboxCaller(); +error InvalidCallerTriggered(); error PromisesNotResolved(); error InvalidPromise(); error InvalidIndex(); diff --git a/contracts/protocol/utils/common/Structs.sol b/contracts/protocol/utils/common/Structs.sol index 2b7c1f55..91091792 100644 --- a/contracts/protocol/utils/common/Structs.sol +++ b/contracts/protocol/utils/common/Structs.sol @@ -75,9 +75,9 @@ struct PlugConfig { address appGateway; address switchboard; } -//inbox: -struct CallFromChainParams { - bytes32 callId; +//trigger: +struct TriggerParams { + bytes32 triggerId; bytes32 params; address plug; address appGateway; diff --git a/contracts/protocol/watcherPrecompile/WatcherPrecompile.sol b/contracts/protocol/watcherPrecompile/WatcherPrecompile.sol index c8bc8a76..f7dc8789 100644 --- a/contracts/protocol/watcherPrecompile/WatcherPrecompile.sol +++ b/contracts/protocol/watcherPrecompile/WatcherPrecompile.sol @@ -234,10 +234,10 @@ contract WatcherPrecompile is RequestHandler { maxTimeoutDelayInSeconds = maxTimeoutDelayInSeconds_; } - // ================== On-Chain Inbox ================== + // ================== On-Chain Trigger ================== function callAppGateways( - CallFromChainParams[] calldata params_, + TriggerParams[] calldata params_, uint256 signatureNonce_, bytes calldata signature_ ) external { @@ -248,32 +248,29 @@ contract WatcherPrecompile is RequestHandler { ); for (uint256 i = 0; i < params_.length; i++) { - if (appGatewayCalled[params_[i].callId]) revert AppGatewayAlreadyCalled(); + if (appGatewayCalled[params_[i].triggerId]) revert AppGatewayAlreadyCalled(); + + address appGateway = _decodeAppGateway(params_[i].triggerId); if ( !watcherPrecompileConfig__.isValidPlug( - params_[i].appGateway, + appGateway, params_[i].chainSlug, params_[i].plug ) - ) revert InvalidInboxCaller(); - - appGatewayCalled[params_[i].callId] = true; - IAppGateway(params_[i].appGateway).callFromChain( - params_[i].chainSlug, - params_[i].plug, - params_[i].params, - params_[i].payload - ); + ) revert InvalidCallerTriggered(); - emit CalledAppGateway( - params_[i].callId, - params_[i].chainSlug, - params_[i].plug, - params_[i].appGateway, - params_[i].params, - params_[i].payload - ); + appGatewayCaller = appGateway; + appGatewayCalled[params_[i].triggerId] = true; + + (bool success, ) = address(appGateway).call(params_[i].payload); + if (!success) { + emit AppGatewayCallFailed(params_[i].triggerId); + } else { + emit CalledAppGateway(params_[i].triggerId); + } } + + appGatewayCaller = address(0); } // ================== Helper functions ================== @@ -285,4 +282,8 @@ contract WatcherPrecompile is RequestHandler { function getRequestParams(uint40 requestCount) external view returns (RequestParams memory) { return requestParams[requestCount]; } + + function _decodeAppGateway(bytes32 triggerId_) internal pure returns (address) { + return address(uint160(uint256(triggerId_) >> 64)); + } } diff --git a/contracts/protocol/watcherPrecompile/WatcherPrecompileStorage.sol b/contracts/protocol/watcherPrecompile/WatcherPrecompileStorage.sol index 974a0b03..1dff2b6f 100644 --- a/contracts/protocol/watcherPrecompile/WatcherPrecompileStorage.sol +++ b/contracts/protocol/watcherPrecompile/WatcherPrecompileStorage.sol @@ -9,74 +9,74 @@ import "./DumpDecoder.sol"; import {IMiddleware} from "../../interfaces/IMiddleware.sol"; import {QUERY, FINALIZE, SCHEDULE} from "../utils/common/Constants.sol"; -import {TimeoutDelayTooLarge, TimeoutAlreadyResolved, InvalidInboxCaller, ResolvingTimeoutTooEarly, CallFailed, AppGatewayAlreadyCalled, InvalidWatcherSignature, NonceUsed} from "../utils/common/Errors.sol"; -import {ResolvedPromises, AppGatewayConfig, LimitParams, WriteFinality, UpdateLimitParams, PlugConfig, DigestParams, TimeoutRequest, CallFromChainParams, QueuePayloadParams, PayloadParams, RequestParams} from "../utils/common/Structs.sol"; +import {TimeoutDelayTooLarge, TimeoutAlreadyResolved, InvalidCallerTriggered, ResolvingTimeoutTooEarly, CallFailed, AppGatewayAlreadyCalled, InvalidWatcherSignature, NonceUsed} from "../utils/common/Errors.sol"; +import {ResolvedPromises, AppGatewayConfig, LimitParams, WriteFinality, UpdateLimitParams, PlugConfig, DigestParams, TimeoutRequest, TriggerParams, QueuePayloadParams, PayloadParams, RequestParams} from "../utils/common/Structs.sol"; abstract contract WatcherPrecompileStorage is IWatcherPrecompile { // slots [0-49]: gap for future storage variables uint256[50] _gap_before; - // slot 50: evmxSlug + // slot 50 /// @notice The chain slug of the watcher precompile uint32 public evmxSlug; - // slot 51: isNonceUsed - /// @notice Maps nonce to whether it has been used - /// @dev signatureNonce => isValid - mapping(uint256 => bool) public isNonceUsed; - - // slot 52: maxTimeoutDelayInSeconds - uint256 public maxTimeoutDelayInSeconds; - - // slot 53: payloadCounter /// @notice Counter for tracking payload requests uint40 public payloadCounter; - // slot 54: timeoutCounter /// @notice Counter for tracking timeout requests uint40 public timeoutCounter; - // slot 55: expiryTime + uint40 public nextRequestCount; + + uint40 public nextBatchCount; + + // slot 51: maxTimeoutDelayInSeconds + uint256 public maxTimeoutDelayInSeconds; + + // slot 52: expiryTime /// @notice The expiry time for the payload uint256 public expiryTime; - // slot 56: timeoutRequests + // slot 53: appGatewayCaller + /// @notice The address of the app gateway caller from a chain + address public appGatewayCaller; + + // slot 54: isNonceUsed + /// @notice Maps nonce to whether it has been used + /// @dev signatureNonce => isValid + mapping(uint256 => bool) public isNonceUsed; + + // slot 55: timeoutRequests /// @notice Mapping to store timeout requests /// @dev timeoutId => TimeoutRequest struct mapping(bytes32 => TimeoutRequest) public timeoutRequests; - // slot 57: watcherProofs + // slot 56: watcherProofs /// @notice Mapping to store watcher proofs /// @dev payloadId => proof bytes mapping(bytes32 => bytes) public watcherProofs; - // slot 58: appGatewayCalled - /// @notice Mapping to store if appGateway has been called with trigger from on-chain Inbox - /// @dev callId => bool + // slot 57: appGatewayCalled + /// @notice Mapping to store if appGateway has been called with trigger from on-chain plug + /// @dev triggerId => bool mapping(bytes32 => bool) public appGatewayCalled; - // slot 59: nextRequestCount - uint40 public nextRequestCount; - - // slot 60: nextBatchCount - uint40 public nextBatchCount; - - // slot 61: requestParams + // slot 58: requestParams mapping(uint40 => RequestParams) public requestParams; - // slot 62: batchPayloadIds + // slot 59: batchPayloadIds mapping(uint40 => bytes32[]) public batchPayloadIds; - // slot 63: requestBatchIds + // slot 60: requestBatchIds mapping(uint40 => uint40[]) public requestBatchIds; - // slot 64: payloads + // slot 61: payloads mapping(bytes32 => PayloadParams) public payloads; - // slot 65: isPromiseExecuted + // slot 62: isPromiseExecuted mapping(bytes32 => bool) public isPromiseExecuted; - // slot 66: watcherPrecompileLimits__ + // slot 63: watcherPrecompileLimits__ IWatcherPrecompileLimits public watcherPrecompileLimits__; - // slot 67: watcherPrecompileConfig__ + // slot 64: watcherPrecompileConfig__ IWatcherPrecompileConfig public watcherPrecompileConfig__; - // slots [68-117]: gap for future storage variables + // slots [65-114]: gap for future storage variables uint256[50] _gap_after; } diff --git a/test/Inbox.t.sol b/test/Inbox.t.sol index f45277fd..6da8f8dc 100644 --- a/test/Inbox.t.sol +++ b/test/Inbox.t.sol @@ -5,24 +5,32 @@ import {CounterAppGateway} from "./apps/app-gateways/counter/CounterAppGateway.s import {Counter} from "./apps/app-gateways/counter/Counter.sol"; import "./DeliveryHelper.t.sol"; -contract InboxTest is DeliveryHelperTest { +contract TriggerTest is DeliveryHelperTest { uint256 constant feesAmount = 0.01 ether; CounterAppGateway public gateway; - Counter public inbox; + Counter public counter; + + event AppGatewayCallRequested( + bytes32 triggerId, + uint32 chainSlug, + address plug, + bytes overrides, + bytes payload + ); function setUp() public { // Setup core test infrastructure setUpDeliveryHelper(); - // Deploy the inbox contract - inbox = new Counter(); + // Deploy the counter contract + counter = new Counter(); // Deploy the gateway with fees gateway = new CounterAppGateway(address(addressResolver), createFees(feesAmount)); - gateway.setIsValidPlug(arbChainSlug, address(inbox)); + gateway.setIsValidPlug(arbChainSlug, address(counter)); - // Connect the inbox to the gateway and socket - inbox.initSocket( + // Connect the counter to the gateway and socket + counter.initSocket( address(gateway), address(arbConfig.socket), address(arbConfig.switchboard) @@ -31,7 +39,7 @@ contract InboxTest is DeliveryHelperTest { // Setup gateway config for the watcher AppGatewayConfig[] memory gateways = new AppGatewayConfig[](1); gateways[0] = AppGatewayConfig({ - plug: address(inbox), + plug: address(counter), chainSlug: arbChainSlug, appGateway: address(gateway), switchboard: address(arbConfig.switchboard) @@ -45,24 +53,32 @@ contract InboxTest is DeliveryHelperTest { watcherPrecompileConfig.setAppGateways(gateways, signatureNonce++, watcherSignature); hoax(watcherEOA); - watcherPrecompileConfig.setIsValidPlug(arbChainSlug, address(inbox), true); + watcherPrecompileConfig.setIsValidPlug(arbChainSlug, address(counter), true); } - function testInboxIncrement() public { + function testIncrementAfterTrigger() public { // Initial counter value should be 0 assertEq(gateway.counterVal(), 0, "Initial gateway counter should be 0"); // Simulate a message from another chain through the watcher uint256 incrementValue = 5; + bytes32 triggerId = _encodeTriggerId(address(gateway), arbChainSlug); + bytes memory payload = abi.encodeWithSelector( + CounterAppGateway.increase.selector, + incrementValue + ); + + vm.expectEmit(true, true, true, true); + emit AppGatewayCallRequested(triggerId, arbChainSlug, address(counter), bytes(""), payload); + counter.increaseOnGateway(incrementValue); - bytes32 callId = inbox.increaseOnGateway(incrementValue); - CallFromChainParams[] memory params = new CallFromChainParams[](1); - params[0] = CallFromChainParams({ - callId: callId, + TriggerParams[] memory params = new TriggerParams[](1); + params[0] = TriggerParams({ + triggerId: triggerId, chainSlug: arbChainSlug, appGateway: address(gateway), - plug: address(inbox), - payload: abi.encode(incrementValue), + plug: address(counter), + payload: payload, params: bytes32(0) }); @@ -74,4 +90,13 @@ contract InboxTest is DeliveryHelperTest { // Check counter was incremented assertEq(gateway.counterVal(), incrementValue, "Gateway counter should be incremented"); } + + function _encodeTriggerId(address appGateway_, uint256 chainSlug_) internal returns (bytes32) { + return + bytes32( + (uint256(chainSlug_) << 224) | + (uint256(uint160(appGateway_)) << 64) | + triggerCounter++ + ); + } } diff --git a/test/SetupTest.t.sol b/test/SetupTest.t.sol index 8a6ee9a2..32112c65 100644 --- a/test/SetupTest.t.sol +++ b/test/SetupTest.t.sol @@ -44,6 +44,7 @@ contract SetupTest is Test { uint256 public signatureNonce; uint256 public payloadIdCounter; uint256 public timeoutIdCounter; + uint256 public triggerCounter; uint256 public defaultLimit = 1000; bytes public asyncPromiseBytecode = type(AsyncPromise).creationCode; diff --git a/test/apps/app-gateways/counter/Counter.sol b/test/apps/app-gateways/counter/Counter.sol index 9625635d..b3bec2cb 100644 --- a/test/apps/app-gateways/counter/Counter.sol +++ b/test/apps/app-gateways/counter/Counter.sol @@ -4,9 +4,14 @@ pragma solidity >=0.7.0 <0.9.0; import "solady/auth/Ownable.sol"; import "../../../../contracts/base/PlugBase.sol"; +interface ICounterAppGateway { + function increase(uint256 value_) external returns (bytes32); +} + contract Counter is Ownable, PlugBase { uint256 public counter; event CounterIncreased(uint256 value); + function increase() external onlySocket { counter++; emit CounterIncreased(counter); @@ -17,6 +22,7 @@ contract Counter is Ownable, PlugBase { } function increaseOnGateway(uint256 value_) external returns (bytes32) { - return _callAppGateway(abi.encode(value_), bytes32(0)); + // can set overrides here: _setOverrides(params_); + return ICounterAppGateway(address(socket__)).increase(value_); } } diff --git a/test/apps/app-gateways/counter/CounterAppGateway.sol b/test/apps/app-gateways/counter/CounterAppGateway.sol index deef0e53..1911e0f2 100644 --- a/test/apps/app-gateways/counter/CounterAppGateway.sol +++ b/test/apps/app-gateways/counter/CounterAppGateway.sol @@ -97,19 +97,13 @@ contract CounterAppGateway is AppGatewayBase, Ownable { } } - // INBOX + // trigger from a chain function setIsValidPlug(uint32 chainSlug_, address plug_) public { watcherPrecompileConfig().setIsValidPlug(chainSlug_, plug_, true); } - function callFromChain( - uint32, - address, - bytes32, - bytes calldata payload_ - ) external override onlyWatcherPrecompile { - uint256 value = abi.decode(payload_, (uint256)); - counterVal += value; + function increase(uint256 value_) external onlyWatcherPrecompile { + counterVal += value_; } // TIMEOUT diff --git a/test/mock/MockSocket.sol b/test/mock/MockSocket.sol index da1765a9..1776c491 100644 --- a/test/mock/MockSocket.sol +++ b/test/mock/MockSocket.sol @@ -65,7 +65,7 @@ contract MockSocket is ISocket { //////////////////////////////////////////////////////////// ////////////////////// State Vars ////////////////////////// //////////////////////////////////////////////////////////// - uint64 public callCounter; + uint64 public triggerCounter; uint32 public chainSlug; enum ExecutionStatus { @@ -89,24 +89,15 @@ contract MockSocket is ISocket { /** * @notice To send message to a connected remote chain. Should only be called by a plug. - * @param payload bytes to be delivered to the Plug on the siblingChainSlug_ - * @param params a 32 bytes param to add details for execution, for eg: fees to be paid for execution */ function callAppGateway( bytes calldata payload, - bytes32 params - ) external returns (bytes32 callId) { + bytes calldata overrides + ) external returns (bytes32 triggerId) { PlugConfig memory plugConfig = _plugConfigs[msg.sender]; // creates a unique ID for the message - callId = _encodeCallId(plugConfig.appGateway); - emit AppGatewayCallRequested( - callId, - chainSlug, - msg.sender, - plugConfig.appGateway, - params, - payload - ); + triggerId = _encodeTriggerId(plugConfig.appGateway); + emit AppGatewayCallRequested(triggerId, chainSlug, msg.sender, overrides, payload); } /** @@ -174,12 +165,14 @@ contract MockSocket is ISocket { } // Packs the local plug, local chain slug, remote chain slug and nonce - // callCount++ will take care of call id overflow as well - // callId(256) = localChainSlug(32) | appGateway_(160) | nonce(64) - function _encodeCallId(address appGateway_) internal returns (bytes32) { + // triggerCounter++ will take care of call id overflow as well + // triggerId(256) = localChainSlug(32) | appGateway_(160) | nonce(64) + function _encodeTriggerId(address appGateway_) internal returns (bytes32) { return bytes32( - (uint256(chainSlug) << 224) | (uint256(uint160(appGateway_)) << 64) | callCounter++ + (uint256(chainSlug) << 224) | + (uint256(uint160(appGateway_)) << 64) | + triggerCounter++ ); } } diff --git a/test/mock/MockWatcherPrecompile.sol b/test/mock/MockWatcherPrecompile.sol index 42247124..7d886e6c 100644 --- a/test/mock/MockWatcherPrecompile.sol +++ b/test/mock/MockWatcherPrecompile.sol @@ -5,9 +5,9 @@ import "../../contracts/interfaces/IAppGateway.sol"; import "../../contracts/interfaces/IWatcherPrecompile.sol"; import "../../contracts/interfaces/IPromise.sol"; -import {TimeoutRequest, CallFromChainParams, PlugConfig, ResolvedPromises, AppGatewayConfig} from "../../contracts/protocol/utils/common/Structs.sol"; +import {TimeoutRequest, TriggerParams, PlugConfig, ResolvedPromises, AppGatewayConfig} from "../../contracts/protocol/utils/common/Structs.sol"; import {QUERY, FINALIZE, SCHEDULE} from "../../contracts/protocol/utils/common/Constants.sol"; -import {TimeoutDelayTooLarge, TimeoutAlreadyResolved, InvalidInboxCaller, ResolvingTimeoutTooEarly, CallFailed, AppGatewayAlreadyCalled} from "../../contracts/protocol/utils/common/Errors.sol"; +import {TimeoutDelayTooLarge, TimeoutAlreadyResolved, ResolvingTimeoutTooEarly, CallFailed, AppGatewayAlreadyCalled} from "../../contracts/protocol/utils/common/Errors.sol"; import "solady/utils/ERC1967Factory.sol"; /// @title WatcherPrecompile @@ -28,14 +28,7 @@ contract MockWatcherPrecompile { error InvalidChainSlug(); error InvalidTransmitter(); - event CalledAppGateway( - bytes32 callId, - uint32 chainSlug, - address plug, - address appGateway, - bytes32 params, - bytes payload - ); + event CalledAppGateway(bytes32 triggerId); /// @notice Emitted when a new query is requested /// @param chainSlug The identifier of the destination chain @@ -154,18 +147,11 @@ contract MockWatcherPrecompile { } } - // ================== On-Chain Inbox ================== + // ================== On-Chain Trigger ================== - function callAppGateways(CallFromChainParams[] calldata params_) external { + function callAppGateways(TriggerParams[] calldata params_) external { for (uint256 i = 0; i < params_.length; i++) { - emit CalledAppGateway( - params_[i].callId, - params_[i].chainSlug, - params_[i].plug, - params_[i].appGateway, - params_[i].params, - params_[i].payload - ); + emit CalledAppGateway(params_[i].triggerId); } }