mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-04-19 03:01:06 -04:00
* initial commit for cli integration of web3signer * resolving conflicts and execution * remove aggregation slot from proto * rem aggregation slot * define a sync message block root struct * fix sync message name * sync message block root struct * amend where sync committee block root is used * altered switch statement to return correct json request by type * fixing fork data import, types, and unit tests * reverting unwanted changes * reverting more unwanted changes * fixing deepsource issues * fixing formatting * more fixes for deepsource and code clean up * only want to fetch once for fetch validating public keys * adding more comments * new unit tests for requests and fixing a mapper issue * Update validator/client/validator.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update validator/accounts/wallet/wallet.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * adjusting comment * adjusting comment * fixing import organization * including more unit tests * adding new cli edit * adding in checks for wallet initialize * adding web3signer flags to main.go * some how resolved files did not save correctly * adding in check to make sure web flag only works with types imported and derived * Update validator/client/sync_committee.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update validator/client/aggregate.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update validator/accounts/wallet/wallet.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/wallet/wallet.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/wallet/wallet.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/main.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/flags/flags.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/flags/flags.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/wallet/wallet.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/wallet/wallet.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * reverting changes that accidently got checked in * reverting * reverting * continuing to revert unintenteded changes * reverting * removing more unneeded changes * addressing review comment * initial refactor * adding in more clarifying comments * fixing mock * resolving desource issues * addressing gosec scan for helper go file * addressing gosec * trying to fix bazel build * removal of interface to fix build * fixing maligned struct * addressing deepsource * fixing deepsource * addressing efficiency of type checking * fixing bazel test failure * fixing go linter errors * gaz * web changes * add w3signer * new kind * proper use * align * adding prysm validator flags to help flags list * addressing root comment * ci lint * fixing standardapi tests * fixing accounts_test after removal of keymanager from rpc server * fixing more unit tests * Update cmd/validator/flags/flags.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update cmd/validator/flags/flags.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update validator/client/service.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update validator/client/service.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * addressing missed err checks * fixing mock tests * fixing gofmt * unskipping minimal e2e test and removing related TODOs * Update testing/endtoend/components/validator.go Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> * Update testing/endtoend/components/validator.go Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> * adding some error wrapers to clarify failure point * fixing bazel build with new error checks * taking preston's advice to make test fail faster to understand what's going on with the test * checking if genesis validators root is not zero hash * adding check for genesis validators root giving zero hash * fixing missing dependency * adding check for wallet * log all * fixing errors for http responses * switching marshal to pretty print * adding pretty sign request test * fixing base url setting * adding in check for web3signer and temporary wallet instead of having to open the wallet * refactoring web3signer to not require wallet * bazel build fix * fixing gazelle build * adding content type of request * fixing more bazel * removing unused code * removing unused comments * adding skip test back in * addressing a validation and error message * fix parse * body * fixing logic for datadir * improving error handling * show resp * fix * sign resp as str * point of pointer remove * sign resp * unmarshal sig resp * read body as str * adding more verbose logging * removing unused result * fixing unit test * reconfiguring files to properly nest code and mocks * fix build issue * using context when using client function calls * fixing based on suggestion * addressing comments * gaz * removing defined max timeout * reverting json print pretty * Update validator/accounts/wallet_edit.go Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> * removing unneeded code restrictions * should not introduce new code that may impact existing key manager types * adjusting comments * adding in json validation * running go mod tidy * some logging * more logs * fixing typo * remove logs * testing without byte trim * fixing order or properties * gaz * tidy * reverting some logs * removing the confusing comments * Update validator/client/aggregate.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * Update validator/client/aggregate.go Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> * addressing pr comments * editing bytes test * Run gazelle update-repos * run gazelle * improving unit test coverage * fixing text * fixing a potential escaped error Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
413 lines
10 KiB
Go
413 lines
10 KiB
Go
// Package bytesutil defines helper methods for converting integers to byte slices.
|
|
package bytesutil
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"math/bits"
|
|
"regexp"
|
|
|
|
"github.com/pkg/errors"
|
|
types "github.com/prysmaticlabs/eth2-types"
|
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
)
|
|
|
|
var hexRegex = regexp.MustCompile("^0x[0-9a-fA-F]+$")
|
|
|
|
// ToBytes returns integer x to bytes in little-endian format at the specified length.
|
|
// Spec defines similar method uint_to_bytes(n: uint) -> bytes, which is equivalent to ToBytes(n, 8).
|
|
func ToBytes(x uint64, length int) []byte {
|
|
if length < 0 {
|
|
length = 0
|
|
}
|
|
makeLength := length
|
|
if length < 8 {
|
|
makeLength = 8
|
|
}
|
|
bytes := make([]byte, makeLength)
|
|
binary.LittleEndian.PutUint64(bytes, x)
|
|
return bytes[:length]
|
|
}
|
|
|
|
// Bytes1 returns integer x to bytes in little-endian format, x.to_bytes(1, 'little').
|
|
func Bytes1(x uint64) []byte {
|
|
bytes := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(bytes, x)
|
|
return bytes[:1]
|
|
}
|
|
|
|
// Bytes2 returns integer x to bytes in little-endian format, x.to_bytes(2, 'little').
|
|
func Bytes2(x uint64) []byte {
|
|
bytes := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(bytes, x)
|
|
return bytes[:2]
|
|
}
|
|
|
|
// Bytes3 returns integer x to bytes in little-endian format, x.to_bytes(3, 'little').
|
|
func Bytes3(x uint64) []byte {
|
|
bytes := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(bytes, x)
|
|
return bytes[:3]
|
|
}
|
|
|
|
// Bytes4 returns integer x to bytes in little-endian format, x.to_bytes(4, 'little').
|
|
func Bytes4(x uint64) []byte {
|
|
bytes := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(bytes, x)
|
|
return bytes[:4]
|
|
}
|
|
|
|
// Bytes8 returns integer x to bytes in little-endian format, x.to_bytes(8, 'little').
|
|
func Bytes8(x uint64) []byte {
|
|
bytes := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(bytes, x)
|
|
return bytes
|
|
}
|
|
|
|
// Bytes32 returns integer x to bytes in little-endian format, x.to_bytes(32, 'little').
|
|
func Bytes32(x uint64) []byte {
|
|
bytes := make([]byte, 32)
|
|
binary.LittleEndian.PutUint64(bytes, x)
|
|
return bytes
|
|
}
|
|
|
|
// FromBytes4 returns an integer which is stored in the little-endian format(4, 'little')
|
|
// from a byte array.
|
|
func FromBytes4(x []byte) uint64 {
|
|
if len(x) < 4 {
|
|
return 0
|
|
}
|
|
empty4bytes := make([]byte, 4)
|
|
return binary.LittleEndian.Uint64(append(x[:4], empty4bytes...))
|
|
}
|
|
|
|
// FromBytes8 returns an integer which is stored in the little-endian format(8, 'little')
|
|
// from a byte array.
|
|
func FromBytes8(x []byte) uint64 {
|
|
if len(x) < 8 {
|
|
return 0
|
|
}
|
|
return binary.LittleEndian.Uint64(x)
|
|
}
|
|
|
|
// ToBytes4 is a convenience method for converting a byte slice to a fix
|
|
// sized 4 byte array. This method will truncate the input if it is larger
|
|
// than 4 bytes.
|
|
func ToBytes4(x []byte) [4]byte {
|
|
var y [4]byte
|
|
copy(y[:], x)
|
|
return y
|
|
}
|
|
|
|
// ToBytes32 is a convenience method for converting a byte slice to a fix
|
|
// sized 32 byte array. This method will truncate the input if it is larger
|
|
// than 32 bytes.
|
|
func ToBytes32(x []byte) [32]byte {
|
|
var y [32]byte
|
|
copy(y[:], x)
|
|
return y
|
|
}
|
|
|
|
// ToBytes48 is a convenience method for converting a byte slice to a fix
|
|
// sized 48 byte array. This method will truncate the input if it is larger
|
|
// than 48 bytes.
|
|
func ToBytes48(x []byte) [48]byte {
|
|
var y [48]byte
|
|
copy(y[:], x)
|
|
return y
|
|
}
|
|
|
|
// ToBytes64 is a convenience method for converting a byte slice to a fix
|
|
// sized 64 byte array. This method will truncate the input if it is larger
|
|
// than 64 bytes.
|
|
func ToBytes64(x []byte) [64]byte {
|
|
var y [64]byte
|
|
copy(y[:], x)
|
|
return y
|
|
}
|
|
|
|
// ToBytes96 is a convenience method for converting a byte slice to a fix
|
|
// sized 96 byte array. This method will truncate the input if it is larger
|
|
// than 96 bytes.
|
|
func ToBytes96(x []byte) [96]byte {
|
|
var y [96]byte
|
|
copy(y[:], x)
|
|
return y
|
|
}
|
|
|
|
// ToBool is a convenience method for converting a byte to a bool.
|
|
// This method will use the first bit of the 0 byte to generate the returned value.
|
|
func ToBool(x byte) bool {
|
|
return x&1 == 1
|
|
}
|
|
|
|
// FromBytes2 returns an integer which is stored in the little-endian format(2, 'little')
|
|
// from a byte array.
|
|
func FromBytes2(x []byte) uint16 {
|
|
if len(x) < 2 {
|
|
return 0
|
|
}
|
|
return binary.LittleEndian.Uint16(x[:2])
|
|
}
|
|
|
|
// FromBool is a convenience method for converting a bool to a byte.
|
|
// This method will use the first bit to generate the returned value.
|
|
func FromBool(x bool) byte {
|
|
if x {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// FromBytes48 is a convenience method for converting a fixed-size byte array
|
|
// to a byte slice.
|
|
func FromBytes48(x [48]byte) []byte {
|
|
return x[:]
|
|
}
|
|
|
|
// FromBytes48Array is a convenience method for converting an array of
|
|
// fixed-size byte arrays to an array of byte slices.
|
|
func FromBytes48Array(x [][48]byte) [][]byte {
|
|
y := make([][]byte, len(x))
|
|
for i := range x {
|
|
y[i] = x[i][:]
|
|
}
|
|
return y
|
|
}
|
|
|
|
// Trunc truncates the byte slices to 6 bytes.
|
|
func Trunc(x []byte) []byte {
|
|
if len(x) > 6 {
|
|
return x[:6]
|
|
}
|
|
return x
|
|
}
|
|
|
|
// ToLowInt64 returns the lowest 8 bytes interpreted as little endian.
|
|
func ToLowInt64(x []byte) int64 {
|
|
if len(x) < 8 {
|
|
return 0
|
|
}
|
|
// Use the first 8 bytes.
|
|
x = x[:8]
|
|
return int64(binary.LittleEndian.Uint64(x))
|
|
}
|
|
|
|
// SafeCopyRootAtIndex takes a copy of an 32-byte slice in a slice of byte slices. Returns error if index out of range.
|
|
func SafeCopyRootAtIndex(input [][]byte, idx uint64) ([]byte, error) {
|
|
if input == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
if uint64(len(input)) <= idx {
|
|
return nil, fmt.Errorf("index %d out of range", idx)
|
|
}
|
|
item := make([]byte, 32)
|
|
copy(item, input[idx])
|
|
return item, nil
|
|
}
|
|
|
|
// SafeCopyBytes will copy and return a non-nil byte array, otherwise it returns nil.
|
|
func SafeCopyBytes(cp []byte) []byte {
|
|
if cp != nil {
|
|
copied := make([]byte, len(cp))
|
|
copy(copied, cp)
|
|
return copied
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SafeCopy2dBytes will copy and return a non-nil 2d byte array, otherwise it returns nil.
|
|
func SafeCopy2dBytes(ary [][]byte) [][]byte {
|
|
if ary != nil {
|
|
copied := make([][]byte, len(ary))
|
|
for i, a := range ary {
|
|
copied[i] = SafeCopyBytes(a)
|
|
}
|
|
return copied
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SafeCopy2d32Bytes will copy and return a non-nil 2d byte array, otherwise it returns nil.
|
|
func SafeCopy2d32Bytes(ary [][32]byte) [][32]byte {
|
|
if ary != nil {
|
|
copied := make([][32]byte, len(ary))
|
|
copy(copied, ary)
|
|
return copied
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ReverseBytes32Slice will reverse the provided slice's order.
|
|
func ReverseBytes32Slice(arr [][32]byte) [][32]byte {
|
|
for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {
|
|
arr[i], arr[j] = arr[j], arr[i]
|
|
}
|
|
return arr
|
|
}
|
|
|
|
// PadTo pads a byte slice to the given size. If the byte slice is larger than the given size, the
|
|
// original slice is returned.
|
|
func PadTo(b []byte, size int) []byte {
|
|
if len(b) > size {
|
|
return b
|
|
}
|
|
return append(b, make([]byte, size-len(b))...)
|
|
}
|
|
|
|
// SetBit sets the index `i` of bitlist `b` to 1.
|
|
// It grows and returns a longer bitlist with 1 set
|
|
// if index `i` is out of range.
|
|
func SetBit(b []byte, i int) []byte {
|
|
if i >= len(b)*8 {
|
|
h := (i + (8 - i%8)) / 8
|
|
b = append(b, make([]byte, h-len(b))...)
|
|
}
|
|
|
|
bit := uint8(1 << (i % 8))
|
|
b[i/8] |= bit
|
|
return b
|
|
}
|
|
|
|
// ClearBit clears the index `i` of bitlist `b`.
|
|
// Returns the original bitlist if the index `i`
|
|
// is out of range.
|
|
func ClearBit(b []byte, i int) []byte {
|
|
if i >= len(b)*8 || i < 0 {
|
|
return b
|
|
}
|
|
|
|
bit := uint8(1 << (i % 8))
|
|
b[i/8] &^= bit
|
|
return b
|
|
}
|
|
|
|
// MakeEmptyBitlists returns an empty bitlist with
|
|
// input size `i`.
|
|
func MakeEmptyBitlists(i int) []byte {
|
|
return make([]byte, (i+(8-i%8))/8)
|
|
}
|
|
|
|
// HighestBitIndex returns the index of the highest
|
|
// bit set from bitlist `b`.
|
|
func HighestBitIndex(b []byte) (int, error) {
|
|
if len(b) == 0 {
|
|
return 0, errors.New("input list can't be empty or nil")
|
|
}
|
|
|
|
for i := len(b) - 1; i >= 0; i-- {
|
|
if b[i] == 0 {
|
|
continue
|
|
}
|
|
return bits.Len8(b[i]) + (i * 8), nil
|
|
}
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
// HighestBitIndexAt returns the index of the highest
|
|
// bit set from bitlist `b` that is at `index` (inclusive).
|
|
func HighestBitIndexAt(b []byte, index int) (int, error) {
|
|
bLength := len(b)
|
|
if b == nil || bLength == 0 {
|
|
return 0, errors.New("input list can't be empty or nil")
|
|
}
|
|
if index < 0 {
|
|
return 0, errors.Errorf("index is negative: %d", index)
|
|
}
|
|
|
|
start := index / 8
|
|
if start >= bLength {
|
|
start = bLength - 1
|
|
}
|
|
|
|
mask := byte(1<<(index%8) - 1)
|
|
for i := start; i >= 0; i-- {
|
|
if index/8 > i {
|
|
mask = 0xff
|
|
}
|
|
masked := b[i] & mask
|
|
minBitsMasked := bits.Len8(masked)
|
|
if b[i] == 0 || (minBitsMasked == 0 && index/8 <= i) {
|
|
continue
|
|
}
|
|
|
|
return minBitsMasked + (i * 8), nil
|
|
}
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
// Uint64ToBytesLittleEndian conversion.
|
|
func Uint64ToBytesLittleEndian(i uint64) []byte {
|
|
buf := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(buf, i)
|
|
return buf
|
|
}
|
|
|
|
// Uint64ToBytesBigEndian conversion.
|
|
func Uint64ToBytesBigEndian(i uint64) []byte {
|
|
buf := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(buf, i)
|
|
return buf
|
|
}
|
|
|
|
// BytesToUint64BigEndian conversion. Returns 0 if empty bytes or byte slice with length less
|
|
// than 8.
|
|
func BytesToUint64BigEndian(b []byte) uint64 {
|
|
if len(b) < 8 { // This will panic otherwise.
|
|
return 0
|
|
}
|
|
return binary.BigEndian.Uint64(b)
|
|
}
|
|
|
|
// EpochToBytesLittleEndian conversion.
|
|
func EpochToBytesLittleEndian(i types.Epoch) []byte {
|
|
return Uint64ToBytesLittleEndian(uint64(i))
|
|
}
|
|
|
|
// EpochToBytesBigEndian conversion.
|
|
func EpochToBytesBigEndian(i types.Epoch) []byte {
|
|
return Uint64ToBytesBigEndian(uint64(i))
|
|
}
|
|
|
|
// BytesToEpochBigEndian conversion.
|
|
func BytesToEpochBigEndian(b []byte) types.Epoch {
|
|
return types.Epoch(BytesToUint64BigEndian(b))
|
|
}
|
|
|
|
// SlotToBytesBigEndian conversion.
|
|
func SlotToBytesBigEndian(i types.Slot) []byte {
|
|
return Uint64ToBytesBigEndian(uint64(i))
|
|
}
|
|
|
|
// BytesToSlotBigEndian conversion.
|
|
func BytesToSlotBigEndian(b []byte) types.Slot {
|
|
return types.Slot(BytesToUint64BigEndian(b))
|
|
}
|
|
|
|
// IsHex checks whether the byte array is a hex number prefixed with '0x'.
|
|
func IsHex(b []byte) bool {
|
|
if b == nil {
|
|
return false
|
|
}
|
|
return hexRegex.Match(b)
|
|
}
|
|
|
|
// ReverseByteOrder Switch the endianness of a byte slice by reversing its order.
|
|
// this function does not modify the actual input bytes.
|
|
func ReverseByteOrder(input []byte) []byte {
|
|
b := make([]byte, len(input))
|
|
copy(b, input)
|
|
for i := 0; i < len(b)/2; i++ {
|
|
b[i], b[len(b)-i-1] = b[len(b)-i-1], b[i]
|
|
}
|
|
return b
|
|
}
|
|
|
|
// NonZeroRoot returns whether or not a root is of proper length and non-zero hash.
|
|
func NonZeroRoot(root []byte) bool {
|
|
return len(root) == fieldparams.RootLength && string(make([]byte, fieldparams.RootLength)) != string(root)
|
|
}
|