xmtp / xps-gateway

XPS (XMTP Postal Service) JSON-RPC for xmtp-specific interactions with decentralized networks
https://xmtp.github.io/xps-gateway/
MIT License
2 stars 1 forks source link

Feature request: Return Transaction Hash instead of waiting for Tx Inclusion #52

Open insipx opened 9 months ago

insipx commented 9 months ago

Is your feature request related to a problem?

for context: https://github.com/xmtp/xps-gateway/pull/50#discussion_r1470035231

We currently wait on PendingTransaction until it is included

Describe the solution to the problem

Return a transaction hash and let the client wait

Describe the uses cases for the feature

Avoids unnecessary waiting in the RPC server

37ng commented 8 months ago

I think the gateway shouldn't return tx hash, it should limit the blockchain logic within it. However it's always possible for a tx to fail and it's the gateway who should take care of monitor / resend logic instead of its client.

So I'm proposing a "two-checkmarks" mechanism to solve this problem: 1st ☑️ happens when the gateway received the request and sent a tx to blockchain, without waiting, it returns the result with a pending status.

2nd ☑️ happens when the gateway confirmed that the tx is included. Then the gateway update the status to success or failed depending on the blockchain response. If the tx is lost due to network issue, the gateway should resend it.

insipx commented 8 months ago

Yeah, that makes sense. We would basically be emulating the ethers api -- we could even just send a struct wrapping PendingTransaction, which is a future that just polls the PendingTransaction future

this would then resolve to success or failure

37ng commented 8 months ago

we could even just send a struct wrapping PendingTransaction

Do you mean gateway sends a PendingTransaction back to its client? Would that mean the client would need to deal with blockchain specifics?

I think it's important for gateway to abstract away all the blockchain details. It only tells the client simple responses like success, pending or failure.

insipx commented 8 months ago

Not necessarily, we would still have control over the blockchain specifics via visibility. I was thinking of something like this:

pub struct Pending {
    ethers_pending: PendingTransaction,
    pub status: Status
}

impl Future for Pending {
    fn poll(self: &mut Pin<Self>) -> Result<PollResult> {
        self.ethers_pending.poll()
    }
}

Client-side


// make a request and get back our pending struct
let pending = client.grant_installation(/* .. */).await?;
let result = pending.await;
assert_eq!(result.status, Status::Success);

which essentially mimics the ethers-api, but i'm open to doing it differently

I'm skeptical of this part:

2nd ☑️ happens when the gateway confirmed that the tx is included. Then the gateway update the status to success or failed depending on the blockchain response. If the tx is lost due to network issue, the gateway should resend it.

It is essentially what this Pending future accomplishes; we can add extra information to our poll implementation if we would want to abstract away the blockchain data, I just don't want to be writing poll impls for blockchain stuff from scratch/adding more endpoints

37ng commented 8 months ago

I agree, this is cleaner. And appreciate the sample code, that's very helpful.