mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
continued rework
This commit is contained in:
parent
037d06e3b2
commit
b4976948f2
4 changed files with 128 additions and 144 deletions
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,56 +36,54 @@ 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}),
|
|
||||||
},
|
|
||||||
common.BytesToHash([]byte{0x10}): {
|
|
||||||
20: common.BytesToHash([]byte{1, 2, 3, 4}),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
StorageReads: map[common.Hash]struct{}{
|
common.BytesToHash([]byte{0x10}): {
|
||||||
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7}): {},
|
20: common.BytesToHash([]byte{1, 2, 3, 4}),
|
||||||
},
|
},
|
||||||
BalanceChanges: map[uint16]*uint256.Int{
|
|
||||||
1: uint256.NewInt(100),
|
|
||||||
2: uint256.NewInt(500),
|
|
||||||
},
|
|
||||||
NonceChanges: map[uint16]uint64{
|
|
||||||
1: 2,
|
|
||||||
2: 6,
|
|
||||||
},
|
|
||||||
CodeChanges: map[uint16]CodeChange{0: {
|
|
||||||
TxIdx: 0,
|
|
||||||
Code: common.Hex2Bytes("deadbeef"),
|
|
||||||
}},
|
|
||||||
},
|
},
|
||||||
common.BytesToAddress([]byte{0xff, 0xff, 0xff}): {
|
storageReads: map[common.Hash]struct{}{
|
||||||
StorageWrites: map[common.Hash]map[uint16]common.Hash{
|
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7}): {},
|
||||||
common.BytesToHash([]byte{0x01}): {
|
},
|
||||||
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
|
balanceChanges: map[uint16]*uint256.Int{
|
||||||
3: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
|
1: uint256.NewInt(100),
|
||||||
},
|
2: uint256.NewInt(500),
|
||||||
common.BytesToHash([]byte{0x10}): {
|
},
|
||||||
21: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
nonceChanges: map[uint16]uint64{
|
||||||
},
|
1: 2,
|
||||||
|
2: 6,
|
||||||
|
},
|
||||||
|
codeChanges: map[uint16]CodeChange{0: {
|
||||||
|
TxIdx: 0,
|
||||||
|
Code: common.Hex2Bytes("deadbeef"),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
common.BytesToAddress([]byte{0xff, 0xff, 0xff}): {
|
||||||
|
storageWrites: map[common.Hash]map[uint16]common.Hash{
|
||||||
|
common.BytesToHash([]byte{0x01}): {
|
||||||
|
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
|
||||||
|
3: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
|
||||||
},
|
},
|
||||||
StorageReads: map[common.Hash]struct{}{
|
common.BytesToHash([]byte{0x10}): {
|
||||||
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}): {},
|
21: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
||||||
},
|
|
||||||
BalanceChanges: map[uint16]*uint256.Int{
|
|
||||||
2: uint256.NewInt(100),
|
|
||||||
3: uint256.NewInt(500),
|
|
||||||
},
|
|
||||||
NonceChanges: map[uint16]uint64{
|
|
||||||
1: 2,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
storageReads: map[common.Hash]struct{}{
|
||||||
|
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}): {},
|
||||||
|
},
|
||||||
|
balanceChanges: map[uint16]*uint256.Int{
|
||||||
|
2: uint256.NewInt(100),
|
||||||
|
3: uint256.NewInt(500),
|
||||||
|
},
|
||||||
|
nonceChanges: map[uint16]uint64{
|
||||||
|
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
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue