fix: DeliverMessageSend discards FSM read errors and issues conflicting Set+Delete for drained self-transfers - #1
Open
amathxbt wants to merge 1 commit into
Conversation
… ops in DeliverMessageSend Two issues in DeliverMessageSend(): 1. When the StateRead response carries an FSM-level error (response.Error != nil), the handler returned Error: err instead of Error: response.Error. Since err was already confirmed nil a few lines above, this silently discarded the real error and let the function fall through to unmarshal zero-value account bytes as if the read had simply returned empty state. CheckTx already handles this correctly (err = resp.Error); DeliverMessageSend did not. Fixed to propagate response.Error. 2. For a self-transfer that drains the balance to exactly zero, fromKey == toKey, but the write batch included both a Set for toKey and a Delete for fromKey -- i.e. a Set and a Delete for the identical key in one batch. That is undefined/apply-order-dependent in the underlying store, which is a state-determinism risk across nodes. Fixed to only include the 'to' Set when it targets a distinct account from 'from'.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug 1 — swallowed FSM error
errwas already confirmednila few lines above, so whenresponse.Error != nilthis branch always returnsError: nil— the real FSM-level error is discarded. Execution then falls through toUnmarshal(fromBytes, from)etc. with empty byte slices (sinceresponse.Resultsis empty whenresponse.Erroris set), silently treating a failed read as an empty/zero-value account rather than surfacing what actually went wrong.CheckTxhandles the identical situation correctly a few lines above in the same file:DeliverMessageSendshould do the same. Fixed to returnresponse.Error.Bug 2 — conflicting Set+Delete on the same key
For a self-transfer (
msg.FromAddress == msg.ToAddress) that drains the balance to exactly zero,fromKey == toKey(the code even special-cases this above withto = from). This write batch therefore contains both a Set and a Delete for the identical key, which is apply-order-dependent in the underlying store. On a blockchain this is a determinism risk: if different store implementations (or even the same implementation under different internal orderings) resolve Set-vs-Delete-on-same-key differently, nodes could diverge on whether the account ends up deleted or persisted with a zero balance.Fixed to only include the
toSet when it targets an account distinct fromfrom, so a drained self-transfer results in a single unambiguous Delete.Testing
Traced both code paths by hand against the existing (correct)
CheckTxpattern and the self-transfer branch above it. No existing test suite in this repo to extend.