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/optics-core/contracts/governance/GovernanceMessage.sol

280 lines
7.6 KiB

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
pragma experimental ABIEncoderV2;
import "@summa-tx/memview-sol/contracts/TypedMemView.sol";
library GovernanceMessage {
using TypedMemView for bytes;
using TypedMemView for bytes29;
uint256 private constant CALL_PREFIX_LEN = 64;
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
uint256 private constant MSG_PREFIX_NUM_ITEMS = 2;
uint256 private constant MSG_PREFIX_LEN = 2;
uint256 private constant GOV_ACTION_LEN = 37;
enum Types {
Invalid, // 0
Call, // 1
TransferGovernor, // 2
SetRouter, // 3
Data // 4
}
struct Call {
bytes32 to;
bytes data;
}
modifier typeAssert(bytes29 _view, Types _t) {
_view.assertType(uint40(_t));
_;
}
// Types.Call
function data(bytes29 _view) internal view returns (bytes memory _data) {
_data = TypedMemView.clone(
_view.slice(CALL_PREFIX_LEN, dataLen(_view), uint40(Types.Data))
);
}
function formatCalls(Call[] memory _calls)
internal
view
returns (bytes memory _msg)
{
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
uint256 _numCalls = _calls.length;
bytes29[] memory _encodedCalls =
new bytes29[](_numCalls + MSG_PREFIX_NUM_ITEMS);
// Add Types.Call identifier
_encodedCalls[0] = abi.encodePacked(Types.Call).ref(0);
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
// Add number of calls
_encodedCalls[1] = bytes1(uint8(_numCalls));
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
for (uint256 i = 0; i < _numCalls; i++) {
Call memory _call = _calls[i];
bytes29 _callMsg =
abi.encodePacked(_call.to, _call.data.length, _call.data).ref(
0
);
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
_encodedCalls[i + MSG_PREFIX_NUM_ITEMS] = _callMsg;
}
_msg = TypedMemView.join(_encodedCalls);
}
function formatTransferGovernor(uint32 _domain, bytes32 _governor)
internal
view
returns (bytes memory _msg)
{
_msg = TypedMemView.clone(
mustBeTransferGovernor(
abi
.encodePacked(Types.TransferGovernor, _domain, _governor)
.ref(0)
)
);
}
function formatSetRouter(uint32 _domain, bytes32 _router)
internal
view
returns (bytes memory _msg)
{
_msg = TypedMemView.clone(
mustBeSetRouter(
abi.encodePacked(Types.SetRouter, _domain, _router).ref(0)
)
);
}
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
function getCalls(bytes29 _msg) internal view returns (Call[] memory) {
uint8 _numCalls = uint8(_msg.indexUint(1, 1));
// Skip message prefix
bytes29 _msgPtr =
_msg.slice(
MSG_PREFIX_LEN,
_msg.len() - MSG_PREFIX_LEN,
uint40(Types.Call)
);
Call[] memory _calls = new Call[](_numCalls);
uint256 counter = 0;
while (_msgPtr.len() > 0) {
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
_calls[counter].to = to(_msgPtr);
_calls[counter].data = data(_msgPtr);
_msgPtr = nextCall(_msgPtr);
counter++;
}
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
return _calls;
}
function nextCall(bytes29 _view)
internal
pure
typeAssert(_view, Types.Call)
returns (bytes29)
{
uint256 lastCallLen = CALL_PREFIX_LEN + dataLen(_view);
return
_view.slice(
lastCallLen,
_view.len() - lastCallLen,
uint40(Types.Call)
);
}
function messageType(bytes29 _view) internal pure returns (Types) {
return Types(uint8(_view.typeOf()));
}
/*
Message fields
*/
// All Types
function identifier(bytes29 _view) internal pure returns (uint8) {
return uint8(_view.indexUint(0, 1));
}
// Types.Call
function to(bytes29 _view) internal pure returns (bytes32) {
return _view.index(0, 32);
}
// Types.Call
function dataLen(bytes29 _view) internal pure returns (uint256) {
return uint256(_view.index(32, 32));
}
// Types.TransferGovernor & Types.EnrollRemote
function domain(bytes29 _view) internal pure returns (uint32) {
return uint32(_view.indexUint(1, 4));
}
// Types.EnrollRemote
function router(bytes29 _view) internal pure returns (bytes32) {
return _view.index(5, 32);
}
// Types.TransferGovernor
function governor(bytes29 _view) internal pure returns (bytes32) {
return _view.index(5, 32);
}
/*
Message Type: CALL
struct Call {
test: cross chain governance (#312) * fix: OpticsIdentifier as_ref casts ethereum address conditionally * feature: adds GovernanceRouter test boilerplate and fixes ConnectionManager test setup * test: adds testProcess and revert message utility * test: adds test for handle revert with unenrolled replica * test: adds test for reverting in handle on nonGovernorRouter message * rename: formattedMessage --> opticsMessage * prog: blocked on incorrect setting of governorDomain = localDomain * fix: fix after domainHash rebase * test: adds success case transfer governor test * test: adds setRouter message success case * prog: Call message success case failing due to datalen mismatches * prog: storing in dynamic struct array reverts silently * add: initial setup * add: transfer governorship test * add: signUpdate * refactor: combine bridgerouter tests * fix: cast to address, set sequence * delete: old gov router tests * Fix transfer governor test * fix: debug call storage, get sequence * fix: bad merge rust code * revert: stale changes * refactor: nits, create thirdDomain/thirdRouter vars * refactor: extract some code into formatOpticsMessage * refactor: formatOpticsMessage * refactor: deployOptics and devDeployOptics * fix: bug, clean up code * lint * fix: add numCalls (#315) * fix: initial stab at adding numCalls * debugging: numCall type conversion * fix: read _numCalls from bytes29 * use MSG_PREFIX_LEN * clean: remove unused imports * fix: data bug, refactor a bit * add: Transaction reverted silently * fix: bug in formatCalls * refactor: formatCalls * add: check ret value for testProcess from GovernorRouter * enhance: more explicit naming * rename: BYTE_LEN to NUM_ITEMS * slow down turbo * enhance: assign _numCalls variable Co-authored-by: Luke Tchang <ltchang@stanford.edu> Co-authored-by: anna-caroll <anna.s.carroll@gmail.com>
4 years ago
identifier, // message ID -- 1 byte
numCalls, // number of calls -- 1 byte
calls[], {
to, // address to call -- 32 bytes
dataLen, // call data length -- 32 bytes,
data // call data -- 0+ bytes (length unknown)
}
}
*/
function isValidCall(bytes29 _view) internal pure returns (bool) {
return
identifier(_view) == uint8(Types.Call) &&
_view.len() >= CALL_PREFIX_LEN;
}
function isCall(bytes29 _view) internal pure returns (bool) {
return isValidCall(_view) && messageType(_view) == Types.Call;
}
function tryAsCall(bytes29 _view) internal pure returns (bytes29) {
if (isValidCall(_view)) {
return _view.castTo(uint40(Types.Call));
}
return TypedMemView.nullView();
}
function mustBeCalls(bytes29 _view) internal pure returns (bytes29) {
return tryAsCall(_view).assertValid();
}
/*
Message Type: TRANSFER GOVERNOR
struct TransferGovernor {
identifier, // message ID -- 1 byte
domain, // domain of new governor -- 4 bytes
addr // address of new governor -- 32 bytes
}
*/
function isValidTransferGovernor(bytes29 _view)
internal
pure
returns (bool)
{
return
identifier(_view) == uint8(Types.TransferGovernor) &&
_view.len() == GOV_ACTION_LEN;
}
function isTransferGovernor(bytes29 _view) internal pure returns (bool) {
return
isValidTransferGovernor(_view) &&
messageType(_view) == Types.TransferGovernor;
}
function tryAsTransferGovernor(bytes29 _view)
internal
pure
returns (bytes29)
{
if (isValidTransferGovernor(_view)) {
return _view.castTo(uint40(Types.TransferGovernor));
}
return TypedMemView.nullView();
}
function mustBeTransferGovernor(bytes29 _view)
internal
pure
returns (bytes29)
{
return tryAsTransferGovernor(_view).assertValid();
}
/*
Message Type: ENROLL ROUTER
struct SetRouter {
identifier, // message ID -- 1 byte
domain, // domain of new router -- 4 bytes
addr // address of new router -- 32 bytes
}
*/
function isValidSetRouter(bytes29 _view) internal pure returns (bool) {
return
identifier(_view) == uint8(Types.SetRouter) &&
_view.len() == GOV_ACTION_LEN;
}
function isSetRouter(bytes29 _view) internal pure returns (bool) {
return isValidSetRouter(_view) && messageType(_view) == Types.SetRouter;
}
function tryAsSetRouter(bytes29 _view) internal pure returns (bytes29) {
if (isValidSetRouter(_view)) {
return _view.castTo(uint40(Types.SetRouter));
}
return TypedMemView.nullView();
}
function mustBeSetRouter(bytes29 _view) internal pure returns (bytes29) {
return tryAsSetRouter(_view).assertValid();
}
}