-
Notifications
You must be signed in to change notification settings - Fork 857
Handle accounts with non-zero code hashes in BeginTx #1079
Conversation
@z2trillion this PR has been draft for a while. The code only introduces a new test, does it still make sense to move forward with this? |
8 months ago the test failed because the code hash for accounts in the process of being created wasn't being set the the correct value of keccak(nil). I think this got fixed now that we're using I can add a comment to the test explaining what it catches, or I can just close this PR. |
|
This is actually still a problem. 771f58f adds a test that fails when the account that's being created already has a non-zero balance (and hence a non-zero code hash). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with some minor feedback and notes.
if (!receiver_exists && !value.is_zero()) || must_create { | ||
if !receiver_exists && (!value.is_zero() || must_create) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is not a request for change but a note for other reviewers:
I wrapped my head around this expression and finally figured out a more straightforward way to convince myself the proposed change is correct.
- If the expression evaluates true, we create an account with an empty hash. Specifically, update the codehash from 0 to the EMPTY_CODE_HASH.
- In the previous expression, the
must_create
dominates the outcome. If the call is CREATE, then even if the receiver_exists, the receiver account is still created with the empty hash. - In the proposed expression, the
!receiver_exists
dominates the outcome. If the receiver already exists, there's no way to mess up the account code hash again. This is the behavior that makes sense.
The failing case is captured in the test case create_tx_for_existing_account
.
I've included my previous elaborate boolean analysis in the "Details".
Details
Let A = (!receiver_exists), B = !value.is_zero(), and C = must_create,
- before: (A && B) || C
- after: A && (B || C)
The two expressions disagree on the following cases
- A = False, B = False, C = True
- A = False, B = True, C = True
In both cases, the receiver exists, and the call is CREATE.
If the value is zero, the expression before still creates the account with the empty codehash, but the proposed one doesn't.
If the value is NOT zero, the expression before still creates the account with the empty codehash, but the proposed one doesn't.
A | B | C | Output |
---|---|---|---|
0 | 0 | 0 | F |
0 | 0 | 1 | T |
0 | 1 | 0 | F |
0 | 1 | 1 | T |
1 | 0 | 0 | F |
1 | 0 | 1 | T |
1 | 1 | 0 | T |
1 | 1 | 1 | T |
A | B | C | Output |
---|---|---|---|
0 | 0 | 0 | F |
0 | 0 | 1 | F |
0 | 1 | 0 | F |
0 | 1 | 1 | F |
1 | 0 | 0 | F |
1 | 0 | 1 | T |
1 | 1 | 0 | T |
1 | 1 | 1 | T |
Co-authored-by: Chih Cheng Liang <chihchengliang@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I've left a few minor questions, and I think following CC's request to add some comments #1079 (comment) would be really nice.
Co-authored-by: Chih Cheng Liang <chihchengliang@gmail.com>
…gas and max-priority-fee-per-gas parsing in testool. (privacy-scaling-explorations#1079)
This occurs when an address already exists because it has a non-zero balance.