-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error handling in the sendTransaction function #46
Comments
Hey @jinoosss, Thank you for opening up the issue, these are completely valid questions 🙏 I definitely believe the transaction send method definitely should alert of any errors that occurred during broadcast. As for the error handling, I'm not sure there are any Gno-specific errors, all of these seem to be TM2 related. Am I wrong here? I will look into adding this functionality soon, or we can coordinate together if you'd like to take a go at it 💪 |
Thanks for the comment. I'd be pleased to coordinate with you. Do you have a way of handling TM2 errors in mind? I personally thought about throwing an error (based on the TM2 response error type). |
Hey @jinoosss, Sorry for the somewhat late reply on this issue. I like the idea of throwing an error, I think it's one of the most cleanest ones and doesn't change the API drastically I need to look into how these errors are returned to clients, as I suspect they're being encoded in amino (we might need to proto them out into a JS type). I'll open a draft PR and add you to get your opinion on changes 🙏 |
Just verified it locally and have more information on this issue. The problem lies with how
Simulation checksThese types of transaction checks actually run the message associated with the transaction. What does this mean? Basic TX verificationThis type of transaction check simply verifies that the transaction is valid enough to enter the transaction pool (mempool), and be picked up later by the block building process.
You will notice that this type of check does not execute the actual transaction messages (ie. fund transfers). The problemThis sort of brings us to the problem at hand:
What can we do?The way I see it, there are 2 action points:
I need to sync with the core team to figure out how to tackle the second point, as it's a much bigger change than the first one. |
I've opened up a small PR to address point 1: Please let me know what you think 🙏 |
@zivkovicmilos, I think it's a good idea to throw a clear error so that it can be used without knowing the core of the chain. I'll take a closer look at the PR you suggested and offer further comments. |
BTW please take a look at the comments in tm2/pkg/bft/rpc/core/mempool.go for details of response format for broadcast_tx_* calls.
It runs the tx in a cachewrapped context so that all the changes can be discarded if there is an error during execution (delivertx). But for clarity I think we should not call this "simulation" since it does write if the tx succeeds, and also baseapp.Simulate() is an existing function which works similarly, except it always discards the result. (if we wanted, we could consider exposing a "simulate" RPC endpoint, but I think that's outside the scope of this issue, and also we'd have to figure out how to throttle it somehow.)
broadcast_tx_commit isn't the best for production usage because it runs a redundant checktx step. That is, it first runs checktx, and if that succeeds, then runs delivertx, but that means the ante handler is run twice. (I think we could just modify broadcast_tx_commit to make the checktx step optional, if I'm not mistaken. Also we can take a look at tm1 or comet to see what they do.) But in order to get the actual result value, of course we do have to wait until the block commits (since the result can depend on prior txs). So I'm not sure it's "unfavorable" unless you have a series of txs to commit at once. If you don't want to make a blocking rpc request like broadcast_tx_commit, then as per the comments in mempool.go you can listen to the websocket for events. If it is not acceptable to lose results upon websocket failure (since reconnecting the websocket doesn't replay old events) then we should use the event store system which is specifically for replaying the same events as the websocket (and the external indexer should use this because indexing requires impotency and thus requires event replay from last height known by the indexer). (do we have a PR for that? I remember discussing this months ago but don't recall seeing the code for it)
The transaction receipt is already passed to tm2 as follows:
(See also gnolang/gno#968 first) All deterministic receipt information should go in all three structures... for example, tx events from the app (in the case of gno.land, these are events published via gno function calls like std.Emit() perhaps.
The results are available from the "block_results" ABCI call, but this isn't the best way to get the result of a tx based on its hash. The right rpc endpoint for that is "tx", but it is currently commented out (see tm2/pkg/bft/rpc/core/tx.go) because the tx_indexer logic was removed. Has there been any work on the replayable event store and external tx indexer? Maybe the external tx index is what should ultimately serve results from tx hashes. This rpc endpoint would arguably get hammered by user clients, so it might make sense to offload that into the external tx indexer which can solve for throughput, rather than requiring a cluster of tm2 nodes to do the same. |
Based on our discussions on gnolang/gno#546, there is work being done on two fronts:
|
Currently, providers only validate for success/failure of calls in general.
However, when we call broadcast_tx of the sendTransaction function,
we can get an error about the transaction as a response.
This error cannot be checked in the block, so I think error handling is necessary.
@zivkovicmilos I have a few questions.
(If we use the gno response as is, the error types need to be checked in the gno repository and handled)
** gno errors: https://github.com/gnolang/gno/blob/0b38c8d793f83d50929ca27351f2b3cb89e9b974/tm2/pkg/std/errors.go
The text was updated successfully, but these errors were encountered: