core/types: add eip-7928 block-level access list structures

This commit is contained in:
Jared Wasinger 2025-07-02 21:18:54 +09:00
parent efbba965b5
commit b3775601ac
13 changed files with 2298 additions and 5 deletions

227
core/types/bal/bal.go Normal file
View file

@ -0,0 +1,227 @@
package bal
import (
"bytes"
"fmt"
"maps"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
)
// BlockAccessList contains post-block modified state and some state accessed
// in execution (account addresses and storage keys).
type BlockAccessList struct {
accounts map[common.Address]*accountAccess
}
// NewBlockAccessList instantiates an empty access list.
func NewBlockAccessList() BlockAccessList {
return BlockAccessList{
accounts: make(map[common.Address]*accountAccess),
}
}
// AccountRead records the address of an account that has been read during execution.
func (b *BlockAccessList) AccountRead(addr common.Address) {
if _, ok := b.accounts[addr]; !ok {
b.accounts[addr] = newAccountAccess()
}
}
// StorageRead records a storage key read during execution.
func (b *BlockAccessList) StorageRead(address common.Address, key common.Hash) {
if _, ok := b.accounts[address]; !ok {
b.accounts[address] = newAccountAccess()
}
if _, ok := b.accounts[address].StorageWrites[key]; ok {
return
}
b.accounts[address].StorageReads[key] = struct{}{}
}
// StorageWrite records the post-transaction value of a mutated storage slot.
// The storage slot is removed from the list of read slots.
func (b *BlockAccessList) StorageWrite(txIdx uint16, address common.Address, key, value common.Hash) {
if _, ok := b.accounts[address]; !ok {
b.accounts[address] = newAccountAccess()
}
if _, ok := b.accounts[address].StorageWrites[key]; !ok {
b.accounts[address].StorageWrites[key] = make(slotWrites)
}
b.accounts[address].StorageWrites[key][txIdx] = value
delete(b.accounts[address].StorageReads, key)
}
// CodeChange records the code of a newly-created contract.
func (b *BlockAccessList) CodeChange(address common.Address, txIndex uint16, code []byte) {
if _, ok := b.accounts[address]; !ok {
b.accounts[address] = newAccountAccess()
}
b.accounts[address].CodeChange = &codeChange{
TxIndex: txIndex,
Code: bytes.Clone(code),
}
}
// NonceDiff records tx post-state nonce of any contract-like accounts whose nonce was incremented
func (b *BlockAccessList) NonceDiff(address common.Address, txIdx uint16, postNonce uint64) {
if _, ok := b.accounts[address]; !ok {
b.accounts[address] = newAccountAccess()
}
b.accounts[address].NonceChanges[txIdx] = postNonce
}
// BalanceChange records the post-transaction balance of an account whose
// balance changed.
func (b *BlockAccessList) BalanceChange(txIdx uint16, address common.Address, balance *uint256.Int) {
if _, ok := b.accounts[address]; !ok {
b.accounts[address] = newAccountAccess()
}
b.accounts[address].BalanceChanges[txIdx] = balance.Clone()
}
// contains the post-transaction balances of an account, keyed by transaction indices
// where it was changed.
type balanceDiff map[uint16]*uint256.Int
// copy returns a deep copy of the object
func (b balanceDiff) copy() balanceDiff {
res := make(balanceDiff)
for idx, balance := range b {
res[idx] = balance.Clone()
}
return res
}
// PrettyPrint returns a human-readable representation of the access list
func (b *BlockAccessList) PrettyPrint() string {
enc := b.toEncodingObj()
return enc.prettyPrint()
}
// Hash computes the SSZ hash of the access list
func (b *BlockAccessList) Hash() common.Hash {
hash, err := b.toEncodingObj().HashTreeRoot()
if err != nil {
// errors here are related to BAL values exceeding maximum size defined
// by the spec. Hard-fail because these cases are not expected to be hit
// under reasonable conditions.
panic(err)
}
return hash
}
// codeChange contains the code deployed at an address and the transaction
// index where the deployment took place.
type codeChange struct {
TxIndex uint16
Code []byte `json:"code,omitempty"`
}
// post-state values of an account's storage slots modified in a block, keyed
// by slot key
type storageWrites map[common.Hash]slotWrites
func (s storageWrites) copy() storageWrites {
res := make(storageWrites)
for slot, writes := range s {
res[slot] = maps.Clone(writes)
}
return res
}
// accountAccess contains post-block account state for mutations as well as
// all storage keys that were read during execution.
type accountAccess struct {
StorageWrites storageWrites `json:"storageWrites,omitempty"`
StorageReads map[common.Hash]struct{} `json:"storageReads,omitempty"`
BalanceChanges balanceDiff `json:"balanceChanges,omitempty"`
NonceChanges accountNonceDiffs `json:"nonceChanges,omitempty"`
// only set for contract accounts which were deployed in the block
CodeChange *codeChange `json:"codeChange,omitempty"`
}
func newAccountAccess() *accountAccess {
return &accountAccess{
StorageWrites: make(map[common.Hash]slotWrites),
StorageReads: make(map[common.Hash]struct{}),
BalanceChanges: make(balanceDiff),
NonceChanges: make(accountNonceDiffs),
}
}
// the post-state nonce values of a contract account keyed by tx index
type accountNonceDiffs map[uint16]uint64
// the post-state values of a storage slot, keyed by tx index
type slotWrites map[uint16]common.Hash
// Copy returns a deep copy of the access list.
func (b *BlockAccessList) Copy() *BlockAccessList {
res := new(BlockAccessList)
for addr, aa := range b.accounts {
var aaCopy accountAccess
aaCopy.StorageWrites = aa.StorageWrites.copy()
aaCopy.StorageReads = maps.Clone(aa.StorageReads)
aaCopy.BalanceChanges = aa.BalanceChanges.copy()
aaCopy.NonceChanges = maps.Clone(aa.NonceChanges)
if aa.CodeChange != nil {
aaCopy.CodeChange = &codeChange{
TxIndex: aa.CodeChange.TxIndex,
Code: bytes.Clone(aa.CodeChange.Code),
}
}
res.accounts[addr] = &aaCopy
}
return res
}
func (e *encodingBlockAccessList) prettyPrint() string {
var res bytes.Buffer
printWithIndent := func(indent int, text string) {
fmt.Fprintf(&res, "%s%s\n", strings.Repeat(" ", indent), text)
}
for _, accountDiff := range e.Accesses {
printWithIndent(0, fmt.Sprintf("%x:", accountDiff.Address))
printWithIndent(1, "storage writes:")
for _, sWrite := range accountDiff.StorageWrites {
printWithIndent(2, fmt.Sprintf("%x:", sWrite.Slot))
for _, access := range sWrite.Accesses {
printWithIndent(3, fmt.Sprintf("%d: %x", access.TxIdx, access.ValueAfter))
}
}
printWithIndent(1, "storage reads:")
for _, slot := range accountDiff.StorageReads {
printWithIndent(2, fmt.Sprintf("%x", slot))
}
printWithIndent(1, "balance changes:")
for _, change := range accountDiff.BalanceChanges {
balance := new(uint256.Int).SetBytes(change.Balance[:]).String()
printWithIndent(2, fmt.Sprintf("%d: %s", change.TxIdx, balance))
}
printWithIndent(1, "nonce changes:")
for _, change := range accountDiff.NonceChanges {
printWithIndent(2, fmt.Sprintf("%d: %d", change.TxIdx, change.Nonce))
}
if len(accountDiff.Code) > 0 {
printWithIndent(1, "code:")
printWithIndent(2, fmt.Sprintf("%d: %x", accountDiff.Code[0].TxIndex, accountDiff.Code[0].Code))
}
}
return res.String()
}

