From b3775601ac2d886acfbf8ceef0452810b0257a9b Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Wed, 2 Jul 2025 21:18:54 +0900 Subject: [PATCH] core/types: add eip-7928 block-level access list structures --- core/types/bal/bal.go | 227 +++++ core/types/bal/bal_encoding.go | 368 +++++++ ...al_encoding_rlp_accountaccess_generated.go | 253 +++++ ...bal_encoding_rlp_accountnonce_generated.go | 41 + ...al_encoding_rlp_balancechange_generated.go | 41 + ..._encoding_rlp_blockaccesslist_generated.go | 280 ++++++ .../bal_encoding_rlp_codechange_generated.go | 41 + ...bal_encoding_rlp_storagewrite_generated.go | 41 + core/types/bal/bal_encoding_ssz_generated.go | 906 ++++++++++++++++++ core/types/bal/bal_test.go | 92 ++ ...2_block_access_list_with_reads_eip7928.ssz | Bin 0 -> 36280 bytes go.mod | 3 +- go.sum | 10 +- 13 files changed, 2298 insertions(+), 5 deletions(-) create mode 100644 core/types/bal/bal.go create mode 100644 core/types/bal/bal_encoding.go create mode 100644 core/types/bal/bal_encoding_rlp_accountaccess_generated.go create mode 100644 core/types/bal/bal_encoding_rlp_accountnonce_generated.go create mode 100644 core/types/bal/bal_encoding_rlp_balancechange_generated.go create mode 100644 core/types/bal/bal_encoding_rlp_blockaccesslist_generated.go create mode 100644 core/types/bal/bal_encoding_rlp_codechange_generated.go create mode 100644 core/types/bal/bal_encoding_rlp_storagewrite_generated.go create mode 100644 core/types/bal/bal_encoding_ssz_generated.go create mode 100644 core/types/bal/bal_test.go create mode 100644 core/types/testdata/22615532_block_access_list_with_reads_eip7928.ssz diff --git a/core/types/bal/bal.go b/core/types/bal/bal.go new file mode 100644 index 0000000000..019a576e2b --- /dev/null +++ b/core/types/bal/bal.go @@ -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() +} diff --git a/core/types/bal/bal_encoding.go b/core/types/bal/bal_encoding.go new file mode 100644 index 0000000000..5fde0c74b9 --- /dev/null +++ b/core/types/bal/bal_encoding.go @@ -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 +} diff --git a/core/types/bal/bal_encoding_rlp_accountaccess_generated.go b/core/types/bal/bal_encoding_rlp_accountaccess_generated.go new file mode 100644 index 0000000000..320f7c9d90 --- /dev/null +++ b/core/types/bal/bal_encoding_rlp_accountaccess_generated.go @@ -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 +} diff --git a/core/types/bal/bal_encoding_rlp_accountnonce_generated.go b/core/types/bal/bal_encoding_rlp_accountnonce_generated.go new file mode 100644 index 0000000000..605ba1dd91 --- /dev/null +++ b/core/types/bal/bal_encoding_rlp_accountnonce_generated.go @@ -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 +} diff --git a/core/types/bal/bal_encoding_rlp_balancechange_generated.go b/core/types/bal/bal_encoding_rlp_balancechange_generated.go new file mode 100644 index 0000000000..75014a00f2 --- /dev/null +++ b/core/types/bal/bal_encoding_rlp_balancechange_generated.go @@ -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 +} diff --git a/core/types/bal/bal_encoding_rlp_blockaccesslist_generated.go b/core/types/bal/bal_encoding_rlp_blockaccesslist_generated.go new file mode 100644 index 0000000000..aacb940eca --- /dev/null +++ b/core/types/bal/bal_encoding_rlp_blockaccesslist_generated.go @@ -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 +} diff --git a/core/types/bal/bal_encoding_rlp_codechange_generated.go b/core/types/bal/bal_encoding_rlp_codechange_generated.go new file mode 100644 index 0000000000..aafeb591cf --- /dev/null +++ b/core/types/bal/bal_encoding_rlp_codechange_generated.go @@ -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 +} diff --git a/core/types/bal/bal_encoding_rlp_storagewrite_generated.go b/core/types/bal/bal_encoding_rlp_storagewrite_generated.go new file mode 100644 index 0000000000..a5f851bfe7 --- /dev/null +++ b/core/types/bal/bal_encoding_rlp_storagewrite_generated.go @@ -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 +} diff --git a/core/types/bal/bal_encoding_ssz_generated.go b/core/types/bal/bal_encoding_ssz_generated.go new file mode 100644 index 0000000000..fdea76b327 --- /dev/null +++ b/core/types/bal/bal_encoding_ssz_generated.go @@ -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) +} diff --git a/core/types/bal/bal_test.go b/core/types/bal/bal_test.go new file mode 100644 index 0000000000..dfb4fe5fdf --- /dev/null +++ b/core/types/bal/bal_test.go @@ -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) + } +} diff --git a/core/types/testdata/22615532_block_access_list_with_reads_eip7928.ssz b/core/types/testdata/22615532_block_access_list_with_reads_eip7928.ssz new file mode 100644 index 0000000000000000000000000000000000000000..a3f23822a81c995a4b4679dca0bb1676d7a479e3 GIT binary patch literal 36280 zcmcG%2Rv8p|37~0J(HE}y)v>>c1DRrvXYTqQpw&SE26S8v$OZ8tPqi1Hkk>Dh!X$n z;Emg@+`q@?`+q$iPv@N1b-kX~p65Dms1O9{pg@o&Dg<3ZgCHq%2#N+629U>qppTdk zM1=)G`T!N!z%vd6i2}F)lmM{fLJ%o21nB`J0I(l{pc??G0COY|#CjBhECG@Mg2*7K z0bq^-f@CNG2LK}#1epT70GI%vJq|%e0JQ+?06f$XbO)f59)gsaAjlV>8UURcf+PSO z0IC7dSs+Le;5jPP608C$lpgKd4-^L&;faL2SUrj(B z0Q3S-n?jHsKm`C~2I>yL9e^x=ICBWXv;gG+;0-`-3F;X@B)}kmsWk-U00`TF@a}-L z1H{~gpicl)wh*KN5Dd@=(0>o)s~yN!0LTNx5x^Iq8UWoB)D-{+fC7LOfKy(eyZ~we zFz*9906&0k0BauzN(UhJ1#tuL2B-wUd;p#Sya5^k`1~Nq7N8S=+#kd-0OSe48h~IR z-~reaRGD+S^*Z^Q!g$=`!+yc6Kv@B>wg;Ht9ux(XWsOGHP;cj}jPuMN!#GwXGkPN1 z&f410FG=8cb25$(Bk%*N0uY=M_%Fd2{1*t4NR{%tXA@a;KQQPr4q{kQ0Z zxU=dLGR}D&G({V$s95Lpd=UM>)=_fPy=+F!I(LRE@d30PMjcBRxb#^g{QeZ#VBlSyPKfAKMXwF?|; zj!jZHxBet=+(tq^hOG9#tBsPs7rS`vBU)dPp1NCPI4j;v5*62Nn1u-d^-lzw`YWlo z3I%d5%%Dm0FlE?Q&-9*-dnz6mrWk-PrD!636zTnRJq7_w%S@7NW3iM( z#9mx#KfU^7{HqQ3Q}QwqVq;7RUO3k500#=nQm8Ev3B~#?RbJbY;y22b4h1)F!|b5jgk%7AEFlu?pl6N=XnB}W zbq&%c8R#)YUp5%ThaA5btbFfxzFq4shbi!Zz_#Z{Y5VzVg|q>$v)Q?}9~xPDT<(e-maBam+@_y*6)^5?=mb>}I0o^50oDqlo-u ze5jA(L`G|#=y~iRdTfKclqe_E(agq3Z%j961Vwb)ns2de{7Kdea7HBq+77FSg#?kG zHR#6drag(GZj*<*(VkMpihXtcuAAa}3hD}9BUCo-Z)6IO*AlgrBuWg(!(H11zQE;y z0HW^5?&Pd^l*{XlDBDO`Xzuuy5^Y1L{EJ9lJ88Q0C@a3E?@fG*CWJkFMQ}*$a6s6| zMQ^ljlS}OMFzBU5JvVjVyJS6cQjfx#ZDBmG6a?GCV}K5*7YJa2XSgr8<)knF$`{Ah zfrT@eS%H7)Yyvs;xuW_S-O<~Zuj~9e1?S$@7yxee302T&2{O&;yNd3g)4ALm`IU+( zO-NJd{hLNr+dWIUpPqFZ%D+nYW#TQ(-&l|%Ieta^#L*Zu9aaX?=*$Y=?sU6qC}h9x z60yT&XwpeDfNTh|u13n;c_yTNbtd;%pV1H3ksmR#eK)VBnBmyfUvV`pe=;n9!`gVJ z->^oof%(dDGlPaxB7Re>XDxqbQr>&?J8i1#xnF72{jQ;p^ucTrb!S)@W7JN$P1;V4=l zWwgCzY(&g0vHg}Zz&F~irQ}V5pFc|n(V#`-EhYYY-PJakr)+d&NFlfIHA{Zo40hko zu|ITL)Z9hR00OQvzL(XzPVf(0P80jABk0yE+zDHP>C!)d3Z7r4YhJ?=en##5cr7f;h!BlqAU4-x=EH(y>G=e{`{<6% zI(y?f0}={jS1{6^(oo#i>q7Lz5QLGIF6{R^t7|*?z$-=uf1Cffdo{|A8O96jD~awQ z)o{$W1mnfRob-%wn_l(%kB;GK76$WCebkRyP6#G zrLoEjomhJ`{?m#gM>?_hXx7K%PS$ts)ENjPmx+u`!K4#+*H5n9vW5jmC*B@SESrdH zQz!l&%^Mx6FpExtT}`3ck(Z~3I^hvuOE3x_%EhUpqq*Jq(NaTzYLDhY z8?l?5z;-tZ^ccmlAI^md3V_AjwqO*OIYl|tG}9myz)x*ko_Wy#?H>dqq;T2PrLHRuzGJ~1n zcY3>H2}U`G)!eBXJ;gnKI3=AWMT3;~YSc8`v*yn2)fk_sW>7x=4^7>Z%hT`-VoNZ} zIj>i&=+cAb{T|Jma+6Og2n7WDX`{a@3a0RT{Pc{w{v;wIBECe|XjOZ${Q<9(Til8l zyD_4#htq=q!tM`O6r%NKCMLt8jWe0|T19WZmbpT%9gpCFuW-G9^LaN0VAo+G`>n0K zDun2ThP&;l)tH*h2Zc7wg}*-brfG*NMvw$?Jz>9bmHtQqN%2A zwM^qIA7k$%q9zZrxFheBFJ{V3%yUpu%-k8PE<54{q4(12xSuKSL;uj%aXI`+bF%!n z6~!CAdv5$*j{-d^#S2bEkTs&DPzkVqJi?NU8&SxV<{g(MTfl#1xHX}eN(Bm3U4bPMa3meM}FSV0rTwE5U}#QJ*%|(lrp4< z+V}iGXk5Byvl-^|3XF-x&G{@k7+mG{03M|-0)zv|X>H8jaLKU6PhLHW5lKy;U_Cr* z*D?91Wj-J$iMpQTdnHj? z%&m!KGiA<}f3pyIvE&!TX*Z-kAN0E7O>}?lqrB@J8eU-D+s=lPn?zRUUd@#iy*`u6 z@+1Z24qwsI{2OP=f3y5EG7$1;?jtvueBy@|$ixZxS&BoBRPmSJ>vFtdJt0K0LEN1x zi++RkcFB)0=?ShV$qTb}uT55zEYJ4yNtmS=;dixo87iNzJZ3p2AYn&P5XCaCIyPz9 z)b5p6e^CDK&QFj@rcMTcMnt2K_>)6h``S?8n0H3eV(AdNmG^#2xF+xRVpp%t+6(<$ zICBarciBn{J;oCaPnj=jkK)fvHYM_R-CXlA+|RMU^ta}k^x>W7e#f=;E;jb{G{)cX#^@pLV~4np zAL2f7i2LLr?o)@je?G*0n!&cMtxt=OaKT0ewYjae`&vW}FQS~`D_lEZAo@mdtLQj8 z8Pf?dj@DhSc3yKyUR?_E7IyZs5KF%TTfqGTGpNo8?Cl?b^WOvqZj+RoKFC6GG+Psp z#u%)?BN&?C{YS1c&B%>SN}LqpBsl$+qA~2=FI8mD%=rss4_B@p zSFT`M^m$(zvVLSRQqC#;frB+ljO6+GjH2(fI{7&U53rn6KYbF+&Lc7XJkT7t$}8(k zg?ZH9?FM?yul_Ulo`h2xPC1&4-VR`uw(+JGcx`%9H}P7O&XtfRBc?C!y7Rf)Z;5;; zWhbq(7d+A{4ZX-uoU)?2x>kx|fW~XA>(urz@mbX=Co_#69ZB{mvy@u;lwMP6M_i?; zi!W|zTMQ0=@-sKRWE*T4~PZ~cPj81U}Y&iooF`8DQrqGt`;&de0)<|%B9wlZ`{ZU`}FVkzkPMfxpV zJK(ogk>b&SJ|Tg0ti7y=TD!vm3Eella;3_NmQ617@$~ZQ725IG`)*S6p8~@Za1gaN z8I&dh|Gm~C8NxMXcRqe#L8DW%1WoZxW%keXRbP$qo!7cSIW*>J5z=OJXMhNQ{rv0? z+%1;7O}6s=3(m(Lo_T#Nx$g~)tDjI{u&}GUb|d`-LppYHx7*9UM2Ej`!J>tztvZe@us~vqkC(}KI^i4 znRRNsF&5|BmrE^*TDFcUL^du9XMB!$OVUkMjXZWg_xzZ9JYUvjRI7*1!Iq5CFV+2jMJcz(GPq9aFh(qj$65CR2$-r}}#qQKz*7rg7boC`M6X&e!9BX-%Mn6s3X7`3-$s~4Q9>lS`CW77$rrZ3; zT;bZ;OXEqMsd+y{T=lxd(zk(ZAZ95g{Ly|6xUTJ;J<;F3%;`qRdo%A_+Hif0vJLM# z@wr?ytRtF&2U+f}Y9ZwJsRB63wR}ztA-*NKq%|GGN#Evv79*ARm+ZHM)4scghX_1x zsf>$cj<0k=ARfZbJp_*F@~&mM}hyQ}_i z9X<0O_Oj~4P;UYX@C!jlpuX)p0p)?NRF=o(?x^WJKDS*)t(_Nd?Bz$aznzsMx|b8$ zcaQVzx&no|5+o#bPK+W6vx?OOzHC3(k){Q-SSWFAQjTds-!eCazlST-l*7xJL6XpoC&5Xwd=Yhyw}JN8JS+ zUt53*0AvsWd4M2*P5?^4r4Nt{Fay8`Y`GY39`(4rP8vC!^6dLj;XW-XF_DE0h4xI8 z&n0Q|)|)#5yX#IsdY~M_Qp5+$XLrJ3|Y97jcH zKcse6{Wq2_s;^?Y_Ja})(m$hx6C2)GbuKSZ&cA4rK$2)2^=moz-&hW87Q4#pySE44 zy*;D_l^iyn74ou}Dr)%i-p)Ewx{{1^gYmRs(bOD~U3UuEeH`6uD1AQqxnieezNx1X zuJtxqQQb|O%p$@UdHGHB`8CaH<8ra{_KMeeE*!x=U$UTn46+`2uag4zFOi_%Z~%P; z0`PdH1rP@?0l*2|4-rf_2NC-&><_kmZ!h`36>U8uu7Bhr-pc~}xu(-GI44rk!+xAI#0K*b!fpXH$NF44)8 zM5N|+7b*T!8)#*xrL~f*^S7w8d6ecK8@5q-_CeMb%kz)PzdI~)A9)wcTX)o`B4beM zaJ2NHd^+a;>eU_Xg9L_cpYG1h0puILvY zbmf;AJnVdg_gl(0)pNhmPCf-;eIoh)2ipw#Dj?-Clv zehxU^yZg%EflSIB1CqoHeou4V&^X+%xy#9l`$U=g!IpdHWLtY0lE+6}iQ5vD-?_?u z50^18FsawudG{p`=n(+7e-mU$gNXD&Bk76dsSFe18^$Ti=yOZ^;|`}Ev1UdlUMg%4 zi@w5YN&#_OZ_QaH=UC^^PExxL^ao0dCF@^m=HWbWpAwGKmf%$mt8K)c?URSbpKRr! z^w9{snCXq7?9K?yg8MYIXX1%(BH{thT(q`I z&^z7Bs?RFtDrKKAk<(b0j$NQMQ=u9w;_NZrksxcs$E@^)A(VF`ap}_S<3?1MGO|RE zQj3@dWF#s|uSvZ3+u`NWBpZz|JSUa#2@wrrf_}Es zGhm0mf*6^1K_hHb%d6fa4;8%?wQwXcb514=X^1YQ<3?vK!;_m~#o3QOlTI(@j-f=K z%0)62yo}4+(_>*;MKYVn|A7894rzO|`!)-h1;M|CY%$@wqpmnfRuo%k(wN@p*}&O0>rpH_C(sLNH4 zjzW&NFgKYMWLvn7Y4@NuHi#7e&d6?y&ImuSmF(`hTaoDXH?W?yQ%V{82Cd$Gx1sIj zuBMr+*`U3Vvp)rJDt6z}`1^i2)gr}haxU__NN%$2v7k%O0_n}={47{eQukZJwR`uy z!=-pb+?MP!xo4pyC3xKo&aEXzun8$Q_qj;DRUo+?eUf3tzHdJV96H;k@2x*+3xnhq zgv#enw$tJ}{W2_w8PEUmUXDX>`pkYyIP~4tjnZ=yy?55vS7Gzy3(Tc_tA3_^CGX12 zH|Far?8FPhh8H^y;@FDoX6OVc$6qRmyWv6zo$?cg;_)Ks`%IECyOf#2OXOq=2E z`vdP;`SeI%%;`>4z4jodT)NifF|LhcL@N&-6|1_-M5JAk(BUjFX_WqXI@wY&<7Y1n z4Ds)N8$9ad_Lkt0HUA@{yf)LmG_k+2$Pc_(Da8%_RCsk?^!7jg|Gs;>Kfry@SjtcB zc*>MMcvhCX9_{!f{o~Bit(|>>RNxtbeRlgF!3^!Ma@gYQ^kJj;g<#kG$jp`#D|cSu z($+UfY4o#P+g~H$_OSa74iTRVPlfo$Nv~e5|DB}&x>bDEva6!WW1G^ znytl^6nr?wX4Upuo&$dM0k8lz1<5Lmvh}*MXynd@Es|BJ+A_NO_&F>Hq19?ufy4^vgPt-c8@vppv(?qpR4=zZ8CRl6ueHRg@;D*59c^zQ6(j8}v7Z zn(xl}y8gi9Ok{8N$5fs6BK3Sl#w2k`gUFBm+S59!1+BZEv(QhwVwwss-8Q87>>7mH z{ObD0BlxueKkb`xXzHYNC{O0Ds^^`q4s+Lc@HZw5X3X>nixq8>#&Ed&dD73oF`cKF zEYw%~F?%pNo8K~=0vmw5JwOHb`nd|FVjVW(JU3LVuRjkkxAb8PloEXG^0l9n__<9m z1ouL_vqbO!9W=Lu^?wo23;$J6HIZZQ=65yDN6vM0-)U^;Jd=B8eSe<;hfq%6#=2VE;yNnYIhpCzFiJl^F1CexN2keQF+Y9TE|B& zK4;o&@7$mfW$gjnHVgn#0p7 ztL3z`8cGP9nnQNnVIRX>{$40&@2r1_{d!}BW4fHElWuvj6EBlhquE&G2it#PIf5^7 z+2<#5D#P$Xu_0CMF|kw+e}1|~cOs&ncbi2M%iT8jZ2lRSgWfS{F<`uOQX-%xjV-Lm z@;sh?j^g!^I#uM>3Fwl78mAc3e~Amy4gJfvT_cyzq}VV`Nu3!rs%LiHI zm*=?SJ*XGcNPmb=yL}+k_*Nvrb~&Ys{v0oF;ADpN^Y^`1jD&KdW&;dGr`PoLtCnx# zrt^nZMW#KQp|JRnlV#C;p4z9m;KWil->ou(09|c5zl3M!v3V0R&kNoBiO*hP8-#mM zjo+OD;K^q$4>&xG5rZ(d`*636EF*6rC%dQaIfE6{jfX^nBJS^HjORKnhEX(sEYd4QvVbChdEG3hvYOxqiHp^~bq?!BvNq zBgu}L>MikGw_~(P3Yp(81h@CVWh@WySJ@go|Ln#1&rYxlro~~iEB!a0SkHM6O>J;r zrjtFFcdY$#Kk5FwkO54)t0eHY0IxWiT>b*2y&bqQF0ne=qt^?!nBpGY%~MltI<2yL z5C`+Ne{i9;lIYP%)nx|nMYiO+R-ltvw)LIy^koJ;JGSxSgK;A=X50A#B6=v~#>n;h#6Ty46l z2_IiSxyN@>3_;hit*> zV7fX~QOIkyU}W+Jjcv+YmkYrIUlHTm-kQjqcUk7h8H;k{2SdGN_tgie#?n*2y?mWp zF^I5i0G0?G818>p9#;S0ivBmjG$ePvH6k+i*)uf|LrBKyj_T7W@$$RDr)&$?rSSwc zgRI^k=eyDn@B7Jk!=_iehrrls={h1E@Dq5=yd0HuZSgIqc9y;;o=>@Pt0| zuv!()aebs(Ka2dG)}8cUdrC0Rws+VFIi31f*f4ZMQnG`Gu8=dN+8a|sydZ9)5Wfx) zIwA+*D~2Wy;gvWX;f_EY+3ast%Tsr6<5nu`3aey#zttGCsgQ11Xg6|DGx|~5O>pP( z_n@Qw1T7;cdVkr=4YKhzi%&%~8%!{IXL;N4R#ze&yKIT%RFqy(r{gM0aA6UBG2?iw zXx{HuSKZ&C3J)YD&R#?_X7PDtD8kOrCaD?gdh$zK${BOjm%W0b?$6HDB};$1Wz8Dy zHio8pc_iDo`?>>Z2~hd)|~C`N(o&E$gR?#x>&>*Sf2k2XXA4_Jwe#YQYzC z0UQuwGuxTPbdWEn1jpgzrAmw5w~A&1^=U8%ym#RZS_1-m_b$#A#+|sr(H@4w)qLJ#ULs*moFhGz=X zIHzv0{_*cW3I6SEr;7aBX;UL|*r;?!DwGa!zi^1V$|3Hmhqzxf>2I(~OV5^w_k`#! zkDDS9X(glGLmT6>FQ|HpCDommG(f8!Kfj{eQQrmnWeU}~qfZ7$3rgdZ{Q{FUsgJ4F zEI;ovzUDlVlpk44&8=4xh-VZU7oGc7-FGkz(*^U9vywp*YBOF~DXpm%h!M_KW(t_<&Q18@seMOcy?oBJG4Ui7-n zRpiF%H(bXrM6ER3&(k6=`$U|)gRqnbzO}Z2F#OYXr-dSC6x4ofU3;0~Mt`$%jswep zaqb1Cc4=x;Jju1ywnaPt3Wx`-vxcxH&F9_^y{}=1{&W?O{&V8mcEC=z_KAksdJon|t zv9zG+-dD6`Ey!@2Q{D>kz`sb|r&`LsKj0pcD3MI6M{|s@?)MC_3^nyoIU$ccX2QCt zfo0cCbQlXXl~Yqqm7#K^?R#-asLXf08a1EDg_aAfA{eJ#yLzcR#?U?$kRQqd$IuYp z=|c3mSC$erq&8|aSL4i*pA;(%sW;S>O(v;TQ}Ih5)_%=-<3Gl`$?gJv01VI*&m_>~mt__2?<<>4dL& zFF4lg^kfT;gw}=%KWPpV>tv>3%eUt4S*ChsHR6GNE#m30Wq;>fBtx@ao6Ze#mwTVH zrrf=%X)e%tWN5N9iMe3>nr$|m=ZDsq2SiDRiGK>%v!hxOe1CkQx?W=xn+R3m-4Q#t z{F6UD9!3kueTkWOu(^=jkM_%tt15zae@%mH+unH_O>Q5Nu8$XqYn4|uN0ZnhnlN@w zNYVWd6N?8~^6afCoA2(tj-9}lxpM7znsVKx%nRS&7f~E+xi`$McX#)_<%BqExhV}? zTf)*EtobM3V`w45^abG{us6s9?u`#C^}|jAcqgwLoucu(cS?r)v3y~wV{ig{93md@ z712JWb_2%=X{zaapCPrgUi6LW=k6{1jvvh7t=Rb?b83uub!S%FUf~vT&?ocqmrMMEB5LmzXr=6@WapZ+3TZsU zFS5vuO{2R>Mx5ZrWo)^UK*N>cUv?x<=Y$U(+mP#dSs^<0NwPj%`3KJ|deix-@zOdS z0`4p}%p1ip$nGzT{WX}nUO}fp&yVkW?5|Y6vKt#uzU%t8b>=VX?DXdHpyUux7**(8 z^u8VWdu3d=*hE|Nyj)FQGRoXC)1^P)z|WR-OsPl|9V@s zKL#|b`~mq*ehvQQVoqlo5?ARc-MI#?aPr6fYi}Fw;}PF+fLmlU_D(Wa+~eSE+?M!< zOFE+?_vggCaEUb#tt`V`qi;DZ{WQkqGtzqgqjK2txNbIn0p}fb)leF=Q}Rm@mZpFn z0j#0qhy85H~3&@Z6lCeLT%StBd?$Y%`LVaPuB&?()gaMxh zRf8onp}DEVvn#NVW`yFFgPmR-@2#{9rd0IvHg;z(m7KhYazUx-JId3K!9Jsh)iBvH zzAM?9q~)AXzSfEJmn?qBoa7jdtV;+`wtjb-&QVeEw<~&Zw@>Ej*%phwkkAoD_JIyv zc09{>C!CpE2dnZ_-H-ngNo_Z{gJJKN8AQunW^WrFlR96E#fp4~WjgQ171`=g#hY^_ z@&086hA||*UoO)=x)>0Uf!fX3+WqLL@hy}nGI=}B&jKz=Nv@GC#GYfGZm9}au;;QO z(gLJQjDpyvTg;7Q^vwDjJaZH$X~Ty9Enx17861UXyF+i$q}_7hLV5|&Yr(Q#kBKCHJIl%uD8mKnX`(`e0Z#GzC? zJWOCM|JwiAA~Vw%N3VeW=#=qfFwu2l93J^^tT7oLZ6vMPHN__0rYX|}H*TT1&VDC8 z6KjaJV;Fw*jFrbkDzRMj{Shh+n>um`A{0si$5KRn~v-GTh4-yHla-RX|C>jnRQ zdH7F{U}X8L@Ez6~536mVBPX)&P|jSVab2G5%dN+&RI}7OD3||{SDRn9hxtk21XOju zZY{!e;&wWz$k|%4vu;lXkw)Nujo}be#7R9@M;vF|f$@-^g&BQkbA!^fi#C{6Zkg#F zEld7x9>(dVd!kUfv1_f2oTB~FJ6o!PAl@G=w6C~?3C?$ggYO|aDLmM5qT(4;twJJ8 z65Y%WN+I5EMu&#*1c6&4Hd2AL3_RoJTt2aV%r~(xlIl z17loKq{*384jkKZw3!q!-^9POpwcs*2oR`nacf^V(ZMsZ^zgX**KbQV%rE|E)g5~7 za-udD-^%G_CC6V`kVu(7u*I&;YaSTI|E@%Asr<rW2bdYnVt4?91&Q`CRpL2Nz$ z!5MrYq25O&na9GNwMwtkewTneQT+YzO<8kY|JSPvcG@2#RM%f*)T{~5F6DSI6^GO0 z6RFsIFfa}YH>i)fW)gYaUL){reu-=vzt?r0Cxr!k6$R3|C-P&&Ge6qjx8_WWxE&aA zB2h&%9>4ZuOXcV-yEYQ1=dCp+W?16->y%H+%_{O(@LrvsxaA>RRdFt-V`bd2$&5p~ zyU!ErTD)vC`OV5fypx?jUY{gc!3*S5VPgA0x%;0Z%-B znvMV_c!t-nPi85QmDYIkVuT_DPKZ8aeJa%S^dZ5lYn3(1Qp1Sh23)JC0S=PYua>+t zT)nTNq3lWSyEL-UtfGdLHL2+_#d5bk-p`(&L({%yvXb>IuKkTgSadFIjwaSt%>1A* z_UQQc+#ht?a*%S5u4B*rLARZU^`;lC)4gBbJY9;`bXtX>L%UjD!h6=#qQw`l9x?YllMj+KWC0=kF`sr8q}+wNhZ1;Z)4u} zDc;!g*4{o3F?R0mi!;gaNaA+=GKniO3#p^?7p!V~rpO(W(;|reW%KRUG%ENlG;rz& z0SS;UZ-93I#Gte_0b&5g0N6nvXAMvUum)fRHi^>#<^co&j}riru2n~N2BiS9^RcA6 zHH-J3-O%JuY91#Jwd?zEz2U|*T#mcv+`z+rK?yx_ij@!lo)^Dah;>=Q8t01%RFwjL zk#B9C+^d);+i!cLont+e1wwHqZxtc`>LMNDBk{yBO7Vzl{ln4W(d+WbNSJ3j?h8Me z_1`}4{HGr=+SrgJ>`?3u6I;%E?}q+~vUh=>I_ZpW*GM^zPOMkhXklO8IDUdF5*!yM z=+7*Zrq-47HJAHXgE{bXZ-uR9y%yu{9bX;8GHdFq{8gSq%YgFm`AL|CWPe`#;~D)~ zbE=_2y*6XjFZPG_r+(tuc`2z>k>nc{^geND@<@7V_I&df*7lr``G@`PgK_fMVze|% z#Zx*15h_{bZ^-R$R#4C)NDA)9*Vp;U^uuxa=NXb++s(U+&IVTpZ;E4y#!!=&$XDfJ zgslu!jacf&(4T$GEFip6Ev^1?^K0(-}lb%LGqnn(&D2}*nbdqkrgG|MrjC@u=euu?_L3Fx@DtL7KFyDXcH&xVh5FF!|fx!VL$X>@1$2H<0BzQKvw z{BH4YEL*gxtr;oRE{}M!?{Q&QNU9eeM-vtlns}tp#P$)b;!SAgp*aU$-q=@A=x3$ka%<|V#Jd!yazcf?o$5md36yP9S*UI4&rGhr}(xB%1wU~h8)^`8VCu6I&U zCb3o4SH_l7%E#wfUf+Ar#(^aCu(kN)?K(XAZU6ZYbpcpWVxeGqa>=l_k>et(HzsG3UlJ5*_myGU>QQ@JK>)Ci${mmnrTVGPq z2T*)1OqZ8*M;d-4wX*rW5ZJN2s}aEKWY3v*gv{!dWe_88Xu!)M`APEu=Z8kn^RFX^ z&HnbM2q|mju>pxz)>Y{r+GiyCiJ7jPajr2*;rqhP@a5-QX)BXubCi&KcIapm_w+_C z1~kY>p#40qvc>X;G3!CCC(?PefzYmnpH(fm4Qu+b+68I1gW^=qf0D)G z$zTewu}$X-POY+vf#b60^xGaja4S4nQJuQS*0A^*k`p|uJl%7jRRynhMu?UEZUviG zq1Uovd8t^Y6~}oIq+9QsE+G|}J?Nj79uFMKyB#f~on`x6*Yks_p9b}~m4oQgWx|;% zgGZkS190`ylr=F1Q_F4+IWFHVG%?#)e{j|Aq~QlH8W**v%y0BoXPyPSX!mE%)_bc? zH_LS6Tc%?REnfA}xsHa)K+7X0;-7Yu)j&BSZaIuyFt1&SF4!Bx0;Q1g)Tt>iicqOg z9@H+ZFcfpn5x1uy$2XKxKE}zXEU9I)u$f8!u(+!5;o*+~BdqWCh7sBc6M=Ri*DX)o z!KJaEL{_IwO{ngPtavIwr!dk?i!AAo5?Sh?A@mD<(dJ0qY+ocf4X?SOWKcQ%*+yi{ zfsD1NJf?11Hi=_ra~4>S^zbi+4lAMb{rWooEiw~dLZ=+>)?ur%N{aXdA53B_wvwwM z&+&;~(sv73@JC*kOei!_80KxJYeKGfvu`o_biEtt))E6-nTf?w+lYHTdRzjgGbRo+ zs?8iTr;Zo6#g{T*Dw>*jhFp-v$9=5kas2x@6_kYK%WWe_?{k7r7M&E? z;Eq`-DUN(`%!@>HxhK3M1gC-tQ}e16c7f1~TP&X6=4|zOMyKZI+*{b(7Ge{6IC*N% zjUsanq1z>-oV!N%s=W;D0ou2hZ44*_zpr=&fA(awA@-kYCW6p?U#v(s-WKPagT^1f z@V-jS&3THSFY#WwDZT!wH{8lG-P3WhwKtaYKOHo-?4H6tWjBYL>Xx!E`q zhjkrC(QL0mN=!^o=KG_RoEnJtbHFPchTW#jkVVn}IN!eHVz zr=&k@5AQ~y13w7t-HkeD8?5s=j^lAx(l@>S0Z!a?XPa9&;m2?><_5T|4GNdxzW8tN zq`@y?{_2JfVfk@53w*ldvIB2Z@sAwBFKuz2W3>;Wn$=29eXdouY2jlin=LOo^!+%T zF{s6dmDnM1T{*;k^^jOXhqxm}-HRfV;=)^{XF&4jD`@*EH+;)R+?4E-ycHxi^X4kF zK6c8+G|`LWl&=nTb3CPI?vKHgd%XjgT6%nzW}yAEBKvJslB`#=F$K9!V9jI|K4fNm<*+sy&`Cz zCM`O^>}_qXdh+!NL_LPDuoaBmUlhC?|8A6~BkA%BkJe{mS*X!;6iZ>)U1SsAK96mF zQv&bW@_|~604jKXZ$*rLO1F@UnK84Xm3}bAA}D|Ds0FoVU6#_YDe6(uf7LmpofAyJ z8VC|2_TScSn||Pc{w7#?d6koP=Clq_r(ATLhlWs<1)ju->BmE#ZF>iq=HG`m1qX{O z8q2?`F}eBv_p5b$9_n!gbqjUtM5dCXlPpv*hopk+5cgwQ4yDGlgQDc)BSeMM8CYt> zAJ)C#Jcjq?`azB%fC--Ac5M0lyvZ_eBa*+(U|KBti+SS{rjq6o8qcD1=3k?^Ev>@2 z_NTWX5OUmW6ut{d+DdQEg~*xcQa@Mr9Id=b<7yozt7c*L*fTf%HOKMdV;Wcg#uAO* zsxwahsG20=Xe$YBmf%Z%r|Sz-lfQ%_BVQ@e%{50YqxiJZ4+woAlC+us(asv8hQWbt znP_%pxarf^n(T3c22#PsG(+Jdjz*GvwF6z{H__F*)>*ClXY8yeUY*r^Kp<%0DMJ%G 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 literal 0 HcmV?d00001 diff --git a/go.mod b/go.mod index c3b27d405e..6b63450a91 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/ethereum/c-kzg-4844/v2 v2.1.0 github.com/ethereum/go-verkle v0.2.2 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/fsnotify/fsnotify v1.6.0 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/deepmap/oapi-codegen v1.6.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/getsentry/sentry-go v0.27.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect diff --git a/go.sum b/go.sum index 6f31f96ec2..db59c74229 100644 --- a/go.sum +++ b/go.sum @@ -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_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/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/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/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= 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/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk= -github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +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/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI= 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/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY= 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.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= +github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4= +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/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=