Skip to content

Commit

Permalink
evm: separate manager execution cost
Browse files Browse the repository at this point in the history
  • Loading branch information
gator-boi committed Mar 21, 2024
1 parent 3a3ed59 commit 8b00d62
Show file tree
Hide file tree
Showing 17 changed files with 557 additions and 314 deletions.
17 changes: 16 additions & 1 deletion evm/src/NativeTransfers/NonFungibleNttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ contract NonFungibleNttManager is INonFungibleNttManager, ManagerBase {

// =============== External Interface ==================================================

function quoteDeliveryPrice(
uint16 recipientChain,
bytes memory transceiverInstructions
) public view virtual returns (uint256[] memory, uint256) {
address[] memory enabledTransceivers = _getEnabledTransceiversStorage();

TransceiverStructs.TransceiverInstruction[] memory instructions = TransceiverStructs
.parseTransceiverInstructions(transceiverInstructions, enabledTransceivers.length);

// TODO: Compute execution cost here.
return _quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers, 0);
}

function transfer(
uint256[] memory tokenIds,
uint16 recipientChain,
Expand Down Expand Up @@ -213,12 +226,13 @@ contract NonFungibleNttManager is INonFungibleNttManager, ManagerBase {
}

// Fetch quotes and prepare for transfer.
// TODO: compute execution cost here.
(
address[] memory enabledTransceivers,
TransceiverStructs.TransceiverInstruction[] memory instructions,
uint256[] memory priceQuotes,
uint256 totalPriceQuote
) = _prepareForTransfer(recipientChain, transceiverInstructions);
) = _prepareForTransfer(recipientChain, transceiverInstructions, 0);

uint64 sequence = _useMessageSequence();

Expand All @@ -242,6 +256,7 @@ contract NonFungibleNttManager is INonFungibleNttManager, ManagerBase {
recipientChain,
_getPeersStorage()[recipientChain].peerAddress,
priceQuotes,
0,
instructions,
enabledTransceivers,
encodedNttManagerPayload
Expand Down
17 changes: 16 additions & 1 deletion evm/src/NativeTransfers/NttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,19 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {

// ==================== External Interface ===============================================

/// @inheritdoc INttManager
function quoteDeliveryPrice(
uint16 recipientChain,
bytes memory transceiverInstructions
) public view virtual returns (uint256[] memory, uint256) {
address[] memory enabledTransceivers = _getEnabledTransceiversStorage();

TransceiverStructs.TransceiverInstruction[] memory instructions = TransceiverStructs
.parseTransceiverInstructions(transceiverInstructions, enabledTransceivers.length);

return _quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers, 0);
}

/// @inheritdoc INttManager
function transfer(
uint256 amount,
Expand Down Expand Up @@ -394,12 +407,13 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
address sender,
bytes memory transceiverInstructions
) internal returns (uint64 msgSequence) {
// TODO: compute execution cost here.
(
address[] memory enabledTransceivers,
TransceiverStructs.TransceiverInstruction[] memory instructions,
uint256[] memory priceQuotes,
uint256 totalPriceQuote
) = _prepareForTransfer(recipientChain, transceiverInstructions);
) = _prepareForTransfer(recipientChain, transceiverInstructions, 0);

// push it on the stack again to avoid a stack too deep error
uint64 seq = sequence;
Expand All @@ -422,6 +436,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
recipientChain,
_getPeersStorage()[recipientChain].peerAddress,
priceQuotes,
0,
instructions,
enabledTransceivers,
encodedNttManagerPayload
Expand Down
23 changes: 12 additions & 11 deletions evm/src/NativeTransfers/shared/ManagerBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ abstract contract ManagerBase is
}
}

// =============== External Logic =============================================================
// =============== Internal Logic ===========================================================

/// @inheritdoc IManagerBase
function quoteDeliveryPrice(
function _quoteDeliveryPrice(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,
address[] memory enabledTransceivers
) public view returns (uint256[] memory, uint256) {
address[] memory enabledTransceivers,
uint256 managerExecutionCost
) internal view returns (uint256[] memory, uint256) {
uint256 numEnabledTransceivers = enabledTransceivers.length;
mapping(address => TransceiverInfo) storage transceiverInfos = _getTransceiverInfosStorage();

Expand All @@ -101,16 +101,14 @@ abstract contract ManagerBase is
address transceiverAddr = enabledTransceivers[i];
uint8 registeredTransceiverIndex = transceiverInfos[transceiverAddr].index;
uint256 transceiverPriceQuote = ITransceiver(transceiverAddr).quoteDeliveryPrice(
recipientChain, transceiverInstructions[registeredTransceiverIndex]
recipientChain, transceiverInstructions[registeredTransceiverIndex], managerExecutionCost
);
priceQuotes[i] = transceiverPriceQuote;
totalPriceQuote += transceiverPriceQuote;
}
return (priceQuotes, totalPriceQuote);
}

// =============== Internal Logic ===========================================================

