Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modifying IGP to be a hook #2638

Merged
merged 13 commits into from
Aug 15, 2023
13 changes: 0 additions & 13 deletions rust/Cargo.lock
aroralanuk marked this conversation as resolved.
Show resolved Hide resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 17 additions & 9 deletions solidity/contracts/Mailbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ contract Mailbox is IMailbox, Versioned, Ownable {

// A monotonically increasing nonce for outbound unique message IDs.
uint32 public nonce;
bytes32 public latestDispatchedId;

// The default ISM, used if the recipient fails to specify one.
IInterchainSecurityModule public defaultIsm;

// The default post dispatch hook, used for post processing of dispatched messages.
IPostDispatchHook public defaultHook;

// Mapping of message ID to sender of the call that processed the message.
// Mapping of message ID to delivery context that processed the message.
struct Delivery {
address sender;
// uint48 value?
Expand Down Expand Up @@ -101,7 +102,8 @@ contract Mailbox is IMailbox, Versioned, Ownable {
_destinationDomain,
_recipientAddress,
_messageBody,
bytes("")
defaultHook,
_messageBody[0:0]
);
}

Expand Down Expand Up @@ -135,7 +137,7 @@ contract Mailbox is IMailbox, Versioned, Ownable {
bytes calldata messageBody,
IPostDispatchHook hook,
bytes calldata metadata
) public returns (bytes32) {
) public payable returns (bytes32) {
// Format the message into packed bytes.
bytes memory message = Message.formatMessage(
VERSION,
Expand All @@ -150,6 +152,7 @@ contract Mailbox is IMailbox, Versioned, Ownable {
// effects
nonce += 1;
bytes32 id = message.id();
latestDispatchedId = id;
emit DispatchId(id);
emit Dispatch(message);

Expand Down Expand Up @@ -186,18 +189,23 @@ contract Mailbox is IMailbox, Versioned, Ownable {

address recipient = _message.recipientAddress();

// effects
deliveries[_id] = Delivery({
sender: msg.sender
// value: uint48(msg.value),
// timestamp: uint48(block.number)
});
emit Process(_message);
emit ProcessId(_id);

// interactions
// Verify the message via the ISM.
IInterchainSecurityModule _ism = IInterchainSecurityModule(
recipientIsm(recipient)
);
require(_ism.verify(_metadata, _message), "verification failed");

// effects
deliveries[_id] = Delivery({sender: msg.sender});
emit Process(_message);
emit ProcessId(_id);

// Deliver the message to the recipient. (interactions)
// Deliver the message to the recipient.
IMessageRecipient(recipient).handle{value: msg.value}(
_message.origin(),
_message.sender(),
Expand Down
14 changes: 12 additions & 2 deletions solidity/contracts/client/MailboxClient.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ pragma solidity >=0.6.11;

// ============ Internal Imports ============
import {IMailbox} from "../interfaces/IMailbox.sol";
import {Message} from "../libs/Message.sol";

// ============ External Imports ============
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

abstract contract MailboxClient {
using Message for bytes;

IMailbox immutable mailbox;

constructor(address _mailbox) {
require(Address.isContract(_mailbox), "!contract");
require(Address.isContract(_mailbox), "MailboxClient: invalid mailbox");
mailbox = IMailbox(_mailbox);
}

Expand All @@ -21,7 +24,14 @@ abstract contract MailboxClient {
* @notice Only accept messages from an Hyperlane Mailbox contract
*/
modifier onlyMailbox() {
require(msg.sender == address(mailbox), "!mailbox");
require(
msg.sender == address(mailbox),
"MailboxClient: sender not mailbox"
);
_;
}

function isLatestDispatched(bytes32 id) internal view returns (bool) {
return mailbox.latestDispatchedId() == id;
}
}
101 changes: 0 additions & 101 deletions solidity/contracts/hooks/AbstractBridgeHook.sol

This file was deleted.

24 changes: 0 additions & 24 deletions solidity/contracts/hooks/AbstractHook.sol

This file was deleted.

52 changes: 30 additions & 22 deletions solidity/contracts/hooks/AbstractMessageIdAuthHook.sol
aroralanuk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,23 @@ pragma solidity >=0.8.0;
@@@@@@@@@ @@@@@@@@*/

// ============ Internal Imports ============
import {AbstractHook} from "./AbstractHook.sol";
import {AbstractMessageIdAuthorizedIsm} from "../isms/hook/AbstractMessageIdAuthorizedIsm.sol";
import {TypeCasts} from "../libs/TypeCasts.sol";
import {Message} from "../libs/Message.sol";
import {OPStackHookMetadata} from "../libs/hooks/OPStackHookMetadata.sol";
import {MailboxClient} from "../client/MailboxClient.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";

// ============ External Imports ============
import {ICrossDomainMessenger} from "../interfaces/optimism/ICrossDomainMessenger.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

/**
* @title AbstractMessageIdAuthHook
* @notice Message hook to inform an Abstract Message ID ISM of messages published through
* the native OPStack bridge.
* a third-party bridge.
* @dev V3 WIP
*/
abstract contract AbstractMessageIdAuthHook is AbstractHook {
abstract contract AbstractMessageIdAuthHook is
IPostDispatchHook,
MailboxClient
{
using Message for bytes;

// ============ Constants ============
Expand All @@ -44,43 +43,52 @@ abstract contract AbstractMessageIdAuthHook is AbstractHook {
// ============ Constructor ============

constructor(
address _mailbox,
address mailbox,
uint32 _destinationDomain,
address _ism
) AbstractHook(_mailbox) {
) MailboxClient(mailbox) {
require(_ism != address(0), "invalid ISM");
require(_destinationDomain != 0, "invalid destination domain");
ism = _ism;
destinationDomain = _destinationDomain;
}

function _sendMessageId(bytes calldata metadata, bytes memory payload)
internal
virtual;
// ============ External functions ============

/**
* @notice Hook to inform the optimism ISM of messages published through.
* metadata The metadata for the hook caller
* @param message The message being dispatched
*/
function _postDispatch(bytes calldata metadata, bytes calldata message)
internal
function postDispatch(bytes calldata metadata, bytes calldata message)
external
payable
override
returns (IPostDispatchHook)
{
bytes32 id = message.id();
require(
isLatestDispatched(id),
"AbstractMessageIdAuthHook: message not latest dispatched"
);
require(
message.destination() == destinationDomain,
"invalid destination domain"
"AbstractMessageIdAuthHook: invalid destination domain"
);

bytes memory payload = abi.encodeCall(
AbstractMessageIdAuthorizedIsm.verifyMessageId,
message.id()
id
);
_sendMessageId(metadata, payload);

// no next post-dispatch hook
// TODO: consider configuring?
return IPostDispatchHook(address(0));
}

// ============ Internal functions ============

/**
* @notice Send a message to the ISM.
* @param metadata The metadata for the hook caller
* @param payload The payload for call to the ISM
*/
function _sendMessageId(bytes calldata metadata, bytes memory payload)
internal
virtual;
}
Loading
Loading