From bb7eace165e7207f0fd24003ec5fdad918328a8d Mon Sep 17 00:00:00 2001 From: Bruce Riley Date: Tue, 21 Jan 2025 11:27:54 -0600 Subject: [PATCH] evm: Remove dead transceiver code --- evm/echidna/FuzzNttManager.sol | 28 --- evm/src/libraries/TransceiverStructs.sol | 294 ---------------------- evm/test/RateLimit.t.sol | 16 -- evm/test/TransceiverStructs.t.sol | 149 +---------- evm/test/libraries/TransceiverHelpers.sol | 32 +-- 5 files changed, 18 insertions(+), 501 deletions(-) diff --git a/evm/echidna/FuzzNttManager.sol b/evm/echidna/FuzzNttManager.sol index 03f507648..6d9876d47 100644 --- a/evm/echidna/FuzzNttManager.sol +++ b/evm/echidna/FuzzNttManager.sol @@ -405,19 +405,6 @@ contract FuzzNttManager is FuzzingHelpers { errorSelector == selectorToUint(IManagerBase.PeerNotRegistered.selector), "NttManager: transfer expected to fail if sending to an unset peer" ); - } else if ( - errorSelector == selectorToUint(TransceiverStructs.InvalidInstructionIndex.selector) - ) { - TransceiverStructs.TransceiverInstruction[] memory instructions = TransceiverStructs - .parseTransceiverInstructions(encodedInstructions, numRegisteredTransceivers); - for (uint256 i = 0; i < instructions.length; ++i) { - if (instructions[i].index < numRegisteredTransceivers) { - assertWithMsg( - false, - "NttManager: transfer should not fail if instruction index is in bounds" - ); - } - } } else { assertWithMsg(false, "NttManager: transfer unexpected revert"); } @@ -481,21 +468,6 @@ contract FuzzNttManager is FuzzingHelpers { == selectorToUint(IRateLimiter.OutboundQueuedTransferStillQueued.selector), "NttManager: completeOutboundQueuedTransfer expected to fail if not queued for long enough" ); - } else if ( - errorSelector == selectorToUint(TransceiverStructs.InvalidInstructionIndex.selector) - ) { - TransceiverStructs.TransceiverInstruction[] memory instructions = TransceiverStructs - .parseTransceiverInstructions( - queuedTransfer.transceiverInstructions, numRegisteredTransceivers - ); - for (uint256 i = 0; i < instructions.length; ++i) { - if (instructions[i].index < numRegisteredTransceivers) { - assertWithMsg( - false, - "NttManager: transfer should not fail if instruction index is in bounds" - ); - } - } } else if (numEnabledTransceivers == 0) { // In this case the sender should be able to cancel their outbound queued transfer try nttManager.cancelOutboundQueuedTransfer(messageSequence) { diff --git a/evm/src/libraries/TransceiverStructs.sol b/evm/src/libraries/TransceiverStructs.sol index 3ffb4157c..64ba41550 100644 --- a/evm/src/libraries/TransceiverStructs.sol +++ b/evm/src/libraries/TransceiverStructs.sol @@ -19,21 +19,6 @@ library TransceiverStructs { /// @param prefix The prefix that was found in the encoded message. error IncorrectPrefix(bytes4 prefix); - /// @notice Error thrown when the transceiver instructions aren't - /// encoded with strictly increasing indices - /// @dev Selector 0x0555a4b9. - /// @param lastIndex Last parsed instruction index - /// @param instructionIndex The instruction index that was unordered - error UnorderedInstructions(uint256 lastIndex, uint256 instructionIndex); - - /// @notice Error thrown when a transceiver instruction index - /// is greater than the number of registered transceivers - /// @dev We index from 0 so if providedIndex == numTransceivers then we're out-of-bounds too - /// @dev Selector 0x689f5016. - /// @param providedIndex The index specified in the instruction - /// @param numTransceivers The number of registered transceivers - error InvalidInstructionIndex(uint256 providedIndex, uint256 numTransceivers); - /// @dev Prefix for all NativeTokenTransfer payloads /// This is 0x99'N''T''T' bytes4 constant NTT_PREFIX = 0x994E5454; @@ -184,283 +169,4 @@ library TransceiverStructs { } encoded.checkLength(offset); } - - /// @dev Message emitted by Transceiver implementations. - /// Each message includes an Transceiver-specified 4-byte prefix. - /// The wire format is as follows: - /// - prefix - 4 bytes - /// - sourceNttManagerAddress - 32 bytes - /// - recipientNttManagerAddress - 32 bytes - /// - nttManagerPayloadLength - 2 bytes - /// - nttManagerPayload - `nttManagerPayloadLength` bytes - /// - transceiverPayloadLength - 2 bytes - /// - transceiverPayload - `transceiverPayloadLength` bytes - struct TransceiverMessage { - /// @notice Address of the NttManager contract that emitted this message. - bytes32 sourceNttManagerAddress; - /// @notice Address of the NttManager contract that receives this message. - bytes32 recipientNttManagerAddress; - /// @notice Payload provided to the Transceiver contract by the NttManager contract. - bytes nttManagerPayload; - /// @notice Optional payload that the transceiver can encode and use for its own message passing purposes. - bytes transceiverPayload; - } - - // @notice Encodes an Transceiver message for communication between the - // NttManager and the Transceiver. - // @param m The TransceiverMessage struct containing the message details. - // @return encoded The byte array corresponding to the encoded message. - // @custom:throw PayloadTooLong if the length of transceiverId, nttManagerPayload, - // or transceiverPayload exceeds the allowed maximum. - function encodeTransceiverMessage( - bytes4 prefix, - TransceiverMessage memory m - ) public pure returns (bytes memory encoded) { - if (m.nttManagerPayload.length > type(uint16).max) { - revert PayloadTooLong(m.nttManagerPayload.length); - } - uint16 nttManagerPayloadLength = uint16(m.nttManagerPayload.length); - - if (m.transceiverPayload.length > type(uint16).max) { - revert PayloadTooLong(m.transceiverPayload.length); - } - uint16 transceiverPayloadLength = uint16(m.transceiverPayload.length); - - return abi.encodePacked( - prefix, - m.sourceNttManagerAddress, - m.recipientNttManagerAddress, - nttManagerPayloadLength, - m.nttManagerPayload, - transceiverPayloadLength, - m.transceiverPayload - ); - } - - function buildAndEncodeTransceiverMessage( - bytes4 prefix, - bytes32 sourceNttManagerAddress, - bytes32 recipientNttManagerAddress, - bytes memory nttManagerMessage, - bytes memory transceiverPayload - ) public pure returns (TransceiverMessage memory, bytes memory) { - TransceiverMessage memory transceiverMessage = TransceiverMessage({ - sourceNttManagerAddress: sourceNttManagerAddress, - recipientNttManagerAddress: recipientNttManagerAddress, - nttManagerPayload: nttManagerMessage, - transceiverPayload: transceiverPayload - }); - bytes memory encoded = encodeTransceiverMessage(prefix, transceiverMessage); - return (transceiverMessage, encoded); - } - - /// @dev Parses an encoded message and extracts information into an TransceiverMessage struct. - /// @param encoded The encoded bytes containing information about the TransceiverMessage. - /// @return transceiverMessage The parsed TransceiverMessage struct. - /// @custom:throw IncorrectPrefix if the prefix of the encoded message does not - /// match the expected prefix. - function parseTransceiverMessage( - bytes4 expectedPrefix, - bytes memory encoded - ) internal pure returns (TransceiverMessage memory transceiverMessage) { - uint256 offset = 0; - bytes4 prefix; - - (prefix, offset) = encoded.asBytes4Unchecked(offset); - - if (prefix != expectedPrefix) { - revert IncorrectPrefix(prefix); - } - - (transceiverMessage.sourceNttManagerAddress, offset) = encoded.asBytes32Unchecked(offset); - (transceiverMessage.recipientNttManagerAddress, offset) = encoded.asBytes32Unchecked(offset); - uint16 nttManagerPayloadLength; - (nttManagerPayloadLength, offset) = encoded.asUint16Unchecked(offset); - (transceiverMessage.nttManagerPayload, offset) = - encoded.sliceUnchecked(offset, nttManagerPayloadLength); - uint16 transceiverPayloadLength; - (transceiverPayloadLength, offset) = encoded.asUint16Unchecked(offset); - (transceiverMessage.transceiverPayload, offset) = - encoded.sliceUnchecked(offset, transceiverPayloadLength); - - // Check if the entire byte array has been processed - encoded.checkLength(offset); - } - - /// @dev Parses the payload of an Transceiver message and returns - /// the parsed NttManagerMessage struct. - /// @param expectedPrefix The prefix that should be encoded in the nttManager message. - /// @param payload The payload sent across the wire. - function parseTransceiverAndNttManagerMessage( - bytes4 expectedPrefix, - bytes memory payload - ) public pure returns (TransceiverMessage memory, NttManagerMessage memory) { - // parse the encoded message payload from the Transceiver - TransceiverMessage memory parsedTransceiverMessage = - parseTransceiverMessage(expectedPrefix, payload); - - // parse the encoded message payload from the NttManager - NttManagerMessage memory parsedNttManagerMessage = - parseNttManagerMessage(parsedTransceiverMessage.nttManagerPayload); - - return (parsedTransceiverMessage, parsedNttManagerMessage); - } - - /// @dev Variable-length transceiver-specific instruction that can be passed by the caller to the nttManager. - /// The index field refers to the index of the registeredTransceiver that this instruction should be passed to. - /// The serialization format is: - /// - index - 1 byte - /// - payloadLength - 1 byte - /// - payload - `payloadLength` bytes - struct TransceiverInstruction { - uint8 index; - bytes payload; - } - - function encodeTransceiverInstruction( - TransceiverInstruction memory instruction - ) public pure returns (bytes memory) { - if (instruction.payload.length > type(uint8).max) { - revert PayloadTooLong(instruction.payload.length); - } - uint8 payloadLength = uint8(instruction.payload.length); - return abi.encodePacked(instruction.index, payloadLength, instruction.payload); - } - - function parseTransceiverInstructionUnchecked( - bytes memory encoded, - uint256 offset - ) public pure returns (TransceiverInstruction memory instruction, uint256 nextOffset) { - (instruction.index, nextOffset) = encoded.asUint8Unchecked(offset); - uint8 instructionLength; - (instructionLength, nextOffset) = encoded.asUint8Unchecked(nextOffset); - (instruction.payload, nextOffset) = encoded.sliceUnchecked(nextOffset, instructionLength); - } - - function parseTransceiverInstructionChecked( - bytes memory encoded - ) public pure returns (TransceiverInstruction memory instruction) { - uint256 offset = 0; - (instruction, offset) = parseTransceiverInstructionUnchecked(encoded, offset); - encoded.checkLength(offset); - } - - /// @dev Encode an array of multiple variable-length transceiver-specific instructions. - /// The serialization format is: - /// - instructionsLength - 1 byte - /// - `instructionsLength` number of serialized `TransceiverInstruction` types. - function encodeTransceiverInstructions( - TransceiverInstruction[] memory instructions - ) public pure returns (bytes memory) { - if (instructions.length > type(uint8).max) { - revert PayloadTooLong(instructions.length); - } - uint256 instructionsLength = instructions.length; - - bytes memory encoded; - for (uint256 i = 0; i < instructionsLength; i++) { - bytes memory innerEncoded = encodeTransceiverInstruction(instructions[i]); - encoded = bytes.concat(encoded, innerEncoded); - } - return abi.encodePacked(uint8(instructionsLength), encoded); - } - - function parseTransceiverInstructions( - bytes memory encoded, - uint256 numRegisteredTransceivers - ) public pure returns (TransceiverInstruction[] memory) { - uint256 offset = 0; - uint256 instructionsLength; - (instructionsLength, offset) = encoded.asUint8Unchecked(offset); - - // We allocate an array with the length of the number of registered transceivers - // This gives us the flexibility to not have to pass instructions for transceivers that - // don't need them - TransceiverInstruction[] memory instructions = - new TransceiverInstruction[](numRegisteredTransceivers); - - uint256 lastIndex = 0; - for (uint256 i = 0; i < instructionsLength; i++) { - TransceiverInstruction memory instruction; - (instruction, offset) = parseTransceiverInstructionUnchecked(encoded, offset); - - uint8 instructionIndex = instruction.index; - - // The instructions passed in have to be strictly increasing in terms of transceiver index - if (i != 0 && instructionIndex <= lastIndex) { - revert UnorderedInstructions(lastIndex, instructionIndex); - } - - // Instruction index is out of bounds - if (instructionIndex >= numRegisteredTransceivers) { - revert InvalidInstructionIndex(instructionIndex, numRegisteredTransceivers); - } - - lastIndex = instructionIndex; - - instructions[instructionIndex] = instruction; - } - - encoded.checkLength(offset); - - return instructions; - } - - struct TransceiverInit { - bytes4 transceiverIdentifier; - bytes32 nttManagerAddress; - uint8 nttManagerMode; - bytes32 tokenAddress; - uint8 tokenDecimals; - } - - function encodeTransceiverInit( - TransceiverInit memory init - ) public pure returns (bytes memory) { - return abi.encodePacked( - init.transceiverIdentifier, - init.nttManagerAddress, - init.nttManagerMode, - init.tokenAddress, - init.tokenDecimals - ); - } - - function decodeTransceiverInit( - bytes memory encoded - ) public pure returns (TransceiverInit memory init) { - uint256 offset = 0; - (init.transceiverIdentifier, offset) = encoded.asBytes4Unchecked(offset); - (init.nttManagerAddress, offset) = encoded.asBytes32Unchecked(offset); - (init.nttManagerMode, offset) = encoded.asUint8Unchecked(offset); - (init.tokenAddress, offset) = encoded.asBytes32Unchecked(offset); - (init.tokenDecimals, offset) = encoded.asUint8Unchecked(offset); - encoded.checkLength(offset); - } - - struct TransceiverRegistration { - bytes4 transceiverIdentifier; - uint16 transceiverChainId; - bytes32 transceiverAddress; - } - - function encodeTransceiverRegistration( - TransceiverRegistration memory registration - ) public pure returns (bytes memory) { - return abi.encodePacked( - registration.transceiverIdentifier, - registration.transceiverChainId, - registration.transceiverAddress - ); - } - - function decodeTransceiverRegistration( - bytes memory encoded - ) public pure returns (TransceiverRegistration memory registration) { - uint256 offset = 0; - (registration.transceiverIdentifier, offset) = encoded.asBytes4Unchecked(offset); - (registration.transceiverChainId, offset) = encoded.asUint16Unchecked(offset); - (registration.transceiverAddress, offset) = encoded.asBytes32Unchecked(offset); - encoded.checkLength(offset); - } } diff --git a/evm/test/RateLimit.t.sol b/evm/test/RateLimit.t.sol index 7c67dc54c..6f50fb287 100644 --- a/evm/test/RateLimit.t.sol +++ b/evm/test/RateLimit.t.sol @@ -1106,22 +1106,6 @@ contract TestRateLimit is Test, IRateLimiterEvents { // bytes memory encodedEm; uint256 inboundLimit = inboundLimitAmt; TrimmedAmount trimmedAmount = packTrimmedAmount(uint64(amount), 8); - // { - // TransceiverStructs.TransceiverMessage memory em; - // (m, em) = TransceiverHelpersLib.attestTransceiversHelper( - // user_B, - // 0, - // chainId, - // nttManager, - // nttManager, - // trimmedAmount, - // inboundLimit.trim(token.decimals(), token.decimals()), - // transceivers - // ); - // encodedEm = TransceiverStructs.encodeTransceiverMessage( - // TransceiverHelpersLib.TEST_TRANSCEIVER_PAYLOAD_PREFIX, em - // ); - // } ( TransceiverStructs.NttManagerMessage memory m, diff --git a/evm/test/TransceiverStructs.t.sol b/evm/test/TransceiverStructs.t.sol index b71524736..235c3c888 100644 --- a/evm/test/TransceiverStructs.t.sol +++ b/evm/test/TransceiverStructs.t.sol @@ -6,6 +6,7 @@ import "forge-std/Test.sol"; import "../src/libraries/TransceiverStructs.sol"; import "../src/interfaces/IManagerBase.sol"; import "../src/interfaces/INttManager.sol"; +import "./libraries/TransceiverHelpers.sol"; contract TestTransceiverStructs is Test { using TrimmedAmountLib for uint256; @@ -13,115 +14,7 @@ contract TestTransceiverStructs is Test { // TODO: add some negative tests for unknown message types etc - function test_serialize_TransceiverInit() public { - bytes4 wh_prefix = 0x9c23bd3b; - TransceiverStructs.TransceiverInit memory ti = TransceiverStructs.TransceiverInit({ - transceiverIdentifier: wh_prefix, - nttManagerAddress: hex"BABABABABABA", - nttManagerMode: uint8(IManagerBase.Mode.LOCKING), - tokenAddress: hex"DEDEDEDEDEDEDE", - tokenDecimals: 16 - }); - - bytes memory encodedTransceiverInit = TransceiverStructs.encodeTransceiverInit(ti); - - bytes memory encodedExpected = - vm.parseBytes(vm.readLine("./test/payloads/transceiver_info_1.txt")); - assertEq(encodedTransceiverInit, encodedExpected); - } - - function test_SerdeRoundtrip_TransceiverInit( - TransceiverStructs.TransceiverInit memory ti - ) public { - bytes memory message = TransceiverStructs.encodeTransceiverInit(ti); - TransceiverStructs.TransceiverInit memory parsed = - TransceiverStructs.decodeTransceiverInit(message); - - assertEq(ti.transceiverIdentifier, parsed.transceiverIdentifier); - assertEq(ti.nttManagerAddress, parsed.nttManagerAddress); - assertEq(ti.nttManagerMode, parsed.nttManagerMode); - assertEq(ti.tokenAddress, parsed.tokenAddress); - assertEq(ti.tokenDecimals, parsed.tokenDecimals); - } - - function test_serialize_TransceiverRegistration() public { - bytes4 wh_prefix = 0x18fc67c2; - TransceiverStructs.TransceiverRegistration memory tr = TransceiverStructs - .TransceiverRegistration({ - transceiverIdentifier: wh_prefix, - transceiverChainId: 23, - transceiverAddress: hex"BABABAFEFE" - }); - - bytes memory encodedTransceiverRegistration = - TransceiverStructs.encodeTransceiverRegistration(tr); - - bytes memory encodedExpected = - vm.parseBytes(vm.readLine("./test/payloads/transceiver_registration_1.txt")); - assertEq(encodedTransceiverRegistration, encodedExpected); - } - - function test_SerdeRoundtrip_TransceiverRegistration( - TransceiverStructs.TransceiverRegistration memory tr - ) public { - bytes memory message = TransceiverStructs.encodeTransceiverRegistration(tr); - - TransceiverStructs.TransceiverRegistration memory parsed = - TransceiverStructs.decodeTransceiverRegistration(message); - - assertEq(tr.transceiverIdentifier, parsed.transceiverIdentifier); - assertEq(tr.transceiverChainId, parsed.transceiverChainId); - assertEq(tr.transceiverAddress, parsed.transceiverAddress); - } - - function test_serialize_TransceiverMessage() public { - TransceiverStructs.NativeTokenTransfer memory ntt = TransceiverStructs.NativeTokenTransfer({ - amount: packTrimmedAmount(uint64(1234567), 7), - sourceToken: hex"BEEFFACE", - to: hex"FEEBCAFE", - toChain: 17, - additionalPayload: "" - }); - - TransceiverStructs.NttManagerMessage memory mm = TransceiverStructs.NttManagerMessage({ - id: hex"128434bafe23430000000000000000000000000000000000ce00aa0000000000", - sender: hex"46679213412343", - payload: TransceiverStructs.encodeNativeTokenTransfer(ntt) - }); - - bytes4 wh_prefix = 0x9945FF10; - TransceiverStructs.TransceiverMessage memory em = TransceiverStructs.TransceiverMessage({ - sourceNttManagerAddress: hex"042942FAFABE", - recipientNttManagerAddress: hex"042942FABABE", - nttManagerPayload: TransceiverStructs.encodeNttManagerMessage(mm), - transceiverPayload: new bytes(0) - }); - - bytes memory encodedTransceiverMessage = - TransceiverStructs.encodeTransceiverMessage(wh_prefix, em); - - // this is a useful test case for implementations on other runtimes - bytes memory encodedExpected = - vm.parseBytes(vm.readLine("./test/payloads/transceiver_message_1.txt")); - assertEq(encodedTransceiverMessage, encodedExpected); - - TransceiverStructs.TransceiverMessage memory emParsed = - TransceiverStructs.parseTransceiverMessage(wh_prefix, encodedTransceiverMessage); - - TransceiverStructs.NttManagerMessage memory mmParsed = - TransceiverStructs.parseNttManagerMessage(emParsed.nttManagerPayload); - - // deep equality check - assertEq(abi.encode(mmParsed), abi.encode(mm)); - - TransceiverStructs.NativeTokenTransfer memory nttParsed = - TransceiverStructs.parseNativeTokenTransfer(mmParsed.payload); - - // deep equality check - assertEq(abi.encode(nttParsed), abi.encode(ntt)); - } - - function test_parse_TransceiverMessageWithEmptyPayload() public { + function test_serialize_NttManagerMessage() public { TransceiverStructs.NativeTokenTransfer memory ntt = TransceiverStructs.NativeTokenTransfer({ amount: packTrimmedAmount(uint64(1234567), 7), sourceToken: hex"BEEFFACE", @@ -136,20 +29,10 @@ contract TestTransceiverStructs is Test { payload: TransceiverStructs.encodeNativeTokenTransfer(ntt) }); - bytes4 wh_prefix = 0x9945FF10; - - // this message can't be generated but does technically adhere to the spec - bytes memory encodedExpected = - vm.parseBytes(vm.readLine("./test/payloads/transceiver_message_with_empty_payload.txt")); - - TransceiverStructs.TransceiverMessage memory emParsed = - TransceiverStructs.parseTransceiverMessage(wh_prefix, encodedExpected); + bytes memory encoded = TransceiverStructs.encodeNttManagerMessage(mm); TransceiverStructs.NttManagerMessage memory mmParsed = - TransceiverStructs.parseNttManagerMessage(emParsed.nttManagerPayload); - - // add empty payload length - mm.payload = abi.encodePacked(mm.payload, hex"0000"); + TransceiverStructs.parseNttManagerMessage(encoded); // deep equality check assertEq(abi.encode(mmParsed), abi.encode(mm)); @@ -161,7 +44,7 @@ contract TestTransceiverStructs is Test { assertEq(abi.encode(nttParsed), abi.encode(ntt)); } - function test_serialize_TransceiverMessageWithAdditionalPayload() public { + function test_serialize_NttManagerMessageWithAdditionalPayload() public { TransceiverStructs.NativeTokenTransfer memory ntt = TransceiverStructs.NativeTokenTransfer({ amount: packTrimmedAmount(uint64(1234567), 7), sourceToken: hex"BEEFFACE", @@ -176,28 +59,10 @@ contract TestTransceiverStructs is Test { payload: TransceiverStructs.encodeNativeTokenTransfer(ntt) }); - bytes4 wh_prefix = 0x9945FF10; - TransceiverStructs.TransceiverMessage memory em = TransceiverStructs.TransceiverMessage({ - sourceNttManagerAddress: hex"042942FAFABE", - recipientNttManagerAddress: hex"042942FABABE", - nttManagerPayload: TransceiverStructs.encodeNttManagerMessage(mm), - transceiverPayload: new bytes(0) - }); - - bytes memory encodedTransceiverMessage = - TransceiverStructs.encodeTransceiverMessage(wh_prefix, em); - - // this is a useful test case for implementations on other runtimes - bytes memory encodedExpected = vm.parseBytes( - vm.readLine("./test/payloads/transceiver_message_with_32byte_payload.txt") - ); - assertEq(encodedTransceiverMessage, encodedExpected); - - TransceiverStructs.TransceiverMessage memory emParsed = - TransceiverStructs.parseTransceiverMessage(wh_prefix, encodedTransceiverMessage); + bytes memory encoded = TransceiverStructs.encodeNttManagerMessage(mm); TransceiverStructs.NttManagerMessage memory mmParsed = - TransceiverStructs.parseNttManagerMessage(emParsed.nttManagerPayload); + TransceiverStructs.parseNttManagerMessage(encoded); // deep equality check assertEq(abi.encode(mmParsed), abi.encode(mm)); diff --git a/evm/test/libraries/TransceiverHelpers.sol b/evm/test/libraries/TransceiverHelpers.sol index ce62ab5e4..482124c21 100644 --- a/evm/test/libraries/TransceiverHelpers.sol +++ b/evm/test/libraries/TransceiverHelpers.sol @@ -170,27 +170,6 @@ library TransceiverHelpersLib { ); } - function buildTransceiverMessageWithNttManagerPayload( - bytes32 id, - bytes32 sender, - bytes32 sourceNttManager, - bytes32 recipientNttManager, - bytes memory payload - ) internal pure returns (TransceiverStructs.NttManagerMessage memory, bytes memory) { - TransceiverStructs.NttManagerMessage memory m = - TransceiverStructs.NttManagerMessage(id, sender, payload); - bytes memory nttManagerMessage = TransceiverStructs.encodeNttManagerMessage(m); - bytes memory transceiverMessage; - (, transceiverMessage) = TransceiverStructs.buildAndEncodeTransceiverMessage( - TEST_TRANSCEIVER_PAYLOAD_PREFIX, - sourceNttManager, - recipientNttManager, - nttManagerMessage, - new bytes(0) - ); - return (m, transceiverMessage); - } - error TransferSentEventNotFoundInLogs(uint64 nttSeqNo); error ExecutorEventNotFoundInLogs(uint64 nttSeqNo, bytes32 payloadHash); @@ -250,4 +229,15 @@ library TransceiverHelpersLib { (payloadLen, offset) = execPayload.asUint32(offset); (payload, offset) = execPayload.sliceUnchecked(offset, payloadLen); } + + /// @dev Variable-length transceiver-specific instruction that can be passed by the caller to the nttManager. + /// The index field refers to the index of the registeredTransceiver that this instruction should be passed to. + /// The serialization format is: + /// - index - 1 byte + /// - payloadLength - 1 byte + /// - payload - `payloadLength` bytes + struct TransceiverInstruction { + uint8 index; + bytes payload; + } }