-
Notifications
You must be signed in to change notification settings - Fork 3.8k
A transaction that will normally fail to execute due to a uniqueness violation, if submitted as a deferred transaction will partially execute instead of failing entirely as expected #6214
Comments
Those look like log entries. Are you getting those results out of the history plugin’s json rpc api? |
The history plugin relies on chainbase’s undo to clean up garbage results as a side effect of controller’s use of undo. |
The first snippet is output from cleos get actions, the second is log output in nodeos. |
What do you mean by "partially execute"? |
The transaction that was broadcasted had 3 actions in it as shown above (prepare, transfer, activate). The transaction is designed such that if it would be submitted again as a duplicate then the activate action would try to insert a duplicate row and cause the entire transaction to fail. In the action log above i submitted the same transaction twice - it succeeded the first time as expected but the second time should have failed completely but actually one of the actions were applied according to anything listening on the applied transaction signal such as the history api and my plugin. The transaction fails as expected when submitted as a normal transaction with nothing applied. If it’s executed as a deferred transaction then the first action (prepare) emits an applied transaction signal and is saved in the history plugin while the other 2 actions are not applied as expected. |
I see what happened. The signaling is correct. The way the history plugin relies on undo backfired. |
Signaling: it’s marked as a hard_fail, something plugins should either filter on or record. Recoding it allows you to see why deferred transactions fail. state_history_plugin records deferred failures. |
On the postgresql side of things: clients which only care about executed actions will include “where transaction_status=‘executed’” |
Analysis: the history plugin has a core assumption that it can blindly store traces without any status checking. The idea is that anything it stores will be rolled back by undo when there's a problem. Problem: controller sometimes does the undo before sending Potential fix: the history plugin will have to check for the existence of a transaction receipt. If it's absent or indicates failure then it shouldn't store the trace. Caution for history plugin users: the history plugin is deprecated. It may have additional unnoticed border cases. Caution for other plugin authors: even after this fix, the history plugin will still rely on undo, which greatly simplifies its logic. Plugins which store data outside of chainbase have a much higher burden. The history plugin is not suitable as a reference. |
Isn't it interesting to have the Perhaps the user should check for the status? |
@acoutts is that on mainnet? if so, would you share the transaction ID? |
Absolutely. That's what the mongodb and state history plugins do, but only for deferred since those are part of consensus. The deprecated history plugin won't after this fix. |
@abourget this was just on my local testnet. |
Resolved by #6220. |
When submitting a transaction that will cause a uniqueness constraint violation, it will fail immediately when submitting the transaction through cleos as expected. But submitting the exact same transaction as a deferred transaction causes some of the actions to succeed according to the history plugin and signals from the chain plugin while throwing the uniqueness constraint violation in nodeos:
Line 27 is an attempt to submit a duplicate transaction already done in line 19.
I haven't confirmed yet if any contract tables were actually changed or if it's just a bug in the history plugin where it shouldn't have recorded the second transaction attempt at line 27 due to it failing for uniqueness constraint violation.
Here is the nodeos output including some tags from the different signals in the chain plugin showing that the action trace was visible in accepted/applied transaction even though the transaction should have failed:
The text was updated successfully, but these errors were encountered: