Skip to content

Commit

Permalink
feat(protocol): add a view function isSignalReceived for Bridge relay…
Browse files Browse the repository at this point in the history
…er/UI (#16591)
  • Loading branch information
dantaik authored Apr 2, 2024
1 parent da5a039 commit 39d4be6
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
17 changes: 17 additions & 0 deletions packages/protocol/contracts/signal/ISignalService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
56 changes: 55 additions & 1 deletion packages/protocol/contracts/signal/SignalService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ contract SignalService is EssentialContract, ISignalService {
bytes32 _signal,
bytes calldata _proof
)
public
external
virtual
validSender(_app)
nonZeroValue(_signal)
Expand Down Expand Up @@ -132,6 +132,59 @@ 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];

_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;

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,
Expand Down Expand Up @@ -211,6 +264,7 @@ contract SignalService is EssentialContract, ISignalService {
address _signalService
)
internal
view
virtual
validSender(_app)
nonZeroValue(_signal)
Expand Down

1 comment on commit 39d4be6

@pete799
Copy link

@pete799 pete799 commented on 39d4be6 Apr 2, 2024

Choose a reason for hiding this comment

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

good

Please sign in to comment.