View file

@ -0,0 +1,368 @@
package bal
import (
"bytes"
"fmt"
"io"
"sort"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
"github.com/holiman/uint256"
)
//go:generate go run github.com/ferranbt/fastssz/sszgen --output bal_encoding_ssz_generated.go --path . --objs encodingStorageWrite,encodingCodeChange,encodingBalanceChange,encodingAccountNonce,encodingAccountAccess,encodingBlockAccessList
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_storagewrite_generated.go -type encodingStorageWrite -decoder
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_codechange_generated.go -type encodingCodeChange -decoder
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_balancechange_generated.go -type encodingBalanceChange -decoder
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_accountnonce_generated.go -type encodingAccountNonce -decoder
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_accountaccess_generated.go -type encodingAccountAccess -decoder
//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -out bal_encoding_rlp_blockaccesslist_generated.go -type encodingBlockAccessList -decoder
// These are objects used as input for the access list encoding. They mirror
// the spec format.
type encodingBlockAccessList struct {
Accesses []encodingAccountAccess `ssz-max:"300000"`
}
// toBlockAccessList converts out of the encoding format, returning an error if
// values in the encoder object are not properly ordered according to the spec.
func (e *encodingBlockAccessList) toBlockAccessList() (*BlockAccessList, error) {
res := NewBlockAccessList()
var prevAccount *common.Address
for _, encAccountAccess := range e.Accesses {
if prevAccount != nil {
if bytes.Compare(encAccountAccess.Address[:], (*prevAccount)[:]) <= 0 {
return nil, fmt.Errorf("block access list accounts not in lexicographic order")
}
}
aa, err := encAccountAccess.toAccountAccess()
if err != nil {
return nil, err
}
res.accounts[encAccountAccess.Address] = aa
}
return &res, nil
}
type encodingCodeChange struct {
TxIndex uint16
Code []byte `ssz-max:"24576"`
}
type encodingAccountAccess struct {
Address [20]byte `ssz-size:"20"`
StorageWrites []encodingSlotWrites `ssz-max:"300000"`
StorageReads [][32]byte `ssz-max:"300000"`
BalanceChanges []encodingBalanceChange `ssz-max:"300000"`
NonceChanges []encodingAccountNonce `ssz-max:"300000"`
Code []encodingCodeChange `ssz-max:"1"`
}
// toAccountAccess converts the account accesses out of encoding format.
// If any of the keys in the encoding object are not ordered according to the
// spec, an error is returned.
func (e *encodingAccountAccess) toAccountAccess() (*accountAccess, error) {
res := accountAccess{
StorageWrites: make(map[common.Hash]slotWrites),
StorageReads: make(map[common.Hash]struct{}),
BalanceChanges: make(balanceDiff),
NonceChanges: make(accountNonceDiffs),
CodeChange: nil,
}
{
var prevWriteSlot *[32]byte
for _, write := range e.StorageWrites {
if prevWriteSlot != nil {
if bytes.Compare((*prevWriteSlot)[:], write.Slot[:]) >= 0 {
return nil, fmt.Errorf("storage writes slots lexicographic order")
}
}
wr, err := write.toSlotWrites()
if err != nil {
return nil, err
}
res.StorageWrites[write.Slot] = wr
prevWriteSlot = &write.Slot
}
}
{
var prevReadSlot *[32]byte
for _, read := range e.StorageReads {
if prevReadSlot != nil {
if bytes.Compare((*prevReadSlot)[:], read[:]) >= 0 {
return nil, fmt.Errorf("storage read slots not in lexicographic order")
}
}
res.StorageReads[read] = struct{}{}
prevReadSlot = &read
}
}
{
var prevBalanceChangeIdx *uint16
for _, balanceChange := range e.BalanceChanges {
if prevBalanceChangeIdx != nil {
if *prevBalanceChangeIdx >= balanceChange.TxIdx {
return nil, fmt.Errorf("balance changes not in ascending order by tx index")
}
}
res.BalanceChanges[balanceChange.TxIdx] = new(uint256.Int).SetBytes(balanceChange.Balance[:])
prevBalanceChangeIdx = &balanceChange.TxIdx
}
}
{
var prevNonceDiffIdx *uint16
for _, nonceDiff := range e.NonceChanges {
if prevNonceDiffIdx != nil {
if *prevNonceDiffIdx >= nonceDiff.TxIdx {
return nil, fmt.Errorf("nonce diffs not in ascending order by tx index")
}
}
res.NonceChanges[nonceDiff.TxIdx] = nonceDiff.Nonce
prevNonceDiffIdx = &nonceDiff.TxIdx
}
}
{
if len(e.Code) == 1 {
codeChange := codeChange{e.Code[0].TxIndex, bytes.Clone(e.Code[0].Code)}
res.CodeChange = &codeChange
}
}
return &res, nil
}
type encodingBalance [16]byte
func (b *encodingBalance) set(val *uint256.Int) *encodingBalance {
valBytes := val.Bytes()
if len(valBytes) > 16 {
panic("can't encode value that is greater than 16 bytes in size")
}
copy(b[16-len(valBytes):], valBytes[:])
return b
}
type encodingBalanceChange struct {
TxIdx uint16 `ssz-size:"2"`
Balance encodingBalance
}
type encodingAccountNonce struct {
TxIdx uint16 `ssz-size:"2"`
Nonce uint64 `ssz-size:"8"`
}
// EncodeRLP returns the SSZ-encoded access list wrapped into RLP bytes
func (b *BlockAccessList) EncodeRLP(wr io.Writer) error {
w := rlp.NewEncoderBuffer(wr)
buf, err := b.encodeSSZ()
if err != nil {
return err
}
w.WriteBytes(buf)
return w.Flush()
}
// DecodeRLP decodes the access list
func (b *BlockAccessList) DecodeRLP(s *rlp.Stream) error {
encBytes, err := s.Bytes()
if err != nil {
return err
}
return b.decodeSSZ(encBytes)
}
var _ rlp.Encoder = &BlockAccessList{}
var _ rlp.Decoder = &BlockAccessList{}
// toEncoderObj returns an instance of the slot writes which will be used as
// the input for encoding.
func (s slotWrites) toEncoderObj(slot common.Hash) encodingSlotWrites {
res := encodingSlotWrites{
Slot: slot,
}
var storageWriteIdxs []uint16
for idx := range s {
storageWriteIdxs = append(storageWriteIdxs, idx)
}
sort.Slice(storageWriteIdxs, func(i, j int) bool {
return storageWriteIdxs[i] < storageWriteIdxs[j]
})
for _, idx := range storageWriteIdxs {
res.Accesses = append(res.Accesses, encodingStorageWrite{
TxIdx: idx,
ValueAfter: s[idx],
})
}
return res
}
// toEncodingObj creates an instance of the accountAccess of the type that is
// used as input for the encoding.
func (a *accountAccess) toEncodingObj(addr common.Address) encodingAccountAccess {
res := encodingAccountAccess{
Address: addr,
StorageWrites: make([]encodingSlotWrites, 0),
StorageReads: make([][32]byte, 0),
BalanceChanges: make([]encodingBalanceChange, 0),
NonceChanges: make([]encodingAccountNonce, 0),
Code: nil,
}
{
var writeSlots []common.Hash
for slot := range a.StorageWrites {
writeSlots = append(writeSlots, slot)
}
sort.Slice(writeSlots, func(i, j int) bool {
return bytes.Compare(writeSlots[i][:], writeSlots[j][:]) < 0
})
for _, slot := range writeSlots {
res.StorageWrites = append(res.StorageWrites, a.StorageWrites[slot].toEncoderObj(slot))
}
}
{
var readSlots []common.Hash
for slot := range a.StorageReads {
readSlots = append(readSlots, slot)
}
sort.Slice(readSlots, func(i, j int) bool {
return bytes.Compare(readSlots[i][:], readSlots[j][:]) < 0
})
for _, slot := range readSlots {
res.StorageReads = append(res.StorageReads, slot)
}
}
{
var balanceChangeIdxs []uint16
for idx := range a.BalanceChanges {
balanceChangeIdxs = append(balanceChangeIdxs, idx)
}
sort.Slice(balanceChangeIdxs, func(i, j int) bool {
return balanceChangeIdxs[i] < balanceChangeIdxs[j]
})
for _, idx := range balanceChangeIdxs {
res.BalanceChanges = append(res.BalanceChanges, encodingBalanceChange{
TxIdx: idx,
Balance: *new(encodingBalance).set(a.BalanceChanges[idx]),
})
}
}
{
var nonceChangeIdxs []uint16
for idx := range a.NonceChanges {
nonceChangeIdxs = append(nonceChangeIdxs, idx)
}
sort.Slice(nonceChangeIdxs, func(i, j int) bool {
return nonceChangeIdxs[i] < nonceChangeIdxs[j]
})
for _, idx := range nonceChangeIdxs {
res.NonceChanges = append(res.NonceChanges, encodingAccountNonce{
TxIdx: idx,
Nonce: a.NonceChanges[idx],
})
}
}
if a.CodeChange != nil {
res.Code = []encodingCodeChange{
{
a.CodeChange.TxIndex,
bytes.Clone(a.CodeChange.Code),
},
}
}
return res
}
// toEncodingObj returns an instance of the access list expressed as the type
// which is used as input for the decoding.
func (b *BlockAccessList) toEncodingObj() *encodingBlockAccessList {
var res encodingBlockAccessList
var addrs []common.Address
for addr := range b.accounts {
addrs = append(addrs, addr)
}
sort.Slice(addrs, func(i, j int) bool {
return bytes.Compare(addrs[i][:], addrs[j][:]) < 0
})
for _, addr := range addrs {
res.Accesses = append(res.Accesses, b.accounts[addr].toEncodingObj(addr))
}
return &res
}
func (b *BlockAccessList) encodeSSZ() ([]byte, error) {
encoderObj := b.toEncodingObj()
dst, err := encoderObj.MarshalSSZTo(nil)
if err != nil {
return nil, err
}
return dst, nil
}
func (b *BlockAccessList) decodeSSZ(buf []byte) error {
var enc encodingBlockAccessList
if err := enc.UnmarshalSSZ(buf); err != nil {
return err
}
res, err := enc.toBlockAccessList()
if err != nil {
return err
}
*b = *res
return nil
}
// used as input for encoding.
type encodingStorageWrite struct {
TxIdx uint16
ValueAfter [32]byte `ssz-size:"32"`
}
// used as input for encoding. Storage writes are expected to be sorted
// lexicographically by their storage key.
type encodingSlotWrites struct {
Slot [32]byte `ssz-size:"32"`
Accesses []encodingStorageWrite `ssz-max:"300000"`
}
// toSlotWrites returns an instance of the encoding-representation slot writes in
// working representation.
func (e *encodingSlotWrites) toSlotWrites() (slotWrites, error) {
var prev *uint16
res := make(slotWrites)
for _, write := range e.Accesses {
if prev != nil {
if *prev >= write.TxIdx {
return nil, fmt.Errorf("storage write tx indices not in order")
}
}
res[write.TxIdx] = write.ValueAfter
prev = &write.TxIdx
}
return res, nil
}

