User sends a transaction to the bridge contract on xDai to initiate a withdrawal.
The requested xDai withdrawal amount is sent to an 0x address, and the
UserRequestForSignature method is called. Example tx: https://blockscout.com/poa/xdai/tx/0x8e23cf0ab01476c2df5b71a72603f2c229d3d9a63ad6ca71ce164798f3733826/internal_transactions
The request generates an event on the xDai side.
Bridge validator nodes catch this event and send confirmation (signatures) to the contract on the xDai side.
Once enough signatures are collected (currently 3 of 4), one of the bridge validators* sends the signatures and message to Ethereum. *This is not a centralized process, anyone can extract this information and send to Ethereum. If a transaction stalls due to congestion, this transaction can be re-submitted by any user with a higher gas price.
The bridge contract on Ethereum checks that the signatures are valid. If they are, the requested Dai is unlocked for the user. Note: This final step may be delayed if Ethereum mainnet is congested.
To track the relay we locate the originating transaction, find the corresponding transactions from confirmed validators, then find the transaction with signatures on Ethereum.
Code that checks the signatures and unblocks funds on Ethereum (starting from
executeSignatures (line 752))
Example transaction that makes this call: https://etherscan.io/tx/0x74efc3302beeaa14fda51e03cfedd03693961db41b1b9b6069c576431f844c91