Skip to content
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

Implement EXTCODE* changes for pdn-5 (#13106) #13448

Merged
merged 4 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions core/state/intra_block_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,17 +278,6 @@ func (sdb *IntraBlockState) ResolveCode(addr libcommon.Address) []byte {
return sdb.GetCode(addr)
}

func (sdb *IntraBlockState) ResolveCodeSize(addr libcommon.Address) int {
// eip-7702
size := sdb.GetCodeSize(addr)
if size == types.DelegateDesignationCodeSize {
// might be delegated designation
return len(sdb.ResolveCode(addr))
}

return size
}

func (sdb *IntraBlockState) GetDelegatedDesignation(addr libcommon.Address) (libcommon.Address, bool) {
// eip-7702
code := sdb.GetCode(addr)
Expand Down
2 changes: 1 addition & 1 deletion core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
data.Reset()

// 1. chainId check
if auth.ChainID != 0 && (!rules.ChainID.IsUint64() || rules.ChainID.Uint64() != auth.ChainID) {
if !auth.ChainID.IsZero() && rules.ChainID.String() != auth.ChainID.String() {
log.Debug("invalid chainID, skipping", "chainId", auth.ChainID, "auth index", i)
continue
}
Expand Down
17 changes: 9 additions & 8 deletions core/types/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
)

type Authorization struct {
ChainID uint64
ChainID uint256.Int
Address libcommon.Address
Nonce uint64
YParity uint8
Expand All @@ -38,7 +38,7 @@ func (ath *Authorization) copy() *Authorization {
}

func (ath *Authorization) RecoverSigner(data *bytes.Buffer, b []byte) (*libcommon.Address, error) {
authLen := rlp2.U64Len(ath.ChainID)
authLen := (1 + rlp.Uint256LenExcludingHead(&ath.ChainID))
authLen += (1 + length.Addr)
authLen += rlp2.U64Len(ath.Nonce)

Expand All @@ -47,7 +47,7 @@ func (ath *Authorization) RecoverSigner(data *bytes.Buffer, b []byte) (*libcommo
}

// chainId, address, nonce
if err := rlp.EncodeInt(ath.ChainID, data, b); err != nil {
if err := ath.ChainID.EncodeRLP(data); err != nil {
return nil, err
}

Expand Down Expand Up @@ -96,9 +96,9 @@ func (ath *Authorization) RecoverSigner(data *bytes.Buffer, b []byte) (*libcommo
}

func authorizationSize(auth Authorization) (authLen int) {
authLen = rlp2.U64Len(auth.ChainID)
authLen = (1 + rlp.Uint256LenExcludingHead(&auth.ChainID))
authLen += rlp2.U64Len(auth.Nonce)
authLen += (1 + length.Addr)
authLen += 1 + length.Addr

authLen += rlp2.U64Len(uint64(auth.YParity)) + (1 + rlp.Uint256LenExcludingHead(&auth.R)) + (1 + rlp.Uint256LenExcludingHead(&auth.S))

Expand All @@ -124,10 +124,11 @@ func decodeAuthorizations(auths *[]Authorization, s *rlp.Stream) error {
for _, err = s.List(); err == nil; _, err = s.List() {
auth := Authorization{}

// chainId
if auth.ChainID, err = s.Uint(); err != nil {
var chainId []byte
if chainId, err = s.Uint256Bytes(); err != nil {
return err
}
auth.ChainID.SetBytes(chainId)

// address
if b, err = s.Bytes(); err != nil {
Expand Down Expand Up @@ -191,7 +192,7 @@ func encodeAuthorizations(authorizations []Authorization, w io.Writer, b []byte)
}

// 1. encode ChainId
if err := rlp.EncodeInt(auth.ChainID, w, b); err != nil {
if err := auth.ChainID.EncodeRLP(w); err != nil {
return err
}
// 2. encode Address
Expand Down
7 changes: 6 additions & 1 deletion core/types/encdec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ func (tr *TRand) RandUint64() *uint64 {
return &a
}

func (tr *TRand) RandUint256() *uint256.Int {
a := new(uint256.Int).SetBytes(tr.RandBytes(tr.RandIntInRange(1, 32)))
return a
}

func (tr *TRand) RandBig() *big.Int {
return big.NewInt(int64(tr.rnd.Int()))
}
Expand Down Expand Up @@ -120,7 +125,7 @@ func (tr *TRand) RandAuthorizations(size int) []Authorization {
auths := make([]Authorization, size)
for i := 0; i < size; i++ {
auths[i] = Authorization{
ChainID: *tr.RandUint64(),
ChainID: *tr.RandUint256(),
Address: tr.RandAddress(),
Nonce: *tr.RandUint64(),
YParity: uint8(*tr.RandUint64()),
Expand Down
10 changes: 7 additions & 3 deletions core/types/transaction_marshalling.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type txJSON struct {
}

type JsonAuthorization struct {
ChainID hexutil.Uint64 `json:"chainId"`
ChainID hexutil.Big `json:"chainId"`
Address libcommon.Address `json:"address"`
Nonce hexutil.Uint64 `json:"nonce"`
V hexutil.Uint64 `json:"v"`
Expand All @@ -60,7 +60,7 @@ type JsonAuthorization struct {
}

func (a JsonAuthorization) FromAuthorization(authorization Authorization) JsonAuthorization {
a.ChainID = (hexutil.Uint64)(authorization.ChainID)
a.ChainID = hexutil.Big(*authorization.ChainID.ToBig())
a.Address = authorization.Address
a.Nonce = (hexutil.Uint64)(authorization.Nonce)

Expand All @@ -72,10 +72,14 @@ func (a JsonAuthorization) FromAuthorization(authorization Authorization) JsonAu

func (a JsonAuthorization) ToAuthorization() (Authorization, error) {
auth := Authorization{
ChainID: a.ChainID.Uint64(),
Address: a.Address,
Nonce: a.Nonce.Uint64(),
}
chainId, overflow := uint256.FromBig((*big.Int)(&a.ChainID))
if overflow {
return auth, errors.New("chainId in authorization does not fit in 256 bits")
}
auth.ChainID = *chainId
yParity := a.V.Uint64()
if yParity >= 1<<8 {
return auth, errors.New("y parity in authorization does not fit in 8 bits")
Expand Down
3 changes: 0 additions & 3 deletions core/vm/eips.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,6 @@ func enable7516(jt *JumpTable) {
}

func enable7702(jt *JumpTable) {
jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP7702
jt[EXTCODESIZE].dynamicGas = gasEip7702CodeCheck
jt[EXTCODEHASH].dynamicGas = gasEip7702CodeCheck
jt[CALL].dynamicGas = gasCallEIP7702
jt[CALLCODE].dynamicGas = gasCallCodeEIP7702
jt[STATICCALL].dynamicGas = gasStaticCallEIP7702
Expand Down
1 change: 0 additions & 1 deletion core/vm/evmtypes/evmtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ type IntraBlockState interface {
// eip-7702; delegated designations
ResolveCodeHash(common.Address) common.Hash
ResolveCode(common.Address) []byte
ResolveCodeSize(common.Address) int
GetDelegatedDesignation(common.Address) (common.Address, bool)

AddRefund(uint64)
Expand Down
29 changes: 25 additions & 4 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package vm

import (
"errors"
"fmt"
"math"

Expand Down Expand Up @@ -374,7 +375,15 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte

func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.Peek()
slot.SetUint64(uint64(interpreter.evm.IntraBlockState().ResolveCodeSize(slot.Bytes20())))
addr := slot.Bytes20()
codeSize := interpreter.evm.IntraBlockState().GetCodeSize(addr)
if codeSize == types.DelegateDesignationCodeSize {
_, ok := interpreter.evm.IntraBlockState().GetDelegatedDesignation(addr)
if ok {
codeSize = 2 // first two bytes only: EIP-7702
}
}
slot.SetUint64(uint64(codeSize))
return nil, nil
}

Expand Down Expand Up @@ -411,7 +420,12 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
addr := libcommon.Address(a.Bytes20())
len64 := length.Uint64()

codeCopy := getDataBig(interpreter.evm.IntraBlockState().ResolveCode(addr), &codeOffset, len64)
code := interpreter.evm.IntraBlockState().GetCode(addr)
if _, ok := types.ParseDelegation(code); ok {
code = append([]byte{}, (params.DelegatedDesignationPrefix[0:2])...)
}

codeCopy := getDataBig(code, &codeOffset, len64)
scope.Memory.Set(memOffset.Uint64(), len64, codeCopy)
return nil, nil
}
Expand Down Expand Up @@ -460,7 +474,14 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
if interpreter.evm.IntraBlockState().Empty(address) {
slot.Clear()
} else {
slot.SetBytes(interpreter.evm.IntraBlockState().ResolveCodeHash(address).Bytes())
var codeHash libcommon.Hash
_, ok := interpreter.evm.IntraBlockState().GetDelegatedDesignation(address)
if ok {
codeHash = params.DelegatedCodeHash
} else {
codeHash = interpreter.evm.IntraBlockState().GetCodeHash(address)
}
slot.SetBytes(codeHash.Bytes())
}
return nil, nil
}
Expand Down Expand Up @@ -519,7 +540,7 @@ func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
var overflow bool
v, overflow = uint256.FromBig(interpreter.evm.Context.Difficulty)
if overflow {
return nil, fmt.Errorf("interpreter.evm.Context.Difficulty higher than 2^256-1")
return nil, errors.New("interpreter.evm.Context.Difficulty higher than 2^256-1")
}
}
scope.Stack.Push(v)
Expand Down
56 changes: 2 additions & 54 deletions core/vm/operations_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
}

// Check if code is a delegation and if so, charge for resolution.
if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr)
if ok {
var ddCost uint64
if evm.intraBlockState.AddAddressToAccessList(dd) {
ddCost = params.ColdAccountAccessCostEIP2929
Expand Down Expand Up @@ -296,56 +297,3 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
return gas, nil
}
}

func gasEip7702CodeCheck(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) {
addr := libcommon.Address(stack.Peek().Bytes20())
// The warm storage read cost is already charged as constantGas
// Check slot presence in the access list
var cost uint64
if evm.intraBlockState.AddAddressToAccessList(addr) {
// Check if code is a delegation and if so, charge for resolution
cost = params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929
}

if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
if evm.intraBlockState.AddAddressToAccessList(dd) {
cost += params.ColdAccountAccessCostEIP2929
} else {
cost += params.WarmStorageReadCostEIP2929
}
}

return cost, nil
}

func gasExtCodeCopyEIP7702(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) {
// memory expansion first (dynamic part of pre-2929 implementation)
gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize)
if err != nil {
return 0, err
}
addr := libcommon.Address(stack.Peek().Bytes20())
// Check slot presence in the access list
if evm.intraBlockState.AddAddressToAccessList(addr) {
var overflow bool
// We charge (cold-warm), since 'warm' is already charged as constantGas
if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929-params.WarmStorageReadCostEIP2929); overflow {
return 0, ErrGasUintOverflow
}
}

// Check if addr has a delegation and if so, charge for resolution
if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
var overflow bool
if evm.intraBlockState.AddAddressToAccessList(dd) {
if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929); overflow {
return 0, ErrGasUintOverflow
}
} else {
if gas, overflow = math.SafeAdd(gas, params.WarmStorageReadCostEIP2929); overflow {
return 0, ErrGasUintOverflow
}
}
}
return gas, nil
}
1 change: 1 addition & 0 deletions params/protocol_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ const (
)

var DelegatedDesignationPrefix = []byte{0xef, 0x01, 0x00}
var DelegatedCodeHash = common.HexToHash("0xeadcdba66a79ab5dce91622d1d75c8cff5cff0b96944c3bf1072cd08ce018329")

// EIP-4788: Beacon block root in the EVM
var BeaconRootsAddress = common.HexToAddress("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02")
Expand Down
Loading