View file

@ -0,0 +1,253 @@
// Code generated by rlpgen. DO NOT EDIT.
package bal
import "github.com/ethereum/go-ethereum/rlp"
import "io"
func (obj *encodingAccountAccess) EncodeRLP(_w io.Writer) error {
w := rlp.NewEncoderBuffer(_w)
_tmp0 := w.List()
w.WriteBytes(obj.Address[:])
_tmp1 := w.List()
for _, _tmp2 := range obj.StorageWrites {
_tmp3 := w.List()
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.ListEnd(_tmp6)
}
w.ListEnd(_tmp4)
w.ListEnd(_tmp3)
}
w.ListEnd(_tmp1)
_tmp7 := w.List()
for _, _tmp8 := range obj.StorageReads {
w.WriteBytes(_tmp8[:])
}
w.ListEnd(_tmp7)
_tmp9 := w.List()
for _, _tmp10 := range obj.BalanceChanges {
_tmp11 := w.List()
w.WriteUint64(uint64(_tmp10.TxIdx))
w.WriteBytes(_tmp10.Balance[:])
w.ListEnd(_tmp11)
}
w.ListEnd(_tmp9)
_tmp12 := w.List()
for _, _tmp13 := range obj.NonceChanges {
_tmp14 := w.List()
w.WriteUint64(uint64(_tmp13.TxIdx))
w.WriteUint64(_tmp13.Nonce)
w.ListEnd(_tmp14)
}
w.ListEnd(_tmp12)
_tmp15 := w.List()
for _, _tmp16 := range obj.Code {
_tmp17 := w.List()
w.WriteUint64(uint64(_tmp16.TxIndex))
w.WriteBytes(_tmp16.Code)
w.ListEnd(_tmp17)
}
w.ListEnd(_tmp15)
w.ListEnd(_tmp0)
return w.Flush()
}
func (obj *encodingAccountAccess) DecodeRLP(dec *rlp.Stream) error {
var _tmp0 encodingAccountAccess
{
if _, err := dec.List(); err != nil {
return err
}
// Address:
var _tmp1 [20]byte
if err := dec.ReadBytes(_tmp1[:]); err != nil {
return err
}
_tmp0.Address = _tmp1
// StorageWrites:
var _tmp2 []encodingSlotWrites
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp3 encodingSlotWrites
{
if _, err := dec.List(); err != nil {
return err
}
// Slot:
var _tmp4 [32]byte
if err := dec.ReadBytes(_tmp4[:]); err != nil {
return err
}
_tmp3.Slot = _tmp4
// Accesses:
var _tmp5 []encodingStorageWrite
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp6 encodingStorageWrite
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp7, err := dec.Uint16()
if err != nil {
return err
}
_tmp6.TxIdx = _tmp7
// ValueAfter:
var _tmp8 [32]byte
if err := dec.ReadBytes(_tmp8[:]); err != nil {
return err
}
_tmp6.ValueAfter = _tmp8
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp5 = append(_tmp5, _tmp6)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp3.Accesses = _tmp5
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp2 = append(_tmp2, _tmp3)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp0.StorageWrites = _tmp2
// StorageReads:
var _tmp9 [][32]byte
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp10 [32]byte
if err := dec.ReadBytes(_tmp10[:]); err != nil {
return err
}
_tmp9 = append(_tmp9, _tmp10)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp0.StorageReads = _tmp9
// BalanceChanges:
var _tmp11 []encodingBalanceChange
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp12 encodingBalanceChange
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp13, err := dec.Uint16()
if err != nil {
return err
}
_tmp12.TxIdx = _tmp13
// Balance:
var _tmp14 encodingBalance
if err := dec.ReadBytes(_tmp14[:]); err != nil {
return err
}
_tmp12.Balance = _tmp14
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp11 = append(_tmp11, _tmp12)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp0.BalanceChanges = _tmp11
// NonceChanges:
var _tmp15 []encodingAccountNonce
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp16 encodingAccountNonce
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp17, err := dec.Uint16()
if err != nil {
return err
}
_tmp16.TxIdx = _tmp17
// Nonce:
_tmp18, err := dec.Uint64()
if err != nil {
return err
}
_tmp16.Nonce = _tmp18
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp15 = append(_tmp15, _tmp16)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp0.NonceChanges = _tmp15
// Code:
var _tmp19 []encodingCodeChange
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp20 encodingCodeChange
{
if _, err := dec.List(); err != nil {
return err
}
// TxIndex:
_tmp21, err := dec.Uint16()
if err != nil {
return err
}
_tmp20.TxIndex = _tmp21
// Code:
_tmp22, err := dec.Bytes()
if err != nil {
return err
}
_tmp20.Code = _tmp22
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp19 = append(_tmp19, _tmp20)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp0.Code = _tmp19
if err := dec.ListEnd(); err != nil {
return err
}
}
*obj = _tmp0
return nil
}

View file

@ -0,0 +1,41 @@
// Code generated by rlpgen. DO NOT EDIT.
package bal
import "github.com/ethereum/go-ethereum/rlp"
import "io"
func (obj *encodingAccountNonce) EncodeRLP(_w io.Writer) error {
w := rlp.NewEncoderBuffer(_w)
_tmp0 := w.List()
w.WriteUint64(uint64(obj.TxIdx))
w.WriteUint64(obj.Nonce)
w.ListEnd(_tmp0)
return w.Flush()
}
func (obj *encodingAccountNonce) DecodeRLP(dec *rlp.Stream) error {
var _tmp0 encodingAccountNonce
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp1, err := dec.Uint16()
if err != nil {
return err
}
_tmp0.TxIdx = _tmp1
// Nonce:
_tmp2, err := dec.Uint64()
if err != nil {
return err
}
_tmp0.Nonce = _tmp2
if err := dec.ListEnd(); err != nil {
return err
}
}
*obj = _tmp0
return nil
}

View file

@ -0,0 +1,41 @@
// Code generated by rlpgen. DO NOT EDIT.
package bal
import "github.com/ethereum/go-ethereum/rlp"
import "io"
func (obj *encodingBalanceChange) EncodeRLP(_w io.Writer) error {
w := rlp.NewEncoderBuffer(_w)
_tmp0 := w.List()
w.WriteUint64(uint64(obj.TxIdx))
w.WriteBytes(obj.Balance[:])
w.ListEnd(_tmp0)
return w.Flush()
}
func (obj *encodingBalanceChange) DecodeRLP(dec *rlp.Stream) error {
var _tmp0 encodingBalanceChange
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp1, err := dec.Uint16()
if err != nil {
return err
}
_tmp0.TxIdx = _tmp1
// Balance:
var _tmp2 encodingBalance
if err := dec.ReadBytes(_tmp2[:]); err != nil {
return err
}
_tmp0.Balance = _tmp2
if err := dec.ListEnd(); err != nil {
return err
}
}
*obj = _tmp0
return nil
}

