optics-monorepo icon indicating copy to clipboard operation
optics-monorepo copied to clipboard

How to track a message through the Home and Replica contracts?

Open nambrot opened this issue 3 years ago • 20 comments

I know we talked about this on the meeting already, but somehow I can't piece it together again. In the interest of transparency, I figure I move the convo here.

When I enqueue a message through the TokenBridge xApp, how can I track its "status" on the receiving domain/replica?

I vaguely remember that I was supposed to parse out the sequence number, but I don't remember why. Was tracking the leaf (keccak of message) and its message status on the replica not sufficient?

Unrelatedly, I was curious about the use of the nextToProcess variable? I see it assigned, but never really used?

nambrot avatar Aug 16 '21 19:08 nambrot

Oh, was it because messages are likely to be proveAndProcessed and therefore the thing to track is actually the root of the tree in which the message first appears?

nambrot avatar Aug 16 '21 19:08 nambrot

  1. poll the replica to see if await replica.confirmAt(newRoot) >= now. if 0, the root is unknown. if set, it's the time at which the message is eligible for processing.
  2. poll await replica.messages(leafHash) for the message status

nextToProcess is externalized to agents to simplify implementation

prestwich avatar Aug 16 '21 19:08 prestwich

Thanks for the prompt response.

How do I determine the root of the enqueue? It's not part of the emitted event as far as I can tell? Do I have to make the view call right after the tx? It technically won't give me "the" root of my message right, it could be an arbitrary root after "my root"?

What do I do if the updater doesn't call Replica#update with my root but with any root after mine?

nambrot avatar Aug 16 '21 19:08 nambrot

Also, I don't know if it's related, but with the current event emission, it is impossible to track the transaction that will process the message on the replica correct? As in if I want to show the etherscan tx that results in the transfer on the receiving domain, I don't think I can easily do it?

nambrot avatar Aug 16 '21 20:08 nambrot

These are all problems for a standalone tx indexer, which we have not yet written

prestwich avatar Aug 16 '21 21:08 prestwich

So for the TokenBridge GUI, what would you recommend for "tracking" a transfer of a token? just do the polling of 2)?

nambrot avatar Aug 16 '21 21:08 nambrot

yeah, that'll work

prestwich avatar Aug 16 '21 21:08 prestwich

to find the root containing a message, use eth_getLogs Update events starting from the block in which the TX was confirmed. If an Update event occurs in the block, compare tx indices. Accept the Update if its index is later than the enqueue Otherwise sort returned logs by block height and take the first

prestwich avatar Aug 16 '21 22:08 prestwich

🙏 for the convenience events. Quick comment: (hope you don't mind me adding them here since the PR already merged). Even with the root in the Dispatch event, it will still be challenging to "track" the root update on the Replica since it could be any root after "our root" that is being updated on the Replica right? Put differently, our root may never appear again, either on Home or Replica (other than technically when it gets dequeued on Home)? (all this is assuming that the updater will not update every single root, but batch roots)

nambrot avatar Aug 17 '21 00:08 nambrot

"the successor of the current root" is a sufficient heuristic. Only breaks in uncommon race conditions

prestwich avatar Aug 17 '21 00:08 prestwich

How do I determine whether a given root is a successor of the current root?

nambrot avatar Aug 17 '21 00:08 nambrot

you use the Update event

prestwich avatar Aug 17 '21 00:08 prestwich

Sorry I must be missing something, but what if the root prior to the message is A, the root of our message is B and then the root of a message after us is C. If there is an update event from A -> C, wouldn't we be unable to find an update involving B? Or are you saying that in practice, updaters will always update every single root and not batch?

nambrot avatar Aug 17 '21 00:08 nambrot

why do you need to know anything about B when C necessarily includes it?

prestwich avatar Aug 17 '21 01:08 prestwich

How do I know that C is a successor of B? Or put differently, how do I know for a given Update whether it includes my root if its not equal to either _oldRoot or _newRoot?

nambrot avatar Aug 17 '21 01:08 nambrot

"the successor of the current root" is a sufficient heuristic. Only breaks in uncommon race conditions

prestwich avatar Aug 17 '21 01:08 prestwich

How do I know that C is a successor of B

because the Dispatch event with root C will be emitted after the Dispatch event with root B not necessarily the most elegant interface, i will readily admit

anna-carroll avatar Aug 18 '21 13:08 anna-carroll

here's how you can do this as a xApp developer:

  1. when you enqueue the message, check the Dispatch event and store latestUpdatedRoot and messageHash
  2. get the Update event on the Home where latestUpdatedRoot (from original Dispatch event) == oldRoot (2nd indexed param on Update event) - this means your message has been included in the update on the Home domain
  3. get the Update event on the Replica where latestUpdatedRoot (from original Dispatch event) == oldRoot (2nd indexed param on Update event) - this means your message has been relayed to the destination domain
  4. get the Process event on the Replica where messageHash (from original Dispatch event) == messageHash (1st indexed param on Process event) - this means your message has been processed on the destination domain - the second arg, success, is true if the call was executed successfully or false if there was a revert at the contract level

Note: in 2, 3, and 4 when I say "get" the event, there are two possible methods:

  • setup an event listener that is triggered whenever new events are fired, and check each to see if it is the event in question
  • poll for the event in question at regular intervals

anna-carroll avatar Aug 18 '21 13:08 anna-carroll

@anna-carroll @prestwich Do you think we should include this issue in the #599 Epic or is it fine to fully document this post-release?

yourbuddyconner avatar Aug 18 '21 20:08 yourbuddyconner

ideally we build out a whole TS lib for accessing optics that does this for you automagically. but that's a future future. in the meantime, add this to documentation

prestwich avatar Aug 18 '21 22:08 prestwich