Skip to content

Commit

Permalink
expire for never delivered msg
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoch05 committed Dec 13, 2023
1 parent 108e3ab commit 1212491
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
2 changes: 1 addition & 1 deletion helix-contract/contracts/interfaces/IMessager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ interface ILowLevelMessageReceiver {
interface IMessageId {
function latestSentMessageId() external view returns(bytes32);
function latestRecvMessageId() external view returns(bytes32);
function messageDelivered(bytes32 messageId) external view returns(bool);
function messageDeliveredOrSlashed(bytes32 messageId) external view returns(bool);
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ contract xTokenBridgeBase is Initializable, Pausable, AccessController, DailyLim
function _assertMessageIsDelivered(uint256 _remoteChainId, bytes32 _transferId) view internal {
MessagerService memory service = messagers[_remoteChainId];
require(service.receiveService != address(0), "bridge not configured");
require(IMessageId(service.receiveService).messageDelivered(_transferId), "message not delivered");
require(IMessageId(service.receiveService).messageDeliveredOrSlashed(_transferId), "message not delivered");
}

// the latest received message id
Expand Down
23 changes: 21 additions & 2 deletions helix-contract/contracts/messagers/MsglineMessager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import "../utils/AccessController.sol";
import "../interfaces/IMessageLine.sol";

contract MsglineMessager is Application, AccessController {
// expire time = 1 hour
uint256 constant public SLASH_EXPIRE_TIME = 3600;

IMessageLine public immutable msgline;

struct RemoteMessager {
Expand All @@ -21,6 +24,9 @@ contract MsglineMessager is Application, AccessController {
mapping(bytes32=>address) public remoteAppReceivers;
mapping(bytes32=>address) public remoteAppSenders;

// transferId => timestamp
mapping(bytes32=>uint256) public slashTransferIds;

event CallerUnMatched(uint256 srcAppChainId, bytes32 transferId, address srcAppAddress);
event CallResult(uint256 srcAppChainId, bytes32 transferId, bool result);

Expand Down Expand Up @@ -84,6 +90,10 @@ contract MsglineMessager is Application, AccessController {
bytes32 key = keccak256(abi.encodePacked(srcChainId, _localAppAddress));
bytes32 transferId = latestRecvMessageId();

if (_messageSlashed(transferId)) {
return;
}

// check remote appSender
if (_remoteAppAddress != remoteAppSenders[key]) {
emit CallerUnMatched(_srcAppChainId, transferId, _remoteAppAddress);
Expand All @@ -94,6 +104,15 @@ contract MsglineMessager is Application, AccessController {
emit CallResult(_srcAppChainId, transferId, success);
}

function slashMessage(bytes32 transferId) external {
slashTransferIds[transferId] = block.timestamp;
}

function _messageSlashed(bytes32 transferId) internal view returns(bool) {
uint256 slashTimestamp = slashTransferIds[transferId];
return slashTimestamp > 0 && slashTimestamp + SLASH_EXPIRE_TIME < block.timestamp;
}

function latestSentMessageId() external view returns(bytes32) {
return msgline.sentMessageId();
}
Expand All @@ -102,8 +121,8 @@ contract MsglineMessager is Application, AccessController {
return msgline.recvMessageId();
}

function messageDelivered(bytes32 messageId) external view returns(bool) {
return msgline.dones(messageId);
function messageDeliveredOrSlashed(bytes32 transferId) external view returns(bool) {
return msgline.dones(transferId) || _messageSlashed(transferId);
}

function messagePayload(address _from, address _to, bytes memory _message) public view returns(bytes memory) {
Expand Down

0 comments on commit 1212491

Please sign in to comment.