2

In the developer portal it says:

Deferred actions get scheduled to run, at best, at a later time, at the producer's discretion. There is no guarantee that a deferred action will be executed.

How can I find out from within a smart contract if my deferred transaction was ever executed?

If it is "dropped" by a producer, will it still call the onerror action in my contract?

3

Todd Fleming answered this in the EOS Developers Telegram channel as follows:

Todd Fleming

There isn't an intrinsic to do it. Flag seems like a good option.

Refering to Gassa's answer about setting a flag.

Me:

Thanks. What if it's important to distinguish 1) dropped transactions and 2) transactions that executed but failed due to an assertion error?

Todd Fleming

There's no reliable way. onerror is unreliable. Deferred transactions aren't as useful as we hoped. Making useful guarantees on them conflicts with more important guarantees which won out.

2

I don't know about the proposed solution (the onerror part of the question). This answer deals differently with the original problem.

At the very least, the original action can maintain a flag in the RAM, and the deferred one can clear that flag upon completion. It might naturally be more than just a flag, depending on what you want it to do.

A practical example is eosio.system with its name bidding feature. A bid event should return EOS to the previous bidder. Instead of just sending EOS (which would be a vulnerability), it makes a record in the refunds_table, and then tries to send a deferred transaction with bidrefund action. The bidrefund action transfers the EOS and clears the refunds_table entry. In case the deferred transaction fails for any reason, the bidrefund action can be called again anytime, without the eosio.system contract's permission. The code can be found here.

  • 1
    The fundamental problem is that there can be two cases why the flag was not cleared: 1. The deferred transaction was dropped 2. The deferred transaction ran but raised an assertion error. In my case, it's really important to be able to distinguish these two cases. Imagine the same scenario of transferring funds. This works fine for a system contract with unlimited RAM, but it would make my contract vulnerable to a RAM pollution attack if I don't clear the flag upon errors. But I want to retry in the dropped case, whereas I can clear the flag in the second case. – cmichel - LearnEOS.dev Nov 28 '18 at 18:30

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.