Skip to content

Commit 92bd2ba

Browse files
authored
Make access list trace order deterministic (#17291)
This is a fix to avoid access list tracing from returning results in random map order by adding code to preserve insetion order. This will make access list RPC's return the same results when called with the same input. I made the fix to address what I thought was a regression - it seems with the right version of json-diff this is not strictly necessary - however I think its a reasonable fix to include.
1 parent 891d506 commit 92bd2ba

File tree

1 file changed

+26
-20
lines changed

1 file changed

+26
-20
lines changed

eth/tracers/logger/access_list_tracer.go

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ type accessList map[common.Address]accessListSlots
3737

3838
// accessListSlots is an accumulator for the set of storage slots within a single
3939
// contract that an EVM contract execution touches.
40-
type accessListSlots map[common.Hash]struct{}
40+
type accessListSlots struct {
41+
order int
42+
slots map[common.Hash]int
43+
}
4144

4245
// newAccessList creates a new accessList.
4346
func newAccessList() accessList {
@@ -48,7 +51,7 @@ func newAccessList() accessList {
4851
func (al accessList) addAddress(address common.Address) {
4952
// Set address if not previously present
5053
if _, present := al[address]; !present {
51-
al[address] = make(map[common.Hash]struct{})
54+
al[address] = accessListSlots{len(al), map[common.Hash]int{}}
5255
}
5356
}
5457

@@ -58,7 +61,10 @@ func (al accessList) addSlot(address common.Address, slot common.Hash) {
5861
al.addAddress(address)
5962

6063
// Set the slot on the surely existent storage set
61-
al[address][slot] = struct{}{}
64+
storage := al[address]
65+
if _, ok := storage.slots[slot]; !ok {
66+
storage.slots[slot] = len(storage.slots)
67+
}
6268
}
6369

6470
// equal checks if the content of the current access list is the same as the
@@ -79,19 +85,19 @@ func (al accessList) equal(other accessList) bool {
7985
}
8086
}
8187
// Accounts match, cross reference the storage slots too
82-
for addr, slots := range al {
83-
otherslots := other[addr]
88+
for addr, storage := range al {
89+
otherStorage := other[addr]
8490

85-
if len(slots) != len(otherslots) {
91+
if len(storage.slots) != len(otherStorage.slots) {
8692
return false
8793
}
88-
for hash := range slots {
89-
if _, ok := otherslots[hash]; !ok {
94+
for hash := range storage.slots {
95+
if _, ok := otherStorage.slots[hash]; !ok {
9096
return false
9197
}
9298
}
93-
for hash := range otherslots {
94-
if _, ok := slots[hash]; !ok {
99+
for hash := range otherStorage.slots {
100+
if _, ok := storage.slots[hash]; !ok {
95101
return false
96102
}
97103
}
@@ -105,24 +111,24 @@ func (al accessList) Equal(other accessList) bool {
105111

106112
// accesslist converts the accesslist to a types.AccessList.
107113
func (al accessList) accessList() types.AccessList {
108-
acl := make(types.AccessList, 0, len(al))
109-
for addr, slots := range al {
110-
tuple := types.AccessTuple{Address: addr, StorageKeys: []common.Hash{}}
111-
for slot := range slots {
112-
tuple.StorageKeys = append(tuple.StorageKeys, slot)
114+
acl := make(types.AccessList, len(al))
115+
for addr, storage := range al {
116+
tuple := types.AccessTuple{Address: addr, StorageKeys: make([]common.Hash, len(storage.slots))}
117+
for slot, pos := range storage.slots {
118+
tuple.StorageKeys[pos] = slot
113119
}
114-
acl = append(acl, tuple)
120+
acl[storage.order] = tuple
115121
}
116122
return acl
117123
}
118124

119125
// accesslist converts the accesslist to a types.AccessList.
120126
func (al accessList) accessListSorted() types.AccessList {
121127
acl := make(types.AccessList, 0, len(al))
122-
for addr, slots := range al {
123-
storageKeys := make([]common.Hash, 0, len(slots))
124-
for slot := range slots {
125-
storageKeys = append(storageKeys, slot)
128+
for addr, storage := range al {
129+
storageKeys := make([]common.Hash, len(storage.slots))
130+
for slot, pos := range storage.slots {
131+
storageKeys[pos] = slot
126132
}
127133
sort.Slice(storageKeys, func(i, j int) bool {
128134
return storageKeys[i].Cmp(storageKeys[j]) < 0

0 commit comments

Comments
 (0)