diff --git a/core/types/log.go b/core/types/log.go index 5895578c509..f9433e9a422 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -21,6 +21,7 @@ package types import ( "io" + "slices" "github.com/erigontech/erigon-lib/common/hexutil" @@ -79,6 +80,17 @@ type ErigonLogs []*ErigonLog type Logs []*Log +func (logs Logs) Copy() Logs { + if logs == nil { + return nil + } + logsCopy := make(Logs, len(logs)) + for i, log := range logs { + logsCopy[i] = log.Copy() + } + return logsCopy +} + func (logs Logs) Filter(addrMap map[libcommon.Address]struct{}, topics [][]libcommon.Hash, maxLogs uint64) Logs { topicMap := make(map[int]map[libcommon.Hash]struct{}, 7) @@ -251,19 +263,13 @@ func (l *Log) DecodeRLP(s *rlp.Stream) error { // Copy creates a deep copy of the Log. func (l *Log) Copy() *Log { - topics := make([]libcommon.Hash, 0, len(l.Topics)) - for _, topic := range l.Topics { - topicCopy := libcommon.BytesToHash(topic.Bytes()) - topics = append(topics, topicCopy) + if l == nil { + return nil } - - data := make([]byte, len(l.Data)) - copy(data, l.Data) - return &Log{ Address: libcommon.BytesToAddress(l.Address.Bytes()), - Topics: topics, - Data: data, + Topics: slices.Clone(l.Topics), + Data: slices.Clone(l.Data), BlockNumber: l.BlockNumber, TxHash: libcommon.BytesToHash(l.TxHash.Bytes()), TxIndex: l.TxIndex, diff --git a/core/types/receipt.go b/core/types/receipt.go index ae633066264..271b25507b8 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -26,6 +26,7 @@ import ( "fmt" "io" "math/big" + "slices" libcommon "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/hexutil" @@ -272,33 +273,21 @@ func (r *Receipt) statusEncoding() []byte { // Copy creates a deep copy of the Receipt. func (r *Receipt) Copy() *Receipt { - postState := make([]byte, len(r.PostState)) - copy(postState, r.PostState) - - bloom := BytesToBloom(r.Bloom.Bytes()) - - logs := make(Logs, 0, len(r.Logs)) - for _, log := range r.Logs { - logs = append(logs, log.Copy()) + if r == nil { + return nil } - - txHash := libcommon.BytesToHash(r.TxHash.Bytes()) - contractAddress := libcommon.BytesToAddress(r.ContractAddress.Bytes()) - blockHash := libcommon.BytesToHash(r.BlockHash.Bytes()) - blockNumber := big.NewInt(0).Set(r.BlockNumber) - return &Receipt{ Type: r.Type, - PostState: postState, + PostState: slices.Clone(r.PostState), Status: r.Status, CumulativeGasUsed: r.CumulativeGasUsed, - Bloom: bloom, - Logs: logs, - TxHash: txHash, - ContractAddress: contractAddress, + Bloom: BytesToBloom(r.Bloom.Bytes()), + Logs: r.Logs.Copy(), + TxHash: libcommon.BytesToHash(r.TxHash.Bytes()), + ContractAddress: libcommon.BytesToAddress(r.ContractAddress.Bytes()), GasUsed: r.GasUsed, - BlockHash: blockHash, - BlockNumber: blockNumber, + BlockHash: libcommon.BytesToHash(r.BlockHash.Bytes()), + BlockNumber: big.NewInt(0).Set(r.BlockNumber), TransactionIndex: r.TransactionIndex, } } @@ -353,9 +342,12 @@ type Receipts []*Receipt func (rs Receipts) Len() int { return len(rs) } func (rs Receipts) Copy() Receipts { - rsCopy := make(Receipts, 0, rs.Len()) - for _, r := range rs { - rsCopy = append(rsCopy, r.Copy()) + if rs == nil { + return nil + } + rsCopy := make(Receipts, rs.Len()) + for i, r := range rs { + rsCopy[i] = r.Copy() } return rsCopy } diff --git a/turbo/jsonrpc/receipts/receipts_generator.go b/turbo/jsonrpc/receipts/receipts_generator.go index 4848ef0e6f4..05d6f92fa7b 100644 --- a/turbo/jsonrpc/receipts/receipts_generator.go +++ b/turbo/jsonrpc/receipts/receipts_generator.go @@ -103,7 +103,7 @@ func (g *Generator) PrepareEnv(ctx context.Context, block *types.Block, cfg *cha } func (g *Generator) addToCache(header *types.Header, receipts types.Receipts) { - g.receiptsCache.Add(header.Hash(), receipts.Copy()) + g.receiptsCache.Add(header.Hash(), receipts.Copy()) // .Copy() helps pprof to attribute memory to cache - instead of evm (where it was allocated). } func (g *Generator) GetReceipt(ctx context.Context, cfg *chain.Config, tx kv.Tx, block *types.Block, index int, optimize bool) (*types.Receipt, error) {