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/test/cross-chain/crossChainTestUtils.js

204 lines
5.7 KiB

const { expect } = require('chai');
const {
getHome,
getReplica,
getUpdaterObject,
} = require('./deployCrossChainTest');
/*
* Enqueue a message to the specified Home contract
* and return the updated root
*
* @param chainDetails - ChainDetails type containing every deployed domain
* @param homeDomain - domain of the Home contract to which we will enqueue the message
* @param messageDetails - Message type containing
* the message string,
* the destination domain to which the message will be sent,
* the recipient address on the destination domain to which the message will be dispatched
*
* @return newRoot - bytes32 of the latest root
*/
async function enqueueMessageToHome(chainDetails, homeDomain, messageDetails) {
const home = getHome(chainDetails, homeDomain);
const { message, destinationDomain, recipientAddress } = messageDetails;
// Send message with random signer address as msg.sender
await home.enqueue(
destinationDomain,
optics.ethersAddressToBytes32(recipientAddress),
ethers.utils.formatBytes32String(message),
);
const [, newRoot] = await home.suggestUpdate();
return newRoot;
}
/*
* Enqueue a set of messages to the specified Home contract,
* then sign and submit an update to the Home contract
*
* @param chainDetails - ChainDetails type containing every deployed domain
* @param homeDomain - domain of the Home contract to which we will enqueue all of messages / submit the update
* @param messages - Message[]
*
* @return update - Update type
*/
async function enqueueMessagesAndUpdateHome(
chainDetails,
homeDomain,
messages,
) {
const home = getHome(chainDetails, homeDomain);
const updater = getUpdaterObject(chainDetails, homeDomain);
const startRoot = await home.current();
// enqueue each message to Home and get the intermediate root
const enqueuedRoots = [];
for (let message of messages) {
const newRoot = await enqueueMessageToHome(
chainDetails,
homeDomain,
message,
);
enqueuedRoots.push(newRoot);
}
// ensure that Home queue contains
// all of the roots we just enqueued
for (let root of enqueuedRoots) {
expect(await home.queueContains(root)).to.be.true;
}
// sign & submit an update from startRoot to finalRoot
const finalRoot = enqueuedRoots[enqueuedRoots.length - 1];
const { signature } = await updater.signUpdate(startRoot, finalRoot);
await expect(home.update(startRoot, finalRoot, signature))
.to.emit(home, 'Update')
.withArgs(homeDomain, startRoot, finalRoot, signature);
// ensure that Home root is now finalRoot
expect(await home.current()).to.equal(finalRoot);
// ensure that Home queue no longer contains
// any of the roots we just enqueued -
// they should be removed from queue when update is submitted
for (let root of enqueuedRoots) {
expect(await home.queueContains(root)).to.be.false;
}
const update = {
startRoot,
finalRoot,
signature,
};
return update;
}
/*
* Enqueue a signed update to the Replica contract
*
* @param chainDetails - ChainDetails type containing every deployed domain
* @param latestUpdateOnOriginChain - Update type, the last Update submitted to the Home chain for this Replica
* @param homeDomain - domain of the Home contract from which the update originated
* @param replicaDomain - domain of the Replica contract where the update will be submitted
*
* @return finalRoot - updated state root enqueued to the Replica
*/
async function enqueueUpdateToReplica(
chainDetails,
latestUpdateOnOriginChain,
homeDomain,
replicaDomain,
) {
const replica = getReplica(chainDetails, replicaDomain, homeDomain);
const { startRoot, finalRoot, signature } = latestUpdateOnOriginChain;
await expect(replica.update(startRoot, finalRoot, signature))
.to.emit(replica, 'Update')
.withArgs(homeDomain, startRoot, finalRoot, signature);
expect(await replica.queueEnd()).to.equal(finalRoot);
return finalRoot;
}
/*
* Format into a Message type
*
* @param messageString - string for the body of the message
* @param messageDestinationDomain - domain where the message will be sent
* @param messageRecipient - recipient of the message on the destination domain
*
* @return message - Message type
*/
function formatMessage(
messageString,
messageDestinationDomain,
messageRecipient,
) {
const message = {
message: messageString,
destinationDomain: messageDestinationDomain,
recipientAddress: messageRecipient,
};
return message;
}
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
async function formatOpticsMessage(
replica,
governorRouter,
destinationRouter,
message,
) {
const sequence = await replica.nextToProcess();
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
const governorDomain = await governorRouter.localDomain();
const destinationDomain = await destinationRouter.localDomain();
// Create Optics message that is sent from the governor domain and governor
// to the nonGovernorRouter on the nonGovernorDomain
const opticsMessage = optics.formatMessage(
governorDomain,
governorRouter.address,
sequence,
destinationDomain,
destinationRouter.address,
message,
);
// Set message status to MessageStatus.Pending
await replica.setMessagePending(opticsMessage);
return opticsMessage;
}
async function formatCall(destinationContract, functionStr, functionArgs) {
// Set up data for call message
const callFunc = destinationContract.interface.getFunction(functionStr);
const callDataEncoded = destinationContract.interface.encodeFunctionData(
callFunc,
functionArgs,
);
return {
to: optics.ethersAddressToBytes32(destinationContract.address),
data: callDataEncoded,
};
}
module.exports = {
enqueueUpdateToReplica,
enqueueMessagesAndUpdateHome,
formatMessage,
formatCall,
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
formatOpticsMessage,
};