Redelivery fixes (#61)

* smart contract changes for redelivery

* Tests pass for new Redelivery interface

* remove console logs

* forge fmt

* forwarding interface fix

* Remove the rolloverChain parameter from requestForward

Co-authored-by: chase-45 <chasemoran45@gmail.com>
This commit is contained in:
derpy-duck 2023-01-26 15:10:44 -05:00 committed by GitHub
parent 5a3ff82c43
commit 673542854d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 55 deletions

View File

@ -39,14 +39,14 @@ contract CoreRelayer is CoreRelayerGovernance {
error RolloverChainNotIncluded(); // Rollover chain was not included in the forwarding request
error ChainNotFoundInDeliveryRequests(uint16 chainId); // Required chain not found in the delivery requests
error ReentrantCall();
error InvalidEmitterInOriginalDeliveryVM();
error InvalidEmitterInOriginalDeliveryVM(uint8 index);
error InvalidRedeliveryVM(string reason);
error InvalidEmitterInRedeliveryVM();
error MismatchingRelayProvidersInRedelivery(); // The same relay provider must be specified when doing a single VAA redeliver
error ProviderAddressIsNotSender(); // msg.sender must be the provider
error RedeliveryRequestDoesNotTargetThisChain();
error OriginalDeliveryRequestDidNotTargetThisChain();
error InvalidVaa(uint256 deliveryIndex); // Invalid VAA at delivery index
error InvalidVaa(uint8 index);
error InvalidEmitter();
error DeliveryRequestNotSufficientlyFunded(); // This delivery request was not sufficiently funded, and must request redelivery
error UnexpectedRelayer(); // Specified relayer is not the relayer delivering the message
@ -68,15 +68,12 @@ contract CoreRelayer is CoreRelayerGovernance {
return requestMultidelivery(container, nonce);
}
function requestForward(DeliveryRequest memory request, uint16 rolloverChain, uint32 nonce, IRelayProvider provider)
public
payable
{
function requestForward(DeliveryRequest memory request, uint32 nonce, IRelayProvider provider) public payable {
DeliveryRequest[] memory requests = new DeliveryRequest[](1);
requests[0] = request;
DeliveryRequestsContainer memory container =
DeliveryRequestsContainer({payloadId: 1, relayProviderAddress: address(provider), requests: requests});
return requestMultiforward(container, rolloverChain, nonce);
return requestMultiforward(container, request.targetChain, nonce);
}
//REVISE consider adding requestMultiRedeliveryByTxHash
@ -539,20 +536,9 @@ contract CoreRelayer is CoreRelayerGovernance {
//cache wormhole
IWormhole wormhole = wormhole();
//validate the original delivery VM
(IWormhole.VM memory originalDeliveryVM, bool valid, string memory reason) =
wormhole.parseAndVerifyVM(targetParams.sourceEncodedVMs[targetParams.deliveryIndex]);
if (!valid) {
revert InvalidVaa(targetParams.deliveryIndex);
}
if (!verifyRelayerVM(originalDeliveryVM)) {
// Original Delivery VM has a invalid emitter
revert InvalidEmitterInOriginalDeliveryVM();
}
//validate the redelivery VM
IWormhole.VM memory redeliveryVM;
(redeliveryVM, valid, reason) = wormhole.parseAndVerifyVM(targetParams.redeliveryVM);
(IWormhole.VM memory redeliveryVM, bool valid, string memory reason) =
wormhole.parseAndVerifyVM(targetParams.redeliveryVM);
if (!valid) {
revert InvalidRedeliveryVM(reason);
}
@ -561,10 +547,26 @@ contract CoreRelayer is CoreRelayerGovernance {
revert InvalidEmitterInRedeliveryVM();
}
RedeliveryByTxHashInstruction memory redeliveryInstruction =
decodeRedeliveryByTxHashInstruction(redeliveryVM.payload);
//validate the original delivery VM
IWormhole.VM memory originalDeliveryVM;
(originalDeliveryVM, valid, reason) =
wormhole.parseAndVerifyVM(targetParams.sourceEncodedVMs[redeliveryInstruction.deliveryIndex]);
if (!valid) {
revert InvalidVaa(redeliveryInstruction.deliveryIndex);
}
if (!verifyRelayerVM(originalDeliveryVM)) {
// Original Delivery VM has a invalid emitter
revert InvalidEmitterInOriginalDeliveryVM(redeliveryInstruction.deliveryIndex);
}
DeliveryInstruction memory instruction;
(instruction, valid) = validateRedeliverySingle(
decodeRedeliveryByTxHashInstruction(redeliveryVM.payload),
decodeDeliveryInstructionsContainer(originalDeliveryVM.payload).instructions[targetParams.multisendIndex]
redeliveryInstruction,
decodeDeliveryInstructionsContainer(originalDeliveryVM.payload).instructions[redeliveryInstruction
.multisendIndex]
);
if (!valid) {
@ -892,7 +894,9 @@ contract CoreRelayer is CoreRelayerGovernance {
uint16(request.sourceChain),
bytes32(request.sourceTxHash),
uint32(request.sourceNonce),
uint16(request.targetChain)
uint16(request.targetChain),
uint8(request.deliveryIndex),
uint8(request.multisendIndex)
);
encoded = abi.encodePacked(
encoded,

View File

@ -37,6 +37,12 @@ contract CoreRelayerMessages is CoreRelayerStructs, CoreRelayerGetters {
instruction.targetChain = encoded.toUint16(index);
index += 2;
instruction.deliveryIndex = encoded.toUint8(index);
index += 1;
instruction.multisendIndex = encoded.toUint8(index);
index += 1;
instruction.newMaximumRefundTarget = encoded.toUint256(index);
index += 32;

View File

@ -40,8 +40,6 @@ abstract contract CoreRelayerStructs {
struct TargetRedeliveryByTxHashParamsSingle {
bytes redeliveryVM;
bytes[] sourceEncodedVMs;
uint8 deliveryIndex;
uint8 multisendIndex;
address payable relayerRefundAddress;
}
@ -59,6 +57,8 @@ abstract contract CoreRelayerStructs {
bytes32 sourceTxHash;
uint32 sourceNonce;
uint16 targetChain;
uint8 deliveryIndex;
uint8 multisendIndex;
uint256 newComputeBudget;
uint256 newApplicationBudget;
bytes newRelayParameters;
@ -99,6 +99,8 @@ abstract contract CoreRelayerStructs {
bytes32 sourceTxHash;
uint32 sourceNonce;
uint16 targetChain;
uint8 deliveryIndex;
uint8 multisendIndex;
uint256 newMaximumRefundTarget;
uint256 newApplicationBudgetTarget;
ExecutionParameters executionParameters;

View File

@ -14,9 +14,7 @@ interface ICoreRelayer {
payable
returns (uint64 sequence);
function requestForward(DeliveryRequest memory request, uint16 rolloverChain, uint32 nonce, IRelayProvider provider)
external
payable;
function requestForward(DeliveryRequest memory request, uint32 nonce, IRelayProvider provider) external payable;
function requestRedelivery(RedeliveryByTxHashRequest memory request, uint32 nonce, IRelayProvider provider)
external
@ -108,6 +106,8 @@ interface ICoreRelayer {
bytes32 sourceTxHash;
uint32 sourceNonce;
uint16 targetChain;
uint8 deliveryIndex;
uint8 multisendIndex;
uint256 newComputeBudget;
uint256 newApplicationBudget;
bytes newRelayParameters;
@ -142,8 +142,6 @@ interface ICoreRelayer {
struct TargetRedeliveryByTxHashParamsSingle {
bytes redeliveryVM;
bytes[] sourceEncodedVMs;
uint8 deliveryIndex;
uint8 multisendIndex;
address payable relayerRefundAddress;
}
@ -172,6 +170,8 @@ interface ICoreRelayer {
bytes32 sourceTxHash;
uint32 sourceNonce;
uint16 targetChain;
uint8 deliveryIndex;
uint8 multisendIndex;
uint256 newMaximumRefundTarget;
uint256 newApplicationBudgetTarget;
ExecutionParameters executionParameters;

View File

@ -112,7 +112,7 @@ contract MockRelayerIntegration is IWormholeReceiver {
relayParameters: relayer.getDefaultRelayParams()
});
relayer.requestForward(request, parsed.emitterChainId, parsed.nonce, relayer.getDefaultRelayProvider());
relayer.requestForward(request, parsed.nonce, relayer.getDefaultRelayProvider());
}
unchecked {

View File

@ -510,6 +510,8 @@ contract TestCoreRelayer is Test {
sourceTxHash: deliveryVaaHash,
sourceNonce: 1,
targetChain: setup.targetChainId,
deliveryIndex: uint8(1),
multisendIndex: uint8(0),
newComputeBudget: payment - setup.source.wormhole.messageFee(),
newApplicationBudget: newApplicationBudgetFee,
newRelayParameters: setup.source.coreRelayer.getDefaultRelayParams()
@ -565,6 +567,8 @@ contract TestCoreRelayer is Test {
sourceTxHash: deliveryVaaHash,
sourceNonce: 1,
targetChain: setup.targetChainId,
deliveryIndex: 1,
multisendIndex: 0,
newComputeBudget: payment - setup.source.wormhole.messageFee(),
newApplicationBudget: newApplicationBudgetFee,
newRelayParameters: setup.source.coreRelayer.getDefaultRelayParams()
@ -587,6 +591,8 @@ contract TestCoreRelayer is Test {
sourceTxHash: deliveryVaaHash,
sourceNonce: 1,
targetChain: setup.targetChainId,
deliveryIndex: 1,
multisendIndex: 0,
newComputeBudget: payment - setup.source.wormhole.messageFee(),
newApplicationBudget: newApplicationBudgetFee - 1,
newRelayParameters: setup.source.coreRelayer.getDefaultRelayParams()
@ -730,6 +736,8 @@ contract TestCoreRelayer is Test {
sourceTxHash: stack.deliveryVaaHash,
sourceNonce: 1,
targetChain: setup.targetChainId,
deliveryIndex: 1,
multisendIndex: 0,
newComputeBudget: stack.payment - setup.source.wormhole.messageFee(),
newApplicationBudget: 0,
newRelayParameters: setup.source.coreRelayer.getDefaultRelayParams()
@ -750,7 +758,7 @@ contract TestCoreRelayer is Test {
stack.entries[0], setup.sourceChainId, address(setup.source.coreRelayer)
);
stack.originalDelivery = pastDeliveries[stack.deliveryVaaHash];
stack.originalDelivery = pastDeliveries[keccak256(abi.encodePacked(stack.deliveryVaaHash, uint8(0)))];
bytes memory fakeVM = abi.encodePacked(stack.originalDelivery.encodedVMs[1]);
bytes memory correctVM = abi.encodePacked(stack.originalDelivery.encodedVMs[1]);
@ -760,8 +768,6 @@ contract TestCoreRelayer is Test {
stack.package = ICoreRelayer.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: stack.redeliveryVM,
sourceEncodedVMs: stack.originalDelivery.encodedVMs,
deliveryIndex: stack.originalDelivery.deliveryIndex,
multisendIndex: stack.originalDelivery.multisendIndex,
relayerRefundAddress: payable(setup.target.relayer)
});
@ -772,7 +778,7 @@ contract TestCoreRelayer is Test {
+ setup.target.wormhole.messageFee();
vm.prank(setup.target.relayer);
vm.expectRevert(abi.encodeWithSignature("InvalidVaa(uint256)", 1));
vm.expectRevert(abi.encodeWithSignature("InvalidVaa(uint8)", 1));
setup.target.coreRelayer.redeliverSingle{value: stack.budget}(stack.package);
stack.originalDelivery.encodedVMs[1] = stack.originalDelivery.encodedVMs[0];
@ -780,13 +786,11 @@ contract TestCoreRelayer is Test {
stack.package = ICoreRelayer.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: stack.redeliveryVM,
sourceEncodedVMs: stack.originalDelivery.encodedVMs,
deliveryIndex: stack.originalDelivery.deliveryIndex,
multisendIndex: stack.originalDelivery.multisendIndex,
relayerRefundAddress: payable(setup.target.relayer)
});
vm.prank(setup.target.relayer);
vm.expectRevert(abi.encodeWithSignature("InvalidEmitterInOriginalDeliveryVM()"));
vm.expectRevert(abi.encodeWithSignature("InvalidEmitterInOriginalDeliveryVM(uint8)", 1));
setup.target.coreRelayer.redeliverSingle{value: stack.budget}(stack.package);
stack.originalDelivery.encodedVMs[1] = correctVM;
@ -794,8 +798,6 @@ contract TestCoreRelayer is Test {
stack.package = ICoreRelayer.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: stack.redeliveryVM,
sourceEncodedVMs: stack.originalDelivery.encodedVMs,
deliveryIndex: stack.originalDelivery.deliveryIndex,
multisendIndex: stack.originalDelivery.multisendIndex,
relayerRefundAddress: payable(setup.target.relayer)
});
@ -806,8 +808,6 @@ contract TestCoreRelayer is Test {
stack.package = ICoreRelayer.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: fakeVM,
sourceEncodedVMs: stack.originalDelivery.encodedVMs,
deliveryIndex: stack.originalDelivery.deliveryIndex,
multisendIndex: stack.originalDelivery.multisendIndex,
relayerRefundAddress: payable(setup.target.relayer)
});
@ -821,8 +821,6 @@ contract TestCoreRelayer is Test {
stack.package = ICoreRelayer.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: fakeVM,
sourceEncodedVMs: stack.originalDelivery.encodedVMs,
deliveryIndex: stack.originalDelivery.deliveryIndex,
multisendIndex: stack.originalDelivery.multisendIndex,
relayerRefundAddress: payable(setup.target.relayer)
});
@ -846,8 +844,6 @@ contract TestCoreRelayer is Test {
stack.package = ICoreRelayer.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: fakeVM,
sourceEncodedVMs: stack.originalDelivery.encodedVMs,
deliveryIndex: stack.originalDelivery.deliveryIndex,
multisendIndex: stack.originalDelivery.multisendIndex,
relayerRefundAddress: payable(setup.target.relayer)
});
@ -914,8 +910,6 @@ contract TestCoreRelayer is Test {
stack.package = ICoreRelayer.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: correctVM,
sourceEncodedVMs: stack.originalDelivery.encodedVMs,
deliveryIndex: stack.originalDelivery.deliveryIndex,
multisendIndex: stack.originalDelivery.multisendIndex,
relayerRefundAddress: payable(setup.target.relayer)
});
@ -1050,7 +1044,7 @@ contract TestCoreRelayer is Test {
+ setup.target.wormhole.messageFee();
vm.prank(setup.target.relayer);
vm.expectRevert(abi.encodeWithSignature("InvalidVaa(uint256)", 1));
vm.expectRevert(abi.encodeWithSignature("InvalidVaa(uint8)", 1));
setup.target.coreRelayer.deliverSingle{value: stack.budget}(stack.package);
stack.encodedVMs[1] = stack.encodedVMs[0];
@ -1253,26 +1247,22 @@ contract TestCoreRelayer is Test {
uint256 wormholeFee = map[targetChain].wormhole.messageFee();
vm.prank(map[targetChain].relayer);
map[targetChain].coreRelayer.deliverSingle{value: (budget + wormholeFee)}(package);
pastDeliveries[parsed.hash] = package;
pastDeliveries[keccak256(abi.encodePacked(parsed.hash, k))] = package;
}
} else if (payloadId == 2) {
ICoreRelayer.RedeliveryByTxHashInstruction memory instruction =
contracts.coreRelayer.getRedeliveryByTxHashInstruction(parsed.payload);
ICoreRelayer.TargetDeliveryParametersSingle memory originalDelivery =
pastDeliveries[instruction.sourceTxHash];
pastDeliveries[keccak256(abi.encodePacked(instruction.sourceTxHash, instruction.multisendIndex))];
uint16 targetChain = instruction.targetChain;
uint256 budget = instruction.newMaximumRefundTarget + instruction.newApplicationBudgetTarget
+ map[targetChain].wormhole.messageFee();
ICoreRelayer.TargetRedeliveryByTxHashParamsSingle memory package = ICoreRelayer
.TargetRedeliveryByTxHashParamsSingle({
redeliveryVM: encodedVM,
sourceEncodedVMs: originalDelivery.encodedVMs,
deliveryIndex: originalDelivery.deliveryIndex,
multisendIndex: originalDelivery.multisendIndex,
relayerRefundAddress: payable(map[targetChain].relayer)
});
vm.prank(map[targetChain].relayer);
map[targetChain].coreRelayer.redeliverSingle{value: budget}(package);
}