aurora-is-near / rainbow-bridge-client

Monorepo containing Aurora-maintained libraries for using the Rainbow Bridge
https://github.com/near/rainbow-bridge-client/tree/main/packages/client#readme
MIT License
25 stars 7 forks source link

View function to check used proofs in ethereum without changing contract #40

Open mfornet opened 3 years ago

mfornet commented 3 years ago

In order to check if a proof was already used we need to check in a dictionary inside an ethereum contract if the proof exists already.

Implement this as a function so it can be reused for several tools, in particular for frontend while restoring tx. Relevant comments: https://github.com/aurora-is-near/rainbow-bridge-frontend/issues/235#issuecomment-841173161

I'm thinking in the following interface:

function proofExists(web3, lockerAddress, proof) {
    // Return true if the proof already exists, false otherwise
}
sept-en commented 3 years ago

Good idea! But this is relevant for Near->Eth transfer, not the other way.

For the Eth->Near transfer to check if the proof exists or not we can have the following solution: 1) Generate proof for the event 2) Create a key for that: sha256(proof.log_index + proof.receipt_index + header_data). 3) Check the storage of the Near contract having the proof prefix and key that was created on step 2.

mfornet commented 3 years ago

Done: https://github.com/aurora-is-near/rainbow-bridge-client/pull/37

mfornet commented 3 years ago

@paouvrard is this working for eNEAR unlock txs too? (https://github.com/aurora-is-near/near-erc20-connector)

paouvrard commented 3 years ago

@paouvrard is this working for eNEAR unlock txs too? (https://github.com/aurora-is-near/near-erc20-connector)

@mfornet yes

paouvrard commented 3 years ago

This is implemented using ethgetStorageAt, but hadn't realized that `usedProofs` is public so we can also use it's getter.

On a related topic, what would be useful is to be able to determine the transfer finalization tx hash (which recorded the proof in usedProofs_) given the transfer initialization tx hash. This should be possible for $NEAR -> eNEAR transfers as the event ConsumedProof can be searched to determine the tx hash: https://github.com/aurora-is-near/near-erc20-connector/blob/9bad75a00dde669906ea3e27792dfeacd57d8bba/eNear/contracts/Bridge.sol#L13

The token connector doesn't provide such event, but it should still be possible to determine the correct finalization tx hash with reasonable accuracy by searching for the Transfer event. If more than 1 transfer with same amount and recipient is made inside the search range, we can choose to keep only the 1st one assuming the search range starts when the light client to Ethereum has synced and the transfers were finalized in the same order that they were initiated.

For Eth -> NEAR transfers it looks doable for example by querying the finish_deposit call receipt to the indexer, but please advise.

cc @mfornet @sept-en

mfornet commented 3 years ago

On a related topic, what would be useful is to be able to determine the transfer finalization tx hash (which recorded the proof in usedProofs_) given the transfer initialization tx hash.

Just to be clear, by this you mean: given a tx hash that initiated the event in Blockchain 1 find the tx hash that finalise it in Blockchain 2?

Out of curiosity, why do you need this. Other than to determine if a transfer was finalised (but this can be done without finding finalisation tx).


For NEAR -> Eth, you can binary search for the block where a proof was included (notice that the function eth_getStorageAt let you view the state at any height), then find the target tx in this block.

Tbh, we should instead improve the interface and emit a log, but upgrading this contract is a complex operation. We should implement this anyway, for now, and ship it in the next upgrade (which is not planned at the moment).

For Eth -> NEAR transfers it looks doable for example by querying the finish_deposit call receipt to the indexer, but please advise.

This should work, since you already know the proof you can filter by success call to finish_deposit with a given proof. But again, we should instead emit a log which is easier to search (still in the indexer).

paouvrard commented 3 years ago

Out of curiosity, why do you need this. Other than to determine if a transfer was finalised (but this can be done without finding finalisation tx).

When the event relayer finalizes Eth -> NEAR transfers for users, it will be nice to show them the transaction which delivered the tokens on NEAR so that there is no confusion. Also when recovering a transfer, we can have a full view of it and display links to blockchain transactions.

For NEAR -> Eth, you can binary search for the block where a proof was included (notice that the function eth_getStorageAt let you view the state at any height), then find the target tx in this block.

Oh yea that works, cool idea ! Users wouldn't be able to make the same lock tx twice in the same block, so once we find the block, the tx hash can be found from the Transfer event.