The home for Hyperlane core contracts, sdk packages, and other infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
hyperlane-monorepo/solidity/contracts/hooks/MerkleTreeHook.sol

87 lines
2.7 KiB

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/*@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@ HYPERLANE @@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
import {MerkleLib} from "../libs/Merkle.sol";
import {Message} from "../libs/Message.sol";
import {MailboxClient} from "../client/MailboxClient.sol";
import {Indexed} from "../libs/Indexed.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
import {AbstractPostDispatchHook} from "./libs/AbstractPostDispatchHook.sol";
import {StandardHookMetadata} from "./libs/StandardHookMetadata.sol";
contract MerkleTreeHook is AbstractPostDispatchHook, MailboxClient, Indexed {
using Message for bytes;
using MerkleLib for MerkleLib.Tree;
using StandardHookMetadata for bytes;
// An incremental merkle tree used to store outbound message IDs.
MerkleLib.Tree internal _tree;
event InsertedIntoTree(bytes32 messageId, uint32 index);
constructor(address _mailbox) MailboxClient(_mailbox) {}
// count cannot exceed 2**TREE_DEPTH, see MerkleLib.sol
function count() public view returns (uint32) {
return uint32(_tree.count);
}
function root() public view returns (bytes32) {
return _tree.root();
}
function tree() public view returns (MerkleLib.Tree memory) {
return _tree;
}
function latestCheckpoint() external view returns (bytes32, uint32) {
return (root(), count() - 1);
}
// ============ External Functions ============
/// @inheritdoc IPostDispatchHook
function hookType() external pure override returns (uint8) {
return uint8(IPostDispatchHook.Types.MERKLE_TREE);
}
// ============ Internal Functions ============
/// @inheritdoc AbstractPostDispatchHook
function _postDispatch(
bytes calldata,
/*metadata*/
bytes calldata message
) internal override {
require(msg.value == 0, "MerkleTreeHook: no value expected");
// ensure messages which were not dispatched are not inserted into the tree
bytes32 id = message.id();
require(_isLatestDispatched(id), "message not dispatching");
uint32 index = count();
_tree.insert(id);
emit InsertedIntoTree(id, index);
}
/// @inheritdoc AbstractPostDispatchHook
function _quoteDispatch(
bytes calldata,
/*metadata*/
bytes calldata /*message*/
) internal pure override returns (uint256) {
return 0;
}
}