mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Adds access list sorting (#8933)
Because access lists use maps with the `StorageKey` as the key, they are subject to inconsistent ordering in the results of the `.accessList()` method. To get around this, an `accessListSorted` method has been added, and exposed with the same name. The `equal` method has also been exposed to allow for equality checks at this level outside of this module. Co-authored-by: 3commascapital <8562488-3commascapital@users.noreply.gitlab.com>
This commit is contained in:
parent
e006db6ed9
commit
07331f900f
@ -17,6 +17,8 @@
|
|||||||
package logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||||
types2 "github.com/ledgerwatch/erigon-lib/types"
|
types2 "github.com/ledgerwatch/erigon-lib/types"
|
||||||
@ -94,6 +96,10 @@ func (al accessList) equal(other accessList) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (al accessList) Equal(other accessList) bool {
|
||||||
|
return al.equal(other)
|
||||||
|
}
|
||||||
|
|
||||||
// accesslist converts the accesslist to a types2.AccessList.
|
// accesslist converts the accesslist to a types2.AccessList.
|
||||||
func (al accessList) accessList() types2.AccessList {
|
func (al accessList) accessList() types2.AccessList {
|
||||||
acl := make(types2.AccessList, 0, len(al))
|
acl := make(types2.AccessList, 0, len(al))
|
||||||
@ -107,6 +113,25 @@ func (al accessList) accessList() types2.AccessList {
|
|||||||
return acl
|
return acl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// accesslist converts the accesslist to a types2.AccessList.
|
||||||
|
func (al accessList) accessListSorted() types2.AccessList {
|
||||||
|
acl := make(types2.AccessList, 0, len(al))
|
||||||
|
for addr, slots := range al {
|
||||||
|
storageKeys := make([]libcommon.Hash, 0, len(slots))
|
||||||
|
for slot := range slots {
|
||||||
|
storageKeys = append(storageKeys, slot)
|
||||||
|
}
|
||||||
|
sort.Slice(storageKeys, func(i, j int) bool {
|
||||||
|
return storageKeys[i].String() < storageKeys[j].String()
|
||||||
|
})
|
||||||
|
acl = append(acl, types2.AccessTuple{
|
||||||
|
Address: addr,
|
||||||
|
StorageKeys: storageKeys,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return acl
|
||||||
|
}
|
||||||
|
|
||||||
// AccessListTracer is a tracer that accumulates touched accounts and storage
|
// AccessListTracer is a tracer that accumulates touched accounts and storage
|
||||||
// slots into an internal set.
|
// slots into an internal set.
|
||||||
type AccessListTracer struct {
|
type AccessListTracer struct {
|
||||||
@ -227,6 +252,11 @@ func (a *AccessListTracer) AccessList() types2.AccessList {
|
|||||||
return a.list.accessList()
|
return a.list.accessList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AccessList returns the current accesslist maintained by the tracer.
|
||||||
|
func (a *AccessListTracer) AccessListSorted() types2.AccessList {
|
||||||
|
return a.list.accessListSorted()
|
||||||
|
}
|
||||||
|
|
||||||
// CreatedContracts returns the set of all addresses of contracts created during tx execution.
|
// CreatedContracts returns the set of all addresses of contracts created during tx execution.
|
||||||
func (a *AccessListTracer) CreatedContracts() map[libcommon.Address]struct{} {
|
func (a *AccessListTracer) CreatedContracts() map[libcommon.Address]struct{} {
|
||||||
return a.createdContracts
|
return a.createdContracts
|
||||||
|
40
eth/tracers/logger/access_list_tracer_test.go
Normal file
40
eth/tracers/logger/access_list_tracer_test.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ledgerwatch/erigon-lib/common"
|
||||||
|
types2 "github.com/ledgerwatch/erigon-lib/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
addr = common.BytesToAddress([]byte{0x01, 0x71})
|
||||||
|
|
||||||
|
slot1 = common.BytesToHash([]byte{0x01})
|
||||||
|
slot2 = common.BytesToHash([]byte{0x02})
|
||||||
|
slot3 = common.BytesToHash([]byte{0x03})
|
||||||
|
slot4 = common.BytesToHash([]byte{0x04})
|
||||||
|
|
||||||
|
ordered = types2.AccessList{{
|
||||||
|
Address: addr,
|
||||||
|
StorageKeys: []common.Hash{
|
||||||
|
slot1,
|
||||||
|
slot2,
|
||||||
|
slot3,
|
||||||
|
slot4,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTracer_AccessList_Order(t *testing.T) {
|
||||||
|
al := newAccessList()
|
||||||
|
al.addAddress(addr)
|
||||||
|
al.addSlot(addr, slot1)
|
||||||
|
al.addSlot(addr, slot4)
|
||||||
|
al.addSlot(addr, slot3)
|
||||||
|
al.addSlot(addr, slot2)
|
||||||
|
require.NotEqual(t, ordered, al.accessList())
|
||||||
|
require.Equal(t, ordered, al.accessListSorted())
|
||||||
|
require.True(t, al.Equal(al))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user