wormhole/ethereum/forge-test/relayer/MockWormhole.sol

290 lines
8.9 KiB
Solidity
Raw Normal View History

Relayer: Ethereum folder Changes for Merging into Main (#3038) * gRelayer: surrounding files * modification to get compilation * restore devnet * remove generic relayer docker * remove wait for relayer engine * keep build time 20 * sh -> bash * sh -> bash * Remove comment * bash -> sh * Revert "bash -> sh" This reverts commit 5c37e92fa19bbdbefc79c8ee0dbceeb127c53373. * bash->sh * gRelayer: ethereum folder changes for generic-relayer-merge * add eth-devnet * Adds .github because workflow needs to install forge * sdk-ci-tests need to install forge * don't wait for nonexistent relayer engine * update package.json and package-lock.json * Remove unnecessary types from package.json * ts-node * gRelayer: ethereum folder changes for generic-relayer-merge * sdk-ci-tests need to install forge * don't wait for nonexistent relayer engine * update package.json and package-lock.json * remove these changes * Relayer: Natspec documentation in IWormholeRelayer (#3032) * WIP * Fixes * Updated interfaces * remove bash * Forward uses same refund chain id and refund address (#3034) * WIP * Fixes * Forward uses same refund chain id and refund address * Updated interfaces * Remove forge build warnings * Add note to interface for resend * via-ir on unless in Tilt * Correct IWormholeReceiver interface * Wormhole message fee now part of quoteDeliveryPrice (#3043) * Fix to PR 3043 * Remove compiler warning * Relayer/address drew review (#3060) * Fix typo in Create2Factory * Add event for contract upgrades * Prevent registering contract if it is already registered * Prevent allowing unset chainId for default delivery provider governance VAA * memory to calldata for external functions in WormholeRelayerSend * continue memory to calldata for external functions * Fix pricing in delivery provider * Sanity check new default delivery provider isn't 0 address * Don't save vaaKey as local variable * cache the length of array rather than iterate every time for vaaKeys * Replacing memory with calldata in few locations * Remove stale file DeliveryProviderMessages * Remove batch VAA sender script * Remove batch VAA from WormholeSimulator * Wait for a confirmation in deploy scripts * remove unnecessary comments * Fix Delivery Provider Pricing and add a test * remove console logs * Revert "continue memory to calldata for external functions" This reverts commit f322afb6c0bbd09e3d04ab42a90e592ff752f6bf. * Revert "memory to calldata for external functions in WormholeRelayerSend" This reverts commit 42fcaad8842d0c81506c9586d8d0fd98f6bb6ae1. * Revert "Don't save vaaKey as local variable" This reverts commit a9172379c564fd430a083645c1c42c78e014d68d. * Revert "cache the length of array rather than iterate every time for vaaKeys" This reverts commit d61380a9b0c0671e67e3bd5d874ae339e180dd34. * Revert "Replacing memory with calldata in few locations" This reverts commit 94e47b6e72eaaa52ac0ba2980c439180401fafd7. * Revert "Fix typo in Create2Factory" This reverts commit a9f7bdf461945c8abf020007d16bbc6b4301d051. * Update contract addresses for via-ir * Slight improvements to delivery provider implementation * typed errors for delivery provider * enable VIA-IR in CI and not in Tilt * correct contract address for via ir * WormholeRelayerSend and WormholeRelayerDelivery (#3082)
2023-06-13 14:01:43 -07:00
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.17;
import "../../contracts/interfaces/IWormhole.sol";
import "../../contracts/libraries/external/BytesLib.sol";
contract MockWormhole is IWormhole {
using BytesLib for bytes;
uint256 private constant VM_VERSION_SIZE = 1;
uint256 private constant VM_GUARDIAN_SET_SIZE = 4;
uint256 private constant VM_SIGNATURE_COUNT_SIZE = 1;
uint256 private constant VM_TIMESTAMP_SIZE = 4;
uint256 private constant VM_NONCE_SIZE = 4;
uint256 private constant VM_EMITTER_CHAIN_ID_SIZE = 2;
uint256 private constant VM_EMITTER_ADDRESS_SIZE = 32;
uint256 private constant VM_SEQUENCE_SIZE = 8;
uint256 private constant VM_CONSISTENCY_LEVEL_SIZE = 1;
uint256 private constant VM_SIZE_MINIMUM = VM_VERSION_SIZE + VM_GUARDIAN_SET_SIZE
+ VM_SIGNATURE_COUNT_SIZE + VM_TIMESTAMP_SIZE + VM_NONCE_SIZE + VM_EMITTER_CHAIN_ID_SIZE
+ VM_EMITTER_ADDRESS_SIZE + VM_SEQUENCE_SIZE + VM_CONSISTENCY_LEVEL_SIZE;
uint256 private constant SIGNATURE_GUARDIAN_INDEX_SIZE = 1;
uint256 private constant SIGNATURE_R_SIZE = 32;
uint256 private constant SIGNATURE_S_SIZE = 32;
uint256 private constant SIGNATURE_V_SIZE = 1;
uint256 private constant SIGNATURE_SIZE_TOTAL =
SIGNATURE_GUARDIAN_INDEX_SIZE + SIGNATURE_R_SIZE + SIGNATURE_S_SIZE + SIGNATURE_V_SIZE;
mapping(address => uint64) public sequences;
// Dictionary of VMs that must be mocked as invalid.
mapping(bytes32 => bool) public invalidVMs;
uint256 currentMsgFee;
uint16 immutable wormholeChainId;
uint256 immutable boundEvmChainId;
constructor(uint16 initChainId, uint256 initEvmChainId) {
wormholeChainId = initChainId;
boundEvmChainId = initEvmChainId;
}
function invalidateVM(bytes calldata encodedVm) external {
VM memory vm = _parseVM(encodedVm);
invalidVMs[vm.hash] = true;
}
function publishMessage(
uint32 nonce,
bytes memory payload,
uint8 consistencyLevel
) external payable returns (uint64 sequence) {
require(msg.value == currentMsgFee, "invalid fee");
sequence = sequences[msg.sender]++;
emit LogMessagePublished(msg.sender, sequence, nonce, payload, consistencyLevel);
}
function parseVM(bytes calldata encodedVm) external pure returns (VM memory vm) {
vm = _parseVM(encodedVm);
}
function parseAndVerifyVM(bytes calldata encodedVm)
external
view
returns (VM memory vm, bool valid, string memory reason)
{
vm = _parseVM(encodedVm);
//behold the rigorous checking!
valid = !invalidVMs[vm.hash];
reason = "";
}
function _parseVM(bytes calldata encodedVm) internal pure returns (VM memory vm) {
require(encodedVm.length >= VM_SIZE_MINIMUM, "vm too small");
bytes memory body;
uint256 offset = 0;
vm.version = encodedVm.toUint8(offset);
offset += 1;
vm.guardianSetIndex = encodedVm.toUint32(offset);
offset += 4;
(vm.signatures, offset) = parseSignatures(encodedVm, offset);
body = encodedVm[offset:];
vm.timestamp = encodedVm.toUint32(offset);
offset += 4;
vm.nonce = encodedVm.toUint32(offset);
offset += 4;
vm.emitterChainId = encodedVm.toUint16(offset);
offset += 2;
vm.emitterAddress = encodedVm.toBytes32(offset);
offset += 32;
vm.sequence = encodedVm.toUint64(offset);
offset += 8;
vm.consistencyLevel = encodedVm.toUint8(offset);
offset += 1;
vm.payload = encodedVm[offset:];
vm.hash = keccak256(abi.encodePacked(keccak256(body)));
}
function parseSignatures(
bytes calldata encodedVm,
uint256 offset
) internal pure returns (Signature[] memory signatures, uint256 offsetAfterParse) {
uint256 sigCount = uint256(encodedVm.toUint8(offset));
offset += 1;
require(
encodedVm.length >= (VM_SIZE_MINIMUM + sigCount * SIGNATURE_SIZE_TOTAL), "vm too small"
);
signatures = new Signature[](sigCount);
for (uint256 i = 0; i < sigCount; ++i) {
uint8 guardianIndex = encodedVm.toUint8(offset);
offset += 1;
bytes32 r = encodedVm.toBytes32(offset);
offset += 32;
bytes32 s = encodedVm.toBytes32(offset);
offset += 32;
uint8 v = encodedVm.toUint8(offset);
offset += 1;
signatures[i] = Signature({
r: r,
s: s,
// The hardcoded 27 comes from the base offset for public key recovery ids, public key type and network
// used in ECDSA signatures for bitcoin and ethereum.
// See https://bitcoin.stackexchange.com/a/5089
v: v + 27,
guardianIndex: guardianIndex
});
}
return (signatures, offset);
}
function initialize() external {}
function quorum(uint256 /*numGuardians*/ )
external
pure
returns (uint256 /*numSignaturesRequiredForQuorum*/ )
{
return 1;
}
/**
* General state and chain observers
*/
function chainId() external view returns (uint16) {
return wormholeChainId;
}
function evmChainId() external view returns (uint256) {
return boundEvmChainId;
}
function getCurrentGuardianSetIndex() external pure returns (uint32) {
return 0;
}
function getGuardianSet(uint32 /*index*/ ) external pure returns (GuardianSet memory) {
revert("unsupported getGuardianSet in wormhole mock");
}
function getGuardianSetExpiry() external pure returns (uint32) {
return 0;
}
function governanceActionIsConsumed(bytes32 /*hash*/ ) external pure returns (bool) {
return false;
}
function isInitialized(address /*impl*/ ) external pure returns (bool) {
return true;
}
function isFork() external pure returns (bool) {
return false;
}
function governanceChainId() external pure returns (uint16) {
return 1;
}
function governanceContract() external pure returns (bytes32) {
return bytes32(0x0000000000000000000000000000000000000000000000000000000000000004);
}
function messageFee() external view returns (uint256) {
return currentMsgFee;
}
function nextSequence(address emitter) external view returns (uint64) {
return sequences[emitter];
}
function verifyVM(VM memory /*vm*/ )
external
pure
returns (bool, /*valid*/ string memory /*reason*/ )
{
revert("unsupported verifyVM in wormhole mock");
}
function verifySignatures(
bytes32, /*hash*/
Signature[] memory, /*signatures*/
GuardianSet memory /*guardianSet*/
) external pure returns (bool, /*valid*/ string memory /*reason*/ ) {
revert("unsupported verifySignatures in wormhole mock");
}
function parseContractUpgrade(bytes memory /*encodedUpgrade*/ )
external
pure
returns (ContractUpgrade memory /*cu*/ )
{
revert("unsupported parseContractUpgrade in wormhole mock");
}
function parseGuardianSetUpgrade(bytes memory /*encodedUpgrade*/ )
external
pure
returns (GuardianSetUpgrade memory /*gsu*/ )
{
revert("unsupported parseGuardianSetUpgrade in wormhole mock");
}
function parseSetMessageFee(bytes memory /*encodedSetMessageFee*/ )
external
pure
returns (SetMessageFee memory /*smf*/ )
{
revert("unsupported parseSetMessageFee in wormhole mock");
}
function parseTransferFees(bytes memory /*encodedTransferFees*/ )
external
pure
returns (TransferFees memory /*tf*/ )
{
revert("unsupported parseTransferFees in wormhole mock");
}
function parseRecoverChainId(bytes memory /*encodedRecoverChainId*/ )
external
pure
returns (RecoverChainId memory /*rci*/ )
{
revert("unsupported parseRecoverChainId in wormhole mock");
}
function submitContractUpgrade(bytes memory /*_vm*/ ) external pure {
revert("unsupported submitContractUpgrade in wormhole mock");
}
function submitSetMessageFee(bytes memory /*_vm*/ ) external pure {
revert("unsupported submitSetMessageFee in wormhole mock");
}
function setMessageFee(uint256 newFee) external {
currentMsgFee = newFee;
}
function submitNewGuardianSet(bytes memory /*_vm*/ ) external pure {
revert("unsupported submitNewGuardianSet in wormhole mock");
}
function submitTransferFees(bytes memory /*_vm*/ ) external pure {
revert("unsupported submitTransferFees in wormhole mock");
}
function submitRecoverChainId(bytes memory /*_vm*/ ) external pure {
revert("unsupported submitRecoverChainId in wormhole mock");
}
}