create transaction

Some corner cases for create
* Don't consume all gas with an invalid EOF contract
* don't allow CREATE/CREATE2 opcodes to create EOF
This commit is contained in:
Danno Ferrin 2024-09-14 16:00:46 -06:00
parent 810397f56d
commit c7efbf466e
2 changed files with 6 additions and 8 deletions

View file

@ -517,7 +517,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
// invalid, the tx is considered valid (so update nonce), but // invalid, the tx is considered valid (so update nonce), but
// is to be treated as an exceptional abort (so burn all gas). // is to be treated as an exceptional abort (so burn all gas).
if errors.Is(vmerr, vm.ErrInvalidEOFInitcode) { if errors.Is(vmerr, vm.ErrInvalidEOFInitcode) {
st.gasRemaining = 0 //st.gasRemaining = 0
st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1) st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1)
} }
} else { } else {

View file

@ -482,11 +482,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// Validate initcode per EOF rules. If caller is EOF and initcode is legacy, fail. // Validate initcode per EOF rules. If caller is EOF and initcode is legacy, fail.
isInitcodeEOF := hasEOFMagic(codeAndHash.code) isInitcodeEOF := hasEOFMagic(codeAndHash.code)
if evm.chainRules.IsPrague { if isInitcodeEOF {
if isInitcodeEOF { if allowEOF {
if !allowEOF {
return nil, common.Address{}, gas, fmt.Errorf("%w: %v", ErrInvalidEOFInitcode, ErrLegacyCode)
}
// If the initcode is EOF, verify it is well-formed. // If the initcode is EOF, verify it is well-formed.
var c Container var c Container
if err := c.UnmarshalBinary(codeAndHash.code, isInitcodeEOF); err != nil { if err := c.UnmarshalBinary(codeAndHash.code, isInitcodeEOF); err != nil {
@ -496,7 +493,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
return nil, common.Address{}, gas, fmt.Errorf("%w: %v", ErrInvalidEOFInitcode, err) return nil, common.Address{}, gas, fmt.Errorf("%w: %v", ErrInvalidEOFInitcode, err)
} }
contract.Container = &c contract.Container = &c
} else if allowEOF { } else {
// Don't allow EOF contract to execute legacy initcode. // Don't allow EOF contract to execute legacy initcode.
return nil, common.Address{}, gas, ErrLegacyCode return nil, common.Address{}, gas, ErrLegacyCode
} }
@ -573,7 +570,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// Reject code starting with 0xEF if EIP-3541 is enabled. // Reject code starting with 0xEF if EIP-3541 is enabled.
if err == nil && len(ret) >= 1 && HasEOFByte(ret) { if err == nil && len(ret) >= 1 && HasEOFByte(ret) {
if evm.chainRules.IsShanghai { if evm.chainRules.IsPrague && isInitcodeEOF {
fmt.Printf("FIXME - valid EOF deployment\n")
// Don't reject EOF contracts after Shanghai // Don't reject EOF contracts after Shanghai
} else if evm.chainRules.IsLondon { } else if evm.chainRules.IsLondon {
err = ErrInvalidCode err = ErrInvalidCode