mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-11 17:31:35 +00:00
core/types/bal: update the BAL definition to the latest spec (#34799)
This PR updates the BAL structure definition to the latest the spec, - Balance has been changed from [16]byte to uint256 - Storage key and value has been changed from [32]byte to uint256 - BlockAccessList has been changed from a struct to a slice of AccountChanges - TxIndex has been changed from uint16 to uint32
This commit is contained in:
parent
b26391773d
commit
2d5da60371
5 changed files with 399 additions and 354 deletions
|
|
@ -25,13 +25,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConstructionAccountAccess contains post-block account state for mutations as well as
|
// 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
|
// all storage keys that were read during execution. It is used when building block
|
||||||
// access list during execution.
|
// access list during execution.
|
||||||
type ConstructionAccountAccess struct {
|
type ConstructionAccountAccess struct {
|
||||||
// StorageWrites is the post-state values of an account's storage slots
|
// StorageWrites is the post-state values of an account's storage slots
|
||||||
// that were modified in a block, keyed by the slot key and the tx index
|
// that were modified in a block, keyed by the slot key and the tx index
|
||||||
// where the modification occurred.
|
// where the modification occurred.
|
||||||
StorageWrites map[common.Hash]map[uint16]common.Hash `json:"storageWrites,omitempty"`
|
StorageWrites map[common.Hash]map[uint32]common.Hash `json:"storageWrites,omitempty"`
|
||||||
|
|
||||||
// StorageReads is the set of slot keys that were accessed during block
|
// StorageReads is the set of slot keys that were accessed during block
|
||||||
// execution.
|
// execution.
|
||||||
|
|
@ -42,25 +42,25 @@ type ConstructionAccountAccess struct {
|
||||||
|
|
||||||
// BalanceChanges contains the post-transaction balances of an account,
|
// BalanceChanges contains the post-transaction balances of an account,
|
||||||
// keyed by transaction indices where it was changed.
|
// keyed by transaction indices where it was changed.
|
||||||
BalanceChanges map[uint16]*uint256.Int `json:"balanceChanges,omitempty"`
|
BalanceChanges map[uint32]*uint256.Int `json:"balanceChanges,omitempty"`
|
||||||
|
|
||||||
// NonceChanges contains the post-state nonce values of an account keyed
|
// NonceChanges contains the post-state nonce values of an account keyed
|
||||||
// by tx index.
|
// by tx index.
|
||||||
NonceChanges map[uint16]uint64 `json:"nonceChanges,omitempty"`
|
NonceChanges map[uint32]uint64 `json:"nonceChanges,omitempty"`
|
||||||
|
|
||||||
// CodeChange contains the post-state contract code of an account keyed
|
// CodeChange contains the post-state contract code of an account keyed
|
||||||
// by tx index.
|
// by tx index.
|
||||||
CodeChange map[uint16][]byte `json:"codeChange,omitempty"`
|
CodeChange map[uint32][]byte `json:"codeChange,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConstructionAccountAccess initializes the account access object.
|
// NewConstructionAccountAccess initializes the account access object.
|
||||||
func NewConstructionAccountAccess() *ConstructionAccountAccess {
|
func NewConstructionAccountAccess() *ConstructionAccountAccess {
|
||||||
return &ConstructionAccountAccess{
|
return &ConstructionAccountAccess{
|
||||||
StorageWrites: make(map[common.Hash]map[uint16]common.Hash),
|
StorageWrites: make(map[common.Hash]map[uint32]common.Hash),
|
||||||
StorageReads: make(map[common.Hash]struct{}),
|
StorageReads: make(map[common.Hash]struct{}),
|
||||||
BalanceChanges: make(map[uint16]*uint256.Int),
|
BalanceChanges: make(map[uint32]*uint256.Int),
|
||||||
NonceChanges: make(map[uint16]uint64),
|
NonceChanges: make(map[uint32]uint64),
|
||||||
CodeChange: make(map[uint16][]byte),
|
CodeChange: make(map[uint32][]byte),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,12 +97,12 @@ func (b *ConstructionBlockAccessList) StorageRead(address common.Address, key co
|
||||||
|
|
||||||
// StorageWrite records the post-transaction value of a mutated storage slot.
|
// StorageWrite records the post-transaction value of a mutated storage slot.
|
||||||
// The storage slot is removed from the list of read slots.
|
// The storage slot is removed from the list of read slots.
|
||||||
func (b *ConstructionBlockAccessList) StorageWrite(txIdx uint16, address common.Address, key, value common.Hash) {
|
func (b *ConstructionBlockAccessList) StorageWrite(txIdx uint32, address common.Address, key, value common.Hash) {
|
||||||
if _, ok := b.Accounts[address]; !ok {
|
if _, ok := b.Accounts[address]; !ok {
|
||||||
b.Accounts[address] = NewConstructionAccountAccess()
|
b.Accounts[address] = NewConstructionAccountAccess()
|
||||||
}
|
}
|
||||||
if _, ok := b.Accounts[address].StorageWrites[key]; !ok {
|
if _, ok := b.Accounts[address].StorageWrites[key]; !ok {
|
||||||
b.Accounts[address].StorageWrites[key] = make(map[uint16]common.Hash)
|
b.Accounts[address].StorageWrites[key] = make(map[uint32]common.Hash)
|
||||||
}
|
}
|
||||||
b.Accounts[address].StorageWrites[key][txIdx] = value
|
b.Accounts[address].StorageWrites[key][txIdx] = value
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ func (b *ConstructionBlockAccessList) StorageWrite(txIdx uint16, address common.
|
||||||
}
|
}
|
||||||
|
|
||||||
// CodeChange records the code of a newly-created contract.
|
// CodeChange records the code of a newly-created contract.
|
||||||
func (b *ConstructionBlockAccessList) CodeChange(address common.Address, txIndex uint16, code []byte) {
|
func (b *ConstructionBlockAccessList) CodeChange(address common.Address, txIndex uint32, code []byte) {
|
||||||
if _, ok := b.Accounts[address]; !ok {
|
if _, ok := b.Accounts[address]; !ok {
|
||||||
b.Accounts[address] = NewConstructionAccountAccess()
|
b.Accounts[address] = NewConstructionAccountAccess()
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +120,7 @@ func (b *ConstructionBlockAccessList) CodeChange(address common.Address, txIndex
|
||||||
|
|
||||||
// NonceChange records tx post-state nonce of any contract-like accounts whose
|
// NonceChange records tx post-state nonce of any contract-like accounts whose
|
||||||
// nonce was incremented.
|
// nonce was incremented.
|
||||||
func (b *ConstructionBlockAccessList) NonceChange(address common.Address, txIdx uint16, postNonce uint64) {
|
func (b *ConstructionBlockAccessList) NonceChange(address common.Address, txIdx uint32, postNonce uint64) {
|
||||||
if _, ok := b.Accounts[address]; !ok {
|
if _, ok := b.Accounts[address]; !ok {
|
||||||
b.Accounts[address] = NewConstructionAccountAccess()
|
b.Accounts[address] = NewConstructionAccountAccess()
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +129,7 @@ func (b *ConstructionBlockAccessList) NonceChange(address common.Address, txIdx
|
||||||
|
|
||||||
// BalanceChange records the post-transaction balance of an account whose
|
// BalanceChange records the post-transaction balance of an account whose
|
||||||
// balance changed.
|
// balance changed.
|
||||||
func (b *ConstructionBlockAccessList) BalanceChange(txIdx uint16, address common.Address, balance *uint256.Int) {
|
func (b *ConstructionBlockAccessList) BalanceChange(txIdx uint32, address common.Address, balance *uint256.Int) {
|
||||||
if _, ok := b.Accounts[address]; !ok {
|
if _, ok := b.Accounts[address]; !ok {
|
||||||
b.Accounts[address] = NewConstructionAccountAccess()
|
b.Accounts[address] = NewConstructionAccountAccess()
|
||||||
}
|
}
|
||||||
|
|
@ -148,21 +148,21 @@ func (b *ConstructionBlockAccessList) Copy() *ConstructionBlockAccessList {
|
||||||
for addr, aa := range b.Accounts {
|
for addr, aa := range b.Accounts {
|
||||||
var aaCopy ConstructionAccountAccess
|
var aaCopy ConstructionAccountAccess
|
||||||
|
|
||||||
slotWrites := make(map[common.Hash]map[uint16]common.Hash, len(aa.StorageWrites))
|
slotWrites := make(map[common.Hash]map[uint32]common.Hash, len(aa.StorageWrites))
|
||||||
for key, m := range aa.StorageWrites {
|
for key, m := range aa.StorageWrites {
|
||||||
slotWrites[key] = maps.Clone(m)
|
slotWrites[key] = maps.Clone(m)
|
||||||
}
|
}
|
||||||
aaCopy.StorageWrites = slotWrites
|
aaCopy.StorageWrites = slotWrites
|
||||||
aaCopy.StorageReads = maps.Clone(aa.StorageReads)
|
aaCopy.StorageReads = maps.Clone(aa.StorageReads)
|
||||||
|
|
||||||
balances := make(map[uint16]*uint256.Int, len(aa.BalanceChanges))
|
balances := make(map[uint32]*uint256.Int, len(aa.BalanceChanges))
|
||||||
for index, balance := range aa.BalanceChanges {
|
for index, balance := range aa.BalanceChanges {
|
||||||
balances[index] = balance.Clone()
|
balances[index] = balance.Clone()
|
||||||
}
|
}
|
||||||
aaCopy.BalanceChanges = balances
|
aaCopy.BalanceChanges = balances
|
||||||
aaCopy.NonceChanges = maps.Clone(aa.NonceChanges)
|
aaCopy.NonceChanges = maps.Clone(aa.NonceChanges)
|
||||||
|
|
||||||
codes := make(map[uint16][]byte, len(aa.CodeChange))
|
codes := make(map[uint32][]byte, len(aa.CodeChange))
|
||||||
for index, code := range aa.CodeChange {
|
for index, code := range aa.CodeChange {
|
||||||
codes[index] = bytes.Clone(code)
|
codes[index] = bytes.Clone(code)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,27 +33,59 @@ import (
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_generated.go -type BlockAccessList -decoder
|
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_generated.go -type AccountAccess -decoder
|
||||||
|
|
||||||
// These are objects used as input for the access list encoding. They mirror
|
// These are objects used as input for the access list encoding. They mirror
|
||||||
// the spec format.
|
// the spec format.
|
||||||
|
|
||||||
// BlockAccessList is the encoding format of ConstructionBlockAccessList.
|
// BlockAccessList is the encoding format of ConstructionBlockAccessList.
|
||||||
type BlockAccessList struct {
|
type BlockAccessList []AccountAccess
|
||||||
Accesses []AccountAccess `ssz-max:"300000"`
|
|
||||||
|
// EncodeRLP implements rlp.Encoder. It encodes the access list as a single
|
||||||
|
// RLP list of AccountAccess entries.
|
||||||
|
func (e BlockAccessList) EncodeRLP(w io.Writer) error {
|
||||||
|
buf := rlp.NewEncoderBuffer(w)
|
||||||
|
l := buf.List()
|
||||||
|
for i := range e {
|
||||||
|
if err := e[i].EncodeRLP(buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.ListEnd(l)
|
||||||
|
return buf.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeRLP implements rlp.Decoder.
|
||||||
|
func (e *BlockAccessList) DecodeRLP(s *rlp.Stream) error {
|
||||||
|
if _, err := s.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var list BlockAccessList
|
||||||
|
for s.MoreDataInList() {
|
||||||
|
var a AccountAccess
|
||||||
|
if err := a.DecodeRLP(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
list = append(list, a)
|
||||||
|
}
|
||||||
|
if err := s.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*e = list
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate returns an error if the contents of the access list are not ordered
|
// Validate returns an error if the contents of the access list are not ordered
|
||||||
// according to the spec or any code changes are contained which exceed protocol
|
// according to the spec or any code changes are contained which exceed protocol
|
||||||
// max code size.
|
// max code size.
|
||||||
func (e *BlockAccessList) Validate() error {
|
func (e *BlockAccessList) Validate(rules params.Rules) error {
|
||||||
if !slices.IsSortedFunc(e.Accesses, func(a, b AccountAccess) int {
|
if !slices.IsSortedFunc(*e, func(a, b AccountAccess) int {
|
||||||
return bytes.Compare(a.Address[:], b.Address[:])
|
return bytes.Compare(a.Address[:], b.Address[:])
|
||||||
}) {
|
}) {
|
||||||
return errors.New("block access list accounts not in lexicographic order")
|
return errors.New("block access list accounts not in lexicographic order")
|
||||||
}
|
}
|
||||||
for _, entry := range e.Accesses {
|
for _, entry := range *e {
|
||||||
if err := entry.validate(); err != nil {
|
if err := entry.validate(rules); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,56 +95,44 @@ func (e *BlockAccessList) Validate() error {
|
||||||
// Hash computes the keccak256 hash of the access list
|
// Hash computes the keccak256 hash of the access list
|
||||||
func (e *BlockAccessList) Hash() common.Hash {
|
func (e *BlockAccessList) Hash() common.Hash {
|
||||||
var enc bytes.Buffer
|
var enc bytes.Buffer
|
||||||
err := e.EncodeRLP(&enc)
|
if err := e.EncodeRLP(&enc); err != nil {
|
||||||
if err != nil {
|
// Errors here are related to BAL values exceeding maximum size defined
|
||||||
// errors here are related to BAL values exceeding maximum size defined
|
// by the spec. Return empty hash because these cases are not expected
|
||||||
// by the spec. Hard-fail because these cases are not expected to be hit
|
// to be hit under reasonable conditions.
|
||||||
// under reasonable conditions.
|
return common.Hash{}
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
return crypto.Keccak256Hash(enc.Bytes())
|
return crypto.Keccak256Hash(enc.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodeBalance encodes the provided balance into 16-bytes.
|
|
||||||
func encodeBalance(val *uint256.Int) [16]byte {
|
|
||||||
valBytes := val.Bytes()
|
|
||||||
if len(valBytes) > 16 {
|
|
||||||
panic("can't encode value that is greater than 16 bytes in size")
|
|
||||||
}
|
|
||||||
var enc [16]byte
|
|
||||||
copy(enc[16-len(valBytes):], valBytes[:])
|
|
||||||
return enc
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodingBalanceChange is the encoding format of BalanceChange.
|
// encodingBalanceChange is the encoding format of BalanceChange.
|
||||||
type encodingBalanceChange struct {
|
type encodingBalanceChange struct {
|
||||||
TxIdx uint16 `ssz-size:"2"`
|
TxIdx uint32
|
||||||
Balance [16]byte `ssz-size:"16"`
|
Balance *uint256.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodingAccountNonce is the encoding format of NonceChange.
|
// encodingAccountNonce is the encoding format of NonceChange.
|
||||||
type encodingAccountNonce struct {
|
type encodingAccountNonce struct {
|
||||||
TxIdx uint16 `ssz-size:"2"`
|
TxIdx uint32
|
||||||
Nonce uint64 `ssz-size:"8"`
|
Nonce uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodingStorageWrite is the encoding format of StorageWrites.
|
// encodingStorageWrite is the encoding format of StorageWrites.
|
||||||
type encodingStorageWrite struct {
|
type encodingStorageWrite struct {
|
||||||
TxIdx uint16
|
TxIdx uint32
|
||||||
ValueAfter [32]byte `ssz-size:"32"`
|
ValueAfter *uint256.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodingStorageWrite is the encoding format of SlotWrites.
|
// encodingStorageWrite is the encoding format of SlotWrites.
|
||||||
type encodingSlotWrites struct {
|
type encodingSlotWrites struct {
|
||||||
Slot [32]byte `ssz-size:"32"`
|
Slot *uint256.Int
|
||||||
Accesses []encodingStorageWrite `ssz-max:"300000"`
|
Accesses []encodingStorageWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate returns an instance of the encoding-representation slot writes in
|
// validate returns an instance of the encoding-representation slot writes in
|
||||||
// working representation.
|
// working representation.
|
||||||
func (e *encodingSlotWrites) validate() error {
|
func (e *encodingSlotWrites) validate() error {
|
||||||
if slices.IsSortedFunc(e.Accesses, func(a, b encodingStorageWrite) int {
|
if slices.IsSortedFunc(e.Accesses, func(a, b encodingStorageWrite) int {
|
||||||
return cmp.Compare[uint16](a.TxIdx, b.TxIdx)
|
return cmp.Compare[uint32](a.TxIdx, b.TxIdx)
|
||||||
}) {
|
}) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -122,27 +142,27 @@ func (e *encodingSlotWrites) validate() error {
|
||||||
// encodingCodeChange contains the runtime bytecode deployed at an address
|
// encodingCodeChange contains the runtime bytecode deployed at an address
|
||||||
// and the transaction index where the deployment took place.
|
// and the transaction index where the deployment took place.
|
||||||
type encodingCodeChange struct {
|
type encodingCodeChange struct {
|
||||||
TxIndex uint16 `ssz-size:"2"`
|
TxIndex uint32
|
||||||
Code []byte `ssz-max:"300000"` // TODO(rjl493456442) shall we put the limit here? The limit will be increased gradually
|
Code []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountAccess is the encoding format of ConstructionAccountAccess.
|
// AccountAccess is the encoding format of ConstructionAccountAccess.
|
||||||
type AccountAccess struct {
|
type AccountAccess struct {
|
||||||
Address [20]byte `ssz-size:"20"` // 20-byte Ethereum address
|
Address [20]byte // 20-byte Ethereum address
|
||||||
StorageWrites []encodingSlotWrites `ssz-max:"300000"` // Storage changes (slot -> [tx_index -> new_value])
|
StorageWrites []encodingSlotWrites // Storage changes (slot -> [tx_index -> new_value])
|
||||||
StorageReads [][32]byte `ssz-max:"300000"` // Read-only storage keys
|
StorageReads []*uint256.Int // Read-only storage keys
|
||||||
BalanceChanges []encodingBalanceChange `ssz-max:"300000"` // Balance changes ([tx_index -> post_balance])
|
BalanceChanges []encodingBalanceChange // Balance changes ([tx_index -> post_balance])
|
||||||
NonceChanges []encodingAccountNonce `ssz-max:"300000"` // Nonce changes ([tx_index -> new_nonce])
|
NonceChanges []encodingAccountNonce // Nonce changes ([tx_index -> new_nonce])
|
||||||
CodeChanges []encodingCodeChange `ssz-max:"300000"` // Code changes ([tx_index -> new_code])
|
CodeChanges []encodingCodeChange // Code changes ([tx_index -> new_code])
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate converts the account accesses out of encoding format.
|
// validate converts the account accesses out of encoding format.
|
||||||
// If any of the keys in the encoding object are not ordered according to the
|
// If any of the keys in the encoding object are not ordered according to the
|
||||||
// spec, an error is returned.
|
// spec, an error is returned.
|
||||||
func (e *AccountAccess) validate() error {
|
func (e *AccountAccess) validate(rules params.Rules) error {
|
||||||
// Check the storage write slots are sorted in order
|
// Check the storage write slots are sorted in order
|
||||||
if !slices.IsSortedFunc(e.StorageWrites, func(a, b encodingSlotWrites) int {
|
if !slices.IsSortedFunc(e.StorageWrites, func(a, b encodingSlotWrites) int {
|
||||||
return bytes.Compare(a.Slot[:], b.Slot[:])
|
return a.Slot.Cmp(b.Slot)
|
||||||
}) {
|
}) {
|
||||||
return errors.New("storage writes slots not in lexicographic order")
|
return errors.New("storage writes slots not in lexicographic order")
|
||||||
}
|
}
|
||||||
|
|
@ -153,36 +173,41 @@ func (e *AccountAccess) validate() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the storage read slots are sorted in order
|
// Check the storage read slots are sorted in order
|
||||||
if !slices.IsSortedFunc(e.StorageReads, func(a, b [32]byte) int {
|
if !slices.IsSortedFunc(e.StorageReads, func(a, b *uint256.Int) int {
|
||||||
return bytes.Compare(a[:], b[:])
|
return a.Cmp(b)
|
||||||
}) {
|
}) {
|
||||||
return errors.New("storage read slots not in lexicographic order")
|
return errors.New("storage read slots not in lexicographic order")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the balance changes are sorted in order
|
// Check the balance changes are sorted in order
|
||||||
if !slices.IsSortedFunc(e.BalanceChanges, func(a, b encodingBalanceChange) int {
|
if !slices.IsSortedFunc(e.BalanceChanges, func(a, b encodingBalanceChange) int {
|
||||||
return cmp.Compare[uint16](a.TxIdx, b.TxIdx)
|
return cmp.Compare[uint32](a.TxIdx, b.TxIdx)
|
||||||
}) {
|
}) {
|
||||||
return errors.New("balance changes not in ascending order by tx index")
|
return errors.New("balance changes not in ascending order by tx index")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the nonce changes are sorted in order
|
// Check the nonce changes are sorted in order
|
||||||
if !slices.IsSortedFunc(e.NonceChanges, func(a, b encodingAccountNonce) int {
|
if !slices.IsSortedFunc(e.NonceChanges, func(a, b encodingAccountNonce) int {
|
||||||
return cmp.Compare[uint16](a.TxIdx, b.TxIdx)
|
return cmp.Compare[uint32](a.TxIdx, b.TxIdx)
|
||||||
}) {
|
}) {
|
||||||
return errors.New("nonce changes not in ascending order by tx index")
|
return errors.New("nonce changes not in ascending order by tx index")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the code changes are sorted in order
|
// Check the code changes are sorted in order
|
||||||
if !slices.IsSortedFunc(e.CodeChanges, func(a, b encodingCodeChange) int {
|
if !slices.IsSortedFunc(e.CodeChanges, func(a, b encodingCodeChange) int {
|
||||||
return cmp.Compare[uint16](a.TxIndex, b.TxIndex)
|
return cmp.Compare[uint32](a.TxIndex, b.TxIndex)
|
||||||
}) {
|
}) {
|
||||||
return errors.New("code changes not in ascending order by tx index")
|
return errors.New("code changes not in ascending order by tx index")
|
||||||
}
|
}
|
||||||
for _, change := range e.CodeChanges {
|
for _, change := range e.CodeChanges {
|
||||||
// TODO(rjl493456442): This check should be fork-aware, since the limit may
|
var sizeLimit int
|
||||||
// differ across forks.
|
switch {
|
||||||
if len(change.Code) > params.MaxCodeSize {
|
case rules.IsAmsterdam:
|
||||||
|
sizeLimit = params.MaxCodeSizeAmsterdam
|
||||||
|
default:
|
||||||
|
sizeLimit = params.MaxCodeSize
|
||||||
|
}
|
||||||
|
if len(change.Code) > sizeLimit {
|
||||||
return errors.New("code change contained oversized code")
|
return errors.New("code change contained oversized code")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -193,16 +218,32 @@ func (e *AccountAccess) validate() error {
|
||||||
func (e *AccountAccess) Copy() AccountAccess {
|
func (e *AccountAccess) Copy() AccountAccess {
|
||||||
res := AccountAccess{
|
res := AccountAccess{
|
||||||
Address: e.Address,
|
Address: e.Address,
|
||||||
StorageReads: slices.Clone(e.StorageReads),
|
StorageReads: make([]*uint256.Int, 0, len(e.StorageReads)),
|
||||||
BalanceChanges: slices.Clone(e.BalanceChanges),
|
BalanceChanges: make([]encodingBalanceChange, 0, len(e.BalanceChanges)),
|
||||||
NonceChanges: slices.Clone(e.NonceChanges),
|
NonceChanges: slices.Clone(e.NonceChanges),
|
||||||
StorageWrites: make([]encodingSlotWrites, 0, len(e.StorageWrites)),
|
StorageWrites: make([]encodingSlotWrites, 0, len(e.StorageWrites)),
|
||||||
CodeChanges: make([]encodingCodeChange, 0, len(e.CodeChanges)),
|
CodeChanges: make([]encodingCodeChange, 0, len(e.CodeChanges)),
|
||||||
}
|
}
|
||||||
|
for _, slot := range e.StorageReads {
|
||||||
|
res.StorageReads = append(res.StorageReads, slot.Clone())
|
||||||
|
}
|
||||||
|
for _, change := range e.BalanceChanges {
|
||||||
|
res.BalanceChanges = append(res.BalanceChanges, encodingBalanceChange{
|
||||||
|
TxIdx: change.TxIdx,
|
||||||
|
Balance: change.Balance.Clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
for _, storageWrite := range e.StorageWrites {
|
for _, storageWrite := range e.StorageWrites {
|
||||||
|
accesses := make([]encodingStorageWrite, 0, len(storageWrite.Accesses))
|
||||||
|
for _, w := range storageWrite.Accesses {
|
||||||
|
accesses = append(accesses, encodingStorageWrite{
|
||||||
|
TxIdx: w.TxIdx,
|
||||||
|
ValueAfter: w.ValueAfter.Clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
res.StorageWrites = append(res.StorageWrites, encodingSlotWrites{
|
res.StorageWrites = append(res.StorageWrites, encodingSlotWrites{
|
||||||
Slot: storageWrite.Slot,
|
Slot: storageWrite.Slot.Clone(),
|
||||||
Accesses: slices.Clone(storageWrite.Accesses),
|
Accesses: accesses,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for _, codeChange := range e.CodeChanges {
|
for _, codeChange := range e.CodeChanges {
|
||||||
|
|
@ -221,13 +262,13 @@ func (b *ConstructionBlockAccessList) EncodeRLP(wr io.Writer) error {
|
||||||
|
|
||||||
var _ rlp.Encoder = &ConstructionBlockAccessList{}
|
var _ rlp.Encoder = &ConstructionBlockAccessList{}
|
||||||
|
|
||||||
// toEncodingObj creates an instance of the ConstructionAccountAccess of the type that is
|
// toEncodingObj creates an instance of the ConstructionAccountAccess of the type
|
||||||
// used as input for the encoding.
|
// that is used as input for the encoding.
|
||||||
func (a *ConstructionAccountAccess) toEncodingObj(addr common.Address) AccountAccess {
|
func (a *ConstructionAccountAccess) toEncodingObj(addr common.Address) AccountAccess {
|
||||||
res := AccountAccess{
|
res := AccountAccess{
|
||||||
Address: addr,
|
Address: addr,
|
||||||
StorageWrites: make([]encodingSlotWrites, 0, len(a.StorageWrites)),
|
StorageWrites: make([]encodingSlotWrites, 0, len(a.StorageWrites)),
|
||||||
StorageReads: make([][32]byte, 0, len(a.StorageReads)),
|
StorageReads: make([]*uint256.Int, 0, len(a.StorageReads)),
|
||||||
BalanceChanges: make([]encodingBalanceChange, 0, len(a.BalanceChanges)),
|
BalanceChanges: make([]encodingBalanceChange, 0, len(a.BalanceChanges)),
|
||||||
NonceChanges: make([]encodingAccountNonce, 0, len(a.NonceChanges)),
|
NonceChanges: make([]encodingAccountNonce, 0, len(a.NonceChanges)),
|
||||||
CodeChanges: make([]encodingCodeChange, 0, len(a.CodeChange)),
|
CodeChanges: make([]encodingCodeChange, 0, len(a.CodeChange)),
|
||||||
|
|
@ -237,18 +278,19 @@ func (a *ConstructionAccountAccess) toEncodingObj(addr common.Address) AccountAc
|
||||||
writeSlots := slices.Collect(maps.Keys(a.StorageWrites))
|
writeSlots := slices.Collect(maps.Keys(a.StorageWrites))
|
||||||
slices.SortFunc(writeSlots, common.Hash.Cmp)
|
slices.SortFunc(writeSlots, common.Hash.Cmp)
|
||||||
for _, slot := range writeSlots {
|
for _, slot := range writeSlots {
|
||||||
var obj encodingSlotWrites
|
obj := encodingSlotWrites{
|
||||||
obj.Slot = slot
|
Slot: new(uint256.Int).SetBytes(slot[:]),
|
||||||
|
}
|
||||||
slotWrites := a.StorageWrites[slot]
|
slotWrites := a.StorageWrites[slot]
|
||||||
obj.Accesses = make([]encodingStorageWrite, 0, len(slotWrites))
|
obj.Accesses = make([]encodingStorageWrite, 0, len(slotWrites))
|
||||||
|
|
||||||
indices := slices.Collect(maps.Keys(slotWrites))
|
indices := slices.Collect(maps.Keys(slotWrites))
|
||||||
slices.SortFunc(indices, cmp.Compare[uint16])
|
slices.SortFunc(indices, cmp.Compare[uint32])
|
||||||
for _, index := range indices {
|
for _, index := range indices {
|
||||||
|
val := slotWrites[index]
|
||||||
obj.Accesses = append(obj.Accesses, encodingStorageWrite{
|
obj.Accesses = append(obj.Accesses, encodingStorageWrite{
|
||||||
TxIdx: index,
|
TxIdx: index,
|
||||||
ValueAfter: slotWrites[index],
|
ValueAfter: new(uint256.Int).SetBytes(val[:]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
res.StorageWrites = append(res.StorageWrites, obj)
|
res.StorageWrites = append(res.StorageWrites, obj)
|
||||||
|
|
@ -258,22 +300,22 @@ func (a *ConstructionAccountAccess) toEncodingObj(addr common.Address) AccountAc
|
||||||
readSlots := slices.Collect(maps.Keys(a.StorageReads))
|
readSlots := slices.Collect(maps.Keys(a.StorageReads))
|
||||||
slices.SortFunc(readSlots, common.Hash.Cmp)
|
slices.SortFunc(readSlots, common.Hash.Cmp)
|
||||||
for _, slot := range readSlots {
|
for _, slot := range readSlots {
|
||||||
res.StorageReads = append(res.StorageReads, slot)
|
res.StorageReads = append(res.StorageReads, new(uint256.Int).SetBytes(slot[:]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert balance changes
|
// Convert balance changes
|
||||||
balanceIndices := slices.Collect(maps.Keys(a.BalanceChanges))
|
balanceIndices := slices.Collect(maps.Keys(a.BalanceChanges))
|
||||||
slices.SortFunc(balanceIndices, cmp.Compare[uint16])
|
slices.SortFunc(balanceIndices, cmp.Compare[uint32])
|
||||||
for _, idx := range balanceIndices {
|
for _, idx := range balanceIndices {
|
||||||
res.BalanceChanges = append(res.BalanceChanges, encodingBalanceChange{
|
res.BalanceChanges = append(res.BalanceChanges, encodingBalanceChange{
|
||||||
TxIdx: idx,
|
TxIdx: idx,
|
||||||
Balance: encodeBalance(a.BalanceChanges[idx]),
|
Balance: a.BalanceChanges[idx].Clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert nonce changes
|
// Convert nonce changes
|
||||||
nonceIndices := slices.Collect(maps.Keys(a.NonceChanges))
|
nonceIndices := slices.Collect(maps.Keys(a.NonceChanges))
|
||||||
slices.SortFunc(nonceIndices, cmp.Compare[uint16])
|
slices.SortFunc(nonceIndices, cmp.Compare[uint32])
|
||||||
for _, idx := range nonceIndices {
|
for _, idx := range nonceIndices {
|
||||||
res.NonceChanges = append(res.NonceChanges, encodingAccountNonce{
|
res.NonceChanges = append(res.NonceChanges, encodingAccountNonce{
|
||||||
TxIdx: idx,
|
TxIdx: idx,
|
||||||
|
|
@ -283,11 +325,16 @@ func (a *ConstructionAccountAccess) toEncodingObj(addr common.Address) AccountAc
|
||||||
|
|
||||||
// Convert code change
|
// Convert code change
|
||||||
codeIndices := slices.Collect(maps.Keys(a.CodeChange))
|
codeIndices := slices.Collect(maps.Keys(a.CodeChange))
|
||||||
slices.SortFunc(codeIndices, cmp.Compare[uint16])
|
slices.SortFunc(codeIndices, cmp.Compare[uint32])
|
||||||
for _, idx := range codeIndices {
|
for _, idx := range codeIndices {
|
||||||
res.CodeChanges = append(res.CodeChanges, encodingCodeChange{
|
res.CodeChanges = append(res.CodeChanges, encodingCodeChange{
|
||||||
TxIndex: idx,
|
TxIndex: idx,
|
||||||
Code: a.CodeChange[idx],
|
|
||||||
|
// TODO(rjl493456442) the contract code is not deep-copied.
|
||||||
|
// In theory the deep-copy is unnecessary, the semantics of
|
||||||
|
// the function should be probably changed that the returned
|
||||||
|
// AccessList is unsafe for modification.
|
||||||
|
Code: a.CodeChange[idx],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|
@ -302,9 +349,9 @@ func (b *ConstructionBlockAccessList) toEncodingObj() *BlockAccessList {
|
||||||
}
|
}
|
||||||
slices.SortFunc(addresses, common.Address.Cmp)
|
slices.SortFunc(addresses, common.Address.Cmp)
|
||||||
|
|
||||||
var res BlockAccessList
|
res := make(BlockAccessList, 0, len(addresses))
|
||||||
for _, addr := range addresses {
|
for _, addr := range addresses {
|
||||||
res.Accesses = append(res.Accesses, b.Accounts[addr].toEncodingObj(addr))
|
res = append(res, b.Accounts[addr].toEncodingObj(addr))
|
||||||
}
|
}
|
||||||
return &res
|
return &res
|
||||||
}
|
}
|
||||||
|
|
@ -314,26 +361,25 @@ func (e *BlockAccessList) PrettyPrint() string {
|
||||||
printWithIndent := func(indent int, text string) {
|
printWithIndent := func(indent int, text string) {
|
||||||
fmt.Fprintf(&res, "%s%s\n", strings.Repeat(" ", indent), text)
|
fmt.Fprintf(&res, "%s%s\n", strings.Repeat(" ", indent), text)
|
||||||
}
|
}
|
||||||
for _, accountDiff := range e.Accesses {
|
for _, accountDiff := range *e {
|
||||||
printWithIndent(0, fmt.Sprintf("%x:", accountDiff.Address))
|
printWithIndent(0, fmt.Sprintf("%x:", accountDiff.Address))
|
||||||
|
|
||||||
printWithIndent(1, "storage writes:")
|
printWithIndent(1, "storage writes:")
|
||||||
for _, sWrite := range accountDiff.StorageWrites {
|
for _, sWrite := range accountDiff.StorageWrites {
|
||||||
printWithIndent(2, fmt.Sprintf("%x:", sWrite.Slot))
|
printWithIndent(2, fmt.Sprintf("%s:", sWrite.Slot.Hex()))
|
||||||
for _, access := range sWrite.Accesses {
|
for _, access := range sWrite.Accesses {
|
||||||
printWithIndent(3, fmt.Sprintf("%d: %x", access.TxIdx, access.ValueAfter))
|
printWithIndent(3, fmt.Sprintf("%d: %s", access.TxIdx, access.ValueAfter.Hex()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printWithIndent(1, "storage reads:")
|
printWithIndent(1, "storage reads:")
|
||||||
for _, slot := range accountDiff.StorageReads {
|
for _, slot := range accountDiff.StorageReads {
|
||||||
printWithIndent(2, fmt.Sprintf("%x", slot))
|
printWithIndent(2, slot.Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
printWithIndent(1, "balance changes:")
|
printWithIndent(1, "balance changes:")
|
||||||
for _, change := range accountDiff.BalanceChanges {
|
for _, change := range accountDiff.BalanceChanges {
|
||||||
balance := new(uint256.Int).SetBytes(change.Balance[:]).String()
|
printWithIndent(2, fmt.Sprintf("%d: %s", change.TxIdx, change.Balance))
|
||||||
printWithIndent(2, fmt.Sprintf("%d: %s", change.TxIdx, balance))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printWithIndent(1, "nonce changes:")
|
printWithIndent(1, "nonce changes:")
|
||||||
|
|
@ -351,11 +397,9 @@ func (e *BlockAccessList) PrettyPrint() string {
|
||||||
|
|
||||||
// Copy returns a deep copy of the access list
|
// Copy returns a deep copy of the access list
|
||||||
func (e *BlockAccessList) Copy() *BlockAccessList {
|
func (e *BlockAccessList) Copy() *BlockAccessList {
|
||||||
cpy := &BlockAccessList{
|
cpy := make(BlockAccessList, 0, len(*e))
|
||||||
Accesses: make([]AccountAccess, 0, len(e.Accesses)),
|
for _, accountAccess := range *e {
|
||||||
|
cpy = append(cpy, accountAccess.Copy())
|
||||||
}
|
}
|
||||||
for _, accountAccess := range e.Accesses {
|
return &cpy
|
||||||
cpy.Accesses = append(cpy.Accesses, accountAccess.Copy())
|
|
||||||
}
|
|
||||||
return cpy
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,274 +3,264 @@
|
||||||
package bal
|
package bal
|
||||||
|
|
||||||
import "github.com/ethereum/go-ethereum/rlp"
|
import "github.com/ethereum/go-ethereum/rlp"
|
||||||
|
import "github.com/holiman/uint256"
|
||||||
import "io"
|
import "io"
|
||||||
|
|
||||||
func (obj *BlockAccessList) EncodeRLP(_w io.Writer) error {
|
func (obj *AccountAccess) EncodeRLP(_w io.Writer) error {
|
||||||
w := rlp.NewEncoderBuffer(_w)
|
w := rlp.NewEncoderBuffer(_w)
|
||||||
_tmp0 := w.List()
|
_tmp0 := w.List()
|
||||||
|
w.WriteBytes(obj.Address[:])
|
||||||
_tmp1 := w.List()
|
_tmp1 := w.List()
|
||||||
for _, _tmp2 := range obj.Accesses {
|
for _, _tmp2 := range obj.StorageWrites {
|
||||||
_tmp3 := w.List()
|
_tmp3 := w.List()
|
||||||
w.WriteBytes(_tmp2.Address[:])
|
if _tmp2.Slot == nil {
|
||||||
|
w.Write(rlp.EmptyString)
|
||||||
|
} else {
|
||||||
|
w.WriteUint256(_tmp2.Slot)
|
||||||
|
}
|
||||||
_tmp4 := w.List()
|
_tmp4 := w.List()
|
||||||
for _, _tmp5 := range _tmp2.StorageWrites {
|
for _, _tmp5 := range _tmp2.Accesses {
|
||||||
_tmp6 := w.List()
|
_tmp6 := w.List()
|
||||||
w.WriteBytes(_tmp5.Slot[:])
|
w.WriteUint64(uint64(_tmp5.TxIdx))
|
||||||
_tmp7 := w.List()
|
if _tmp5.ValueAfter == nil {
|
||||||
for _, _tmp8 := range _tmp5.Accesses {
|
w.Write(rlp.EmptyString)
|
||||||
_tmp9 := w.List()
|
} else {
|
||||||
w.WriteUint64(uint64(_tmp8.TxIdx))
|
w.WriteUint256(_tmp5.ValueAfter)
|
||||||
w.WriteBytes(_tmp8.ValueAfter[:])
|
|
||||||
w.ListEnd(_tmp9)
|
|
||||||
}
|
}
|
||||||
w.ListEnd(_tmp7)
|
|
||||||
w.ListEnd(_tmp6)
|
w.ListEnd(_tmp6)
|
||||||
}
|
}
|
||||||
w.ListEnd(_tmp4)
|
w.ListEnd(_tmp4)
|
||||||
_tmp10 := w.List()
|
|
||||||
for _, _tmp11 := range _tmp2.StorageReads {
|
|
||||||
w.WriteBytes(_tmp11[:])
|
|
||||||
}
|
|
||||||
w.ListEnd(_tmp10)
|
|
||||||
_tmp12 := w.List()
|
|
||||||
for _, _tmp13 := range _tmp2.BalanceChanges {
|
|
||||||
_tmp14 := w.List()
|
|
||||||
w.WriteUint64(uint64(_tmp13.TxIdx))
|
|
||||||
w.WriteBytes(_tmp13.Balance[:])
|
|
||||||
w.ListEnd(_tmp14)
|
|
||||||
}
|
|
||||||
w.ListEnd(_tmp12)
|
|
||||||
_tmp15 := w.List()
|
|
||||||
for _, _tmp16 := range _tmp2.NonceChanges {
|
|
||||||
_tmp17 := w.List()
|
|
||||||
w.WriteUint64(uint64(_tmp16.TxIdx))
|
|
||||||
w.WriteUint64(_tmp16.Nonce)
|
|
||||||
w.ListEnd(_tmp17)
|
|
||||||
}
|
|
||||||
w.ListEnd(_tmp15)
|
|
||||||
_tmp18 := w.List()
|
|
||||||
for _, _tmp19 := range _tmp2.CodeChanges {
|
|
||||||
_tmp20 := w.List()
|
|
||||||
w.WriteUint64(uint64(_tmp19.TxIndex))
|
|
||||||
w.WriteBytes(_tmp19.Code)
|
|
||||||
w.ListEnd(_tmp20)
|
|
||||||
}
|
|
||||||
w.ListEnd(_tmp18)
|
|
||||||
w.ListEnd(_tmp3)
|
w.ListEnd(_tmp3)
|
||||||
}
|
}
|
||||||
w.ListEnd(_tmp1)
|
w.ListEnd(_tmp1)
|
||||||
|
_tmp7 := w.List()
|
||||||
|
for _, _tmp8 := range obj.StorageReads {
|
||||||
|
if _tmp8 == nil {
|
||||||
|
w.Write(rlp.EmptyString)
|
||||||
|
} else {
|
||||||
|
w.WriteUint256(_tmp8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.ListEnd(_tmp7)
|
||||||
|
_tmp9 := w.List()
|
||||||
|
for _, _tmp10 := range obj.BalanceChanges {
|
||||||
|
_tmp11 := w.List()
|
||||||
|
w.WriteUint64(uint64(_tmp10.TxIdx))
|
||||||
|
if _tmp10.Balance == nil {
|
||||||
|
w.Write(rlp.EmptyString)
|
||||||
|
} else {
|
||||||
|
w.WriteUint256(_tmp10.Balance)
|
||||||
|
}
|
||||||
|
w.ListEnd(_tmp11)
|
||||||
|
}
|
||||||
|
w.ListEnd(_tmp9)
|
||||||
|
_tmp12 := w.List()
|
||||||
|
for _, _tmp13 := range obj.NonceChanges {
|
||||||
|
_tmp14 := w.List()
|
||||||
|
w.WriteUint64(uint64(_tmp13.TxIdx))
|
||||||
|
w.WriteUint64(_tmp13.Nonce)
|
||||||
|
w.ListEnd(_tmp14)
|
||||||
|
}
|
||||||
|
w.ListEnd(_tmp12)
|
||||||
|
_tmp15 := w.List()
|
||||||
|
for _, _tmp16 := range obj.CodeChanges {
|
||||||
|
_tmp17 := w.List()
|
||||||
|
w.WriteUint64(uint64(_tmp16.TxIndex))
|
||||||
|
w.WriteBytes(_tmp16.Code)
|
||||||
|
w.ListEnd(_tmp17)
|
||||||
|
}
|
||||||
|
w.ListEnd(_tmp15)
|
||||||
w.ListEnd(_tmp0)
|
w.ListEnd(_tmp0)
|
||||||
return w.Flush()
|
return w.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *BlockAccessList) DecodeRLP(dec *rlp.Stream) error {
|
func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error {
|
||||||
var _tmp0 BlockAccessList
|
var _tmp0 AccountAccess
|
||||||
{
|
{
|
||||||
if _, err := dec.List(); err != nil {
|
if _, err := dec.List(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Accesses:
|
// Address:
|
||||||
var _tmp1 []AccountAccess
|
var _tmp1 [20]byte
|
||||||
|
if err := dec.ReadBytes(_tmp1[:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp0.Address = _tmp1
|
||||||
|
// StorageWrites:
|
||||||
|
var _tmp2 []encodingSlotWrites
|
||||||
if _, err := dec.List(); err != nil {
|
if _, err := dec.List(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for dec.MoreDataInList() {
|
for dec.MoreDataInList() {
|
||||||
var _tmp2 AccountAccess
|
var _tmp3 encodingSlotWrites
|
||||||
{
|
{
|
||||||
if _, err := dec.List(); err != nil {
|
if _, err := dec.List(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Address:
|
// Slot:
|
||||||
var _tmp3 [20]byte
|
var _tmp4 uint256.Int
|
||||||
if err := dec.ReadBytes(_tmp3[:]); err != nil {
|
if err := dec.ReadUint256(&_tmp4); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_tmp2.Address = _tmp3
|
_tmp3.Slot = &_tmp4
|
||||||
// StorageWrites:
|
// Accesses:
|
||||||
var _tmp4 []encodingSlotWrites
|
var _tmp5 []encodingStorageWrite
|
||||||
if _, err := dec.List(); err != nil {
|
if _, err := dec.List(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for dec.MoreDataInList() {
|
for dec.MoreDataInList() {
|
||||||
var _tmp5 encodingSlotWrites
|
var _tmp6 encodingStorageWrite
|
||||||
{
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Slot:
|
|
||||||
var _tmp6 [32]byte
|
|
||||||
if err := dec.ReadBytes(_tmp6[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp5.Slot = _tmp6
|
|
||||||
// Accesses:
|
|
||||||
var _tmp7 []encodingStorageWrite
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for dec.MoreDataInList() {
|
|
||||||
var _tmp8 encodingStorageWrite
|
|
||||||
{
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// TxIdx:
|
|
||||||
_tmp9, err := dec.Uint16()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp8.TxIdx = _tmp9
|
|
||||||
// ValueAfter:
|
|
||||||
var _tmp10 [32]byte
|
|
||||||
if err := dec.ReadBytes(_tmp10[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp8.ValueAfter = _tmp10
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_tmp7 = append(_tmp7, _tmp8)
|
|
||||||
}
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp5.Accesses = _tmp7
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_tmp4 = append(_tmp4, _tmp5)
|
|
||||||
}
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp2.StorageWrites = _tmp4
|
|
||||||
// StorageReads:
|
|
||||||
var _tmp11 [][32]byte
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for dec.MoreDataInList() {
|
|
||||||
var _tmp12 [32]byte
|
|
||||||
if err := dec.ReadBytes(_tmp12[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp11 = append(_tmp11, _tmp12)
|
|
||||||
}
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp2.StorageReads = _tmp11
|
|
||||||
// BalanceChanges:
|
|
||||||
var _tmp13 []encodingBalanceChange
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for dec.MoreDataInList() {
|
|
||||||
var _tmp14 encodingBalanceChange
|
|
||||||
{
|
{
|
||||||
if _, err := dec.List(); err != nil {
|
if _, err := dec.List(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// TxIdx:
|
// TxIdx:
|
||||||
_tmp15, err := dec.Uint16()
|
_tmp7, err := dec.Uint32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_tmp14.TxIdx = _tmp15
|
_tmp6.TxIdx = _tmp7
|
||||||
// Balance:
|
// ValueAfter:
|
||||||
var _tmp16 [16]byte
|
var _tmp8 uint256.Int
|
||||||
if err := dec.ReadBytes(_tmp16[:]); err != nil {
|
if err := dec.ReadUint256(&_tmp8); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_tmp14.Balance = _tmp16
|
_tmp6.ValueAfter = &_tmp8
|
||||||
if err := dec.ListEnd(); err != nil {
|
if err := dec.ListEnd(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_tmp13 = append(_tmp13, _tmp14)
|
_tmp5 = append(_tmp5, _tmp6)
|
||||||
}
|
}
|
||||||
if err := dec.ListEnd(); err != nil {
|
if err := dec.ListEnd(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_tmp2.BalanceChanges = _tmp13
|
_tmp3.Accesses = _tmp5
|
||||||
// NonceChanges:
|
|
||||||
var _tmp17 []encodingAccountNonce
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for dec.MoreDataInList() {
|
|
||||||
var _tmp18 encodingAccountNonce
|
|
||||||
{
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// TxIdx:
|
|
||||||
_tmp19, err := dec.Uint16()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp18.TxIdx = _tmp19
|
|
||||||
// Nonce:
|
|
||||||
_tmp20, err := dec.Uint64()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp18.Nonce = _tmp20
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_tmp17 = append(_tmp17, _tmp18)
|
|
||||||
}
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp2.NonceChanges = _tmp17
|
|
||||||
// CodeChanges:
|
|
||||||
var _tmp21 []encodingCodeChange
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for dec.MoreDataInList() {
|
|
||||||
var _tmp22 encodingCodeChange
|
|
||||||
{
|
|
||||||
if _, err := dec.List(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// TxIndex:
|
|
||||||
_tmp23, err := dec.Uint16()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp22.TxIndex = _tmp23
|
|
||||||
// Code:
|
|
||||||
_tmp24, err := dec.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp22.Code = _tmp24
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_tmp21 = append(_tmp21, _tmp22)
|
|
||||||
}
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_tmp2.CodeChanges = _tmp21
|
|
||||||
if err := dec.ListEnd(); err != nil {
|
if err := dec.ListEnd(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_tmp1 = append(_tmp1, _tmp2)
|
_tmp2 = append(_tmp2, _tmp3)
|
||||||
}
|
}
|
||||||
if err := dec.ListEnd(); err != nil {
|
if err := dec.ListEnd(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_tmp0.Accesses = _tmp1
|
_tmp0.StorageWrites = _tmp2
|
||||||
|
// StorageReads:
|
||||||
|
var _tmp9 []*uint256.Int
|
||||||
|
if _, err := dec.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for dec.MoreDataInList() {
|
||||||
|
var _tmp10 uint256.Int
|
||||||
|
if err := dec.ReadUint256(&_tmp10); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp9 = append(_tmp9, &_tmp10)
|
||||||
|
}
|
||||||
|
if err := dec.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp0.StorageReads = _tmp9
|
||||||
|
// BalanceChanges:
|
||||||
|
var _tmp11 []encodingBalanceChange
|
||||||
|
if _, err := dec.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for dec.MoreDataInList() {
|
||||||
|
var _tmp12 encodingBalanceChange
|
||||||
|
{
|
||||||
|
if _, err := dec.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TxIdx:
|
||||||
|
_tmp13, err := dec.Uint32()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp12.TxIdx = _tmp13
|
||||||
|
// Balance:
|
||||||
|
var _tmp14 uint256.Int
|
||||||
|
if err := dec.ReadUint256(&_tmp14); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp12.Balance = &_tmp14
|
||||||
|
if err := dec.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_tmp11 = append(_tmp11, _tmp12)
|
||||||
|
}
|
||||||
|
if err := dec.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp0.BalanceChanges = _tmp11
|
||||||
|
// NonceChanges:
|
||||||
|
var _tmp15 []encodingAccountNonce
|
||||||
|
if _, err := dec.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for dec.MoreDataInList() {
|
||||||
|
var _tmp16 encodingAccountNonce
|
||||||
|
{
|
||||||
|
if _, err := dec.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TxIdx:
|
||||||
|
_tmp17, err := dec.Uint32()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp16.TxIdx = _tmp17
|
||||||
|
// Nonce:
|
||||||
|
_tmp18, err := dec.Uint64()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp16.Nonce = _tmp18
|
||||||
|
if err := dec.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_tmp15 = append(_tmp15, _tmp16)
|
||||||
|
}
|
||||||
|
if err := dec.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp0.NonceChanges = _tmp15
|
||||||
|
// CodeChanges:
|
||||||
|
var _tmp19 []encodingCodeChange
|
||||||
|
if _, err := dec.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for dec.MoreDataInList() {
|
||||||
|
var _tmp20 encodingCodeChange
|
||||||
|
{
|
||||||
|
if _, err := dec.List(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TxIndex:
|
||||||
|
_tmp21, err := dec.Uint32()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp20.TxIndex = _tmp21
|
||||||
|
// Code:
|
||||||
|
_tmp22, err := dec.Bytes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp20.Code = _tmp22
|
||||||
|
if err := dec.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_tmp19 = append(_tmp19, _tmp20)
|
||||||
|
}
|
||||||
|
if err := dec.ListEnd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_tmp0.CodeChanges = _tmp19
|
||||||
if err := dec.ListEnd(); err != nil {
|
if err := dec.ListEnd(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,16 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/internal/testrand"
|
"github.com/ethereum/go-ethereum/internal/testrand"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
func equalBALs(a *BlockAccessList, b *BlockAccessList) bool {
|
|
||||||
if !reflect.DeepEqual(a, b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeTestConstructionBAL() *ConstructionBlockAccessList {
|
func makeTestConstructionBAL() *ConstructionBlockAccessList {
|
||||||
return &ConstructionBlockAccessList{
|
return &ConstructionBlockAccessList{
|
||||||
map[common.Address]*ConstructionAccountAccess{
|
map[common.Address]*ConstructionAccountAccess{
|
||||||
common.BytesToAddress([]byte{0xff, 0xff}): {
|
common.BytesToAddress([]byte{0xff, 0xff}): {
|
||||||
StorageWrites: map[common.Hash]map[uint16]common.Hash{
|
StorageWrites: map[common.Hash]map[uint32]common.Hash{
|
||||||
common.BytesToHash([]byte{0x01}): {
|
common.BytesToHash([]byte{0x01}): {
|
||||||
1: common.BytesToHash([]byte{1, 2, 3, 4}),
|
1: common.BytesToHash([]byte{1, 2, 3, 4}),
|
||||||
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
|
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
|
||||||
|
|
@ -52,20 +46,20 @@ func makeTestConstructionBAL() *ConstructionBlockAccessList {
|
||||||
StorageReads: map[common.Hash]struct{}{
|
StorageReads: map[common.Hash]struct{}{
|
||||||
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7}): {},
|
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7}): {},
|
||||||
},
|
},
|
||||||
BalanceChanges: map[uint16]*uint256.Int{
|
BalanceChanges: map[uint32]*uint256.Int{
|
||||||
1: uint256.NewInt(100),
|
1: uint256.NewInt(100),
|
||||||
2: uint256.NewInt(500),
|
2: uint256.NewInt(500),
|
||||||
},
|
},
|
||||||
NonceChanges: map[uint16]uint64{
|
NonceChanges: map[uint32]uint64{
|
||||||
1: 2,
|
1: 2,
|
||||||
2: 6,
|
2: 6,
|
||||||
},
|
},
|
||||||
CodeChange: map[uint16][]byte{
|
CodeChange: map[uint32][]byte{
|
||||||
0: common.Hex2Bytes("deadbeef"),
|
0: common.Hex2Bytes("deadbeef"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
common.BytesToAddress([]byte{0xff, 0xff, 0xff}): {
|
common.BytesToAddress([]byte{0xff, 0xff, 0xff}): {
|
||||||
StorageWrites: map[common.Hash]map[uint16]common.Hash{
|
StorageWrites: map[common.Hash]map[uint32]common.Hash{
|
||||||
common.BytesToHash([]byte{0x01}): {
|
common.BytesToHash([]byte{0x01}): {
|
||||||
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
|
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
|
||||||
3: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
|
3: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
|
||||||
|
|
@ -77,14 +71,14 @@ func makeTestConstructionBAL() *ConstructionBlockAccessList {
|
||||||
StorageReads: map[common.Hash]struct{}{
|
StorageReads: map[common.Hash]struct{}{
|
||||||
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}): {},
|
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}): {},
|
||||||
},
|
},
|
||||||
BalanceChanges: map[uint16]*uint256.Int{
|
BalanceChanges: map[uint32]*uint256.Int{
|
||||||
2: uint256.NewInt(100),
|
2: uint256.NewInt(100),
|
||||||
3: uint256.NewInt(500),
|
3: uint256.NewInt(500),
|
||||||
},
|
},
|
||||||
NonceChanges: map[uint16]uint64{
|
NonceChanges: map[uint32]uint64{
|
||||||
1: 2,
|
1: 2,
|
||||||
},
|
},
|
||||||
CodeChange: map[uint16][]byte{
|
CodeChange: map[uint32][]byte{
|
||||||
0: common.Hex2Bytes("deadbeef"),
|
0: common.Hex2Bytes("deadbeef"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -101,13 +95,13 @@ func TestBALEncoding(t *testing.T) {
|
||||||
t.Fatalf("encoding failed: %v\n", err)
|
t.Fatalf("encoding failed: %v\n", err)
|
||||||
}
|
}
|
||||||
var dec BlockAccessList
|
var dec BlockAccessList
|
||||||
if err := dec.DecodeRLP(rlp.NewStream(bytes.NewReader(buf.Bytes()), 10000000)); err != nil {
|
if err := dec.DecodeRLP(rlp.NewStream(bytes.NewReader(buf.Bytes()), 0)); err != nil {
|
||||||
t.Fatalf("decoding failed: %v\n", err)
|
t.Fatalf("decoding failed: %v\n", err)
|
||||||
}
|
}
|
||||||
if dec.Hash() != bal.toEncodingObj().Hash() {
|
if dec.Hash() != bal.toEncodingObj().Hash() {
|
||||||
t.Fatalf("encoded block hash doesn't match decoded")
|
t.Fatalf("encoded block hash doesn't match decoded")
|
||||||
}
|
}
|
||||||
if !equalBALs(bal.toEncodingObj(), &dec) {
|
if !reflect.DeepEqual(bal.toEncodingObj(), &dec) {
|
||||||
t.Fatal("decoded BAL doesn't match")
|
t.Fatal("decoded BAL doesn't match")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,63 +109,79 @@ func TestBALEncoding(t *testing.T) {
|
||||||
func makeTestAccountAccess(sort bool) AccountAccess {
|
func makeTestAccountAccess(sort bool) AccountAccess {
|
||||||
var (
|
var (
|
||||||
storageWrites []encodingSlotWrites
|
storageWrites []encodingSlotWrites
|
||||||
storageReads [][32]byte
|
storageReads []*uint256.Int
|
||||||
balances []encodingBalanceChange
|
balances []encodingBalanceChange
|
||||||
nonces []encodingAccountNonce
|
nonces []encodingAccountNonce
|
||||||
|
codes []encodingCodeChange
|
||||||
)
|
)
|
||||||
|
randSlot := func() *uint256.Int {
|
||||||
|
return new(uint256.Int).SetBytes(testrand.Bytes(32))
|
||||||
|
}
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
slot := encodingSlotWrites{
|
slot := encodingSlotWrites{
|
||||||
Slot: testrand.Hash(),
|
Slot: randSlot(),
|
||||||
}
|
}
|
||||||
for j := 0; j < 3; j++ {
|
for j := 0; j < 3; j++ {
|
||||||
slot.Accesses = append(slot.Accesses, encodingStorageWrite{
|
slot.Accesses = append(slot.Accesses, encodingStorageWrite{
|
||||||
TxIdx: uint16(2 * j),
|
TxIdx: uint32(2 * j),
|
||||||
ValueAfter: testrand.Hash(),
|
ValueAfter: randSlot(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if sort {
|
if sort {
|
||||||
slices.SortFunc(slot.Accesses, func(a, b encodingStorageWrite) int {
|
slices.SortFunc(slot.Accesses, func(a, b encodingStorageWrite) int {
|
||||||
return cmp.Compare[uint16](a.TxIdx, b.TxIdx)
|
return cmp.Compare[uint32](a.TxIdx, b.TxIdx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
storageWrites = append(storageWrites, slot)
|
storageWrites = append(storageWrites, slot)
|
||||||
}
|
}
|
||||||
if sort {
|
if sort {
|
||||||
slices.SortFunc(storageWrites, func(a, b encodingSlotWrites) int {
|
slices.SortFunc(storageWrites, func(a, b encodingSlotWrites) int {
|
||||||
return bytes.Compare(a.Slot[:], b.Slot[:])
|
return a.Slot.Cmp(b.Slot)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
storageReads = append(storageReads, testrand.Hash())
|
storageReads = append(storageReads, randSlot())
|
||||||
}
|
}
|
||||||
if sort {
|
if sort {
|
||||||
slices.SortFunc(storageReads, func(a, b [32]byte) int {
|
slices.SortFunc(storageReads, func(a, b *uint256.Int) int {
|
||||||
return bytes.Compare(a[:], b[:])
|
return a.Cmp(b)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
balances = append(balances, encodingBalanceChange{
|
balances = append(balances, encodingBalanceChange{
|
||||||
TxIdx: uint16(2 * i),
|
TxIdx: uint32(2 * i),
|
||||||
Balance: [16]byte(testrand.Bytes(16)),
|
Balance: new(uint256.Int).SetBytes(testrand.Bytes(16)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if sort {
|
if sort {
|
||||||
slices.SortFunc(balances, func(a, b encodingBalanceChange) int {
|
slices.SortFunc(balances, func(a, b encodingBalanceChange) int {
|
||||||
return cmp.Compare[uint16](a.TxIdx, b.TxIdx)
|
return cmp.Compare[uint32](a.TxIdx, b.TxIdx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
nonces = append(nonces, encodingAccountNonce{
|
nonces = append(nonces, encodingAccountNonce{
|
||||||
TxIdx: uint16(2 * i),
|
TxIdx: uint32(2 * i),
|
||||||
Nonce: uint64(i + 100),
|
Nonce: uint64(i + 100),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if sort {
|
if sort {
|
||||||
slices.SortFunc(nonces, func(a, b encodingAccountNonce) int {
|
slices.SortFunc(nonces, func(a, b encodingAccountNonce) int {
|
||||||
return cmp.Compare[uint16](a.TxIdx, b.TxIdx)
|
return cmp.Compare[uint32](a.TxIdx, b.TxIdx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
codes = append(codes, encodingCodeChange{
|
||||||
|
TxIndex: uint32(2 * i),
|
||||||
|
Code: testrand.Bytes(256),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if sort {
|
||||||
|
slices.SortFunc(codes, func(a, b encodingCodeChange) int {
|
||||||
|
return cmp.Compare[uint32](a.TxIndex, b.TxIndex)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,26 +191,21 @@ func makeTestAccountAccess(sort bool) AccountAccess {
|
||||||
StorageReads: storageReads,
|
StorageReads: storageReads,
|
||||||
BalanceChanges: balances,
|
BalanceChanges: balances,
|
||||||
NonceChanges: nonces,
|
NonceChanges: nonces,
|
||||||
CodeChanges: []encodingCodeChange{
|
CodeChanges: codes,
|
||||||
{
|
|
||||||
TxIndex: 100,
|
|
||||||
Code: testrand.Bytes(256),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTestBAL(sort bool) *BlockAccessList {
|
func makeTestBAL(sort bool) *BlockAccessList {
|
||||||
list := &BlockAccessList{}
|
list := make(BlockAccessList, 0, 5)
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
list.Accesses = append(list.Accesses, makeTestAccountAccess(sort))
|
list = append(list, makeTestAccountAccess(sort))
|
||||||
}
|
}
|
||||||
if sort {
|
if sort {
|
||||||
slices.SortFunc(list.Accesses, func(a, b AccountAccess) int {
|
slices.SortFunc(list, func(a, b AccountAccess) int {
|
||||||
return bytes.Compare(a.Address[:], b.Address[:])
|
return bytes.Compare(a.Address[:], b.Address[:])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return list
|
return &list
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockAccessListCopy(t *testing.T) {
|
func TestBlockAccessListCopy(t *testing.T) {
|
||||||
|
|
@ -216,9 +221,9 @@ func TestBlockAccessListCopy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the mutations on copy won't affect the origin
|
// Make sure the mutations on copy won't affect the origin
|
||||||
for _, aa := range cpyCpy.Accesses {
|
for _, aa := range *cpyCpy {
|
||||||
for i := 0; i < len(aa.StorageReads); i++ {
|
for i := 0; i < len(aa.StorageReads); i++ {
|
||||||
aa.StorageReads[i] = [32]byte(testrand.Bytes(32))
|
aa.StorageReads[i] = new(uint256.Int).SetBytes(testrand.Bytes(32))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(list, cpy) {
|
if !reflect.DeepEqual(list, cpy) {
|
||||||
|
|
@ -229,7 +234,7 @@ func TestBlockAccessListCopy(t *testing.T) {
|
||||||
func TestBlockAccessListValidation(t *testing.T) {
|
func TestBlockAccessListValidation(t *testing.T) {
|
||||||
// Validate the block access list after RLP decoding
|
// Validate the block access list after RLP decoding
|
||||||
enc := makeTestBAL(true)
|
enc := makeTestBAL(true)
|
||||||
if err := enc.Validate(); err != nil {
|
if err := enc.Validate(params.Rules{}); err != nil {
|
||||||
t.Fatalf("Unexpected validation error: %v", err)
|
t.Fatalf("Unexpected validation error: %v", err)
|
||||||
}
|
}
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
@ -241,14 +246,14 @@ func TestBlockAccessListValidation(t *testing.T) {
|
||||||
if err := dec.DecodeRLP(rlp.NewStream(bytes.NewReader(buf.Bytes()), 0)); err != nil {
|
if err := dec.DecodeRLP(rlp.NewStream(bytes.NewReader(buf.Bytes()), 0)); err != nil {
|
||||||
t.Fatalf("Unexpected RLP-decode error: %v", err)
|
t.Fatalf("Unexpected RLP-decode error: %v", err)
|
||||||
}
|
}
|
||||||
if err := dec.Validate(); err != nil {
|
if err := dec.Validate(params.Rules{}); err != nil {
|
||||||
t.Fatalf("Unexpected validation error: %v", err)
|
t.Fatalf("Unexpected validation error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the derived block access list
|
// Validate the derived block access list
|
||||||
cBAL := makeTestConstructionBAL()
|
cBAL := makeTestConstructionBAL()
|
||||||
listB := cBAL.toEncodingObj()
|
listB := cBAL.toEncodingObj()
|
||||||
if err := listB.Validate(); err != nil {
|
if err := listB.Validate(params.Rules{}); err != nil {
|
||||||
t.Fatalf("Unexpected validation error: %v", err)
|
t.Fatalf("Unexpected validation error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,18 +31,24 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types/bal"
|
"github.com/ethereum/go-ethereum/core/types/bal"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeTestBAL(minSize int) *bal.BlockAccessList {
|
func makeTestBAL(minSize int) *bal.BlockAccessList {
|
||||||
n := minSize/33 + 1 // 33 bytes per storage read slot in RLP
|
n := minSize/33 + 1 // 33 bytes per storage read slot in RLP
|
||||||
access := bal.AccountAccess{
|
access := bal.AccountAccess{
|
||||||
Address: common.HexToAddress("0x01"),
|
Address: common.HexToAddress("0x01"),
|
||||||
StorageReads: make([][32]byte, n),
|
StorageReads: make([]*uint256.Int, n),
|
||||||
}
|
}
|
||||||
|
// Use a full-width 32-byte value (top byte 0xff) so each slot still
|
||||||
|
// encodes to 33 RLP bytes regardless of the index.
|
||||||
for i := range access.StorageReads {
|
for i := range access.StorageReads {
|
||||||
binary.BigEndian.PutUint64(access.StorageReads[i][24:], uint64(i))
|
var b [32]byte
|
||||||
|
b[0] = 0xff
|
||||||
|
binary.BigEndian.PutUint64(b[24:], uint64(i))
|
||||||
|
access.StorageReads[i] = new(uint256.Int).SetBytes(b[:])
|
||||||
}
|
}
|
||||||
return &bal.BlockAccessList{Accesses: []bal.AccountAccess{access}}
|
return &bal.BlockAccessList{access}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getChainWithBALs creates a minimal test chain with BALs stored for each block.
|
// getChainWithBALs creates a minimal test chain with BALs stored for each block.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue