github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/eth/tracers/internal/util.go (about)

     1  // Copyright 2023 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  package internal
    17  
    18  import (
    19  	"errors"
    20  	"fmt"
    21  
    22  	"github.com/holiman/uint256"
    23  )
    24  
    25  const (
    26  	memoryPadLimit = 1024 * 1024
    27  )
    28  
    29  // GetMemoryCopyPadded returns offset + size as a new slice.
    30  // It zero-pads the slice if it extends beyond memory bounds.
    31  func GetMemoryCopyPadded(m []byte, offset, size int64) ([]byte, error) {
    32  	if offset < 0 || size < 0 {
    33  		return nil, errors.New("offset or size must not be negative")
    34  	}
    35  	length := int64(len(m))
    36  	if offset+size < length { // slice fully inside memory
    37  		return memoryCopy(m, offset, size), nil
    38  	}
    39  	paddingNeeded := offset + size - length
    40  	if paddingNeeded > memoryPadLimit {
    41  		return nil, fmt.Errorf("reached limit for padding memory slice: %d", paddingNeeded)
    42  	}
    43  	cpy := make([]byte, size)
    44  	if overlap := length - offset; overlap > 0 {
    45  		copy(cpy, MemoryPtr(m, offset, overlap))
    46  	}
    47  	return cpy, nil
    48  }
    49  
    50  func memoryCopy(m []byte, offset, size int64) (cpy []byte) {
    51  	if size == 0 {
    52  		return nil
    53  	}
    54  
    55  	if len(m) > int(offset) {
    56  		cpy = make([]byte, size)
    57  		copy(cpy, m[offset:offset+size])
    58  
    59  		return
    60  	}
    61  
    62  	return
    63  }
    64  
    65  // MemoryPtr returns a pointer to a slice of memory.
    66  func MemoryPtr(m []byte, offset, size int64) []byte {
    67  	if size == 0 {
    68  		return nil
    69  	}
    70  
    71  	if len(m) > int(offset) {
    72  		return m[offset : offset+size]
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  // StackBack returns the n'th item in stack
    79  func StackBack(st []uint256.Int, n int) *uint256.Int {
    80  	return &st[len(st)-n-1]
    81  }