Message State
Messages are sent from the User Application (UA) at sourcesrcUA to the UA at the destination dstUA. Once the message is received by the dstUA, the message is considered delivered (transitioning from INFLIGHT to either SUCCESS or STORED)
| Message State | Cases |
|---|---|
| INFLIGHT | After a message is sent |
| SUCCESS | A1: dstUA success OK() A2: dstUA fails with uncaught exception |
| STORED | B1: dstUA fails with uncaught error / exception |
dstUA is expected to store the message in their contract to be retried (LayerZero will not store any successfully delivered messages). dstUA is expected to monitor and retry STORED messages on behalf of its users.
Case B1: dstUA is expected to gracefully handle all errors/exceptions when receiving a message, and any uncaught errors/exceptions (including out-of-gas) will cause the message to transition into STORED. A STORED message will block the delivery of any future message from srcUA to all dstUA on the same destination chain and can be retried until the message becomes SUCCESS. dstUA should implement a handler to transition the stored message from STORED to SUCCESS. If a bug in dstUA contract results in an unrecoverable error/exception, LayerZero provides a last-resort interface to force resume message delivery, only by the dstUA contract.
Message Ordering
LayerZero provides ordered delivery of messages from a given sender to a destination chain, i.e.srcUA -> dstChain. In other words, the message order nonce is shared by all dstUA on the same dstChain. That’s why a STORED message blocks the message pathway from srcUA to all dstUA on the same destination chain. If it isn’t necessary to preserve the sequential nonce property for a particular dstUA the sender must add the nonce into the payload and handle it end-to-end within the UA. UAs can implement a non-blocking pattern in their contract code.
Extensibility
Message Adapter Parameters
LayerZero allows UAs to add arbitrary transaction params in thesend() function, providing a high level of flexibility and opening up opportunities for a diverse set of 3rd party plugins This is implemented as an unreserved byte array parameter to the send() function, with UAs allowed to write any additional data necessary into that parameter. We recommend that UAs leave some degree of configurability for the extra parameters to allow for feature extensions.
One great feature of _adapterParams is performing an Airdrop.
Patterns
Non-Reentrancy
LayerZero Endpoint has a non-reentrancy guard for both thesend() and receive(), respectively. In other words, both send() and receive() can not call themselves on the same chain. UAs should not rely on LayerZero to perform the non-reentrancy check. However, UAs can query the endpoint to see if the endpoint isSendingPayload() or isReceivingPayload() for finer-grained reentrancy control.
Message Chaining
UAs can callsend() in the receive() calls on the same chain. Example applications for calling send() in the receive() include (e.g. Ping Pong):
- the UA at the source chain wants a message receipt (Chain A -> Chain B -> Chain A)
- the UA at the destination reroutes the message (Chain A -> Chain B -> Chain C)