Skip to content

Commit 07c6e9c

Browse files
authored
Implement EXTCODE* changes for pdn-5 (#13106) (#13448)
See ethereum/EIPs#8969 Issue board: #12401 Cherry pick #13106
1 parent e6b7ad8 commit 07c6e9c

10 files changed

+51
-86
lines changed

core/state/intra_block_state.go

-11
Original file line numberDiff line numberDiff line change
@@ -278,17 +278,6 @@ func (sdb *IntraBlockState) ResolveCode(addr libcommon.Address) []byte {
278278
return sdb.GetCode(addr)
279279
}
280280

281-
func (sdb *IntraBlockState) ResolveCodeSize(addr libcommon.Address) int {
282-
// eip-7702
283-
size := sdb.GetCodeSize(addr)
284-
if size == types.DelegateDesignationCodeSize {
285-
// might be delegated designation
286-
return len(sdb.ResolveCode(addr))
287-
}
288-
289-
return size
290-
}
291-
292281
func (sdb *IntraBlockState) GetDelegatedDesignation(addr libcommon.Address) (libcommon.Address, bool) {
293282
// eip-7702
294283
code := sdb.GetCode(addr)

core/state_transition.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
364364
data.Reset()
365365

366366
// 1. chainId check
367-
if auth.ChainID != 0 && (!rules.ChainID.IsUint64() || rules.ChainID.Uint64() != auth.ChainID) {
367+
if !auth.ChainID.IsZero() && rules.ChainID.String() != auth.ChainID.String() {
368368
log.Debug("invalid chainID, skipping", "chainId", auth.ChainID, "auth index", i)
369369
continue
370370
}

core/types/authorization.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
)
1919

2020
type Authorization struct {
21-
ChainID uint64
21+
ChainID uint256.Int
2222
Address libcommon.Address
2323
Nonce uint64
2424
YParity uint8
@@ -38,7 +38,7 @@ func (ath *Authorization) copy() *Authorization {
3838
}
3939

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

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

4949
// chainId, address, nonce
50-
if err := rlp.EncodeInt(ath.ChainID, data, b); err != nil {
50+
if err := ath.ChainID.EncodeRLP(data); err != nil {
5151
return nil, err
5252
}
5353

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

9898
func authorizationSize(auth Authorization) (authLen int) {
99-
authLen = rlp2.U64Len(auth.ChainID)
99+
authLen = (1 + rlp.Uint256LenExcludingHead(&auth.ChainID))
100100
authLen += rlp2.U64Len(auth.Nonce)
101-
authLen += (1 + length.Addr)
101+
authLen += 1 + length.Addr
102102

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

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

127-
// chainId
128-
if auth.ChainID, err = s.Uint(); err != nil {
127+
var chainId []byte
128+
if chainId, err = s.Uint256Bytes(); err != nil {
129129
return err
130130
}
131+
auth.ChainID.SetBytes(chainId)
131132

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

193194
// 1. encode ChainId
194-
if err := rlp.EncodeInt(auth.ChainID, w, b); err != nil {
195+
if err := auth.ChainID.EncodeRLP(w); err != nil {
195196
return err
196197
}
197198
// 2. encode Address

core/types/encdec_test.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ func (tr *TRand) RandUint64() *uint64 {
3636
return &a
3737
}
3838

39+
func (tr *TRand) RandUint256() *uint256.Int {
40+
a := new(uint256.Int).SetBytes(tr.RandBytes(tr.RandIntInRange(1, 32)))
41+
return a
42+
}
43+
3944
func (tr *TRand) RandBig() *big.Int {
4045
return big.NewInt(int64(tr.rnd.Int()))
4146
}
@@ -120,7 +125,7 @@ func (tr *TRand) RandAuthorizations(size int) []Authorization {
120125
auths := make([]Authorization, size)
121126
for i := 0; i < size; i++ {
122127
auths[i] = Authorization{
123-
ChainID: *tr.RandUint64(),
128+
ChainID: *tr.RandUint256(),
124129
Address: tr.RandAddress(),
125130
Nonce: *tr.RandUint64(),
126131
YParity: uint8(*tr.RandUint64()),

core/types/transaction_marshalling.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type txJSON struct {
5151
}
5252

5353
type JsonAuthorization struct {
54-
ChainID hexutil.Uint64 `json:"chainId"`
54+
ChainID hexutil.Big `json:"chainId"`
5555
Address libcommon.Address `json:"address"`
5656
Nonce hexutil.Uint64 `json:"nonce"`
5757
V hexutil.Uint64 `json:"v"`
@@ -60,7 +60,7 @@ type JsonAuthorization struct {
6060
}
6161

6262
func (a JsonAuthorization) FromAuthorization(authorization Authorization) JsonAuthorization {
63-
a.ChainID = (hexutil.Uint64)(authorization.ChainID)
63+
a.ChainID = hexutil.Big(*authorization.ChainID.ToBig())
6464
a.Address = authorization.Address
6565
a.Nonce = (hexutil.Uint64)(authorization.Nonce)
6666

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

7373
func (a JsonAuthorization) ToAuthorization() (Authorization, error) {
7474
auth := Authorization{
75-
ChainID: a.ChainID.Uint64(),
7675
Address: a.Address,
7776
Nonce: a.Nonce.Uint64(),
7877
}
78+
chainId, overflow := uint256.FromBig((*big.Int)(&a.ChainID))
79+
if overflow {
80+
return auth, errors.New("chainId in authorization does not fit in 256 bits")
81+
}
82+
auth.ChainID = *chainId
7983
yParity := a.V.Uint64()
8084
if yParity >= 1<<8 {
8185
return auth, errors.New("y parity in authorization does not fit in 8 bits")

core/vm/eips.go

-3
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,6 @@ func enable7516(jt *JumpTable) {
324324
}
325325

326326
func enable7702(jt *JumpTable) {
327-
jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP7702
328-
jt[EXTCODESIZE].dynamicGas = gasEip7702CodeCheck
329-
jt[EXTCODEHASH].dynamicGas = gasEip7702CodeCheck
330327
jt[CALL].dynamicGas = gasCallEIP7702
331328
jt[CALLCODE].dynamicGas = gasCallCodeEIP7702
332329
jt[STATICCALL].dynamicGas = gasStaticCallEIP7702

core/vm/evmtypes/evmtypes.go

-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ type IntraBlockState interface {
121121
// eip-7702; delegated designations
122122
ResolveCodeHash(common.Address) common.Hash
123123
ResolveCode(common.Address) []byte
124-
ResolveCodeSize(common.Address) int
125124
GetDelegatedDesignation(common.Address) (common.Address, bool)
126125

127126
AddRefund(uint64)

core/vm/instructions.go

+25-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package vm
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"math"
2223

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

375376
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
376377
slot := scope.Stack.Peek()
377-
slot.SetUint64(uint64(interpreter.evm.IntraBlockState().ResolveCodeSize(slot.Bytes20())))
378+
addr := slot.Bytes20()
379+
codeSize := interpreter.evm.IntraBlockState().GetCodeSize(addr)
380+
if codeSize == types.DelegateDesignationCodeSize {
381+
_, ok := interpreter.evm.IntraBlockState().GetDelegatedDesignation(addr)
382+
if ok {
383+
codeSize = 2 // first two bytes only: EIP-7702
384+
}
385+
}
386+
slot.SetUint64(uint64(codeSize))
378387
return nil, nil
379388
}
380389

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

414-
codeCopy := getDataBig(interpreter.evm.IntraBlockState().ResolveCode(addr), &codeOffset, len64)
423+
code := interpreter.evm.IntraBlockState().GetCode(addr)
424+
if _, ok := types.ParseDelegation(code); ok {
425+
code = append([]byte{}, (params.DelegatedDesignationPrefix[0:2])...)
426+
}
427+
428+
codeCopy := getDataBig(code, &codeOffset, len64)
415429
scope.Memory.Set(memOffset.Uint64(), len64, codeCopy)
416430
return nil, nil
417431
}
@@ -460,7 +474,14 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
460474
if interpreter.evm.IntraBlockState().Empty(address) {
461475
slot.Clear()
462476
} else {
463-
slot.SetBytes(interpreter.evm.IntraBlockState().ResolveCodeHash(address).Bytes())
477+
var codeHash libcommon.Hash
478+
_, ok := interpreter.evm.IntraBlockState().GetDelegatedDesignation(address)
479+
if ok {
480+
codeHash = params.DelegatedCodeHash
481+
} else {
482+
codeHash = interpreter.evm.IntraBlockState().GetCodeHash(address)
483+
}
484+
slot.SetBytes(codeHash.Bytes())
464485
}
465486
return nil, nil
466487
}
@@ -519,7 +540,7 @@ func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
519540
var overflow bool
520541
v, overflow = uint256.FromBig(interpreter.evm.Context.Difficulty)
521542
if overflow {
522-
return nil, fmt.Errorf("interpreter.evm.Context.Difficulty higher than 2^256-1")
543+
return nil, errors.New("interpreter.evm.Context.Difficulty higher than 2^256-1")
523544
}
524545
}
525546
scope.Stack.Push(v)

core/vm/operations_acl.go

+2-54
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
261261
}
262262

263263
// Check if code is a delegation and if so, charge for resolution.
264-
if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
264+
dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr)
265+
if ok {
265266
var ddCost uint64
266267
if evm.intraBlockState.AddAddressToAccessList(dd) {
267268
ddCost = params.ColdAccountAccessCostEIP2929
@@ -296,56 +297,3 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
296297
return gas, nil
297298
}
298299
}
299-
300-
func gasEip7702CodeCheck(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) {
301-
addr := libcommon.Address(stack.Peek().Bytes20())
302-
// The warm storage read cost is already charged as constantGas
303-
// Check slot presence in the access list
304-
var cost uint64
305-
if evm.intraBlockState.AddAddressToAccessList(addr) {
306-
// Check if code is a delegation and if so, charge for resolution
307-
cost = params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929
308-
}
309-
310-
if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
311-
if evm.intraBlockState.AddAddressToAccessList(dd) {
312-
cost += params.ColdAccountAccessCostEIP2929
313-
} else {
314-
cost += params.WarmStorageReadCostEIP2929
315-
}
316-
}
317-
318-
return cost, nil
319-
}
320-
321-
func gasExtCodeCopyEIP7702(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) {
322-
// memory expansion first (dynamic part of pre-2929 implementation)
323-
gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize)
324-
if err != nil {
325-
return 0, err
326-
}
327-
addr := libcommon.Address(stack.Peek().Bytes20())
328-
// Check slot presence in the access list
329-
if evm.intraBlockState.AddAddressToAccessList(addr) {
330-
var overflow bool
331-
// We charge (cold-warm), since 'warm' is already charged as constantGas
332-
if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929-params.WarmStorageReadCostEIP2929); overflow {
333-
return 0, ErrGasUintOverflow
334-
}
335-
}
336-
337-
// Check if addr has a delegation and if so, charge for resolution
338-
if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok {
339-
var overflow bool
340-
if evm.intraBlockState.AddAddressToAccessList(dd) {
341-
if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929); overflow {
342-
return 0, ErrGasUintOverflow
343-
}
344-
} else {
345-
if gas, overflow = math.SafeAdd(gas, params.WarmStorageReadCostEIP2929); overflow {
346-
return 0, ErrGasUintOverflow
347-
}
348-
}
349-
}
350-
return gas, nil
351-
}

params/protocol_params.go

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ const (
182182
)
183183

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

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

0 commit comments

Comments
 (0)