Because several actors dispatch to a separate action to perform persistent state updates or complete another stage of the transaction, atomicity and isolation is not conserved.
Consider the case of a separate message to perform a persistent state update, for example in the nonce actor. When a dispatch to get_nonce is made, if the nonce is updated, the new nonce is dispatched to the set_nonce action of the nonce actor (ctx.self).
If a second get_nonce message had arrived directly after the first, it would receive the same state as the first message and proceed to update the nonce as well, making a duplicate and unnecessary call to the Ethereum node. In this case, the bug is fixed by having the get_nonce action return the new nonce, so in effect the state update is duplicated by get_nonce and set_nonce.
In this case multiple actions served as a simple work around to seperate persistence from the core logic, and breaking acidity has no serious consequence, but there are situations where action composition is more critical. Care has not been taken to avoid this same bug in other actors. The tip actor implements a resolver which is called as separate message. This must cause side effects.
Proposed solution
All actions should call an action function which is described outside the action defintion such that if it is necessary for one action to call some others, they are able to do so with out dispatching a new message, thus maintaining the acidity of the message.
The actor's actions should be composed of functions which accept message bundles.
Because several actors dispatch to a separate action to perform persistent state updates or complete another stage of the transaction, atomicity and isolation is not conserved.
Consider the case of a separate message to perform a persistent state update, for example in the nonce actor. When a dispatch to
get_nonce
is made, if the nonce is updated, the new nonce is dispatched to theset_nonce
action of the nonce actor (ctx.self
).If a second
get_nonce
message had arrived directly after the first, it would receive the same state as the first message and proceed to update the nonce as well, making a duplicate and unnecessary call to the Ethereum node. In this case, the bug is fixed by having theget_nonce
action return the new nonce, so in effect the state update is duplicated byget_nonce
andset_nonce
.In this case multiple actions served as a simple work around to seperate persistence from the core logic, and breaking acidity has no serious consequence, but there are situations where action composition is more critical. Care has not been taken to avoid this same bug in other actors. The
tip
actor implements a resolver which is called as separate message. This must cause side effects.Proposed solution
All actions should call an action function which is described outside the action defintion such that if it is necessary for one action to call some others, they are able to do so with out dispatching a new message, thus maintaining the acidity of the message.
The actor's actions should be composed of functions which accept message bundles.
Example