View file

@ -0,0 +1,280 @@
// Code generated by rlpgen. DO NOT EDIT.
package bal
import "github.com/ethereum/go-ethereum/rlp"
import "io"
func (obj *encodingBlockAccessList) EncodeRLP(_w io.Writer) error {
w := rlp.NewEncoderBuffer(_w)
_tmp0 := w.List()
_tmp1 := w.List()
for _, _tmp2 := range obj.Accesses {
_tmp3 := w.List()
w.WriteBytes(_tmp2.Address[:])
_tmp4 := w.List()
for _, _tmp5 := range _tmp2.StorageWrites {
_tmp6 := w.List()
w.WriteBytes(_tmp5.Slot[:])
_tmp7 := w.List()
for _, _tmp8 := range _tmp5.Accesses {
_tmp9 := w.List()
w.WriteUint64(uint64(_tmp8.TxIdx))
w.WriteBytes(_tmp8.ValueAfter[:])
w.ListEnd(_tmp9)
}
w.ListEnd(_tmp7)
w.ListEnd(_tmp6)
}
w.ListEnd(_tmp4)
_tmp10 := w.List()
for _, _tmp11 := range _tmp2.StorageReads {
w.WriteBytes(_tmp11[:])
}
w.ListEnd(_tmp10)
_tmp12 := w.List()
for _, _tmp13 := range _tmp2.BalanceChanges {
_tmp14 := w.List()
w.WriteUint64(uint64(_tmp13.TxIdx))
w.WriteBytes(_tmp13.Balance[:])
w.ListEnd(_tmp14)
}
w.ListEnd(_tmp12)
_tmp15 := w.List()
for _, _tmp16 := range _tmp2.NonceChanges {
_tmp17 := w.List()
w.WriteUint64(uint64(_tmp16.TxIdx))
w.WriteUint64(_tmp16.Nonce)
w.ListEnd(_tmp17)
}
w.ListEnd(_tmp15)
_tmp18 := w.List()
for _, _tmp19 := range _tmp2.Code {
_tmp20 := w.List()
w.WriteUint64(uint64(_tmp19.TxIndex))
w.WriteBytes(_tmp19.Code)
w.ListEnd(_tmp20)
}
w.ListEnd(_tmp18)
w.ListEnd(_tmp3)
}
w.ListEnd(_tmp1)
w.ListEnd(_tmp0)
return w.Flush()
}
func (obj *encodingBlockAccessList) DecodeRLP(dec *rlp.Stream) error {
var _tmp0 encodingBlockAccessList
{
if _, err := dec.List(); err != nil {
return err
}
// Accesses:
var _tmp1 []encodingAccountAccess
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp2 encodingAccountAccess
{
if _, err := dec.List(); err != nil {
return err
}
// Address:
var _tmp3 [20]byte
if err := dec.ReadBytes(_tmp3[:]); err != nil {
return err
}
_tmp2.Address = _tmp3
// StorageWrites:
var _tmp4 []encodingSlotWrites
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp5 encodingSlotWrites
{
if _, err := dec.List(); err != nil {
return err
}
// Slot:
var _tmp6 [32]byte
if err := dec.ReadBytes(_tmp6[:]); err != nil {
return err
}
_tmp5.Slot = _tmp6
// Accesses:
var _tmp7 []encodingStorageWrite
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp8 encodingStorageWrite
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp9, err := dec.Uint16()
if err != nil {
return err
}
_tmp8.TxIdx = _tmp9
// ValueAfter:
var _tmp10 [32]byte
if err := dec.ReadBytes(_tmp10[:]); err != nil {
return err
}
_tmp8.ValueAfter = _tmp10
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp7 = append(_tmp7, _tmp8)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp5.Accesses = _tmp7
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp4 = append(_tmp4, _tmp5)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp2.StorageWrites = _tmp4
// StorageReads:
var _tmp11 [][32]byte
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp12 [32]byte
if err := dec.ReadBytes(_tmp12[:]); err != nil {
return err
}
_tmp11 = append(_tmp11, _tmp12)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp2.StorageReads = _tmp11
// BalanceChanges:
var _tmp13 []encodingBalanceChange
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp14 encodingBalanceChange
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp15, err := dec.Uint16()
if err != nil {
return err
}
_tmp14.TxIdx = _tmp15
// Balance:
var _tmp16 encodingBalance
if err := dec.ReadBytes(_tmp16[:]); err != nil {
return err
}
_tmp14.Balance = _tmp16
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp13 = append(_tmp13, _tmp14)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp2.BalanceChanges = _tmp13
// NonceChanges:
var _tmp17 []encodingAccountNonce
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp18 encodingAccountNonce
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp19, err := dec.Uint16()
if err != nil {
return err
}
_tmp18.TxIdx = _tmp19
// Nonce:
_tmp20, err := dec.Uint64()
if err != nil {
return err
}
_tmp18.Nonce = _tmp20
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp17 = append(_tmp17, _tmp18)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp2.NonceChanges = _tmp17
// Code:
var _tmp21 []encodingCodeChange
if _, err := dec.List(); err != nil {
return err
}
for dec.MoreDataInList() {
var _tmp22 encodingCodeChange
{
if _, err := dec.List(); err != nil {
return err
}
// TxIndex:
_tmp23, err := dec.Uint16()
if err != nil {
return err
}
_tmp22.TxIndex = _tmp23
// Code:
_tmp24, err := dec.Bytes()
if err != nil {
return err
}
_tmp22.Code = _tmp24
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp21 = append(_tmp21, _tmp22)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp2.Code = _tmp21
if err := dec.ListEnd(); err != nil {
return err
}
}
_tmp1 = append(_tmp1, _tmp2)
}
if err := dec.ListEnd(); err != nil {
return err
}
_tmp0.Accesses = _tmp1
if err := dec.ListEnd(); err != nil {
return err
}
}
*obj = _tmp0
return nil
}

View file

@ -0,0 +1,41 @@
// Code generated by rlpgen. DO NOT EDIT.
package bal
import "github.com/ethereum/go-ethereum/rlp"
import "io"
func (obj *encodingCodeChange) EncodeRLP(_w io.Writer) error {
w := rlp.NewEncoderBuffer(_w)
_tmp0 := w.List()
w.WriteUint64(uint64(obj.TxIndex))
w.WriteBytes(obj.Code)
w.ListEnd(_tmp0)
return w.Flush()
}
func (obj *encodingCodeChange) DecodeRLP(dec *rlp.Stream) error {
var _tmp0 encodingCodeChange
{
if _, err := dec.List(); err != nil {
return err
}
// TxIndex:
_tmp1, err := dec.Uint16()
if err != nil {
return err
}
_tmp0.TxIndex = _tmp1
// Code:
_tmp2, err := dec.Bytes()
if err != nil {
return err
}
_tmp0.Code = _tmp2
if err := dec.ListEnd(); err != nil {
return err
}
}
*obj = _tmp0
return nil
}

View file

@ -0,0 +1,41 @@
// Code generated by rlpgen. DO NOT EDIT.
package bal
import "github.com/ethereum/go-ethereum/rlp"
import "io"
func (obj *encodingStorageWrite) EncodeRLP(_w io.Writer) error {
w := rlp.NewEncoderBuffer(_w)
_tmp0 := w.List()
w.WriteUint64(uint64(obj.TxIdx))
w.WriteBytes(obj.ValueAfter[:])
w.ListEnd(_tmp0)
return w.Flush()
}
func (obj *encodingStorageWrite) DecodeRLP(dec *rlp.Stream) error {
var _tmp0 encodingStorageWrite
{
if _, err := dec.List(); err != nil {
return err
}
// TxIdx:
_tmp1, err := dec.Uint16()
if err != nil {
return err
}
_tmp0.TxIdx = _tmp1
// ValueAfter:
var _tmp2 [32]byte
if err := dec.ReadBytes(_tmp2[:]); err != nil {
return err
}
_tmp0.ValueAfter = _tmp2
if err := dec.ListEnd(); err != nil {
return err
}
}
*obj = _tmp0
return nil
}

View file

@ -0,0 +1,906 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: 5a611ca283f63103b9044df57fda81526194a110bef4d5f1b2035335dfeb3ad6
// Version: 0.1.3
package bal
import (
ssz "github.com/ferranbt/fastssz"
)
// MarshalSSZ ssz marshals the encodingBlockAccessList object
func (e *encodingBlockAccessList) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(e)
}
// MarshalSSZTo ssz marshals the encodingBlockAccessList object to a target array
func (e *encodingBlockAccessList) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(4)
// Offset (0) 'Accesses'
dst = ssz.WriteOffset(dst, offset)
// Field (0) 'Accesses'
if size := len(e.Accesses); size > 300000 {
err = ssz.ErrListTooBigFn("encodingBlockAccessList.Accesses", size, 300000)
return
}
{
offset = 4 * len(e.Accesses)
for ii := 0; ii < len(e.Accesses); ii++ {
dst = ssz.WriteOffset(dst, offset)
offset += e.Accesses[ii].SizeSSZ()
}
}
for ii := 0; ii < len(e.Accesses); ii++ {
if dst, err = e.Accesses[ii].MarshalSSZTo(dst); err != nil {
return
}
}
return
}
// UnmarshalSSZ ssz unmarshals the encodingBlockAccessList object
func (e *encodingBlockAccessList) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 4 {
return ssz.ErrSize
}
tail := buf
var o0 uint64
// Offset (0) 'Accesses'
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
return ssz.ErrOffset
}
if o0 != 4 {
return ssz.ErrInvalidVariableOffset
}
// Field (0) 'Accesses'
{
buf = tail[o0:]
num, err := ssz.DecodeDynamicLength(buf, 300000)
if err != nil {
return err
}
e.Accesses = make([]encodingAccountAccess, num)
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
if err = e.Accesses[indx].UnmarshalSSZ(buf); err != nil {
return err
}
return nil
})
if err != nil {
return err
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the encodingBlockAccessList object
func (e *encodingBlockAccessList) SizeSSZ() (size int) {
size = 4
// Field (0) 'Accesses'
for ii := 0; ii < len(e.Accesses); ii++ {
size += 4
size += e.Accesses[ii].SizeSSZ()
}
return
}
// HashTreeRoot ssz hashes the encodingBlockAccessList object
func (e *encodingBlockAccessList) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(e)
}
// HashTreeRootWith ssz hashes the encodingBlockAccessList object with a hasher
func (e *encodingBlockAccessList) HashTreeRootWith(hh ssz.HashWalker) (err error) {
indx := hh.Index()
// Field (0) 'Accesses'
{
subIndx := hh.Index()
num := uint64(len(e.Accesses))
if num > 300000 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range e.Accesses {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
hh.MerkleizeWithMixin(subIndx, num, 300000)
}
hh.Merkleize(indx)
return
}
// GetTree ssz hashes the encodingBlockAccessList object
func (e *encodingBlockAccessList) GetTree() (*ssz.Node, error) {
return ssz.ProofTree(e)
}
// MarshalSSZ ssz marshals the encodingCodeChange object
func (e *encodingCodeChange) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(e)
}
// MarshalSSZTo ssz marshals the encodingCodeChange object to a target array
func (e *encodingCodeChange) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(6)
// Field (0) 'TxIndex'
dst = ssz.MarshalUint16(dst, e.TxIndex)
// Offset (1) 'Code'
dst = ssz.WriteOffset(dst, offset)
// Field (1) 'Code'
if size := len(e.Code); size > 24576 {
err = ssz.ErrBytesLengthFn("encodingCodeChange.Code", size, 24576)
return
}
dst = append(dst, e.Code...)
return
}
// UnmarshalSSZ ssz unmarshals the encodingCodeChange object
func (e *encodingCodeChange) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 6 {
return ssz.ErrSize
}
tail := buf
var o1 uint64
// Field (0) 'TxIndex'
e.TxIndex = ssz.UnmarshallUint16(buf[0:2])
// Offset (1) 'Code'
if o1 = ssz.ReadOffset(buf[2:6]); o1 > size {
return ssz.ErrOffset
}
if o1 != 6 {
return ssz.ErrInvalidVariableOffset
}
// Field (1) 'Code'
{
buf = tail[o1:]
if len(buf) > 24576 {
return ssz.ErrBytesLength
}
if cap(e.Code) == 0 {
e.Code = make([]byte, 0, len(buf))
}
e.Code = append(e.Code, buf...)
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the encodingCodeChange object
func (e *encodingCodeChange) SizeSSZ() (size int) {
size = 6
// Field (1) 'Code'
size += len(e.Code)
return
}
// HashTreeRoot ssz hashes the encodingCodeChange object
func (e *encodingCodeChange) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(e)
}
// HashTreeRootWith ssz hashes the encodingCodeChange object with a hasher
func (e *encodingCodeChange) HashTreeRootWith(hh ssz.HashWalker) (err error) {
indx := hh.Index()
// Field (0) 'TxIndex'
hh.PutUint16(e.TxIndex)
// Field (1) 'Code'
{
elemIndx := hh.Index()
byteLen := uint64(len(e.Code))
if byteLen > 24576 {
err = ssz.ErrIncorrectListSize
return
}
hh.Append(e.Code)
hh.MerkleizeWithMixin(elemIndx, byteLen, (24576+31)/32)
}
hh.Merkleize(indx)
return
}
// GetTree ssz hashes the encodingCodeChange object
func (e *encodingCodeChange) GetTree() (*ssz.Node, error) {
return ssz.ProofTree(e)
}
// MarshalSSZ ssz marshals the encodingAccountAccess object
func (e *encodingAccountAccess) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(e)
}
// MarshalSSZTo ssz marshals the encodingAccountAccess object to a target array
func (e *encodingAccountAccess) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(40)
// Field (0) 'Address'
dst = append(dst, e.Address[:]...)
// Offset (1) 'StorageWrites'
dst = ssz.WriteOffset(dst, offset)
for ii := 0; ii < len(e.StorageWrites); ii++ {
offset += 4
offset += e.StorageWrites[ii].SizeSSZ()
}
// Offset (2) 'StorageReads'
dst = ssz.WriteOffset(dst, offset)
offset += len(e.StorageReads) * 32
// Offset (3) 'BalanceChanges'
dst = ssz.WriteOffset(dst, offset)
offset += len(e.BalanceChanges) * 18
// Offset (4) 'NonceChanges'
dst = ssz.WriteOffset(dst, offset)
offset += len(e.NonceChanges) * 10
// Offset (5) 'Code'
dst = ssz.WriteOffset(dst, offset)
// Field (1) 'StorageWrites'
if size := len(e.StorageWrites); size > 300000 {
err = ssz.ErrListTooBigFn("encodingAccountAccess.StorageWrites", size, 300000)
return
}
{
offset = 4 * len(e.StorageWrites)
for ii := 0; ii < len(e.StorageWrites); ii++ {
dst = ssz.WriteOffset(dst, offset)
offset += e.StorageWrites[ii].SizeSSZ()
}
}
for ii := 0; ii < len(e.StorageWrites); ii++ {
if dst, err = e.StorageWrites[ii].MarshalSSZTo(dst); err != nil {
return
}
}
// Field (2) 'StorageReads'
if size := len(e.StorageReads); size > 300000 {
err = ssz.ErrListTooBigFn("encodingAccountAccess.StorageReads", size, 300000)
return
}
for ii := 0; ii < len(e.StorageReads); ii++ {
dst = append(dst, e.StorageReads[ii][:]...)
}
// Field (3) 'BalanceChanges'
if size := len(e.BalanceChanges); size > 300000 {
err = ssz.ErrListTooBigFn("encodingAccountAccess.BalanceChanges", size, 300000)
return
}
for ii := 0; ii < len(e.BalanceChanges); ii++ {
if dst, err = e.BalanceChanges[ii].MarshalSSZTo(dst); err != nil {
return
}
}
// Field (4) 'NonceChanges'
if size := len(e.NonceChanges); size > 300000 {
err = ssz.ErrListTooBigFn("encodingAccountAccess.NonceChanges", size, 300000)
return
}
for ii := 0; ii < len(e.NonceChanges); ii++ {
if dst, err = e.NonceChanges[ii].MarshalSSZTo(dst); err != nil {
return
}
}
// Field (5) 'Code'
if size := len(e.Code); size > 1 {
err = ssz.ErrListTooBigFn("encodingAccountAccess.Code", size, 1)
return
}
{
offset = 4 * len(e.Code)
for ii := 0; ii < len(e.Code); ii++ {
dst = ssz.WriteOffset(dst, offset)
offset += e.Code[ii].SizeSSZ()
}
}
for ii := 0; ii < len(e.Code); ii++ {
if dst, err = e.Code[ii].MarshalSSZTo(dst); err != nil {
return
}
}
return
}
// UnmarshalSSZ ssz unmarshals the encodingAccountAccess object
func (e *encodingAccountAccess) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 40 {
return ssz.ErrSize
}
tail := buf
var o1, o2, o3, o4, o5 uint64
// Field (0) 'Address'
copy(e.Address[:], buf[0:20])
// Offset (1) 'StorageWrites'
if o1 = ssz.ReadOffset(buf[20:24]); o1 > size {
return ssz.ErrOffset
}
if o1 != 40 {
return ssz.ErrInvalidVariableOffset
}
// Offset (2) 'StorageReads'
if o2 = ssz.ReadOffset(buf[24:28]); o2 > size || o1 > o2 {
return ssz.ErrOffset
}
// Offset (3) 'BalanceChanges'
if o3 = ssz.ReadOffset(buf[28:32]); o3 > size || o2 > o3 {
return ssz.ErrOffset
}
// Offset (4) 'NonceChanges'
if o4 = ssz.ReadOffset(buf[32:36]); o4 > size || o3 > o4 {
return ssz.ErrOffset
}
// Offset (5) 'Code'
if o5 = ssz.ReadOffset(buf[36:40]); o5 > size || o4 > o5 {
return ssz.ErrOffset
}
// Field (1) 'StorageWrites'
{
buf = tail[o1:o2]
num, err := ssz.DecodeDynamicLength(buf, 300000)
if err != nil {
return err
}
e.StorageWrites = make([]encodingSlotWrites, num)
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
if err = e.StorageWrites[indx].UnmarshalSSZ(buf); err != nil {
return err
}
return nil
})
if err != nil {
return err
}
}
// Field (2) 'StorageReads'
{
buf = tail[o2:o3]
num, err := ssz.DivideInt2(len(buf), 32, 300000)
if err != nil {
return err
}
e.StorageReads = make([][32]byte, num)
for ii := 0; ii < num; ii++ {
copy(e.StorageReads[ii][:], buf[ii*32:(ii+1)*32])
}
}
// Field (3) 'BalanceChanges'
{
buf = tail[o3:o4]
num, err := ssz.DivideInt2(len(buf), 18, 300000)
if err != nil {
return err
}
e.BalanceChanges = make([]encodingBalanceChange, num)
for ii := 0; ii < num; ii++ {
if err = e.BalanceChanges[ii].UnmarshalSSZ(buf[ii*18 : (ii+1)*18]); err != nil {
return err
}
}
}
// Field (4) 'NonceChanges'
{
buf = tail[o4:o5]
num, err := ssz.DivideInt2(len(buf), 10, 300000)
if err != nil {
return err
}
e.NonceChanges = make([]encodingAccountNonce, num)
for ii := 0; ii < num; ii++ {
if err = e.NonceChanges[ii].UnmarshalSSZ(buf[ii*10 : (ii+1)*10]); err != nil {
return err
}
}
}
// Field (5) 'Code'
{
buf = tail[o5:]
num, err := ssz.DecodeDynamicLength(buf, 1)
if err != nil {
return err
}
e.Code = make([]encodingCodeChange, num)
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
if err = e.Code[indx].UnmarshalSSZ(buf); err != nil {
return err
}
return nil
})
if err != nil {
return err
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the encodingAccountAccess object
func (e *encodingAccountAccess) SizeSSZ() (size int) {
size = 40
// Field (1) 'StorageWrites'
for ii := 0; ii < len(e.StorageWrites); ii++ {
size += 4
size += e.StorageWrites[ii].SizeSSZ()
}
// Field (2) 'StorageReads'
size += len(e.StorageReads) * 32
// Field (3) 'BalanceChanges'
size += len(e.BalanceChanges) * 18
// Field (4) 'NonceChanges'
size += len(e.NonceChanges) * 10
// Field (5) 'Code'
for ii := 0; ii < len(e.Code); ii++ {
size += 4
size += e.Code[ii].SizeSSZ()
}
return
}
// HashTreeRoot ssz hashes the encodingAccountAccess object
func (e *encodingAccountAccess) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(e)
}
// HashTreeRootWith ssz hashes the encodingAccountAccess object with a hasher
func (e *encodingAccountAccess) HashTreeRootWith(hh ssz.HashWalker) (err error) {
indx := hh.Index()
// Field (0) 'Address'
hh.PutBytes(e.Address[:])
// Field (1) 'StorageWrites'
{
subIndx := hh.Index()
num := uint64(len(e.StorageWrites))
if num > 300000 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range e.StorageWrites {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
hh.MerkleizeWithMixin(subIndx, num, 300000)
}
// Field (2) 'StorageReads'
{
if size := len(e.StorageReads); size > 300000 {
err = ssz.ErrListTooBigFn("encodingAccountAccess.StorageReads", size, 300000)
return
}
subIndx := hh.Index()
for _, i := range e.StorageReads {
hh.Append(i[:])
}
numItems := uint64(len(e.StorageReads))
hh.MerkleizeWithMixin(subIndx, numItems, 300000)
}
// Field (3) 'BalanceChanges'
{
subIndx := hh.Index()
num := uint64(len(e.BalanceChanges))
if num > 300000 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range e.BalanceChanges {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
hh.MerkleizeWithMixin(subIndx, num, 300000)
}
// Field (4) 'NonceChanges'
{
subIndx := hh.Index()
num := uint64(len(e.NonceChanges))
if num > 300000 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range e.NonceChanges {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
hh.MerkleizeWithMixin(subIndx, num, 300000)
}
// Field (5) 'Code'
{
subIndx := hh.Index()
num := uint64(len(e.Code))
if num > 1 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range e.Code {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
hh.MerkleizeWithMixin(subIndx, num, 1)
}
hh.Merkleize(indx)
return
}
// GetTree ssz hashes the encodingAccountAccess object
func (e *encodingAccountAccess) GetTree() (*ssz.Node, error) {
return ssz.ProofTree(e)
}
// MarshalSSZ ssz marshals the encodingBalanceChange object
func (e *encodingBalanceChange) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(e)
}
// MarshalSSZTo ssz marshals the encodingBalanceChange object to a target array
func (e *encodingBalanceChange) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
// Field (0) 'TxIdx'
dst = ssz.MarshalUint16(dst, e.TxIdx)
// Field (1) 'Balance'
dst = append(dst, e.Balance[:]...)
return
}
// UnmarshalSSZ ssz unmarshals the encodingBalanceChange object
func (e *encodingBalanceChange) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size != 18 {
return ssz.ErrSize
}
// Field (0) 'TxIdx'
e.TxIdx = ssz.UnmarshallUint16(buf[0:2])
// Field (1) 'Balance'
copy(e.Balance[:], buf[2:18])
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the encodingBalanceChange object
func (e *encodingBalanceChange) SizeSSZ() (size int) {
size = 18
return
}
// HashTreeRoot ssz hashes the encodingBalanceChange object
func (e *encodingBalanceChange) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(e)
}
// HashTreeRootWith ssz hashes the encodingBalanceChange object with a hasher
func (e *encodingBalanceChange) HashTreeRootWith(hh ssz.HashWalker) (err error) {
indx := hh.Index()
// Field (0) 'TxIdx'
hh.PutUint16(e.TxIdx)
// Field (1) 'Balance'
hh.PutBytes(e.Balance[:])
hh.Merkleize(indx)
return
}
// GetTree ssz hashes the encodingBalanceChange object
func (e *encodingBalanceChange) GetTree() (*ssz.Node, error) {
return ssz.ProofTree(e)
}
// MarshalSSZ ssz marshals the encodingAccountNonce object
func (e *encodingAccountNonce) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(e)
}
// MarshalSSZTo ssz marshals the encodingAccountNonce object to a target array
func (e *encodingAccountNonce) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
// Field (0) 'TxIdx'
dst = ssz.MarshalUint16(dst, e.TxIdx)
// Field (1) 'Nonce'
dst = ssz.MarshalUint64(dst, e.Nonce)
return
}
// UnmarshalSSZ ssz unmarshals the encodingAccountNonce object
func (e *encodingAccountNonce) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size != 10 {
return ssz.ErrSize
}
// Field (0) 'TxIdx'
e.TxIdx = ssz.UnmarshallUint16(buf[0:2])
// Field (1) 'Nonce'
e.Nonce = ssz.UnmarshallUint64(buf[2:10])
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the encodingAccountNonce object
func (e *encodingAccountNonce) SizeSSZ() (size int) {
size = 10
return
}
// HashTreeRoot ssz hashes the encodingAccountNonce object
func (e *encodingAccountNonce) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(e)
}
// HashTreeRootWith ssz hashes the encodingAccountNonce object with a hasher
func (e *encodingAccountNonce) HashTreeRootWith(hh ssz.HashWalker) (err error) {
indx := hh.Index()
// Field (0) 'TxIdx'
hh.PutUint16(e.TxIdx)
// Field (1) 'Nonce'
hh.PutUint64(e.Nonce)
hh.Merkleize(indx)
return
}
// GetTree ssz hashes the encodingAccountNonce object
func (e *encodingAccountNonce) GetTree() (*ssz.Node, error) {
return ssz.ProofTree(e)
}
// MarshalSSZ ssz marshals the encodingStorageWrite object
func (e *encodingStorageWrite) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(e)
}
// MarshalSSZTo ssz marshals the encodingStorageWrite object to a target array
func (e *encodingStorageWrite) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
// Field (0) 'TxIdx'
dst = ssz.MarshalUint16(dst, e.TxIdx)
// Field (1) 'ValueAfter'
dst = append(dst, e.ValueAfter[:]...)
return
}
// UnmarshalSSZ ssz unmarshals the encodingStorageWrite object
func (e *encodingStorageWrite) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size != 34 {
return ssz.ErrSize
}
// Field (0) 'TxIdx'
e.TxIdx = ssz.UnmarshallUint16(buf[0:2])
// Field (1) 'ValueAfter'
copy(e.ValueAfter[:], buf[2:34])
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the encodingStorageWrite object
func (e *encodingStorageWrite) SizeSSZ() (size int) {
size = 34
return
}
// HashTreeRoot ssz hashes the encodingStorageWrite object
func (e *encodingStorageWrite) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(e)
}
// HashTreeRootWith ssz hashes the encodingStorageWrite object with a hasher
func (e *encodingStorageWrite) HashTreeRootWith(hh ssz.HashWalker) (err error) {
indx := hh.Index()
// Field (0) 'TxIdx'
hh.PutUint16(e.TxIdx)
// Field (1) 'ValueAfter'
hh.PutBytes(e.ValueAfter[:])
hh.Merkleize(indx)
return
}
// GetTree ssz hashes the encodingStorageWrite object
func (e *encodingStorageWrite) GetTree() (*ssz.Node, error) {
return ssz.ProofTree(e)
}
// MarshalSSZ ssz marshals the encodingSlotWrites object
func (e *encodingSlotWrites) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(e)
}
// MarshalSSZTo ssz marshals the encodingSlotWrites object to a target array
func (e *encodingSlotWrites) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(36)
// Field (0) 'Slot'
dst = append(dst, e.Slot[:]...)
// Offset (1) 'Accesses'
dst = ssz.WriteOffset(dst, offset)
// Field (1) 'Accesses'
if size := len(e.Accesses); size > 300000 {
err = ssz.ErrListTooBigFn("encodingSlotWrites.Accesses", size, 300000)
return
}
for ii := 0; ii < len(e.Accesses); ii++ {
if dst, err = e.Accesses[ii].MarshalSSZTo(dst); err != nil {
return
}
}
return
}
// UnmarshalSSZ ssz unmarshals the encodingSlotWrites object
func (e *encodingSlotWrites) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 36 {
return ssz.ErrSize
}
tail := buf
var o1 uint64
// Field (0) 'Slot'
copy(e.Slot[:], buf[0:32])
// Offset (1) 'Accesses'
if o1 = ssz.ReadOffset(buf[32:36]); o1 > size {
return ssz.ErrOffset
}
if o1 != 36 {
return ssz.ErrInvalidVariableOffset
}
// Field (1) 'Accesses'
{
buf = tail[o1:]
num, err := ssz.DivideInt2(len(buf), 34, 300000)
if err != nil {
return err
}
e.Accesses = make([]encodingStorageWrite, num)
for ii := 0; ii < num; ii++ {
if err = e.Accesses[ii].UnmarshalSSZ(buf[ii*34 : (ii+1)*34]); err != nil {
return err
}
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the encodingSlotWrites object
func (e *encodingSlotWrites) SizeSSZ() (size int) {
size = 36
// Field (1) 'Accesses'
size += len(e.Accesses) * 34
return
}
// HashTreeRoot ssz hashes the encodingSlotWrites object
func (e *encodingSlotWrites) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(e)
}
// HashTreeRootWith ssz hashes the encodingSlotWrites object with a hasher
func (e *encodingSlotWrites) HashTreeRootWith(hh ssz.HashWalker) (err error) {
indx := hh.Index()
// Field (0) 'Slot'
hh.PutBytes(e.Slot[:])
// Field (1) 'Accesses'
{
subIndx := hh.Index()
num := uint64(len(e.Accesses))
if num > 300000 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range e.Accesses {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
hh.MerkleizeWithMixin(subIndx, num, 300000)
}
hh.Merkleize(indx)
return
}
// GetTree ssz hashes the encodingSlotWrites object
func (e *encodingSlotWrites) GetTree() (*ssz.Node, error) {
return ssz.ProofTree(e)
}

View file

@ -0,0 +1,92 @@
package bal
import (
"bytes"
"os"
"testing"
"github.com/holiman/uint256"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
)
// test that a populated access list can be encoded/decoded correctly
func TestBALEncoding(t *testing.T) {
b := BlockAccessList{
map[common.Address]*accountAccess{
common.BytesToAddress([]byte{0xff, 0xff}): {
StorageWrites: map[common.Hash]slotWrites{
common.BytesToHash([]byte{0x01}): map[uint16]common.Hash{
1: common.BytesToHash([]byte{1, 2, 3, 4}),
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
},
common.BytesToHash([]byte{0x10}): map[uint16]common.Hash{
20: common.BytesToHash([]byte{1, 2, 3, 4}),
},
},
StorageReads: map[common.Hash]struct{}{
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7}): {},
},
BalanceChanges: balanceDiff{
1: uint256.NewInt(100),
2: uint256.NewInt(500),
},
NonceChanges: accountNonceDiffs{
1: 2,
2: 6,
},
CodeChange: &codeChange{
TxIndex: 0,
Code: common.Hex2Bytes("deadbeef"),
},
},
common.BytesToAddress([]byte{0xff, 0xff, 0xff}): {
StorageWrites: map[common.Hash]slotWrites{
common.BytesToHash([]byte{0x01}): map[uint16]common.Hash{
2: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6}),
3: common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
},
common.BytesToHash([]byte{0x10}): map[uint16]common.Hash{
21: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
},
},
StorageReads: map[common.Hash]struct{}{
common.BytesToHash([]byte{1, 2, 3, 4, 5, 6, 7, 8}): {},
},
BalanceChanges: balanceDiff{
2: uint256.NewInt(100),
3: uint256.NewInt(500),
},
NonceChanges: accountNonceDiffs{
1: 2,
},
},
},
}
var buf bytes.Buffer
err := b.EncodeRLP(&buf)
if err != nil {
t.Fatalf("encoding failed: %v\n", err)
}
var dec BlockAccessList
if err := dec.DecodeRLP(rlp.NewStream(bytes.NewReader(buf.Bytes()), 10000000)); err != nil {
t.Fatalf("decoding failed: %v\n", err)
}
if dec.Hash() != b.Hash() {
t.Fatalf("encoded block hash doesn't match decoded")
}
}
// test that a mainnet BAL produced by https://github.com/nerolation/eth-bal-analysis
// can be decoded.
func TestBALDecoding(t *testing.T) {
data, err := os.ReadFile("testdata/22615532_block_access_list_with_reads_eip7928.ssz")
if err != nil {
t.Fatal(err)
}
var b BlockAccessList
if err := b.decodeSSZ(data); err != nil {
t.Fatal(err)
}
}