function _recordTransceiverAttestation(
uint16 sourceChainId,
TransceiverStructs.ManagerMessage memory payload
Expand Down Expand Up @@ -160,6 +158,7 @@ abstract contract ManagerBase is
uint16 recipientChain,
bytes32 peerAddress,
uint256[] memory priceQuotes,
uint256 managerExecutionCost,
TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,
address[] memory enabledTransceivers,
bytes memory ManagerMessage
Expand All @@ -179,14 +178,16 @@ abstract contract ManagerBase is
recipientChain,
transceiverInstructions[transceiverInfos[transceiverAddr].index],
ManagerMessage,
peerAddress
peerAddress,
managerExecutionCost
);
}
}

function _prepareForTransfer(
uint16 recipientChain,
bytes memory transceiverInstructions
bytes memory transceiverInstructions,
uint256 managerExecutionCost
)
internal
returns (
Expand Down Expand Up @@ -214,7 +215,7 @@ abstract contract ManagerBase is
}

(uint256[] memory priceQuotes, uint256 totalPriceQuote) =
quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers);
_quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers, managerExecutionCost);
{
// check up front that msg.value will cover the delivery price
if (msg.value < totalPriceQuote) {
Expand Down
13 changes: 9 additions & 4 deletions evm/src/Transceiver/Transceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,24 @@ abstract contract Transceiver is
/// @inheritdoc ITransceiver
function quoteDeliveryPrice(
uint16 targetChain,
TransceiverStructs.TransceiverInstruction memory instruction
TransceiverStructs.TransceiverInstruction memory instruction,
uint256 managerExecutionCost
) external view returns (uint256) {
return _quoteDeliveryPrice(targetChain, instruction);
return _quoteDeliveryPrice(targetChain, instruction, managerExecutionCost);
}

/// @inheritdoc ITransceiver
function sendMessage(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction memory instruction,
bytes memory ManagerMessage,
bytes32 recipientNttManagerAddress
bytes32 recipientNttManagerAddress,
uint256 managerExecutionCost
) external payable nonReentrant onlyNttManager {
_sendMessage(
recipientChain,
msg.value,
managerExecutionCost,
msg.sender,
recipientNttManagerAddress,
instruction,
Expand All @@ -122,6 +125,7 @@ abstract contract Transceiver is
function _sendMessage(
uint16 recipientChain,
uint256 deliveryPayment,
uint256 managerExecutionCost,
address caller,
bytes32 recipientNttManagerAddress,
TransceiverStructs.TransceiverInstruction memory transceiverInstruction,
Expand All @@ -147,6 +151,7 @@ abstract contract Transceiver is

function _quoteDeliveryPrice(
uint16 targetChain,
TransceiverStructs.TransceiverInstruction memory transceiverInstruction
TransceiverStructs.TransceiverInstruction memory transceiverInstruction,
uint256 managerExecutionCost
) internal view virtual returns (uint256);
}
14 changes: 9 additions & 5 deletions evm/src/Transceiver/WormholeTransceiver/WormholeTransceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ contract WormholeTransceiver is
address wormholeRelayerAddr,
address specialRelayerAddr,
uint8 _consistencyLevel,
uint256 _gasLimit,
uint256 _attestationGasLimit,
IWormholeTransceiverState.ManagerType _managerType
)
WormholeTransceiverState(
Expand All @@ -48,7 +48,7 @@ contract WormholeTransceiver is
wormholeRelayerAddr,
specialRelayerAddr,
_consistencyLevel,
_gasLimit,
_attestationGasLimit,
_managerType
)
{}
Expand Down Expand Up @@ -148,7 +148,8 @@ contract WormholeTransceiver is

function _quoteDeliveryPrice(
uint16 targetChain,
TransceiverStructs.TransceiverInstruction memory instruction
TransceiverStructs.TransceiverInstruction memory instruction,
uint256 managerExecutionCost
) internal view override returns (uint256 nativePriceQuote) {
// Check the special instruction up front to see if we should skip sending via a relayer
WormholeTransceiverInstruction memory weIns =
Expand All @@ -163,7 +164,9 @@ contract WormholeTransceiver is
}

if (_shouldRelayViaStandardRelaying(targetChain)) {
(uint256 cost,) = wormholeRelayer.quoteEVMDeliveryPrice(targetChain, 0, gasLimit);
(uint256 cost,) = wormholeRelayer.quoteEVMDeliveryPrice(
targetChain, 0, attestationGasLimit + managerExecutionCost
);
return cost;
} else if (isSpecialRelayingEnabled(targetChain)) {
uint256 cost = specialRelayer.quoteDeliveryPrice(getNttManagerToken(), targetChain, 0);
Expand All @@ -176,6 +179,7 @@ contract WormholeTransceiver is
function _sendMessage(
uint16 recipientChain,
uint256 deliveryPayment,
uint256 managerExecutionCost,
address caller,
bytes32 recipientNttManagerAddress,
TransceiverStructs.TransceiverInstruction memory instruction,
Expand Down Expand Up @@ -206,7 +210,7 @@ contract WormholeTransceiver is
fromWormholeFormat(getWormholePeer(recipientChain)),
encodedTransceiverPayload,
0,
gasLimit
attestationGasLimit + managerExecutionCost
);

emit RelayingInfo(uint8(RelayingType.Standard), deliveryPayment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract contract WormholeTransceiverState is IWormholeTransceiverState, Transce
IWormholeRelayer public immutable wormholeRelayer;
ISpecialRelayer public immutable specialRelayer;
uint256 immutable wormholeTransceiver_evmChainId;
uint256 public immutable gasLimit;
uint256 public immutable attestationGasLimit;
ManagerType public immutable managerType;

// ==================== Constants ================================================
Expand All @@ -58,15 +58,15 @@ abstract contract WormholeTransceiverState is IWormholeTransceiverState, Transce
address wormholeRelayerAddr,
address specialRelayerAddr,
uint8 _consistencyLevel,
uint256 _gasLimit,
uint256 _attestationGasLimit,
ManagerType _managerType
) Transceiver(nttManager) {
wormhole = IWormhole(wormholeCoreBridge);
wormholeRelayer = IWormholeRelayer(wormholeRelayerAddr);
specialRelayer = ISpecialRelayer(specialRelayerAddr);
wormholeTransceiver_evmChainId = block.chainid;
consistencyLevel = _consistencyLevel;
gasLimit = _gasLimit;
attestationGasLimit = _attestationGasLimit;
managerType = _managerType;
}

Expand Down
9 changes: 0 additions & 9 deletions evm/src/interfaces/IManagerBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,6 @@ interface IManagerBase {
/// @param chainId The target chain id
error PeerNotRegistered(uint16 chainId);

/// @notice Fetch the delivery price for a given recipient chain transfer.
/// @param recipientChain The chain ID of the transfer destination.
/// @return - The delivery prices associated with each endpoint and the total price.
function quoteDeliveryPrice(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,
address[] memory enabledTransceivers
) external view returns (uint256[] memory, uint256);

/// @notice Sets the threshold for the number of attestations required for a message
/// to be considered valid.
/// @param threshold The new threshold.
Expand Down
9 changes: 9 additions & 0 deletions evm/src/interfaces/INonFungibleNttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ interface INonFungibleNttManager is IManagerBase {

function getMaxBatchSize() external pure returns (uint8);

/// @notice Fetch the delivery price for a given recipient chain transfer.
/// @param recipientChain The chain ID of the transfer destination.
/// @param transceiverInstructions The transceiver specific instructions for quoting and sending
/// @return - The delivery prices associated with each enabled endpoint and the total price.
function quoteDeliveryPrice(
uint16 recipientChain,
bytes memory transceiverInstructions
) external view returns (uint256[] memory, uint256);

function transfer(
uint256[] memory tokenIds,
uint16 recipientChain,
Expand Down
9 changes: 9 additions & 0 deletions evm/src/interfaces/INttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ interface INttManager is IManagerBase {
/// @notice Peer cannot have zero decimals.
error InvalidPeerDecimals();

/// @notice Fetch the delivery price for a given recipient chain transfer.
/// @param recipientChain The chain ID of the transfer destination.
/// @param transceiverInstructions The transceiver specific instructions for quoting and sending
/// @return - The delivery prices associated with each enabled endpoint and the total price.
function quoteDeliveryPrice(
uint16 recipientChain,
bytes memory transceiverInstructions
) external view returns (uint256[] memory, uint256);

/// @notice Transfer a given amount to a recipient on a given chain. This function is called
/// by the user to send the token cross-chain. This function will either lock or burn the
/// sender's tokens. Finally, this function will call into registered `Endpoint` contracts
Expand Down
12 changes: 10 additions & 2 deletions evm/src/interfaces/ITransceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,31 @@ interface ITransceiver {
/// @param recipientChain The Wormhole chain ID of the target chain.
/// @param instruction An additional Instruction provided by the Transceiver to be
/// executed on the recipient chain.
/// @param managerExecutionCost The cost of executing the manager message on the recipient chain.
/// Depending on the target chain, the units may vary. For example, on Ethereum, this is
/// the additional gas cost (in excess of the attestation cost) for executing the manager message.
/// @return deliveryPrice The cost of delivering a message to the recipient chain,
/// in this chain's native token.
function quoteDeliveryPrice(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction memory instruction
TransceiverStructs.TransceiverInstruction memory instruction,
uint256 managerExecutionCost
) external view returns (uint256);

/// @dev Send a message to another chain.
/// @param recipientChain The Wormhole chain ID of the recipient.
/// @param instruction An additional Instruction provided by the Transceiver to be
/// executed on the recipient chain.
/// @param ManagerMessage A message to be sent to the nttManager on the recipient chain.
/// @param managerExecutionCost The cost of executing the manager message on the recipient chain.
/// Depending on the target chain, the units may vary. For example, on Ethereum, this is
/// the additional gas cost (in excess of the attestation cost) for executing the manager message.
function sendMessage(
uint16 recipientChain,
TransceiverStructs.TransceiverInstruction memory instruction,
bytes memory ManagerMessage,
bytes32 recipientNttManagerAddress
bytes32 recipientNttManagerAddress,
uint256 managerExecutionCost
) external payable;

/// @notice Upgrades the transceiver to a new implementation.
Expand Down
Loading

0 comments on commit 8b00d62

Please sign in to comment.