From 18848e42d48786de8da583fec417d9308a181562 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 2 Apr 2024 09:55:28 +0800 Subject: [PATCH 1/2] add a view function isSignalReceived --- .../contracts/signal/ISignalService.sol | 17 ++++++ .../contracts/signal/SignalService.sol | 58 ++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/signal/ISignalService.sol b/packages/protocol/contracts/signal/ISignalService.sol index 83a813ac925..2677fb468c3 100644 --- a/packages/protocol/contracts/signal/ISignalService.sol +++ b/packages/protocol/contracts/signal/ISignalService.sol @@ -106,6 +106,23 @@ interface ISignalService { ) external; + /// @notice Verifies if a signal has been received on the target chain. + /// This is the "readonly" version of proveSignalReceived. + /// @param _chainId The identifier for the source chain from which the + /// signal originated. + /// @param _app The address that initiated the signal. + /// @param _signal The signal (message) to send. + /// @param _proof Merkle proof that the signal was persisted on the + /// source chain. + function isSignalReceived( + uint64 _chainId, + address _app, + bytes32 _signal, + bytes calldata _proof + ) + external + view; + /// @notice Verifies if a particular signal has already been sent. /// @param _app The address that initiated the signal. /// @param _signal The signal (message) that was sent. diff --git a/packages/protocol/contracts/signal/SignalService.sol b/packages/protocol/contracts/signal/SignalService.sol index 4bb26d7c8dd..cf53889e34f 100644 --- a/packages/protocol/contracts/signal/SignalService.sol +++ b/packages/protocol/contracts/signal/SignalService.sol @@ -85,7 +85,7 @@ contract SignalService is EssentialContract, ISignalService { bytes32 _signal, bytes calldata _proof ) - public + external virtual validSender(_app) nonZeroValue(_signal) @@ -132,6 +132,61 @@ contract SignalService is EssentialContract, ISignalService { } } + /// @inheritdoc ISignalService + /// @dev This function may revert. + function isSignalReceived( + uint64 _chainId, + address _app, + bytes32 _signal, + bytes calldata _proof + ) + public + view + validSender(_app) + nonZeroValue(_signal) + { + HopProof[] memory hopProofs = abi.decode(_proof, (HopProof[])); + if (hopProofs.length == 0) revert SS_EMPTY_PROOF(); + + uint64 chainId = _chainId; + address app = _app; + bytes32 signal = _signal; + bytes32 value = _signal; + address signalService = resolve(chainId, "signal_service", false); + + HopProof memory hop; + for (uint256 i; i < hopProofs.length; ++i) { + hop = hopProofs[i]; + + bytes32 signalRoot = _verifyHopProof(chainId, app, signal, value, hop, signalService); + bool isLastHop = i == hopProofs.length - 1; + + if (isLastHop) { + if (hop.chainId != block.chainid) revert SS_INVALID_LAST_HOP_CHAINID(); + signalService = address(this); + } else { + if (hop.chainId == 0 || hop.chainId == block.chainid) { + revert SS_INVALID_MID_HOP_CHAINID(); + } + signalService = resolve(hop.chainId, "signal_service", false); + } + + bool isFullProof = hop.accountProof.length != 0; + + // _cacheChainData(hop, chainId, hop.blockId, signalRoot, isFullProof, isLastHop); + + bytes32 kind = isFullProof ? LibSignals.STATE_ROOT : LibSignals.SIGNAL_ROOT; + signal = signalForChainData(chainId, kind, hop.blockId); + value = hop.rootHash; + chainId = hop.chainId; + app = signalService; + } + + if (value == 0 || value != _loadSignalValue(address(this), signal)) { + revert SS_SIGNAL_NOT_FOUND(); + } + } + /// @inheritdoc ISignalService function isChainDataSynced( uint64 _chainId, @@ -211,6 +266,7 @@ contract SignalService is EssentialContract, ISignalService { address _signalService ) internal + view virtual validSender(_app) nonZeroValue(_signal) From 5a31d9e25dbb0c3a8a7c6c06e92fdfda8e894b17 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 2 Apr 2024 09:58:48 +0800 Subject: [PATCH 2/2] Update SignalService.sol --- packages/protocol/contracts/signal/SignalService.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/protocol/contracts/signal/SignalService.sol b/packages/protocol/contracts/signal/SignalService.sol index cf53889e34f..cc7980a9f08 100644 --- a/packages/protocol/contracts/signal/SignalService.sol +++ b/packages/protocol/contracts/signal/SignalService.sol @@ -158,7 +158,7 @@ contract SignalService is EssentialContract, ISignalService { for (uint256 i; i < hopProofs.length; ++i) { hop = hopProofs[i]; - bytes32 signalRoot = _verifyHopProof(chainId, app, signal, value, hop, signalService); + _verifyHopProof(chainId, app, signal, value, hop, signalService); bool isLastHop = i == hopProofs.length - 1; if (isLastHop) { @@ -173,8 +173,6 @@ contract SignalService is EssentialContract, ISignalService { bool isFullProof = hop.accountProof.length != 0; - // _cacheChainData(hop, chainId, hop.blockId, signalRoot, isFullProof, isLastHop); - bytes32 kind = isFullProof ? LibSignals.STATE_ROOT : LibSignals.SIGNAL_ROOT; signal = signalForChainData(chainId, kind, hop.blockId); value = hop.rootHash;