3
go.mod
View file

@ -24,7 +24,7 @@ require (
github.com/ethereum/c-kzg-4844/v2 v2.1.0 github.com/ethereum/c-kzg-4844/v2 v2.1.0
github.com/ethereum/go-verkle v0.2.2 github.com/ethereum/go-verkle v0.2.2
github.com/fatih/color v1.16.0 github.com/fatih/color v1.16.0
github.com/ferranbt/fastssz v0.1.2 github.com/ferranbt/fastssz v0.1.4
github.com/fjl/gencodec v0.1.0 github.com/fjl/gencodec v0.1.0
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
@ -101,6 +101,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/emicklei/dot v1.6.2 // indirect
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect

10
go.sum
View file

@ -108,14 +108,16 @@ github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjU
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A=
github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w=
github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E=
github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=
github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY=
github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs= github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=
github.com/fjl/gencodec v0.1.0 h1:B3K0xPfc52cw52BBgUbSPxYo+HlLfAgWMVKRWXUXBcs= github.com/fjl/gencodec v0.1.0 h1:B3K0xPfc52cw52BBgUbSPxYo+HlLfAgWMVKRWXUXBcs=
github.com/fjl/gencodec v0.1.0/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI= github.com/fjl/gencodec v0.1.0/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -316,8 +318,8 @@ github.com/protolambda/zrnt v0.34.1 h1:qW55rnhZJDnOb3TwFiFRJZi3yTXFrJdGOFQM7vCwY
github.com/protolambda/zrnt v0.34.1/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs= github.com/protolambda/zrnt v0.34.1/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs=
github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY= github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY=
github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU= github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU=
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw= github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4=
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=