continued rework

This commit is contained in:
Jared Wasinger 2025-10-21 14:09:30 +08:00
parent 037d06e3b2
commit b4976948f2
4 changed files with 128 additions and 144 deletions

View file

@ -42,7 +42,7 @@ type idxAccessListBuilder struct {
accessesStack []map[common.Address]*constructionAccountAccess accessesStack []map[common.Address]*constructionAccountAccess
} }
func newAccessListBuilder() *idxAccessListBuilder { func newIdxAccessListBuilder() *idxAccessListBuilder {
return &idxAccessListBuilder{ return &idxAccessListBuilder{
make(map[common.Address]*accountIdxPrestate), make(map[common.Address]*accountIdxPrestate),
[]map[common.Address]*constructionAccountAccess{ []map[common.Address]*constructionAccountAccess{
@ -233,7 +233,7 @@ func (a *idxAccessListBuilder) finalise() (*StateDiff, StateAccesses) {
// then emptied. // then emptied.
func (c *AccessListBuilder) FinaliseIdxChanges(idx uint16) { func (c *AccessListBuilder) FinaliseIdxChanges(idx uint16) {
pendingDiff, pendingAccesses := c.idxBuilder.finalise() pendingDiff, pendingAccesses := c.idxBuilder.finalise()
c.idxBuilder = newAccessListBuilder() c.idxBuilder = newIdxAccessListBuilder()
// merge the set of state accesses/modifications into the access list: // merge the set of state accesses/modifications into the access list:
// * any account or storage slot which was already recorded as a read // * any account or storage slot which was already recorded as a read
@ -245,40 +245,40 @@ func (c *AccessListBuilder) FinaliseIdxChanges(idx uint16) {
for addr, pendingAcctDiff := range pendingDiff.Mutations { for addr, pendingAcctDiff := range pendingDiff.Mutations {
finalizedAcctChanges, ok := c.FinalizedAccesses[addr] finalizedAcctChanges, ok := c.FinalizedAccesses[addr]
if !ok { if !ok {
finalizedAcctChanges = &ConstructionAccountAccesses{} finalizedAcctChanges = &constructionAccountAccesses{}
c.FinalizedAccesses[addr] = finalizedAcctChanges c.FinalizedAccesses[addr] = finalizedAcctChanges
} }
if pendingAcctDiff.Nonce != nil { if pendingAcctDiff.Nonce != nil {
if finalizedAcctChanges.NonceChanges == nil { if finalizedAcctChanges.nonceChanges == nil {
finalizedAcctChanges.NonceChanges = make(map[uint16]uint64) finalizedAcctChanges.nonceChanges = make(map[uint16]uint64)
} }
finalizedAcctChanges.NonceChanges[idx] = *pendingAcctDiff.Nonce finalizedAcctChanges.nonceChanges[idx] = *pendingAcctDiff.Nonce
} }
if pendingAcctDiff.Balance != nil { if pendingAcctDiff.Balance != nil {
if finalizedAcctChanges.BalanceChanges == nil { if finalizedAcctChanges.balanceChanges == nil {
finalizedAcctChanges.BalanceChanges = make(map[uint16]*uint256.Int) finalizedAcctChanges.balanceChanges = make(map[uint16]*uint256.Int)
} }
finalizedAcctChanges.BalanceChanges[idx] = pendingAcctDiff.Balance finalizedAcctChanges.balanceChanges[idx] = pendingAcctDiff.Balance
} }
if pendingAcctDiff.Code != nil { if pendingAcctDiff.Code != nil {
if finalizedAcctChanges.CodeChanges == nil { if finalizedAcctChanges.codeChanges == nil {
finalizedAcctChanges.CodeChanges = make(map[uint16]CodeChange) finalizedAcctChanges.codeChanges = make(map[uint16]CodeChange)
} }
finalizedAcctChanges.CodeChanges[idx] = CodeChange{idx, pendingAcctDiff.Code} finalizedAcctChanges.codeChanges[idx] = CodeChange{idx, pendingAcctDiff.Code}
} }
if pendingAcctDiff.StorageWrites != nil { if pendingAcctDiff.StorageWrites != nil {
if finalizedAcctChanges.StorageWrites == nil { if finalizedAcctChanges.storageWrites == nil {
finalizedAcctChanges.StorageWrites = make(map[common.Hash]map[uint16]common.Hash) finalizedAcctChanges.storageWrites = make(map[common.Hash]map[uint16]common.Hash)
} }
for key, val := range pendingAcctDiff.StorageWrites { for key, val := range pendingAcctDiff.StorageWrites {
if _, ok := finalizedAcctChanges.StorageWrites[key]; !ok { if _, ok := finalizedAcctChanges.storageWrites[key]; !ok {
finalizedAcctChanges.StorageWrites[key] = make(map[uint16]common.Hash) finalizedAcctChanges.storageWrites[key] = make(map[uint16]common.Hash)
} }
finalizedAcctChanges.StorageWrites[key][idx] = val finalizedAcctChanges.storageWrites[key][idx] = val
if _, ok := finalizedAcctChanges.StorageReads[key]; ok { if _, ok := finalizedAcctChanges.storageReads[key]; ok {
delete(finalizedAcctChanges.StorageReads, key) delete(finalizedAcctChanges.storageReads, key)
} }
} }
} }
@ -288,18 +288,18 @@ func (c *AccessListBuilder) FinaliseIdxChanges(idx uint16) {
for addr, pendingAccountAccesses := range pendingAccesses { for addr, pendingAccountAccesses := range pendingAccesses {
finalizedAcctAccesses, ok := c.FinalizedAccesses[addr] finalizedAcctAccesses, ok := c.FinalizedAccesses[addr]
if !ok { if !ok {
finalizedAcctAccesses = &ConstructionAccountAccesses{} finalizedAcctAccesses = &constructionAccountAccesses{}
c.FinalizedAccesses[addr] = finalizedAcctAccesses c.FinalizedAccesses[addr] = finalizedAcctAccesses
} }
for key := range pendingAccountAccesses { for key := range pendingAccountAccesses {
if _, ok := finalizedAcctAccesses.StorageWrites[key]; ok { if _, ok := finalizedAcctAccesses.storageWrites[key]; ok {
continue continue
} }
if finalizedAcctAccesses.StorageReads == nil { if finalizedAcctAccesses.storageReads == nil {
finalizedAcctAccesses.StorageReads = make(map[common.Hash]struct{}) finalizedAcctAccesses.storageReads = make(map[common.Hash]struct{})
} }
finalizedAcctAccesses.StorageReads[key] = struct{}{} finalizedAcctAccesses.storageReads[key] = struct{}{}
} }
} }
c.lastFinalizedMutations = pendingDiff c.lastFinalizedMutations = pendingDiff
@ -342,7 +342,7 @@ type CodeChange struct {
Code []byte `json:"code,omitempty"` Code []byte `json:"code,omitempty"`
} }
// ConstructionAccountAccesses contains all state mutations which were applied // constructionAccountAccesses contains all state mutations which were applied
// to a single account during the execution of a block. // to a single account during the execution of a block.
// It contains the final values for the account fields and storage slots which // It contains the final values for the account fields and storage slots which
// were mutated, indexed by where they occurred: // were mutated, indexed by where they occurred:
@ -352,17 +352,19 @@ type CodeChange struct {
// //
// It also contains a set of storage slot accesses for state which was accessed // It also contains a set of storage slot accesses for state which was accessed
// but not modified. State accesses are not keyed by an index where they occurred. // but not modified. State accesses are not keyed by an index where they occurred.
type ConstructionAccountAccesses struct { type constructionAccountAccesses struct {
// StorageWrites contain mutated storage slots and their values. // storageWrites contain mutated storage slots and their values.
// It is indexed by storage slot -> access list index -> post-state value // It is indexed by storage slot -> access list index -> post-state value
StorageWrites map[common.Hash]map[uint16]common.Hash storageWrites map[common.Hash]map[uint16]common.Hash
StorageReads map[common.Hash]struct{} storageReads map[common.Hash]struct{}
BalanceChanges map[uint16]*uint256.Int balanceChanges map[uint16]*uint256.Int
NonceChanges map[uint16]uint64 nonceChanges map[uint16]uint64
CodeChanges map[uint16]CodeChange codeChanges map[uint16]CodeChange
} }
type ConstructionBlockAccessList map[common.Address]*constructionAccountAccesses
// constructionAccountAccess contains fields for an account which were modified // constructionAccountAccess contains fields for an account which were modified
// during execution of the current access list index. // during execution of the current access list index.
// It also accumulates a set of storage slots which were accessed but not // It also accumulates a set of storage slots which were accessed but not
@ -477,7 +479,7 @@ func (c *constructionAccountAccess) NonceChange(cur uint64) {
// AccessListBuilder is used to build an EIP-7928 block access list // AccessListBuilder is used to build an EIP-7928 block access list
type AccessListBuilder struct { type AccessListBuilder struct {
FinalizedAccesses map[common.Address]*ConstructionAccountAccesses FinalizedAccesses ConstructionBlockAccessList
idxBuilder *idxAccessListBuilder idxBuilder *idxAccessListBuilder
@ -488,8 +490,8 @@ type AccessListBuilder struct {
// NewAccessListBuilder instantiates an empty access list. // NewAccessListBuilder instantiates an empty access list.
func NewAccessListBuilder() *AccessListBuilder { func NewAccessListBuilder() *AccessListBuilder {
return &AccessListBuilder{ return &AccessListBuilder{
make(map[common.Address]*ConstructionAccountAccesses), make(map[common.Address]*constructionAccountAccesses),
newAccessListBuilder(), newIdxAccessListBuilder(),
nil, nil,
nil, nil,
} }
@ -499,24 +501,24 @@ func NewAccessListBuilder() *AccessListBuilder {
func (c *AccessListBuilder) Copy() *AccessListBuilder { func (c *AccessListBuilder) Copy() *AccessListBuilder {
res := NewAccessListBuilder() res := NewAccessListBuilder()
for addr, aa := range c.FinalizedAccesses { for addr, aa := range c.FinalizedAccesses {
var aaCopy ConstructionAccountAccesses var aaCopy constructionAccountAccesses
slotWrites := make(map[common.Hash]map[uint16]common.Hash, len(aa.StorageWrites)) slotWrites := make(map[common.Hash]map[uint16]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[uint16]*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)
codeChangesCopy := make(map[uint16]CodeChange) codeChangesCopy := make(map[uint16]CodeChange)
for idx, codeChange := range aa.CodeChanges { for idx, codeChange := range aa.codeChanges {
codeChangesCopy[idx] = CodeChange{ codeChangesCopy[idx] = CodeChange{
TxIdx: idx, TxIdx: idx,
Code: bytes.Clone(codeChange.Code), Code: bytes.Clone(codeChange.Code),

View file

@ -19,7 +19,6 @@ package bal
import ( import (
"bytes" "bytes"
"cmp" "cmp"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -67,15 +66,6 @@ func (e *BlockAccessList) DecodeRLP(dec *rlp.Stream) error {
return nil return nil
} }
func (e *BlockAccessList) String() string {
var res bytes.Buffer
enc := json.NewEncoder(&res)
enc.SetIndent("", " ")
// TODO: check error
enc.Encode(e)
return res.String()
}
// 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.
@ -141,7 +131,7 @@ func (e *encodingSlotWrites) validate() error {
return errors.New("storage write tx indices not in order") return errors.New("storage write tx indices not in order")
} }
// AccountAccess is the encoding format of ConstructionAccountAccesses. // AccountAccess is the encoding format of constructionAccountAccesses.
type AccountAccess struct { type AccountAccess struct {
Address common.Address `json:"address,omitempty"` // 20-byte Ethereum address Address common.Address `json:"address,omitempty"` // 20-byte Ethereum address
StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // Storage changes (slot -> [tx_index -> new_value]) StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // Storage changes (slot -> [tx_index -> new_value])
@ -166,7 +156,6 @@ func (e *AccountAccess) validate() error {
return err return err
} }
} }
// test case ideas: keys in both read/writes, duplicate keys in either read/writes
// ensure that the read and write key sets are distinct // ensure that the read and write key sets are distinct
readKeys := make(map[common.Hash]struct{}) readKeys := make(map[common.Hash]struct{})
writeKeys := make(map[common.Hash]struct{}) writeKeys := make(map[common.Hash]struct{})
@ -211,7 +200,6 @@ func (e *AccountAccess) validate() error {
return errors.New("nonce changes not in ascending order by tx index") return errors.New("nonce changes not in ascending order by tx index")
} }
// Convert code change
for _, codeChange := range e.CodeChanges { for _, codeChange := range e.CodeChanges {
if len(codeChange.Code) > params.MaxCodeSize { if len(codeChange.Code) > params.MaxCodeSize {
return fmt.Errorf("code change contained oversized code") return fmt.Errorf("code change contained oversized code")
@ -244,16 +232,9 @@ func (e *AccountAccess) Copy() AccountAccess {
return res return res
} }
// EncodeRLP returns the RLP-encoded access list // toEncodingObj creates an instance of the constructionAccountAccesses of the type that is
func (c *AccessListBuilder) EncodeRLP(wr io.Writer) error {
return c.ToEncodingObj().EncodeRLP(wr)
}
var _ rlp.Encoder = &AccessListBuilder{}
// toEncodingObj creates an instance of the ConstructionAccountAccesses of the type that is
// used as input for the encoding. // used as input for the encoding.
func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) AccountAccess { func (a *constructionAccountAccesses) toEncodingObj(addr common.Address) AccountAccess {
res := AccountAccess{ res := AccountAccess{
Address: addr, Address: addr,
StorageChanges: make([]encodingSlotWrites, 0), StorageChanges: make([]encodingSlotWrites, 0),
@ -264,13 +245,13 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
} }
// Convert write slots // Convert write slots
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 var obj encodingSlotWrites
obj.Slot = slot obj.Slot = 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))
@ -285,39 +266,39 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
} }
// Convert read slots // Convert read slots
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, 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[uint16])
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: new(uint256.Int).Set(a.BalanceChanges[idx]), Balance: new(uint256.Int).Set(a.balanceChanges[idx]),
}) })
} }
// 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[uint16])
for _, idx := range nonceIndices { for _, idx := range nonceIndices {
res.NonceChanges = append(res.NonceChanges, encodingAccountNonce{ res.NonceChanges = append(res.NonceChanges, encodingAccountNonce{
TxIdx: idx, TxIdx: idx,
Nonce: a.NonceChanges[idx], Nonce: a.nonceChanges[idx],
}) })
} }
// Convert code change // Convert code change
codeChangeIdxs := slices.Collect(maps.Keys(a.CodeChanges)) codeChangeIdxs := slices.Collect(maps.Keys(a.codeChanges))
slices.SortFunc(codeChangeIdxs, cmp.Compare[uint16]) slices.SortFunc(codeChangeIdxs, cmp.Compare[uint16])
for _, idx := range codeChangeIdxs { for _, idx := range codeChangeIdxs {
res.CodeChanges = append(res.CodeChanges, CodeChange{ res.CodeChanges = append(res.CodeChanges, CodeChange{
idx, idx,
bytes.Clone(a.CodeChanges[idx].Code), bytes.Clone(a.codeChanges[idx].Code),
}) })
} }
return res return res
@ -325,16 +306,16 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
// ToEncodingObj returns an instance of the access list expressed as the type // ToEncodingObj returns an instance of the access list expressed as the type
// which is used as input for the encoding/decoding. // which is used as input for the encoding/decoding.
func (c *AccessListBuilder) ToEncodingObj() *BlockAccessList { func (c ConstructionBlockAccessList) ToEncodingObj() *BlockAccessList {
var addresses []common.Address var addresses []common.Address
for addr := range c.FinalizedAccesses { for addr := range c {
addresses = append(addresses, addr) addresses = append(addresses, addr)
} }
slices.SortFunc(addresses, common.Address.Cmp) slices.SortFunc(addresses, common.Address.Cmp)
var res BlockAccessList var res BlockAccessList
for _, addr := range addresses { for _, addr := range addresses {
res = append(res, c.FinalizedAccesses[addr].toEncodingObj(addr)) res = append(res, c[addr].toEncodingObj(addr))
} }
return &res return &res
} }

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/holiman/uint256"
) )
func (c *ContractCode) MarshalJSON() ([]byte, error) { func (c *ContractCode) MarshalJSON() ([]byte, error) {
@ -12,23 +13,21 @@ func (c *ContractCode) MarshalJSON() ([]byte, error) {
return json.Marshal(hexStr) return json.Marshal(hexStr)
} }
func (e encodingBalanceChange) MarshalJSON() ([]byte, error) { func (e encodingBalanceChange) MarshalJSON() ([]byte, error) {
type Alias encodingBalanceChange
return json.Marshal(&struct { return json.Marshal(&struct {
TxIdx string `json:"txIndex"` TxIdx string `json:"txIndex"`
*Alias Balance *uint256.Int
}{ }{
TxIdx: fmt.Sprintf("0x%x", e.TxIdx), TxIdx: fmt.Sprintf("0x%x", e.TxIdx),
Alias: (*Alias)(&e), Balance: e.Balance,
}) })
} }
func (e *encodingBalanceChange) UnmarshalJSON(data []byte) error { func (e *encodingBalanceChange) UnmarshalJSON(data []byte) error {
type Alias encodingBalanceChange
aux := &struct { aux := &struct {
TxIdx string `json:"txIndex"` TxIdx string `json:"txIndex"`
*Alias Balance *uint256.Int
}{ }{
Alias: (*Alias)(e), Balance: e.Balance,
} }
if err := json.Unmarshal(data, &aux); err != nil { if err := json.Unmarshal(data, &aux); err != nil {
return err return err
@ -41,27 +40,20 @@ func (e *encodingBalanceChange) UnmarshalJSON(data []byte) error {
return nil return nil
} }
func (e encodingAccountNonce) MarshalJSON() ([]byte, error) { func (e encodingAccountNonce) MarshalJSON() ([]byte, error) {
type Alias encodingAccountNonce
return json.Marshal(&struct { return json.Marshal(&struct {
TxIdx string `json:"txIndex"` TxIdx string `json:"txIndex"`
Nonce string `json:"nonce"` Nonce string `json:"nonce"`
*Alias
}{ }{
TxIdx: fmt.Sprintf("0x%x", e.TxIdx), TxIdx: fmt.Sprintf("0x%x", e.TxIdx),
Nonce: fmt.Sprintf("0x%x", e.Nonce), Nonce: fmt.Sprintf("0x%x", e.Nonce),
Alias: (*Alias)(&e),
}) })
} }
func (e *encodingAccountNonce) UnmarshalJSON(data []byte) error { func (e *encodingAccountNonce) UnmarshalJSON(data []byte) error {
type Alias encodingAccountNonce
aux := &struct { aux := &struct {
TxIdx string `json:"txIndex"` TxIdx string `json:"txIndex"`
Nonce string `json:"nonce"` Nonce string `json:"nonce"`
*Alias }{}
}{
Alias: (*Alias)(e),
}
if err := json.Unmarshal(data, &aux); err != nil { if err := json.Unmarshal(data, &aux); err != nil {
return err return err
} }
@ -105,3 +97,17 @@ func (b BlockAccessList) MarshalJSON() ([]byte, error) {
} }
return json.Marshal(hexutil.Bytes(rlpBytes)) return json.Marshal(hexutil.Bytes(rlpBytes))
} }
func (b BlockAccessList) String() string {
aux := []AccountAccess{}
for _, access := range b {
aux = append(aux, access)
}
res, err := json.MarshalIndent(aux, "", " ")
if err != nil {
panic(err)
}
return string(res)
}

View file

@ -36,11 +36,10 @@ func equalBALs(a *BlockAccessList, b *BlockAccessList) bool {
return true return true
} }
func makeTestConstructionBAL() *AccessListBuilder { func makeTestConstructionBAL() *ConstructionBlockAccessList {
return &AccessListBuilder{ return &ConstructionBlockAccessList{
map[common.Address]*ConstructionAccountAccesses{
common.BytesToAddress([]byte{0xff, 0xff}): { common.BytesToAddress([]byte{0xff, 0xff}): {
StorageWrites: map[common.Hash]map[uint16]common.Hash{ storageWrites: map[common.Hash]map[uint16]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}),
@ -49,24 +48,24 @@ func makeTestConstructionBAL() *AccessListBuilder {
20: common.BytesToHash([]byte{1, 2, 3, 4}), 20: common.BytesToHash([]byte{1, 2, 3, 4}),
}, },
}, },
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[uint16]*uint256.Int{
1: uint256.NewInt(100), 1: uint256.NewInt(100),
2: uint256.NewInt(500), 2: uint256.NewInt(500),
}, },
NonceChanges: map[uint16]uint64{ nonceChanges: map[uint16]uint64{
1: 2, 1: 2,
2: 6, 2: 6,
}, },
CodeChanges: map[uint16]CodeChange{0: { codeChanges: map[uint16]CodeChange{0: {
TxIdx: 0, TxIdx: 0,
Code: common.Hex2Bytes("deadbeef"), Code: 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[uint16]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}),
@ -75,18 +74,17 @@ func makeTestConstructionBAL() *AccessListBuilder {
21: common.BytesToHash([]byte{1, 2, 3, 4, 5}), 21: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
}, },
}, },
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[uint16]*uint256.Int{
2: uint256.NewInt(100), 2: uint256.NewInt(100),
3: uint256.NewInt(500), 3: uint256.NewInt(500),
}, },
NonceChanges: map[uint16]uint64{ nonceChanges: map[uint16]uint64{
1: 2, 1: 2,
}, },
}, },
},
} }
} }
@ -94,7 +92,7 @@ func makeTestConstructionBAL() *AccessListBuilder {
func TestBALEncoding(t *testing.T) { func TestBALEncoding(t *testing.T) {
var buf bytes.Buffer var buf bytes.Buffer
bal := makeTestConstructionBAL() bal := makeTestConstructionBAL()
err := bal.EncodeRLP(&buf) err := bal.ToEncodingObj().EncodeRLP(&buf)
if err != nil { if err != nil {
t.Fatalf("encoding failed: %v\n", err) t.Fatalf("encoding failed: %v\n", err)
} }
@ -250,6 +248,3 @@ func TestBlockAccessListValidation(t *testing.T) {
t.Fatalf("Unexpected validation error: %v", err) t.Fatalf("Unexpected validation error: %v", err)
} }
} }
// BALReader test ideas
// * BAL which doesn't have any pre-tx system contracts should return an empty state diff at idx 0