-
Notifications
You must be signed in to change notification settings - Fork 20.6k
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
core/types: add method to compute transaction intrinsic gas #31109
base: master
Are you sure you want to change the base?
core/types: add method to compute transaction intrinsic gas #31109
Conversation
Please use this method to prevent potential future expansion of the |
core/types/transaction.go
Outdated
if byt != 0 { | ||
nz++ | ||
} | ||
} |
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.
While you're at it, you might as well change the loop to:
z := uint64(bytes.Count(data, []byte{0}))
nz := uint64(len(data)) - z
bytes.Count() uses an optimized assembly implementation to count bytes.
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.
+1
Hi @rjl493456442. Please, can you give me more details on what you mean? |
He means the function |
Okay. I will push the changes. |
Hi @rjl493456442 Can you review the these changes please? |
core/bench_test.go
Outdated
Data: data, | ||
GasPrice: gasPrice, | ||
}) | ||
gas, _ := tx0.IntrinsicGas(&rules) |
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.
Repeating the tx construction here is not great, and hightlights a shortcoming of having IntrinsicGas
as a method of Transaction
: you can't compute the intrinsic gas without creating the tx first, but it's often called to fill in the Gas
of a new transaction. We need to think a bit harder how to solve this one. I have a hunch IntrinsicGas
could be defined over types.TxData
. But then we'd need to implement TxData
in Transaction
.
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.
I think TxData is already in Transaction as the inner field.
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.
OK, I've figured it out. What we need to do is, add a function IntrinsicGas(TxData, *params.Rules)
to core/types
. Keep the IntrinsicGas
method on Transaction
, and make it call this new function on tx.inner
.
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.
OK. I wonder if the IntrinsicGas
function could not have this signature instead: func (data []byte, accessList types.AccessList, authList []types.SetCodeAuthorization, isContractCreation, rules *params.Rules) (uint64, error)
.
It allows to pass fields in tx.inner
instead of tx.inner
, we can then do without a variable of type TxData
if necessary. However, review the modifications please.
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.
Left a few comments. Need to decide how to pass the txdata in state_transition.
Please rebase also when you can.
core/state_transition.go
Outdated
Gas: msg.GasLimit, | ||
Data: msg.Data, | ||
GasPrice: msg.GasPrice, | ||
}) |
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.
I think this isn't great.
By going tx -> msg -> back to tx we require ourselves to convert to msg correct and back correctly. TxData
seems like the right thing to feed IntrinsicGas
, but forcing stuff into a legacy tx when we don't exactly know the origin (or it isn't defined) isn't correct.
This currently fails to compute the intrinsic gas correctly for SetCode
txs, because when converting from msg to a tx, the conversion is for a tx that does not have authorizations. Since SetCode
seems like a perfect superset of all possible values which goes into InstrinsicGas
, but if a new tx type comes along without auths and needs a new input to the IntrinsicGas
computation, we'll have the same problem again.
Seems like there are two paths here:
-
add new struct like
GenericTxData
that implementsTxData
and use this in places where we don't know the tx type -
add a new method on
Message
that infers the tx type and constructs the correctTxData
-
is probably less code, but adds a weird export. 2) is more code, but still has the problem occasionally in other places outside
core
like tests where we want to generically compute some intrinsic gas.
I think I lean towards 1) ?
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.
Thanks for the review. I understand the problems posed. I'm going to look into the new GenericTxData
structure. But I would also like to know if we should then put the IntrinsicGas
method on TxData
or leave it on Transaction
.
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.
I think it should be on Transaction
like you have it.
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.
I also think we can have it on both Transaction and as a standalone function.
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.
Ahh, wait, I see the issue now. So we would need to implement TxData with Message somehow, but that's not possible because it's supposed to be a private interface. One thing we could do is making the intrinsic gas a part of Message as a field. Then we'd compute it earlier, like in ApplyTransaction. Just unsure how much of a ripple effect this has on other 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.
Right. I kinda like this idea of precomputing earlier though.
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.
It will then remove the need for GenericTxData
struct.
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.
Hello @fjl @lightclient. The effect is that the gas must be computed in Message
before calling ApplyMessage
wherever it is executed. Not just at the ApplyTransaction
level. A method SetGas(tx types.TxData, rules *params.Rules)
for Message
can be useful for that.
core/types/transaction.go
Outdated
if byt != 0 { | ||
nz++ | ||
} | ||
} |
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.
+1
core/types/transaction.go
Outdated
data = txdata.data() | ||
accessList = txdata.accessList() | ||
authList = txdata.setCodeAuthorizations() |
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.
I think these can be removed and use the txdata
getter directly
97a96f3
to
ac10896
Compare
} | ||
|
||
// IntrinsicGas computes the 'intrinsic gas' for a message with the given data. | ||
func IntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) { |
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.
It's annoying to have this function return an error. The only cases where it could return an error is for very large data, which is highly unlikely in practice. It should panic in these cases instead.
The function IntrinsicGas
is supposed to be used when construction a new transaction. If we want to be even more safe, we could keep the error-returning variant as an internal function for use in Transaction.IntrinsicGas
, since that one is used to validate transactions received over p2p.
…ated computation bytes count algo
@cedrickah You force-pushed over my commit. Git must have warned about un-synced commits which you probably ignored. Please double check before force pushing. I have now pushed it again. It fixes the TransactionTest in Btw after the latest refactor now many more tests are failing. Please look into them. You can see them on appveyor: https://ci.appveyor.com/project/ethereum/go-ethereum/builds/51553192 (it started another run now so wait a bit). |
Ooh sorry. I'll be more careful. I'm leaning towards |
Hello @s1na . I saw the logs. As we are trying to computer gas in |
Resolves: #31058
Added an
IntrinsicGas()
method incore/types
to compute transaction intrinsic gas.