Skip to content

Commit

Permalink
Merge f14554e into 1b1964b
Browse files Browse the repository at this point in the history
  • Loading branch information
elatoskinas authored Jul 2, 2024
2 parents 1b1964b + f14554e commit f55eebc
Show file tree
Hide file tree
Showing 15 changed files with 868 additions and 817 deletions.
225 changes: 110 additions & 115 deletions contracts/gas-snapshots/ccip.gas-snapshot

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/scripts/native_solc_compile_all_ccip
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SOLC_VERSION="0.8.24"
OPTIMIZE_RUNS=26000
OPTIMIZE_RUNS_OFFRAMP=18000
OPTIMIZE_RUNS_ONRAMP=3600
OPTIMIZE_RUNS_MULTI_OFFRAMP=1800
OPTIMIZE_RUNS_MULTI_OFFRAMP=2400


SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
Expand Down
73 changes: 72 additions & 1 deletion contracts/src/v0.8/ccip/libraries/Internal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ library Internal {
/// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
struct ExecutionReportSingleChain {
uint64 sourceChainSelector; // Source chain selector for which the report is submitted
EVM2EVMMessage[] messages;
Any2EVMRampMessage[] messages;
// Contains a bytes array for each message, each inner bytes array contains bytes per transferred token
bytes[][] offchainTokenData;
bytes32[] proofs;
Expand Down Expand Up @@ -106,13 +106,15 @@ library Internal {
bytes32 messageId; // a hash of the message data
}

// TODO: create new const for EVM2AnyMessage
/// @dev EVM2EVMMessage struct has 13 fields, including 3 variable arrays.
/// Each variable array takes 1 more slot to store its length.
/// When abi encoded, excluding array contents,
/// EVM2EVMMessage takes up a fixed number of 16 lots, 32 bytes each.
/// For structs that contain arrays, 1 more slot is added to the front, reaching a total of 17.
uint256 public constant MESSAGE_FIXED_BYTES = 32 * 17;

// TODO: create new const for EVM2AnyMessage
/// @dev Each token transfer adds 1 EVMTokenAmount and 1 bytes.
/// When abiEncoded, each EVMTokenAmount takes 2 slots, each bytes takes 2 slots, excl bytes contents
uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 4;
Expand All @@ -130,6 +132,19 @@ library Internal {
});
}

function _toAny2EVMMessage(
Any2EVMRampMessage memory original,
Client.EVMTokenAmount[] memory destTokenAmounts
) internal pure returns (Client.Any2EVMMessage memory message) {
return Client.Any2EVMMessage({
messageId: original.header.messageId,
sourceChainSelector: original.header.sourceChainSelector,
sender: abi.encode(original.sender),
data: original.data,
destTokenAmounts: destTokenAmounts
});
}

bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256("EVM2EVMMessageHashV2");

function _hash(EVM2EVMMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) {
Expand Down Expand Up @@ -158,6 +173,37 @@ library Internal {
);
}

bytes32 internal constant ANY_2_EVM_MESSAGE_HASH = keccak256("Any2EVMMessageHashV1");

function _hash(Any2EVMRampMessage memory original, bytes memory onRamp) internal pure returns (bytes32) {
// Fixed-size message fields are included in nested hash to reduce stack pressure.
// This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers.
return keccak256(
abi.encode(
MerkleMultiProof.LEAF_DOMAIN_SEPARATOR,
// Implicit metadata hash
keccak256(
abi.encode(
ANY_2_EVM_MESSAGE_HASH, original.header.sourceChainSelector, original.header.destChainSelector, onRamp
)
),
keccak256(
abi.encode(
original.header.messageId,
original.sender,
original.receiver,
original.header.sequenceNumber,
original.gasLimit,
original.header.nonce
)
),
keccak256(original.data),
keccak256(abi.encode(original.tokenAmounts)),
keccak256(abi.encode(original.sourceTokenData))
)
);
}

/// @notice This methods provides validation for parsing abi encoded addresses by ensuring the
/// address is within the EVM address space. If it isn't it will revert with an InvalidEVMAddress error, which
/// we can catch and handle more gracefully than a revert from abi.decode.
Expand Down Expand Up @@ -200,4 +246,29 @@ library Internal {
Commit,
Execution
}

/// @notice Family-agnostic header for OnRamp & OffRamp messages.
/// The messageId is not expected to match hash(message), since it may originate from another ramp family
// TODO: revisit if destChainSelector is required (likely sufficient to have it implicitly in the commit roots)
struct RampMessageHeader {
bytes32 messageId; // Unique identifier for the message, generated with the source chain's encoding scheme (i.e. not necessarily abi.encoded)
uint64 sourceChainSelector; // ───────╮ the chain selector of the source chain, note: not chainId
uint64 destChainSelector; // | the chain selector of the destination chain, note: not chainId
uint64 sequenceNumber; // │ sequence number, not unique across lanes
uint64 nonce; // ─────────────────────╯ nonce for this lane for this sender, not unique across senders/lanes
}

/// @notice Family-agnostic message routed to an OffRamp
/// Note: hash(Any2EVMRampMessage) != hash(EVM2AnyRampMessage), hash(Any2EVMRampMessage) != messageId
/// due to encoding & parameter differences
struct Any2EVMRampMessage {
RampMessageHeader header; // Message header
bytes sender; // sender address on the source chain
bytes data; // arbitrary data payload supplied by the message sender
address receiver; // receiver address on the destination chain
uint256 gasLimit; // user supplied maximum gas amount available for dest chain execution
// TODO: revisit collapsing tokenAmounts + sourceTokenData into one struct array
Client.EVMTokenAmount[] tokenAmounts; // array of tokens and amounts to transfer
bytes[] sourceTokenData; // array of token data, one per token
}
}
Loading

0 comments on commit f55eebc

Please sign in to comment.