Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit 7b71615

Browse files
authored
Contract changes (#124)
1 parent 2a204b8 commit 7b71615

File tree

7 files changed

+174
-102
lines changed

7 files changed

+174
-102
lines changed

ethereum/contracts/coreRelayer/CoreRelayer.sol

+33-34
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ contract CoreRelayer is CoreRelayerDelivery {
2727
* If maxTransactionFee >= quoteGas(targetChain, gasLimit, getDefaultRelayProvider()), then as long as 'targetAddress''s receiveWormholeMessage function uses at most 'gasLimit' units of gas (and doesn't revert), the delivery will succeed
2828
* @param receiverValue The amount (denominated in source chain currency) that will be converted to target chain currency and passed into the receiveWormholeMessage endpoint as value.
2929
* If receiverValue >= quoteReceiverValue(targetChain, targetAmount, getDefaultRelayProvider()), then at least 'targetAmount' of targetChain currency will be passed into the 'receiveWormholeFunction' as value.
30-
* @param nonce The messages to be relayed are all of the emitted wormhole messages in the current transaction that have nonce 'nonce'.
30+
* @param messages Array of (emitterAddress, sequence, hash) structs identifying each message to be relayed. For each entry in this array, either the (emitterAddress, sequence) pair must be provided, or the hash must be provided.
3131
*
3232
* This function must be called with a payment of at least maxTransactionFee + receiverValue + one wormhole message fee.
3333
*
@@ -40,13 +40,13 @@ contract CoreRelayer is CoreRelayerDelivery {
4040
bytes32 refundAddress,
4141
uint256 maxTransactionFee,
4242
uint256 receiverValue,
43-
uint32 nonce
43+
IWormholeRelayer.MessageInfo[] memory messages
4444
) external payable returns (uint64 sequence) {
4545
sequence = send(
4646
IWormholeRelayer.Send(
4747
targetChain, targetAddress, refundAddress, maxTransactionFee, receiverValue, getDefaultRelayParams()
4848
),
49-
nonce,
49+
messages,
5050
getDefaultRelayProvider()
5151
);
5252
}
@@ -61,7 +61,7 @@ contract CoreRelayer is CoreRelayerDelivery {
6161
*
6262
*
6363
* @param request The Send request containing info about the targetChain, targetAddress, refundAddress, maxTransactionFee, receiverValue, and relayParameters
64-
* @param nonce The messages to be relayed are all of the emitted wormhole messages in the current transaction that have nonce 'nonce'.
64+
* @param messages Array of (emitterAddress, sequence, hash) structs identifying each message to be relayed. For each entry in this array, either the (emitterAddress, sequence) pair must be provided, or the hash must be provided.
6565
* @param relayProvider The address of (the relay provider you wish to deliver the messages)'s contract on this source chain. This must be a contract that implements IRelayProvider.
6666
* If request.maxTransactionFee >= quoteGas(request.targetChain, gasLimit, relayProvider),
6767
* then as long as 'request.targetAddress''s receiveWormholeMessage function uses at most 'gasLimit' units of gas (and doesn't revert), the delivery will succeed
@@ -73,13 +73,13 @@ contract CoreRelayer is CoreRelayerDelivery {
7373
* @return sequence The sequence number for the emitted wormhole message, which contains encoded delivery instructions meant for your specified relay provider.
7474
* The relay provider will listen for these messages, and then execute the delivery as described.
7575
*/
76-
function send(IWormholeRelayer.Send memory request, uint32 nonce, address relayProvider)
77-
public
78-
payable
79-
returns (uint64 sequence)
80-
{
76+
function send(
77+
IWormholeRelayer.Send memory request,
78+
IWormholeRelayer.MessageInfo[] memory messages,
79+
address relayProvider
80+
) public payable returns (uint64 sequence) {
8181
// call multichainSend with one 'Send' in the requests array
82-
sequence = multichainSend(multichainSendContainer(request, relayProvider), nonce);
82+
sequence = multichainSend(multichainSendContainer(request, relayProvider, messages));
8383
}
8484

8585
/**
@@ -112,7 +112,7 @@ contract CoreRelayer is CoreRelayerDelivery {
112112
* If maxTransactionFee >= quoteGas(targetChain, gasLimit, getDefaultRelayProvider()), then as long as 'targetAddress''s receiveWormholeMessage function uses at most 'gasLimit' units of gas (and doesn't revert), the delivery will succeed
113113
* @param receiverValue The amount (denominated in source chain currency) that will be converted to target chain currency and passed into the receiveWormholeMessage endpoint as value.
114114
* If receiverValue >= quoteReceiverValue(targetChain, targetAmount, getDefaultRelayProvider()), then at least 'targetAmount' of targetChain currency will be passed into the 'receiveWormholeFunction' as value.
115-
* @param nonce The messages to be relayed are all of the emitted wormhole messages in the current transaction that have nonce 'nonce'.
115+
* @param messages Array of (emitterAddress, sequence, hash) structs identifying each message to be relayed. For each entry in this array, either the (emitterAddress, sequence) pair must be provided, or the hash must be provided.
116116
*
117117
* This forward will succeed if (leftover funds from the current delivery that would have been refunded) + (any extra msg.value passed into forward) is at least maxTransactionFee + receiverValue + one wormhole message fee.
118118
*/
@@ -122,13 +122,13 @@ contract CoreRelayer is CoreRelayerDelivery {
122122
bytes32 refundAddress,
123123
uint256 maxTransactionFee,
124124
uint256 receiverValue,
125-
uint32 nonce
125+
IWormholeRelayer.MessageInfo[] memory messages
126126
) external payable {
127127
forward(
128128
IWormholeRelayer.Send(
129129
targetChain, targetAddress, refundAddress, maxTransactionFee, receiverValue, getDefaultRelayParams()
130130
),
131-
nonce,
131+
messages,
132132
getDefaultRelayProvider()
133133
);
134134
}
@@ -156,7 +156,7 @@ contract CoreRelayer is CoreRelayerDelivery {
156156
* @param request The Send request containing info about the targetChain, targetAddress, refundAddress, maxTransactionFee, receiverValue, and relayParameters
157157
* (specifically, the send info that will be used to deliver all of the wormhole messages emitted during the execution of oldTargetAddress's receiveWormholeMessages)
158158
* This forward will succeed if (leftover funds from the current delivery that would have been refunded) + (any extra msg.value passed into forward) is at least maxTransactionFee + receiverValue + one wormhole message fee.
159-
* @param nonce The messages to be relayed are all of the emitted wormhole messages in the current transaction (during execution of oldTargetAddress's receiveWormholeMessages) that have nonce 'nonce'.
159+
* @param messages Array of (emitterAddress, sequence, hash) structs identifying each message to be relayed. For each entry in this array, either the (emitterAddress, sequence) pair must be provided, or the hash must be provided.
160160
* @param relayProvider The address of (the relay provider you wish to deliver the messages)'s contract on this source chain. This must be a contract that implements IRelayProvider.
161161
* If request.maxTransactionFee >= quoteGas(request.targetChain, gasLimit, relayProvider),
162162
* then as long as 'request.targetAddress''s receiveWormholeMessage function uses at most 'gasLimit' units of gas (and doesn't revert), the delivery will succeed
@@ -165,24 +165,27 @@ contract CoreRelayer is CoreRelayerDelivery {
165165
*
166166
* This function must be called with a payment of at least request.maxTransactionFee + request.receiverValue + one wormhole message fee.
167167
*/
168-
function forward(IWormholeRelayer.Send memory request, uint32 nonce, address relayProvider) public payable {
168+
function forward(
169+
IWormholeRelayer.Send memory request,
170+
IWormholeRelayer.MessageInfo[] memory messages,
171+
address relayProvider
172+
) public payable {
169173
// call multichainForward with one 'Send' in the requests array
170-
multichainForward(multichainSendContainer(request, relayProvider), nonce);
174+
multichainForward(multichainSendContainer(request, relayProvider, messages));
171175
}
172176

173177
/**
174178
* @notice The multichainSend function delivers all wormhole messages in the current transaction of nonce 'nonce' to many destinations,
175179
* with each destination specified in a Send struct, describing the desired targetAddress, targetChain, maxTransactionFee, receiverValue, refundAddress, and relayParameters
176180
*
177181
* @param sendContainer The MultichainSend struct, containing the array of Send requests, as well as the desired relayProviderAddress
178-
* @param nonce The messages to be relayed are all of the emitted wormhole messages in the current transaction that have nonce 'nonce'
179182
*
180183
* This function must be called with a payment of at least (one wormhole message fee) + Sum_(i=0 -> sendContainer.requests.length - 1) [sendContainer.requests[i].maxTransactionFee + sendContainer.requests[i].receiverValue].
181184
*
182185
* @return sequence The sequence number for the emitted wormhole message, which contains encoded delivery instructions meant for the default wormhole relay provider.
183186
* The relay provider will listen for these messages, and then execute the delivery as described
184187
*/
185-
function multichainSend(IWormholeRelayer.MultichainSend memory sendContainer, uint32 nonce)
188+
function multichainSend(IWormholeRelayer.MultichainSend memory sendContainer)
186189
public
187190
payable
188191
returns (uint64 sequence)
@@ -193,9 +196,6 @@ contract CoreRelayer is CoreRelayerDelivery {
193196
if (totalFee > msg.value) {
194197
revert IWormholeRelayer.MsgValueTooLow();
195198
}
196-
if (nonce == 0) {
197-
revert IWormholeRelayer.NonceIsZero();
198-
}
199199
if (sendContainer.requests.length == 0) {
200200
revert IWormholeRelayer.MultichainSendEmpty();
201201
}
@@ -219,7 +219,7 @@ contract CoreRelayer is CoreRelayerDelivery {
219219
// Publish a wormhole message indicating to the relay provider (who is watching wormhole messages from this contract)
220220
// to relay the messages from this transaction (of nonce 'nonce') to the specified chains, each with the calculated amount of gas and receiverValue
221221
sequence = wormhole.publishMessage{value: wormholeMessageFee}(
222-
nonce, encodeDeliveryInstructionsContainer(instructionsContainer), relayProvider.getConsistencyLevel()
222+
0, encodeDeliveryInstructionsContainer(instructionsContainer), relayProvider.getConsistencyLevel()
223223
);
224224

225225
// Pay the relay provider
@@ -239,19 +239,15 @@ contract CoreRelayer is CoreRelayerDelivery {
239239
* note: If LEFTOVER_VALUE > NEEDED_VALUE, then the maxTransactionFee of the first request in the array of sends will be incremented by 'LEFTOVER_VALUE - NEEDED_VALUE'
240240
*
241241
* @param sendContainer The MultichainSend struct, containing the array of Send requests, as well as the desired relayProviderAddress
242-
* @param nonce The messages to be relayed are all of the emitted wormhole messages in the current transaction that have nonce 'nonce'
243242
*
244243
*/
245-
function multichainForward(IWormholeRelayer.MultichainSend memory sendContainer, uint32 nonce) public payable {
244+
function multichainForward(IWormholeRelayer.MultichainSend memory sendContainer) public payable {
246245
if (!isContractLocked()) {
247246
revert IWormholeRelayer.NoDeliveryInProgress();
248247
}
249248
if (getForwardInstruction().isValid) {
250249
revert IWormholeRelayer.MultipleForwardsRequested();
251250
}
252-
if (nonce == 0) {
253-
revert IWormholeRelayer.NonceIsZero();
254-
}
255251
if (msg.sender != lockedTargetAddress()) {
256252
revert IWormholeRelayer.ForwardRequestFromWrongAddress();
257253
}
@@ -278,7 +274,6 @@ contract CoreRelayer is CoreRelayerDelivery {
278274
setForwardInstruction(
279275
ForwardInstruction({
280276
container: encodeDeliveryInstructionsContainer(instructionsContainer),
281-
nonce: nonce,
282277
msgValue: msg.value,
283278
totalFee: totalFee,
284279
sender: msg.sender,
@@ -431,13 +426,17 @@ contract CoreRelayer is CoreRelayerDelivery {
431426
}
432427

433428
// Helper to put one Send struct into a MultichainSend struct
434-
function multichainSendContainer(IWormholeRelayer.Send memory request, address relayProvider)
435-
internal
436-
pure
437-
returns (IWormholeRelayer.MultichainSend memory container)
438-
{
429+
function multichainSendContainer(
430+
IWormholeRelayer.Send memory request,
431+
address relayProvider,
432+
IWormholeRelayer.MessageInfo[] memory messages
433+
) internal pure returns (IWormholeRelayer.MultichainSend memory container) {
439434
IWormholeRelayer.Send[] memory requests = new IWormholeRelayer.Send[](1);
440435
requests[0] = request;
441-
container = IWormholeRelayer.MultichainSend({relayProviderAddress: relayProvider, requests: requests});
436+
container = IWormholeRelayer.MultichainSend({
437+
relayProviderAddress: relayProvider,
438+
requests: requests,
439+
messages: messages
440+
});
442441
}
443442
}

ethereum/contracts/coreRelayer/CoreRelayerDelivery.sol

+41-9
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ contract CoreRelayerDelivery is CoreRelayerGovernance {
7474
// Publishes the DeliveryInstruction, with a 'sufficientlyFunded' flag indicating whether the forward had enough funds
7575
container.sufficientlyFunded = forwardIsFunded;
7676
wormhole.publishMessage{value: wormholeMessageFee}(
77-
forwardInstruction.nonce,
78-
encodeDeliveryInstructionsContainer(container),
79-
relayProvider.getConsistencyLevel()
77+
0, encodeDeliveryInstructionsContainer(container), relayProvider.getConsistencyLevel()
8078
);
8179

8280
// if funded, pay out reward to provider. Otherwise, the delivery code will handle sending a refund.
@@ -120,6 +118,7 @@ contract CoreRelayerDelivery is CoreRelayerGovernance {
120118
if (isContractLocked()) {
121119
revert IDelivery.ReentrantCall();
122120
}
121+
123122
setContractLock(true);
124123
setLockedTargetAddress(fromWormholeFormat(internalInstruction.targetAddress));
125124

@@ -263,19 +262,20 @@ contract CoreRelayerDelivery is CoreRelayerGovernance {
263262

264263
// Obtain the original delivery VAA
265264
IWormhole.VM memory originalDeliveryVM;
266-
(originalDeliveryVM, valid, reason) =
267-
wormhole.parseAndVerifyVM(targetParams.sourceEncodedVMs[redeliveryInstruction.deliveryIndex]);
265+
(originalDeliveryVM, valid, reason) = wormhole.parseAndVerifyVM(targetParams.originalEncodedDeliveryVAA);
268266

269267
// Check that the original delivery VAA has a valid signature
270268
if (!valid) {
271-
revert IDelivery.InvalidVaa(redeliveryInstruction.deliveryIndex, reason);
269+
revert IDelivery.InvalidDeliveryVaa(reason);
272270
}
273271

274272
// Check that the original delivery VAA's emitter is one of these CoreRelayer contracts
275273
if (!verifyRelayerVM(originalDeliveryVM)) {
276-
revert IDelivery.InvalidEmitterInOriginalDeliveryVM(redeliveryInstruction.deliveryIndex);
274+
revert IDelivery.InvalidEmitterInOriginalDeliveryVM();
277275
}
278276

277+
checkMessageInfosWithVAAs(redeliveryInstruction.messages, targetParams.sourceEncodedVMs);
278+
279279
// Obtain the specific old instruction that was originally executed (and is meant to be re-executed with new parameters)
280280
// specifying the the target chain (must be this chain), target address, refund address, old maximum refund (in this chain's currency),
281281
// old receiverValue (in this chain's currency), old upper bound on gas, and the permissioned address allowed to execute this instruction
@@ -400,11 +400,11 @@ contract CoreRelayerDelivery is CoreRelayerGovernance {
400400

401401
// Obtain the delivery VAA
402402
(IWormhole.VM memory deliveryVM, bool valid, string memory reason) =
403-
wormhole.parseAndVerifyVM(targetParams.encodedVMs[targetParams.deliveryIndex]);
403+
wormhole.parseAndVerifyVM(targetParams.encodedDeliveryVAA);
404404

405405
// Check that the delivery VAA has a valid signature
406406
if (!valid) {
407-
revert IDelivery.InvalidVaa(targetParams.deliveryIndex, reason);
407+
revert IDelivery.InvalidDeliveryVaa(reason);
408408
}
409409

410410
// Check that the delivery VAA's emitter is one of these CoreRelayer contracts
@@ -444,6 +444,8 @@ contract CoreRelayerDelivery is CoreRelayerGovernance {
444444
revert IDelivery.TargetChainIsNotThisChain(deliveryInstruction.targetChain);
445445
}
446446

447+
checkMessageInfosWithVAAs(container.messages, targetParams.encodedVMs);
448+
447449
_executeDelivery(
448450
deliveryInstruction,
449451
targetParams.encodedVMs,
@@ -456,6 +458,36 @@ contract CoreRelayerDelivery is CoreRelayerGovernance {
456458
);
457459
}
458460

461+
function checkMessageInfosWithVAAs(IWormholeRelayer.MessageInfo[] memory messageInfos, bytes[] memory vaas)
462+
internal
463+
view
464+
{
465+
if (messageInfos.length != vaas.length) {
466+
revert IDelivery.MessageInfosLengthDoesNotMatchVaasLength();
467+
}
468+
for (uint8 i = 0; i < messageInfos.length; i++) {
469+
if (!messageInfoMatchesVAA(messageInfos[i], vaas[i])) {
470+
revert IDelivery.MessageInfosDoNotMatchVaas(i);
471+
}
472+
}
473+
}
474+
475+
function messageInfoMatchesVAA(IWormholeRelayer.MessageInfo memory messageInfo, bytes memory vaa)
476+
internal
477+
view
478+
returns (bool)
479+
{
480+
IWormhole.VM memory parsedVaa = wormhole().parseVM(vaa);
481+
bool emitterAddressMatch = messageInfo.emitterAddress == parsedVaa.emitterAddress;
482+
bool sequenceMatch = (messageInfo.sequence == parsedVaa.sequence);
483+
bool emitterAddressAndSequenceEmpty =
484+
(messageInfo.emitterAddress == bytes32(0x0)) && (messageInfo.sequence == 0);
485+
bool vaaHashMatch = (messageInfo.vaaHash == parsedVaa.hash);
486+
bool vaaHashEmpty = messageInfo.vaaHash == bytes32(0x0);
487+
return (emitterAddressMatch && sequenceMatch && (vaaHashEmpty || vaaHashMatch))
488+
|| (emitterAddressAndSequenceEmpty && vaaHashMatch);
489+
}
490+
459491
/**
460492
* @notice Helper function that converts an EVM address to wormhole format
461493
* @param addr (EVM 20-byte address)

0 commit comments

Comments
 (0)