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 0000000000..a3f23822a8 Binary files /dev/null and b/core/types/testdata/22615532_block_access_list_with_reads_eip7928.ssz differ 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=