parent
dc0a64b82b
commit
ebfbdaa708
@ -0,0 +1,40 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.6.11; |
||||
pragma abicoder v2; |
||||
|
||||
// ============ Internal Imports ============ |
||||
import {MultisigValidatorManager} from "./MultisigValidatorManager.sol"; |
||||
import {Inbox} from "../Inbox.sol"; |
||||
|
||||
contract InboxMultisigValidatorManager is MultisigValidatorManager { |
||||
// ============ Constructor ============ |
||||
|
||||
/** |
||||
* @param _remoteDomain The remote domain of the outbox chain. |
||||
*/ |
||||
// solhint-disable-next-line no-empty-blocks |
||||
constructor(uint32 _remoteDomain) MultisigValidatorManager(_remoteDomain) {} |
||||
|
||||
// ============ External Functions ============ |
||||
|
||||
/** |
||||
* @notice Submits a checkpoint signed by a quorum of validators to an Inbox. |
||||
* @dev Reverts if _signatures is not a quorum of validator signatures. |
||||
* @dev Reverts if _signatures is not sorted in ascending order by the signer |
||||
* address, which is required for duplicate detection. |
||||
* @param _inbox The inbox to submit the checkpoint to. |
||||
* @param _root The merkle root of the checkpoint. |
||||
* @param _index The index of the checkpoint. |
||||
* @param _signatures Signatures over the checkpoint to be checked for a validator |
||||
* quorum. Must be sorted in ascending order by signer address. |
||||
*/ |
||||
function checkpoint( |
||||
Inbox _inbox, |
||||
bytes32 _root, |
||||
uint256 _index, |
||||
bytes[] calldata _signatures |
||||
) external { |
||||
require(isQuorum(_root, _index, _signatures), "!quorum"); |
||||
_inbox.checkpoint(_root, _index); |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.6.11; |
||||
pragma abicoder v2; |
||||
|
||||
// ============ Internal Imports ============ |
||||
import {MultisigValidatorManager} from "./MultisigValidatorManager.sol"; |
||||
import {Outbox} from "../Outbox.sol"; |
||||
|
||||
contract OutboxMultisigValidatorManager is MultisigValidatorManager { |
||||
// ============ Events ============ |
||||
|
||||
/** |
||||
* @notice Emitted when proof of an improper checkpoint is submitted. |
||||
* @param root Root of the improper checkpoint. |
||||
* @param index Index of the improper checkpoint. |
||||
* @param signatures A quorum of signatures on the improper checkpoint. |
||||
*/ |
||||
event ImproperCheckpoint( |
||||
address indexed outbox, |
||||
bytes32 indexed root, |
||||
uint256 index, |
||||
bytes[] signatures |
||||
); |
||||
|
||||
// ============ Constructor ============ |
||||
|
||||
/** |
||||
* @param _localDomain The local domain. |
||||
*/ |
||||
// solhint-disable-next-line no-empty-blocks |
||||
constructor(uint32 _localDomain) MultisigValidatorManager(_localDomain) {} |
||||
|
||||
// ============ External Functions ============ |
||||
|
||||
// Determines if a quorum of signers have signed an improper checkpoint, |
||||
// and fails the Outbox if so. |
||||
// If staking / slashing existed, we'd want to check this for individual validator |
||||
// signatures. Because we don't care about that and we don't want a single byzantine |
||||
// validator to be able to fail the outbox, we require a quorum. |
||||
// |
||||
// Gets the domain from IOutbox(_outbox).localDomain(), then |
||||
// requires isQuorum(domain, _root, _index, _signatures), |
||||
// requires that the checkpoint is an improper checkpoint, |
||||
// and calls IOutbox(_outbox).fail(). (Similar behavior as existing improperCheckpoint) |
||||
function improperCheckpoint( |
||||
Outbox _outbox, |
||||
bytes32 _root, |
||||
uint256 _index, |
||||
bytes[] calldata _signatures |
||||
) external { |
||||
require(isQuorum(_root, _index, _signatures), "!quorum"); |
||||
require(!_outbox.isCheckpoint(_root, _index), "!improper checkpoint"); |
||||
_outbox.fail(); |
||||
emit ImproperCheckpoint(address(_outbox), _root, _index, _signatures); |
||||
} |
||||
} |
Loading…
Reference in new issue