fix the last commit

This commit is contained in:
Jared Wasinger 2025-12-16 11:02:30 -08:00
parent 283c334db7
commit c112198644
7 changed files with 103 additions and 82 deletions

View file

@ -95,7 +95,7 @@ func (a *BlockAccessListTracer) OnNonceChange(addr common.Address, prev uint64,
}
func (a *BlockAccessListTracer) OnStorageRead(addr common.Address, key common.Hash) {
a.builder.StorageRead(addr, bal.Storage(key))
a.builder.StorageRead(addr, key)
}
func (a *BlockAccessListTracer) OnAcountRead(addr common.Address) {
@ -103,5 +103,5 @@ func (a *BlockAccessListTracer) OnAcountRead(addr common.Address) {
}
func (a *BlockAccessListTracer) OnStorageChange(addr common.Address, slot common.Hash, prev common.Hash, new common.Hash) {
a.builder.StorageWrite(addr, bal.Storage(slot), bal.Storage(prev), bal.Storage(new))
a.builder.StorageWrite(addr, slot, prev, new)
}

View file

@ -163,7 +163,7 @@ func (r *BALReader) ValidateStateReads(allReads bal.StateAccesses) error {
}
for _, slot := range expectedReads {
if _, ok := reads[slot]; !ok {
if _, ok := reads[slot.ToHash()]; !ok {
return fmt.Errorf("expected read is missing from BAL")
}
}
@ -227,13 +227,13 @@ func (r *BALReader) accountChangesAt(addr common.Address, idx int) *bal.AccountM
for i := len(acct.StorageChanges) - 1; i >= 0; i-- {
if res.StorageWrites == nil {
res.StorageWrites = make(map[bal.Storage]bal.Storage)
res.StorageWrites = make(map[common.Hash]common.Hash)
}
slotWrites := acct.StorageChanges[i]
for j := len(slotWrites.Accesses) - 1; j >= 0; j-- {
if slotWrites.Accesses[j].TxIdx == uint16(idx) {
res.StorageWrites[slotWrites.Slot] = slotWrites.Accesses[j].ValueAfter
res.StorageWrites[slotWrites.Slot.ToHash()] = slotWrites.Accesses[j].ValueAfter.ToHash()
break
}
if slotWrites.Accesses[j].TxIdx < uint16(idx) {
@ -288,10 +288,10 @@ func (r *BALReader) readAccountDiff(addr common.Address, idx int) *bal.AccountMu
}
if len(diff.StorageChanges) > 0 {
res.StorageWrites = make(map[bal.Storage]bal.Storage)
res.StorageWrites = make(map[common.Hash]common.Hash)
for _, slotWrites := range diff.StorageChanges {
for i := 0; i < len(slotWrites.Accesses) && slotWrites.Accesses[i].TxIdx <= uint16(idx); i++ {
res.StorageWrites[slotWrites.Slot] = slotWrites.Accesses[i].ValueAfter
res.StorageWrites[slotWrites.Slot.ToHash()] = slotWrites.Accesses[i].ValueAfter.ToHash()
}
}
}

View file

@ -469,7 +469,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
deleteKeys [][]byte
)
for key, val := range diff.StorageWrites {
if val != (bal.Storage{}) {
if val != (common.Hash{}) {
updateKeys = append(updateKeys, key[:])
updateValues = append(updateValues, common.TrimLeftZeroes(val[:]))

View file

@ -55,7 +55,7 @@ func newAccessListBuilder(logger *slog.Logger) *idxAccessListBuilder {
}
}
func (c *idxAccessListBuilder) storageRead(address common.Address, key Storage) {
func (c *idxAccessListBuilder) storageRead(address common.Address, key common.Hash) {
if _, ok := c.accessesStack[len(c.accessesStack)-1][address]; !ok {
c.accessesStack[len(c.accessesStack)-1][address] = &constructionAccountAccess{}
}
@ -69,12 +69,12 @@ func (c *idxAccessListBuilder) accountRead(address common.Address) {
}
}
func (c *idxAccessListBuilder) storageWrite(address common.Address, key, prevVal, newVal Storage) {
func (c *idxAccessListBuilder) storageWrite(address common.Address, key, prevVal, newVal common.Hash) {
if _, ok := c.prestates[address]; !ok {
c.prestates[address] = &accountIdxPrestate{}
}
if c.prestates[address].storage == nil {
c.prestates[address].storage = make(map[Storage]Storage)
c.prestates[address].storage = make(map[common.Hash]common.Hash)
}
if _, ok := c.prestates[address].storage[key]; !ok {
c.prestates[address].storage[key] = prevVal
@ -134,7 +134,7 @@ func (c *idxAccessListBuilder) codeChange(address common.Address, prev, cur []by
func (c *idxAccessListBuilder) selfDestruct(address common.Address) {
access := c.accessesStack[len(c.accessesStack)-1][address]
if len(access.storageMutations) != 0 && access.storageReads == nil {
access.storageReads = make(map[Storage]struct{})
access.storageReads = make(map[common.Hash]struct{})
}
for key, _ := range access.storageMutations {
access.storageReads[key] = struct{}{}
@ -219,7 +219,7 @@ func (a *idxAccessListBuilder) finalise() (*StateDiff, StateAccesses) {
// if the account has no net mutations against the index prestate, only include
// it in the state read set
if len(access.code) == 0 && access.nonce == nil && access.balance == nil && len(access.storageMutations) == 0 {
stateAccesses[addr] = make(map[Storage]struct{})
stateAccesses[addr] = make(map[common.Hash]struct{})
if access.storageReads != nil {
stateAccesses[addr] = access.storageReads
}
@ -276,11 +276,11 @@ func (c *AccessListBuilder) FinaliseIdxChanges(idx uint16) {
}
if pendingAcctDiff.StorageWrites != nil {
if finalizedAcctChanges.StorageWrites == nil {
finalizedAcctChanges.StorageWrites = make(map[Storage]map[uint16]Storage)
finalizedAcctChanges.StorageWrites = make(map[common.Hash]map[uint16]common.Hash)
}
for key, val := range pendingAcctDiff.StorageWrites {
if _, ok := finalizedAcctChanges.StorageWrites[key]; !ok {
finalizedAcctChanges.StorageWrites[key] = make(map[uint16]Storage)
finalizedAcctChanges.StorageWrites[key] = make(map[uint16]common.Hash)
}
finalizedAcctChanges.StorageWrites[key][idx] = val
@ -310,7 +310,7 @@ func (c *AccessListBuilder) FinaliseIdxChanges(idx uint16) {
continue
}
if finalizedAcctAccesses.StorageReads == nil {
finalizedAcctAccesses.StorageReads = make(map[Storage]struct{})
finalizedAcctAccesses.StorageReads = make(map[common.Hash]struct{})
}
finalizedAcctAccesses.StorageReads[key] = struct{}{}
}
@ -319,13 +319,13 @@ func (c *AccessListBuilder) FinaliseIdxChanges(idx uint16) {
c.lastFinalizedAccesses = pendingAccesses
}
func (c *AccessListBuilder) StorageRead(address common.Address, key Storage) {
func (c *AccessListBuilder) StorageRead(address common.Address, key common.Hash) {
c.idxBuilder.storageRead(address, key)
}
func (c *AccessListBuilder) AccountRead(address common.Address) {
c.idxBuilder.accountRead(address)
}
func (c *AccessListBuilder) StorageWrite(address common.Address, key, prevVal, newVal Storage) {
func (c *AccessListBuilder) StorageWrite(address common.Address, key, prevVal, newVal common.Hash) {
c.idxBuilder.storageWrite(address, key, prevVal, newVal)
}
func (c *AccessListBuilder) BalanceChange(address common.Address, prev, cur *uint256.Int) {
@ -362,14 +362,14 @@ type ConstructionAccountAccesses struct {
// 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
// where the modification occurred.
StorageWrites map[Storage]map[uint16]Storage
StorageWrites map[common.Hash]map[uint16]common.Hash
// StorageReads is the set of slot keys that were accessed during block
// execution.
//
// Storage slots which are both read and written (with changed values)
// storage slots which are both read and written (with changed values)
// appear only in StorageWrites.
StorageReads map[Storage]struct{}
StorageReads map[common.Hash]struct{}
// BalanceChanges contains the post-transaction balances of an account,
// keyed by transaction indices where it was changed.
@ -391,8 +391,8 @@ type constructionAccountAccess struct {
nonce *uint64
balance *uint256.Int
storageMutations map[Storage]Storage
storageReads map[Storage]struct{}
storageMutations map[common.Hash]common.Hash
storageReads map[common.Hash]struct{}
}
// Merge adds the accesses/mutations from other into the calling instance. If
@ -408,7 +408,7 @@ func (c *constructionAccountAccess) Merge(other *constructionAccountAccess) {
}
if other.storageMutations != nil {
if c.storageMutations == nil {
c.storageMutations = make(map[Storage]Storage)
c.storageMutations = make(map[common.Hash]common.Hash)
}
for key, val := range other.storageMutations {
c.storageMutations[key] = val
@ -417,7 +417,7 @@ func (c *constructionAccountAccess) Merge(other *constructionAccountAccess) {
}
if other.storageReads != nil {
if c.storageReads == nil {
c.storageReads = make(map[Storage]struct{})
c.storageReads = make(map[common.Hash]struct{})
}
// TODO: if the state was mutated in the caller, don't add it to the caller's reads.
// need to have a test case for this, verify it fails in the current state, and then fix this bug.
@ -433,7 +433,7 @@ func (c *constructionAccountAccess) Merge(other *constructionAccountAccess) {
func (c *constructionAccountAccess) MergeReads(other *constructionAccountAccess) {
if other.storageMutations != nil {
if c.storageReads == nil {
c.storageReads = make(map[Storage]struct{})
c.storageReads = make(map[common.Hash]struct{})
}
for key, _ := range other.storageMutations {
if _, ok := c.storageMutations[key]; ok {
@ -444,7 +444,7 @@ func (c *constructionAccountAccess) MergeReads(other *constructionAccountAccess)
}
if other.storageReads != nil {
if c.storageReads == nil {
c.storageReads = make(map[Storage]struct{})
c.storageReads = make(map[common.Hash]struct{})
}
for key := range other.storageReads {
if _, ok := c.storageMutations[key]; ok {
@ -455,18 +455,18 @@ func (c *constructionAccountAccess) MergeReads(other *constructionAccountAccess)
}
}
func (c *constructionAccountAccess) StorageRead(key Storage) {
func (c *constructionAccountAccess) StorageRead(key common.Hash) {
if c.storageReads == nil {
c.storageReads = make(map[Storage]struct{})
c.storageReads = make(map[common.Hash]struct{})
}
if _, ok := c.storageMutations[key]; !ok {
c.storageReads[key] = struct{}{}
}
}
func (c *constructionAccountAccess) StorageWrite(key, prevVal, newVal Storage) {
func (c *constructionAccountAccess) StorageWrite(key, prevVal, newVal common.Hash) {
if c.storageMutations == nil {
c.storageMutations = make(map[Storage]Storage)
c.storageMutations = make(map[common.Hash]common.Hash)
}
c.storageMutations[key] = newVal
// a key can be first read and later written, but it must only show up
@ -518,7 +518,7 @@ func (c *AccessListBuilder) Copy() *AccessListBuilder {
for addr, aa := range c.FinalizedAccesses {
var aaCopy ConstructionAccountAccesses
slotWrites := make(map[Storage]map[uint16]Storage, len(aa.StorageWrites))
slotWrites := make(map[common.Hash]map[uint16]common.Hash, len(aa.StorageWrites))
for key, m := range aa.StorageWrites {
slotWrites[key] = maps.Clone(m)
}
@ -558,13 +558,13 @@ type StateDiff struct {
// StateAccesses contains a set of accounts/storage that were accessed during the
// execution of one or more access list indices.
type StateAccesses map[common.Address]map[Storage]struct{}
type StateAccesses map[common.Address]map[common.Hash]struct{}
// Merge combines adds the accesses from other into s.
func (s *StateAccesses) Merge(other StateAccesses) {
for addr, accesses := range other {
if _, ok := (*s)[addr]; !ok {
(*s)[addr] = make(map[Storage]struct{})
(*s)[addr] = make(map[common.Hash]struct{})
}
for slot := range accesses {
(*s)[addr][slot] = struct{}{}
@ -578,16 +578,16 @@ type accountIdxPrestate struct {
balance *uint256.Int
nonce *uint64
code ContractCode
storage map[Storage]Storage
storage map[common.Hash]common.Hash
}
// AccountMutations contains mutations that were made to an account across
// one or more access list indices.
type AccountMutations struct {
Balance *uint256.Int `json:"Balance,omitempty"`
Nonce *uint64 `json:"Nonce,omitempty"`
Code ContractCode `json:"Code,omitempty"`
StorageWrites map[Storage]Storage `json:"StorageWrites,omitempty"`
Balance *uint256.Int `json:"Balance,omitempty"`
Nonce *uint64 `json:"Nonce,omitempty"`
Code ContractCode `json:"Code,omitempty"`
StorageWrites map[common.Hash]common.Hash `json:"StorageWrites,omitempty"`
}
// String returns a human-readable JSON representation of the account mutations.
@ -618,7 +618,7 @@ func (a *AccountMutations) LogDiff(addr common.Address, other *AccountMutations)
if a.StorageWrites != nil || other.StorageWrites != nil {
if !maps.Equal(a.StorageWrites, other.StorageWrites) {
union := make(map[Storage]struct{})
union := make(map[common.Hash]struct{})
for slot, _ := range a.StorageWrites {
union[slot] = struct{}{}
}
@ -626,7 +626,7 @@ func (a *AccountMutations) LogDiff(addr common.Address, other *AccountMutations)
union[slot] = struct{}{}
}
orderedKeys := slices.SortedFunc(maps.Keys(union), func(hash Storage, hash2 Storage) int {
orderedKeys := slices.SortedFunc(maps.Keys(union), func(hash common.Hash, hash2 common.Hash) int {
return bytes.Compare(hash[:], hash2[:])
})

View file

@ -142,19 +142,29 @@ type encodingAccountNonce struct {
// encodingStorageWrite is the encoding format of StorageWrites.
type encodingStorageWrite struct {
TxIdx uint16 `json:"txIndex"`
ValueAfter Storage `json:"valueAfter"`
TxIdx uint16 `json:"txIndex"`
ValueAfter encodedStorage `json:"valueAfter"`
}
// Storage can represent either a storage key or value
type Storage common.Hash
// encodedStorage can represent either a storage key or value
type encodedStorage []byte
// Cmp compares two hashes.
func (h Storage) Cmp(other Storage) int {
return bytes.Compare(h[:], other[:])
func (e *encodedStorage) ToHash() common.Hash {
if e == nil {
return common.Hash{}
}
return common.BytesToHash(*e)
}
func (s *Storage) UnmarshalJSON(b []byte) error {
func newEncodedStorageFromHash(hash common.Hash) encodedStorage {
return bytes.TrimLeft(hash[:], "\x00")
}
func (e *encodedStorage) FromHash(hash common.Hash) {
*e = hash[:]
}
func (s *encodedStorage) UnmarshalJSON(b []byte) error {
var str string
if err := json.Unmarshal(b, &str); err != nil {
return err
@ -177,32 +187,37 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
if len(val) > 32 {
return fmt.Errorf("storage key/value cannot be greater than 32 bytes")
}
// TODO: check is s == nil ?? should be programmer error
*s = make([]byte, len(val)-1)
copy((*s)[:len(val)-1], val[:])
return nil
}
func (s Storage) MarshalJSON() ([]byte, error) {
func (s encodedStorage) MarshalJSON() ([]byte, error) {
trimmed := bytes.TrimLeft(s[:], "\x00")
return json.Marshal(trimmed)
return json.Marshal("0x" + common.Bytes2Hex(trimmed))
}
func (s *Storage) EncodeRLP(_w io.Writer) error {
var obj Storage
func (s *encodedStorage) EncodeRLP(_w io.Writer) error {
var obj encodedStorage
if s != nil {
obj = *s
}
trimmed := bytes.TrimLeft(obj[:], "\x00")
fmt.Println("here")
return rlp.Encode(_w, trimmed)
}
func (s *Storage) DecodeRLP(dec *rlp.Stream) error {
func (s *encodedStorage) DecodeRLP(dec *rlp.Stream) error {
err := dec.ReadBytes((*s)[:])
return err
}
// encodingStorageWrite is the encoding format of SlotWrites.
type encodingSlotWrites struct {
Slot Storage `json:"slot"`
Slot encodedStorage `json:"slot"`
Accesses []encodingStorageWrite `json:"accesses"`
}
@ -217,11 +232,13 @@ func (e *encodingSlotWrites) validate() error {
return errors.New("storage write tx indices not in order")
}
// TODO: represent storage keys as common.Hash. convert them at the time of decoding the BAL
// AccountAccess is the encoding format of ConstructionAccountAccesses.
type AccountAccess struct {
Address common.Address `json:"address,omitempty"` // 20-byte Ethereum address
StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // Storage changes (slot -> [tx_index -> new_value])
StorageReads []Storage `json:"storageReads,omitempty"` // Read-only storage keys
StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // encodedStorage changes (slot -> [tx_index -> new_value])
StorageReads []encodedStorage `json:"storageReads,omitempty"` // Read-only storage keys
BalanceChanges []encodingBalanceChange `json:"balanceChanges,omitempty"` // Balance changes ([tx_index -> post_balance])
NonceChanges []encodingAccountNonce `json:"nonceChanges,omitempty"` // Nonce changes ([tx_index -> new_nonce])
CodeChanges []CodeChange `json:"code,omitempty"` // CodeChanges changes ([tx_index -> new_code])
@ -233,7 +250,8 @@ type AccountAccess struct {
func (e *AccountAccess) validate() error {
// Check the storage write slots are sorted in order
if !slices.IsSortedFunc(e.StorageChanges, func(a, b encodingSlotWrites) int {
return bytes.Compare(a.Slot[:], b.Slot[:])
aHash, bHash := a.Slot.ToHash(), b.Slot.ToHash()
return bytes.Compare(aHash[:], bHash[:])
}) {
return errors.New("storage writes slots not in lexicographic order")
}
@ -242,20 +260,20 @@ func (e *AccountAccess) validate() error {
return err
}
}
readKeys := make(map[Storage]struct{})
writeKeys := make(map[Storage]struct{})
readKeys := make(map[common.Hash]struct{})
writeKeys := make(map[common.Hash]struct{})
for _, readKey := range e.StorageReads {
if _, ok := readKeys[readKey]; ok {
if _, ok := readKeys[readKey.ToHash()]; ok {
return errors.New("duplicate read key")
}
readKeys[readKey] = struct{}{}
readKeys[readKey.ToHash()] = struct{}{}
}
for _, write := range e.StorageChanges {
writeKey := write.Slot
if _, ok := writeKeys[writeKey]; ok {
if _, ok := writeKeys[writeKey.ToHash()]; ok {
return errors.New("duplicate write key")
}
writeKeys[writeKey] = struct{}{}
writeKeys[writeKey.ToHash()] = struct{}{}
}
for readKey := range readKeys {
@ -265,8 +283,9 @@ func (e *AccountAccess) validate() error {
}
// Check the storage read slots are sorted in order
if !slices.IsSortedFunc(e.StorageReads, func(a, b Storage) int {
return bytes.Compare(a[:], b[:])
if !slices.IsSortedFunc(e.StorageReads, func(a, b encodedStorage) int {
aHash, bHash := a.ToHash(), b.ToHash()
return bytes.Compare(aHash[:], bHash[:])
}) {
return errors.New("storage read slots not in lexicographic order")
}
@ -332,7 +351,7 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
res := AccountAccess{
Address: addr,
StorageChanges: make([]encodingSlotWrites, 0),
StorageReads: make([]Storage, 0),
StorageReads: make([]encodedStorage, 0),
BalanceChanges: make([]encodingBalanceChange, 0),
NonceChanges: make([]encodingAccountNonce, 0),
CodeChanges: make([]CodeChange, 0),
@ -340,10 +359,10 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
// Convert write slots
writeSlots := slices.Collect(maps.Keys(a.StorageWrites))
slices.SortFunc(writeSlots, Storage.Cmp)
slices.SortFunc(writeSlots, common.Hash.Cmp)
for _, slot := range writeSlots {
var obj encodingSlotWrites
obj.Slot = Storage(slot)
obj.Slot = newEncodedStorageFromHash(slot)
slotWrites := a.StorageWrites[slot]
obj.Accesses = make([]encodingStorageWrite, 0, len(slotWrites))
@ -353,7 +372,7 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
for _, index := range indices {
obj.Accesses = append(obj.Accesses, encodingStorageWrite{
TxIdx: index,
ValueAfter: Storage(slotWrites[index]),
ValueAfter: newEncodedStorageFromHash(slotWrites[index]),
})
}
res.StorageChanges = append(res.StorageChanges, obj)
@ -361,9 +380,9 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
// Convert read slots
readSlots := slices.Collect(maps.Keys(a.StorageReads))
slices.SortFunc(readSlots, Storage.Cmp)
slices.SortFunc(readSlots, common.Hash.Cmp)
for _, slot := range readSlots {
res.StorageReads = append(res.StorageReads, slot)
res.StorageReads = append(res.StorageReads, newEncodedStorageFromHash(slot))
}
// Convert balance changes

View file

@ -14,12 +14,12 @@ func (obj *AccountAccess) EncodeRLP(_w io.Writer) error {
_tmp1 := w.List()
for _, _tmp2 := range obj.StorageChanges {
_tmp3 := w.List()
w.WriteBytes(_tmp2.Slot[:])
w.WriteBytes(_tmp2.Slot)
_tmp4 := w.List()
for _, _tmp5 := range _tmp2.Accesses {
_tmp6 := w.List()
w.WriteUint64(uint64(_tmp5.TxIdx))
w.WriteBytes(_tmp5.ValueAfter[:])
w.WriteBytes(_tmp5.ValueAfter)
w.ListEnd(_tmp6)
}
w.ListEnd(_tmp4)
@ -28,7 +28,7 @@ func (obj *AccountAccess) EncodeRLP(_w io.Writer) error {
w.ListEnd(_tmp1)
_tmp7 := w.List()
for _, _tmp8 := range obj.StorageReads {
w.WriteBytes(_tmp8[:])
w.WriteBytes(_tmp8)
}
w.ListEnd(_tmp7)
_tmp9 := w.List()
@ -87,8 +87,8 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error {
return err
}
// Slot:
var _tmp4 Storage
if err := dec.ReadBytes(_tmp4[:]); err != nil {
_tmp4, err := dec.Bytes()
if err != nil {
return err
}
_tmp3.Slot = _tmp4
@ -110,8 +110,8 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error {
}
_tmp6.TxIdx = _tmp7
// ValueAfter:
var _tmp8 Storage
if err := dec.ReadBytes(_tmp8[:]); err != nil {
_tmp8, err := dec.Bytes()
if err != nil {
return err
}
_tmp6.ValueAfter = _tmp8
@ -136,13 +136,13 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error {
}
_tmp0.StorageChanges = _tmp2
// StorageReads:
var _tmp9 []Storage
var _tmp9 []encodedStorage
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp10 Storage
if err := dec.ReadBytes(_tmp10[:]); err != nil {
_tmp10, err := dec.Bytes()
if err != nil {
return err
}
_tmp9 = append(_tmp9, _tmp10)

View file

@ -25,6 +25,7 @@ import (
"io"
"math/big"
"reflect"
"runtime/debug"
"strings"
"sync"
@ -672,6 +673,7 @@ func (s *Stream) ReadBytes(b []byte) error {
return nil
case String:
if uint64(len(b)) != size {
debug.PrintStack()
return fmt.Errorf("input value has wrong size %d, want %d", size, len(b))
}
if err = s.readFull(b); err != nil {