-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make CommonTx have TransactionMisc as pointer #9977
Conversation
Add store & load methods for atomic.Values to prevent nil pointer error
W/o this PR, are the implicit copies of |
@yperbasis This issue was encountered when we were developing op-erigon. This CI error occurs because of This CI error was fixed after this PR is applied (testinprod-io#1) |
@yperbasis @somnathb1 Hi team, could you please let me know when it might be reviewed? |
func (ct *CommonTx) StoreFrom(val any) { | ||
ct.initializeMisc() | ||
ct.from.Store(val) | ||
} |
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.
Shouldn't the receivers be for TransactionMisc
instead
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.
If then, we can't wrap initializeMisc()
@@ -455,13 +455,13 @@ func (tx *AccessListTx) FakeSign(address libcommon.Address) (Transaction, error) | |||
cpy.R.Set(u256.Num1) | |||
cpy.S.Set(u256.Num1) | |||
cpy.V.Set(u256.Num4) | |||
cpy.from.Store(address) | |||
cpy.StoreFrom(address) |
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.
Rather than wrapping, checking nil should be a part of the accessing code
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.
So you prefer like this?
if cpy.TransactionMisc == nil {
cpy.TransactionMisc = &TransactionMisc{}
}
cpy.from.Store(address)
I think it's easy to make nil pointer errors if developer forget to check nil. So I wrap store/load methods like this. Can you tell me why you prefer manual nil check?
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.
Because it's never intended to be used with a nil
, and if the developer forgets to check nil, it must be a bug before that point
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.
@somnathb1 Got it. I have some questions:
- Are you talking about only this method(FakeSign)? if so, I agree that it's never called with nil TransactionMisc because it's initialized in copy().
- Or are you talking about every code using the new Load/Store methods in this PR?
I made these new Load/Store methods because I changed the TransactionMisc in TX structs to a pointer, so TransactionMisc won't be initialized automatically when TX instances are initialized. Actually, I saw the nil pointer error before I made these methods.
As you know, TransactionMisc
is used as cache in the current code, so I believe calling load/store methods before creating it is possible.
What do you think? Please let me know if I'm missing something!
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.
All code, in general.
I think, though, that making TransactionMisc
a pointer isn't the right way to go. It should rather be that all places that make use of "creating" a xyz_Tx
object should do it with a store()
call. Thus, this PR, I don't fully agree with
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.
@somnathb1 May I ask you why you don't think making TransactionMisc as a pointer is the right way?
Superseded by PR #11512 |
This is a follow-up of the previous PR: #9667
As described in the previous PR, we must not copy
atomic.Value
, butTransactionMisc
hasatomic.Value
, and it is implicitly copied in such codes (like #9667 (comment)).So I made
CommonTx
haveTransactionMisc
as a pointer to prevent implicit copy.And added store/load methods for
atomic.Value
to prevent nil pointer error at the initial time.The concern about this change is there could be two TX objects which are sharing a same
TransactionMisc
pointer. This could make performance improvement(because cache is preserved), but may make bugs. I wanna ask your opinion. Thanks!