mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 07:37:20 +00:00
core/types/bal: change code change type to list (#33774)
To align with the latest spec of EIP-7928: ``` # CodeChange: [block_access_index, new_code] CodeChange = [BlockAccessIndex, Bytecode] ```
This commit is contained in:
parent
01083736c8
commit
199ac16e07
4 changed files with 61 additions and 54 deletions
|
|
@ -24,13 +24,6 @@ import (
|
|||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// CodeChange contains the runtime bytecode deployed at an address and the
|
||||
// transaction index where the deployment took place.
|
||||
type CodeChange struct {
|
||||
TxIndex uint16
|
||||
Code []byte `json:"code,omitempty"`
|
||||
}
|
||||
|
||||
// ConstructionAccountAccess contains post-block account state for mutations as well as
|
||||
// all storage keys that were read during execution. It is used when building block
|
||||
// access list during execution.
|
||||
|
|
@ -55,9 +48,9 @@ type ConstructionAccountAccess struct {
|
|||
// by tx index.
|
||||
NonceChanges map[uint16]uint64 `json:"nonceChanges,omitempty"`
|
||||
|
||||
// CodeChange is only set for contract accounts which were deployed in
|
||||
// the block.
|
||||
CodeChange *CodeChange `json:"codeChange,omitempty"`
|
||||
// CodeChange contains the post-state contract code of an account keyed
|
||||
// by tx index.
|
||||
CodeChange map[uint16][]byte `json:"codeChange,omitempty"`
|
||||
}
|
||||
|
||||
// NewConstructionAccountAccess initializes the account access object.
|
||||
|
|
@ -67,6 +60,7 @@ func NewConstructionAccountAccess() *ConstructionAccountAccess {
|
|||
StorageReads: make(map[common.Hash]struct{}),
|
||||
BalanceChanges: make(map[uint16]*uint256.Int),
|
||||
NonceChanges: make(map[uint16]uint64),
|
||||
CodeChange: make(map[uint16][]byte),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,10 +114,8 @@ func (b *ConstructionBlockAccessList) CodeChange(address common.Address, txIndex
|
|||
if _, ok := b.Accounts[address]; !ok {
|
||||
b.Accounts[address] = NewConstructionAccountAccess()
|
||||
}
|
||||
b.Accounts[address].CodeChange = &CodeChange{
|
||||
TxIndex: txIndex,
|
||||
Code: bytes.Clone(code),
|
||||
}
|
||||
// TODO(rjl493456442) is it essential to deep-copy the code?
|
||||
b.Accounts[address].CodeChange[txIndex] = bytes.Clone(code)
|
||||
}
|
||||
|
||||
// NonceChange records tx post-state nonce of any contract-like accounts whose
|
||||
|
|
@ -170,12 +162,11 @@ func (b *ConstructionBlockAccessList) Copy() *ConstructionBlockAccessList {
|
|||
aaCopy.BalanceChanges = balances
|
||||
aaCopy.NonceChanges = maps.Clone(aa.NonceChanges)
|
||||
|
||||
if aa.CodeChange != nil {
|
||||
aaCopy.CodeChange = &CodeChange{
|
||||
TxIndex: aa.CodeChange.TxIndex,
|
||||
Code: bytes.Clone(aa.CodeChange.Code),
|
||||
}
|
||||
codes := make(map[uint16][]byte, len(aa.CodeChange))
|
||||
for index, code := range aa.CodeChange {
|
||||
codes[index] = bytes.Clone(code)
|
||||
}
|
||||
aaCopy.CodeChange = codes
|
||||
res.Accounts[addr] = &aaCopy
|
||||
}
|
||||
return &res
|
||||
|
|
|
|||
|
|
@ -119,6 +119,13 @@ func (e *encodingSlotWrites) validate() error {
|
|||
return errors.New("storage write tx indices not in order")
|
||||
}
|
||||
|
||||
// encodingCodeChange contains the runtime bytecode deployed at an address
|
||||
// and the transaction index where the deployment took place.
|
||||
type encodingCodeChange struct {
|
||||
TxIndex uint16 `ssz-size:"2"`
|
||||
Code []byte `ssz-max:"300000"` // TODO(rjl493456442) shall we put the limit here? The limit will be increased gradually
|
||||
}
|
||||
|
||||
// AccountAccess is the encoding format of ConstructionAccountAccess.
|
||||
type AccountAccess struct {
|
||||
Address [20]byte `ssz-size:"20"` // 20-byte Ethereum address
|
||||
|
|
@ -126,7 +133,7 @@ type AccountAccess struct {
|
|||
StorageReads [][32]byte `ssz-max:"300000"` // Read-only storage keys
|
||||
BalanceChanges []encodingBalanceChange `ssz-max:"300000"` // Balance changes ([tx_index -> post_balance])
|
||||
NonceChanges []encodingAccountNonce `ssz-max:"300000"` // Nonce changes ([tx_index -> new_nonce])
|
||||
Code []CodeChange `ssz-max:"1"` // Code changes ([tx_index -> new_code])
|
||||
CodeChanges []encodingCodeChange `ssz-max:"300000"` // Code changes ([tx_index -> new_code])
|
||||
}
|
||||
|
||||
// validate converts the account accesses out of encoding format.
|
||||
|
|
@ -166,9 +173,16 @@ func (e *AccountAccess) validate() error {
|
|||
return errors.New("nonce changes not in ascending order by tx index")
|
||||
}
|
||||
|
||||
// Convert code change
|
||||
if len(e.Code) == 1 {
|
||||
if len(e.Code[0].Code) > params.MaxCodeSize {
|
||||
// Check the code changes are sorted in order
|
||||
if !slices.IsSortedFunc(e.CodeChanges, func(a, b encodingCodeChange) int {
|
||||
return cmp.Compare[uint16](a.TxIndex, b.TxIndex)
|
||||
}) {
|
||||
return errors.New("code changes not in ascending order by tx index")
|
||||
}
|
||||
for _, change := range e.CodeChanges {
|
||||
// TODO(rjl493456442): This check should be fork-aware, since the limit may
|
||||
// differ across forks.
|
||||
if len(change.Code) > params.MaxCodeSize {
|
||||
return errors.New("code change contained oversized code")
|
||||
}
|
||||
}
|
||||
|
|
@ -182,6 +196,8 @@ func (e *AccountAccess) Copy() AccountAccess {
|
|||
StorageReads: slices.Clone(e.StorageReads),
|
||||
BalanceChanges: slices.Clone(e.BalanceChanges),
|
||||
NonceChanges: slices.Clone(e.NonceChanges),
|
||||
StorageWrites: make([]encodingSlotWrites, 0, len(e.StorageWrites)),
|
||||
CodeChanges: make([]encodingCodeChange, 0, len(e.CodeChanges)),
|
||||
}
|
||||
for _, storageWrite := range e.StorageWrites {
|
||||
res.StorageWrites = append(res.StorageWrites, encodingSlotWrites{
|
||||
|
|
@ -189,13 +205,11 @@ func (e *AccountAccess) Copy() AccountAccess {
|
|||
Accesses: slices.Clone(storageWrite.Accesses),
|
||||
})
|
||||
}
|
||||
if len(e.Code) == 1 {
|
||||
res.Code = []CodeChange{
|
||||
{
|
||||
e.Code[0].TxIndex,
|
||||
bytes.Clone(e.Code[0].Code),
|
||||
},
|
||||
}
|
||||
for _, codeChange := range e.CodeChanges {
|
||||
res.CodeChanges = append(res.CodeChanges, encodingCodeChange{
|
||||
TxIndex: codeChange.TxIndex,
|
||||
Code: bytes.Clone(codeChange.Code),
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
@ -212,11 +226,11 @@ var _ rlp.Encoder = &ConstructionBlockAccessList{}
|
|||
func (a *ConstructionAccountAccess) toEncodingObj(addr common.Address) AccountAccess {
|
||||
res := AccountAccess{
|
||||
Address: addr,
|
||||
StorageWrites: make([]encodingSlotWrites, 0),
|
||||
StorageReads: make([][32]byte, 0),
|
||||
BalanceChanges: make([]encodingBalanceChange, 0),
|
||||
NonceChanges: make([]encodingAccountNonce, 0),
|
||||
Code: nil,
|
||||
StorageWrites: make([]encodingSlotWrites, 0, len(a.StorageWrites)),
|
||||
StorageReads: make([][32]byte, 0, len(a.StorageReads)),
|
||||
BalanceChanges: make([]encodingBalanceChange, 0, len(a.BalanceChanges)),
|
||||
NonceChanges: make([]encodingAccountNonce, 0, len(a.NonceChanges)),
|
||||
CodeChanges: make([]encodingCodeChange, 0, len(a.CodeChange)),
|
||||
}
|
||||
|
||||
// Convert write slots
|
||||
|
|
@ -268,13 +282,13 @@ func (a *ConstructionAccountAccess) toEncodingObj(addr common.Address) AccountAc
|
|||
}
|
||||
|
||||
// Convert code change
|
||||
if a.CodeChange != nil {
|
||||
res.Code = []CodeChange{
|
||||
{
|
||||
a.CodeChange.TxIndex,
|
||||
bytes.Clone(a.CodeChange.Code),
|
||||
},
|
||||
}
|
||||
codeIndices := slices.Collect(maps.Keys(a.CodeChange))
|
||||
slices.SortFunc(codeIndices, cmp.Compare[uint16])
|
||||
for _, idx := range codeIndices {
|
||||
res.CodeChanges = append(res.CodeChanges, encodingCodeChange{
|
||||
TxIndex: idx,
|
||||
Code: a.CodeChange[idx],
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
@ -327,9 +341,9 @@ func (e *BlockAccessList) PrettyPrint() string {
|
|||
printWithIndent(2, fmt.Sprintf("%d: %d", change.TxIdx, change.Nonce))
|
||||
}
|
||||
|
||||
if len(accountDiff.Code) > 0 {
|
||||
printWithIndent(1, "code:")
|
||||
printWithIndent(2, fmt.Sprintf("%d: %x", accountDiff.Code[0].TxIndex, accountDiff.Code[0].Code))
|
||||
printWithIndent(1, "code changes:")
|
||||
for _, change := range accountDiff.CodeChanges {
|
||||
printWithIndent(2, fmt.Sprintf("%d: %x", change.TxIndex, change.Code))
|
||||
}
|
||||
}
|
||||
return res.String()
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func (obj *BlockAccessList) EncodeRLP(_w io.Writer) error {
|
|||
}
|
||||
w.ListEnd(_tmp15)
|
||||
_tmp18 := w.List()
|
||||
for _, _tmp19 := range _tmp2.Code {
|
||||
for _, _tmp19 := range _tmp2.CodeChanges {
|
||||
_tmp20 := w.List()
|
||||
w.WriteUint64(uint64(_tmp19.TxIndex))
|
||||
w.WriteBytes(_tmp19.Code)
|
||||
|
|
@ -228,13 +228,13 @@ func (obj *BlockAccessList) DecodeRLP(dec *rlp.Stream) error {
|
|||
return err
|
||||
}
|
||||
_tmp2.NonceChanges = _tmp17
|
||||
// Code:
|
||||
var _tmp21 []CodeChange
|
||||
// CodeChanges:
|
||||
var _tmp21 []encodingCodeChange
|
||||
if _, err := dec.List(); err != nil {
|
||||
return err
|
||||
}
|
||||
for dec.MoreDataInList() {
|
||||
var _tmp22 CodeChange
|
||||
var _tmp22 encodingCodeChange
|
||||
{
|
||||
if _, err := dec.List(); err != nil {
|
||||
return err
|
||||
|
|
@ -260,7 +260,7 @@ func (obj *BlockAccessList) DecodeRLP(dec *rlp.Stream) error {
|
|||
if err := dec.ListEnd(); err != nil {
|
||||
return err
|
||||
}
|
||||
_tmp2.Code = _tmp21
|
||||
_tmp2.CodeChanges = _tmp21
|
||||
if err := dec.ListEnd(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,9 +60,8 @@ func makeTestConstructionBAL() *ConstructionBlockAccessList {
|
|||
1: 2,
|
||||
2: 6,
|
||||
},
|
||||
CodeChange: &CodeChange{
|
||||
TxIndex: 0,
|
||||
Code: common.Hex2Bytes("deadbeef"),
|
||||
CodeChange: map[uint16][]byte{
|
||||
0: common.Hex2Bytes("deadbeef"),
|
||||
},
|
||||
},
|
||||
common.BytesToAddress([]byte{0xff, 0xff, 0xff}): {
|
||||
|
|
@ -85,6 +84,9 @@ func makeTestConstructionBAL() *ConstructionBlockAccessList {
|
|||
NonceChanges: map[uint16]uint64{
|
||||
1: 2,
|
||||
},
|
||||
CodeChange: map[uint16][]byte{
|
||||
0: common.Hex2Bytes("deadbeef"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -179,7 +181,7 @@ func makeTestAccountAccess(sort bool) AccountAccess {
|
|||
StorageReads: storageReads,
|
||||
BalanceChanges: balances,
|
||||
NonceChanges: nonces,
|
||||
Code: []CodeChange{
|
||||
CodeChanges: []encodingCodeChange{
|
||||
{
|
||||
TxIndex: 100,
|
||||
Code: testrand.Bytes(256),
|
||||
|
|
|
|||
Loading…
Reference in a new issue