add globalHookMetadata (#2743)
### Description - Consolidating IGPMetadata and OPStackMetadata to versioned GlobalHookMetadata - Add `supportMetadata` to `IPostDispatchHook` - Metadata Schema [0:1] variant [2:33] msg.value [34:65] Gas limit for message (IGP) [66:85] Refund address for message (IGP) [86:] Custom metadata ### Drive-by changes None ### Related issues - fixes https://github.com/hyperlane-xyz/issues/issues/610 ### Backward compatibility No ### Testing Unit tests --------- Co-authored-by: Yorke Rhodes <yorke@hyperlane.xyz>pull/2748/head
parent
10765b7614
commit
f783c4e96f
@ -0,0 +1,91 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.8.0; |
||||
|
||||
/*@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||
@@@@@ HYPERLANE @@@@@@@ |
||||
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@*/ |
||||
|
||||
// ============ Internal Imports ============ |
||||
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol"; |
||||
import {MailboxClient} from "../client/MailboxClient.sol"; |
||||
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol"; |
||||
|
||||
/** |
||||
* @title AbstractPostDispatch |
||||
* @notice Abstract post dispatch hook supporting the current global hook metadata variant. |
||||
*/ |
||||
abstract contract AbstractPostDispatchHook is IPostDispatchHook { |
||||
using GlobalHookMetadata for bytes; |
||||
|
||||
// ============ External functions ============ |
||||
|
||||
/// @inheritdoc IPostDispatchHook |
||||
function supportsMetadata(bytes calldata metadata) |
||||
public |
||||
pure |
||||
override |
||||
returns (bool) |
||||
{ |
||||
return |
||||
metadata.length == 0 || |
||||
metadata.variant() == GlobalHookMetadata.VARIANT; |
||||
} |
||||
|
||||
/// @inheritdoc IPostDispatchHook |
||||
function postDispatch(bytes calldata metadata, bytes calldata message) |
||||
external |
||||
payable |
||||
override |
||||
{ |
||||
require( |
||||
supportsMetadata(metadata), |
||||
"AbstractPostDispatchHook: invalid metadata variant" |
||||
); |
||||
_postDispatch(metadata, message); |
||||
} |
||||
|
||||
/// @inheritdoc IPostDispatchHook |
||||
function quoteDispatch(bytes calldata metadata, bytes calldata message) |
||||
public |
||||
view |
||||
override |
||||
returns (uint256) |
||||
{ |
||||
require( |
||||
supportsMetadata(metadata), |
||||
"AbstractPostDispatchHook: invalid metadata variant" |
||||
); |
||||
return _quoteDispatch(metadata, message); |
||||
} |
||||
|
||||
// ============ Internal functions ============ |
||||
|
||||
/** |
||||
* @notice Post dispatch hook implementation. |
||||
* @param metadata The metadata of the message being dispatched. |
||||
* @param message The message being dispatched. |
||||
*/ |
||||
function _postDispatch(bytes calldata metadata, bytes calldata message) |
||||
internal |
||||
virtual; |
||||
|
||||
/** |
||||
* @notice Quote dispatch hook implementation. |
||||
* @param metadata The metadata of the message being dispatched. |
||||
* @param message The message being dispatched. |
||||
* @return The quote for the dispatch. |
||||
*/ |
||||
function _quoteDispatch(bytes calldata metadata, bytes calldata message) |
||||
internal |
||||
view |
||||
virtual |
||||
returns (uint256); |
||||
} |
@ -0,0 +1,164 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.8.0; |
||||
|
||||
/*@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||
@@@@@ HYPERLANE @@@@@@@ |
||||
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@*/ |
||||
|
||||
/** |
||||
* Format of metadata: |
||||
* |
||||
* [0:1] variant |
||||
* [2:33] msg.value |
||||
* [34:65] Gas limit for message (IGP) |
||||
* [66:85] Refund address for message (IGP) |
||||
* [86:] Custom metadata |
||||
*/ |
||||
library GlobalHookMetadata { |
||||
uint8 private constant VARIANT_OFFSET = 0; |
||||
uint8 private constant MSG_VALUE_OFFSET = 2; |
||||
uint8 private constant GAS_LIMIT_OFFSET = 34; |
||||
uint8 private constant REFUND_ADDRESS_OFFSET = 66; |
||||
uint256 private constant MIN_METADATA_LENGTH = 86; |
||||
|
||||
uint16 public constant VARIANT = 1; |
||||
|
||||
/** |
||||
* @notice Returns the variant of the metadata. |
||||
* @param _metadata ABI encoded global hook metadata. |
||||
* @return variant of the metadata as uint8. |
||||
*/ |
||||
function variant(bytes calldata _metadata) internal pure returns (uint16) { |
||||
if (_metadata.length < VARIANT_OFFSET + 2) return 0; |
||||
return uint16(bytes2(_metadata[VARIANT_OFFSET:VARIANT_OFFSET + 2])); |
||||
} |
||||
|
||||
/** |
||||
* @notice Returns the specified value for the message. |
||||
* @param _metadata ABI encoded global hook metadata. |
||||
* @return Value for the message as uint256. |
||||
*/ |
||||
function msgValue(bytes calldata _metadata, uint256 _default) |
||||
internal |
||||
pure |
||||
returns (uint256) |
||||
{ |
||||
if (_metadata.length < MSG_VALUE_OFFSET + 32) return _default; |
||||
return |
||||
uint256(bytes32(_metadata[MSG_VALUE_OFFSET:MSG_VALUE_OFFSET + 32])); |
||||
} |
||||
|
||||
/** |
||||
* @notice Returns the specified gas limit for the message. |
||||
* @param _metadata ABI encoded global hook metadata. |
||||
* @return Gas limit for the message as uint256. |
||||
*/ |
||||
function gasLimit(bytes calldata _metadata, uint256 _default) |
||||
internal |
||||
pure |
||||
returns (uint256) |
||||
{ |
||||
if (_metadata.length < GAS_LIMIT_OFFSET + 32) return _default; |
||||
return |
||||
uint256(bytes32(_metadata[GAS_LIMIT_OFFSET:GAS_LIMIT_OFFSET + 32])); |
||||
} |
||||
|
||||
/** |
||||
* @notice Returns the specified refund address for the message. |
||||
* @param _metadata ABI encoded global hook metadata. |
||||
* @return Refund address for the message as address. |
||||
*/ |
||||
function refundAddress(bytes calldata _metadata, address _default) |
||||
internal |
||||
pure |
||||
returns (address) |
||||
{ |
||||
if (_metadata.length < REFUND_ADDRESS_OFFSET + 20) return _default; |
||||
return |
||||
address( |
||||
bytes20( |
||||
_metadata[REFUND_ADDRESS_OFFSET:REFUND_ADDRESS_OFFSET + 20] |
||||
) |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @notice Returns the specified refund address for the message. |
||||
* @param _metadata ABI encoded global hook metadata. |
||||
* @return Refund address for the message as address. |
||||
*/ |
||||
function getCustomMetadata(bytes calldata _metadata) |
||||
internal |
||||
pure |
||||
returns (bytes calldata) |
||||
{ |
||||
if (_metadata.length < MIN_METADATA_LENGTH) return _metadata[0:0]; |
||||
return _metadata[MIN_METADATA_LENGTH:]; |
||||
} |
||||
|
||||
/** |
||||
* @notice Formats the specified gas limit and refund address into global hook metadata. |
||||
* @param _msgValue msg.value for the message. |
||||
* @param _gasLimit Gas limit for the message. |
||||
* @param _refundAddress Refund address for the message. |
||||
* @param _customMetadata Additional metadata to include in the global hook metadata. |
||||
* @return ABI encoded global hook metadata. |
||||
*/ |
||||
function formatMetadata( |
||||
uint256 _msgValue, |
||||
uint256 _gasLimit, |
||||
address _refundAddress, |
||||
bytes memory _customMetadata |
||||
) internal pure returns (bytes memory) { |
||||
return |
||||
abi.encodePacked( |
||||
VARIANT, |
||||
_msgValue, |
||||
_gasLimit, |
||||
_refundAddress, |
||||
_customMetadata |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @notice Formats the specified gas limit and refund address into global hook metadata. |
||||
* @param _msgValue msg.value for the message. |
||||
* @return ABI encoded global hook metadata. |
||||
*/ |
||||
function formatMetadata(uint256 _msgValue) |
||||
internal |
||||
view |
||||
returns (bytes memory) |
||||
{ |
||||
return abi.encodePacked(VARIANT, _msgValue, uint256(0), msg.sender, ""); |
||||
} |
||||
|
||||
/** |
||||
* @notice Formats the specified gas limit and refund address into global hook metadata. |
||||
* @param _gasLimit Gas limit for the message. |
||||
* @param _refundAddress Refund address for the message. |
||||
* @return ABI encoded global hook metadata. |
||||
*/ |
||||
function formatMetadata(uint256 _gasLimit, address _refundAddress) |
||||
internal |
||||
pure |
||||
returns (bytes memory) |
||||
{ |
||||
return |
||||
abi.encodePacked( |
||||
VARIANT, |
||||
uint256(0), |
||||
_gasLimit, |
||||
_refundAddress, |
||||
"" |
||||
); |
||||
} |
||||
} |
@ -1,78 +0,0 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.8.0; |
||||
|
||||
/*@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||
@@@@@ HYPERLANE @@@@@@@ |
||||
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@@ |
||||
@@@@@@@@@ @@@@@@@@*/ |
||||
|
||||
/** |
||||
* Format of metadata: |
||||
* |
||||
* [0:32] Gas limit for message |
||||
* [32:52] Refund address for message |
||||
*/ |
||||
library IGPMetadata { |
||||
uint8 private constant GAS_LIMIT_OFFSET = 0; |
||||
uint8 private constant REFUND_ADDRESS_OFFSET = 32; |
||||
|
||||
/** |
||||
* @notice Returns the specified gas limit for the message. |
||||
* @param _metadata ABI encoded IGP hook metadata. |
||||
* @return Gas limit for the message as uint256. |
||||
*/ |
||||
function gasLimit(bytes calldata _metadata, uint256 _default) |
||||
internal |
||||
pure |
||||
returns (uint256) |
||||
{ |
||||
if (_metadata.length < GAS_LIMIT_OFFSET + 32) return _default; |
||||
return |
||||
uint256(bytes32(_metadata[GAS_LIMIT_OFFSET:GAS_LIMIT_OFFSET + 32])); |
||||
} |
||||
|
||||
/** |
||||
* @notice Returns the specified refund address for the message. |
||||
* @param _metadata ABI encoded IGP hook metadata. |
||||
* @return Refund address for the message as address. |
||||
*/ |
||||
function refundAddress(bytes calldata _metadata, address _default) |
||||
internal |
||||
pure |
||||
returns (address) |
||||
{ |
||||
address _refundAddress; |
||||
if (_metadata.length < REFUND_ADDRESS_OFFSET + 20) { |
||||
_refundAddress = _default; |
||||
} else { |
||||
_refundAddress = address( |
||||
bytes20( |
||||
_metadata[REFUND_ADDRESS_OFFSET:REFUND_ADDRESS_OFFSET + 20] |
||||
) |
||||
); |
||||
if (_refundAddress == address(0)) _refundAddress = _default; |
||||
} |
||||
return _refundAddress; |
||||
} |
||||
|
||||
/** |
||||
* @notice Formats the specified gas limit and refund address into IGP hook metadata. |
||||
* @param _gasLimit Gas limit for the message. |
||||
* @param _refundAddress Refund address for the message. |
||||
* @return ABI encoded IGP hook metadata. |
||||
*/ |
||||
function formatMetadata(uint256 _gasLimit, address _refundAddress) |
||||
internal |
||||
pure |
||||
returns (bytes memory) |
||||
{ |
||||
return abi.encodePacked(bytes32(_gasLimit), bytes20(_refundAddress)); |
||||
} |
||||
} |
@ -1,17 +0,0 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.8.0; |
||||
|
||||
/** |
||||
* Format of metadata: |
||||
* |
||||
* [0:32] Msg value to be sent to L2 |
||||
*/ |
||||
library OPStackHookMetadata { |
||||
function msgValue(bytes calldata _metadata) |
||||
internal |
||||
pure |
||||
returns (uint256) |
||||
{ |
||||
return uint256(bytes32(_metadata[0:32])); |
||||
} |
||||
} |
Loading…
Reference in new issue