mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 22:07:59 -05:00
Compare commits
9 Commits
rm-client-
...
constraint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d64197b33d | ||
|
|
0cc87d5d2c | ||
|
|
df4dde5104 | ||
|
|
420e2c6208 | ||
|
|
1dec9eb912 | ||
|
|
ec955a14ee | ||
|
|
a2951ec37d | ||
|
|
216fdb48cf | ||
|
|
61c5e2a443 |
@@ -118,7 +118,7 @@ func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlo
|
||||
}
|
||||
isValidPayload, err := s.notifyNewPayload(ctx, postStateVersion, postStateHeader, signed)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not verify new payload")
|
||||
return fmt.Errorf("could not verify new payload: %v", err)
|
||||
}
|
||||
if isValidPayload {
|
||||
if err := s.validateMergeTransitionBlock(ctx, preStateVersion, preStateHeader, signed); err != nil {
|
||||
|
||||
@@ -129,6 +129,25 @@ func configureInteropConfig(cliCtx *cli.Context) error {
|
||||
}
|
||||
|
||||
func configureExecutionSetting(cliCtx *cli.Context) error {
|
||||
if cliCtx.IsSet(flags.TerminalTotalDifficultyOverride.Name) {
|
||||
c := params.BeaconConfig()
|
||||
c.TerminalTotalDifficulty = cliCtx.String(flags.TerminalTotalDifficultyOverride.Name)
|
||||
log.WithField("terminal block difficult", c.TerminalTotalDifficulty).Warn("Terminal block difficult overridden")
|
||||
params.OverrideBeaconConfig(c)
|
||||
}
|
||||
if cliCtx.IsSet(flags.TerminalBlockHashOverride.Name) {
|
||||
c := params.BeaconConfig()
|
||||
c.TerminalBlockHash = common.HexToHash(cliCtx.String(flags.TerminalBlockHashOverride.Name))
|
||||
log.WithField("terminal block hash", c.TerminalBlockHash.Hex()).Warn("Terminal block hash overridden")
|
||||
params.OverrideBeaconConfig(c)
|
||||
}
|
||||
if cliCtx.IsSet(flags.TerminalBlockHashActivationEpochOverride.Name) {
|
||||
c := params.BeaconConfig()
|
||||
c.TerminalBlockHashActivationEpoch = types.Epoch(cliCtx.Uint64(flags.TerminalBlockHashActivationEpochOverride.Name))
|
||||
log.WithField("terminal block hash activation epoch", c.TerminalBlockHashActivationEpoch).Warn("Terminal block hash activation epoch overridden")
|
||||
params.OverrideBeaconConfig(c)
|
||||
}
|
||||
|
||||
if !cliCtx.IsSet(flags.SuggestedFeeRecipient.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -92,6 +92,13 @@ func TestConfigureExecutionSetting(t *testing.T) {
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String(flags.SuggestedFeeRecipient.Name, "", "")
|
||||
set.Uint64(flags.TerminalTotalDifficultyOverride.Name, 0, "")
|
||||
set.String(flags.TerminalBlockHashOverride.Name, "", "")
|
||||
set.Uint64(flags.TerminalBlockHashActivationEpochOverride.Name, 0, "")
|
||||
|
||||
require.NoError(t, set.Set(flags.TerminalTotalDifficultyOverride.Name, strconv.Itoa(100)))
|
||||
require.NoError(t, set.Set(flags.TerminalBlockHashOverride.Name, "0xA"))
|
||||
require.NoError(t, set.Set(flags.TerminalBlockHashActivationEpochOverride.Name, strconv.Itoa(200)))
|
||||
require.NoError(t, set.Set(flags.SuggestedFeeRecipient.Name, "0xB"))
|
||||
cliCtx := cli.NewContext(&app, set, nil)
|
||||
err := configureExecutionSetting(cliCtx)
|
||||
@@ -112,6 +119,10 @@ func TestConfigureExecutionSetting(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, common.HexToAddress("0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa"), params.BeaconConfig().DefaultFeeRecipient)
|
||||
|
||||
assert.Equal(t, "100", params.BeaconConfig().TerminalTotalDifficulty)
|
||||
assert.Equal(t, common.HexToHash("0xA"), params.BeaconConfig().TerminalBlockHash)
|
||||
assert.Equal(t, types.Epoch(200), params.BeaconConfig().TerminalBlockHashActivationEpoch)
|
||||
|
||||
}
|
||||
|
||||
func TestConfigureNetwork(t *testing.T) {
|
||||
|
||||
@@ -296,7 +296,7 @@ func handleRPCError(err error) error {
|
||||
return nil
|
||||
}
|
||||
if isTimeout(err) {
|
||||
return errors.Wrapf(ErrHTTPTimeout, "%s", err)
|
||||
return ErrHTTPTimeout
|
||||
}
|
||||
e, ok := err.(rpc.Error)
|
||||
if !ok {
|
||||
@@ -307,7 +307,7 @@ func handleRPCError(err error) error {
|
||||
"here https://docs.prylabs.network/docs/execution-node/authentication")
|
||||
return fmt.Errorf("could not authenticate connection to execution client: %v", err)
|
||||
}
|
||||
return errors.Wrap(err, "got an unexpected error")
|
||||
return fmt.Errorf("got an unexpected error in JSON-RPC response: %v", err)
|
||||
}
|
||||
switch e.ErrorCode() {
|
||||
case -32700:
|
||||
@@ -330,7 +330,7 @@ func handleRPCError(err error) error {
|
||||
// Only -32000 status codes are data errors in the RPC specification.
|
||||
errWithData, ok := err.(rpc.DataError)
|
||||
if !ok {
|
||||
return errors.Wrap(err, "got an unexpected error")
|
||||
return fmt.Errorf("got an unexpected error in JSON-RPC response: %v", err)
|
||||
}
|
||||
return errors.Wrapf(ErrServer, "%v", errWithData.ErrorData())
|
||||
default:
|
||||
|
||||
@@ -211,4 +211,25 @@ var (
|
||||
Usage: "Post bellatrix, this address will receive the transaction fees produced by any blocks from this node. Default to junk whilst bellatrix is in development state. Validator client can override this value through the preparebeaconproposer api.",
|
||||
Value: fieldparams.EthBurnAddressHex,
|
||||
}
|
||||
// TerminalTotalDifficultyOverride specifies the total difficulty to manual overrides the `TERMINAL_TOTAL_DIFFICULTY` parameter.
|
||||
TerminalTotalDifficultyOverride = &cli.StringFlag{
|
||||
Name: "terminal-total-difficulty-override",
|
||||
Usage: "Sets the total difficulty to manual overrides the default TERMINAL_TOTAL_DIFFICULTY value. " +
|
||||
"WARNING: This flag should be used only if you have a clear understanding that community has decided to override the terminal difficulty. " +
|
||||
"Incorrect usage will result in your node experience consensus failure.",
|
||||
}
|
||||
// TerminalBlockHashOverride specifies the terminal block hash to manual overrides the `TERMINAL_BLOCK_HASH` parameter.
|
||||
TerminalBlockHashOverride = &cli.StringFlag{
|
||||
Name: "terminal-block-hash-override",
|
||||
Usage: "Sets the block hash to manual overrides the default TERMINAL_BLOCK_HASH value. " +
|
||||
"WARNING: This flag should be used only if you have a clear understanding that community has decided to override the terminal block hash. " +
|
||||
"Incorrect usage will result in your node experience consensus failure.",
|
||||
}
|
||||
// TerminalBlockHashActivationEpochOverride specifies the terminal block hash epoch to manual overrides the `TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH` parameter.
|
||||
TerminalBlockHashActivationEpochOverride = &cli.Uint64Flag{
|
||||
Name: "terminal-block-hash-epoch-override",
|
||||
Usage: "Sets the block hash epoch to manual overrides the default TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH value. " +
|
||||
"WARNING: This flag should be used only if you have a clear understanding that community has decided to override the terminal block hash activation epoch. " +
|
||||
"Incorrect usage will result in your node experience consensus failure.",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -69,6 +69,9 @@ var appFlags = []cli.Flag{
|
||||
flags.Eth1HeaderReqLimit,
|
||||
flags.MinPeersPerSubnet,
|
||||
flags.SuggestedFeeRecipient,
|
||||
flags.TerminalTotalDifficultyOverride,
|
||||
flags.TerminalBlockHashOverride,
|
||||
flags.TerminalBlockHashActivationEpochOverride,
|
||||
cmd.EnableBackupWebhookFlag,
|
||||
cmd.BackupWebhookOutputDir,
|
||||
cmd.MinimalConfigFlag,
|
||||
|
||||
@@ -137,6 +137,9 @@ var appHelpFlagGroups = []flagGroup{
|
||||
Name: "merge",
|
||||
Flags: []cli.Flag{
|
||||
flags.SuggestedFeeRecipient,
|
||||
flags.TerminalTotalDifficultyOverride,
|
||||
flags.TerminalBlockHashOverride,
|
||||
flags.TerminalBlockHashActivationEpochOverride,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ func RopstenConfig() *BeaconChainConfig {
|
||||
cfg.AltairForkVersion = []byte{0x80, 0x00, 0x00, 0x70}
|
||||
cfg.BellatrixForkEpoch = 750
|
||||
cfg.BellatrixForkVersion = []byte{0x80, 0x00, 0x00, 0x71}
|
||||
cfg.TerminalTotalDifficulty = "43531756765713534"
|
||||
cfg.TerminalTotalDifficulty = "100000000000000000000000"
|
||||
cfg.DepositContractAddress = "0x6f22fFbC56eFF051aECF839396DD1eD9aD6BBA9D"
|
||||
cfg.InitializeForkSchedule()
|
||||
return cfg
|
||||
|
||||
8
container/constraints/BUILD.bazel
Normal file
8
container/constraints/BUILD.bazel
Normal file
@@ -0,0 +1,8 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["constraints.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/container/constraints",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
46
container/constraints/constraints.go
Normal file
46
container/constraints/constraints.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Package constraints defines a set of useful constraints to be used
|
||||
// with type parameters.
|
||||
package constraints
|
||||
|
||||
// Signed is a constraint that permits any signed integer type.
|
||||
// If future releases of Go add new predeclared signed integer types,
|
||||
// this constraint will be modified to include them.
|
||||
type Signed interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64
|
||||
}
|
||||
|
||||
// Unsigned is a constraint that permits any unsigned integer type.
|
||||
// If future releases of Go add new predeclared unsigned integer types,
|
||||
// this constraint will be modified to include them.
|
||||
type Unsigned interface {
|
||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
|
||||
}
|
||||
|
||||
// Integer is a constraint that permits any integer type.
|
||||
// If future releases of Go add new predeclared integer types,
|
||||
// this constraint will be modified to include them.
|
||||
type Integer interface {
|
||||
Signed | Unsigned
|
||||
}
|
||||
|
||||
// Float is a constraint that permits any floating-point type.
|
||||
// If future releases of Go add new predeclared floating-point types,
|
||||
// this constraint will be modified to include them.
|
||||
type Float interface {
|
||||
~float32 | ~float64
|
||||
}
|
||||
|
||||
// Complex is a constraint that permits any complex numeric type.
|
||||
// If future releases of Go add new predeclared complex numeric types,
|
||||
// this constraint will be modified to include them.
|
||||
type Complex interface {
|
||||
~complex64 | ~complex128
|
||||
}
|
||||
|
||||
// Ordered is a constraint that permits any ordered type: any type
|
||||
// that supports the operators < <= >= >.
|
||||
// If future releases of Go add new ordered types,
|
||||
// this constraint will be modified to include them.
|
||||
type Ordered interface {
|
||||
Integer | Float | ~string
|
||||
}
|
||||
@@ -8,7 +8,10 @@ go_library(
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/container/slice",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//consensus-types/primitives:go_default_library"],
|
||||
deps = [
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/constraints:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
@@ -18,5 +21,6 @@ go_test(
|
||||
deps = [
|
||||
":go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/rand:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,8 +4,150 @@ import (
|
||||
"strings"
|
||||
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/container/constraints"
|
||||
)
|
||||
|
||||
// Subset returns true if the first slice is
|
||||
// completely contained in the second slice with time
|
||||
// complexity of approximately o(n).
|
||||
func Subset[T constraints.Ordered](a, b []T) bool {
|
||||
if len(a) > len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
set := make(map[T]uint64, len(b))
|
||||
for _, v := range b {
|
||||
set[v]++
|
||||
}
|
||||
|
||||
for _, v := range a {
|
||||
if count, found := set[v]; !found {
|
||||
return false
|
||||
} else if count < 1 {
|
||||
return false
|
||||
} else {
|
||||
set[v] = count - 1
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Intersection of any number of slices with time
|
||||
// complexity of approximately O(n) leveraging a map to
|
||||
// check for element existence off by a constant factor
|
||||
// of underlying map efficiency.
|
||||
func Intersection[T constraints.Ordered](s ...[]T) []T {
|
||||
if len(s) == 0 {
|
||||
return []T{}
|
||||
}
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
}
|
||||
intersect := make([]T, 0)
|
||||
m := make(map[T]int)
|
||||
for _, k := range s[0] {
|
||||
m[k] = 1
|
||||
}
|
||||
for i, num := 1, len(s); i < num; i++ {
|
||||
for _, k := range s[i] {
|
||||
// Increment and check only if item is present in both, and no increment has happened yet.
|
||||
if _, found := m[k]; found && i == m[k] {
|
||||
m[k]++
|
||||
if m[k] == num {
|
||||
intersect = append(intersect, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return intersect
|
||||
}
|
||||
|
||||
// Union of any number of uint64 slices with time
|
||||
// complexity of approximately O(n) leveraging a map to
|
||||
// check for element existence off by a constant factor
|
||||
// of underlying map efficiency.
|
||||
func Union[T constraints.Ordered](s ...[]T) []T {
|
||||
if len(s) == 0 {
|
||||
return []T{}
|
||||
}
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
}
|
||||
set := s[0]
|
||||
m := make(map[T]bool)
|
||||
for i := 1; i < len(s); i++ {
|
||||
a := s[i-1]
|
||||
b := s[i]
|
||||
for j := 0; j < len(a); j++ {
|
||||
m[a[j]] = true
|
||||
}
|
||||
for j := 0; j < len(b); j++ {
|
||||
if _, found := m[b[j]]; !found {
|
||||
set = append(set, b[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// Uniq returns a slice with only unique
|
||||
// values from the provided list of indices.
|
||||
func Uniq[T constraints.Ordered](a []T) []T {
|
||||
// Remove duplicates indices.
|
||||
intMap := map[T]bool{}
|
||||
cleanedIndices := make([]T, 0, len(a))
|
||||
for _, idx := range a {
|
||||
if intMap[idx] {
|
||||
continue
|
||||
}
|
||||
intMap[idx] = true
|
||||
cleanedIndices = append(cleanedIndices, idx)
|
||||
}
|
||||
return cleanedIndices
|
||||
}
|
||||
|
||||
// IsSorted verifies if a slice is sorted in ascending order.
|
||||
func IsSorted[T constraints.Ordered](a []T) bool {
|
||||
if len(a) == 0 || len(a) == 1 {
|
||||
return true
|
||||
}
|
||||
for i := 1; i < len(a); i++ {
|
||||
if a[i-1] > a[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NotIn returns the items in slice b that are
|
||||
// not in slice a with time complexity of approximately
|
||||
// O(n) leveraging a map to check for element existence
|
||||
// off by a constant factor of underlying map efficiency.
|
||||
func NotIn[T constraints.Ordered](a, b []T) []T {
|
||||
set := make([]T, 0)
|
||||
m := make(map[T]bool)
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
m[a[i]] = true
|
||||
}
|
||||
for i := 0; i < len(b); i++ {
|
||||
if _, found := m[b[i]]; !found {
|
||||
set = append(set, b[i])
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// IsIn returns true if a is in b and False otherwise.
|
||||
func IsIn[T constraints.Ordered](a T, b []T) bool {
|
||||
for _, v := range b {
|
||||
if a == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SubsetUint64 returns true if the first array is
|
||||
// completely contained in the second array with time
|
||||
// complexity of approximately o(n).
|
||||
|
||||
@@ -7,9 +7,10 @@ import (
|
||||
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/container/slice"
|
||||
"github.com/prysmaticlabs/prysm/crypto/rand"
|
||||
)
|
||||
|
||||
func TestSubsetUint64(t *testing.T) {
|
||||
func TestSubset(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
setB []uint64
|
||||
@@ -30,7 +31,28 @@ func TestSubsetUint64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntersectionUint64(t *testing.T) {
|
||||
func TestSubset_Generic(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
setB []uint64
|
||||
out bool
|
||||
}{
|
||||
{[]uint64{1}, []uint64{1, 2, 3, 4}, true},
|
||||
{[]uint64{1, 2, 3, 4}, []uint64{1, 2, 3, 4}, true},
|
||||
{[]uint64{1, 1}, []uint64{1, 2, 3, 4}, false},
|
||||
{[]uint64{}, []uint64{1}, true},
|
||||
{[]uint64{1}, []uint64{}, false},
|
||||
{[]uint64{1, 2, 3, 4, 5}, []uint64{1, 2, 3, 4}, false},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := slice.Subset[uint64](tt.setA, tt.setB)
|
||||
if result != tt.out {
|
||||
t.Errorf("%v, got %v, want %v", tt.setA, result, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntersection(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
setB []uint64
|
||||
@@ -76,7 +98,53 @@ func TestIntersectionUint64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSortedUint64(t *testing.T) {
|
||||
func TestIntersection_Generic(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
setB []uint64
|
||||
setC []uint64
|
||||
out []uint64
|
||||
}{
|
||||
{[]uint64{2, 3, 5}, []uint64{3}, []uint64{3}, []uint64{3}},
|
||||
{[]uint64{2, 3, 5}, []uint64{3, 5}, []uint64{5}, []uint64{5}},
|
||||
{[]uint64{2, 3, 5}, []uint64{3, 5}, []uint64{3, 5}, []uint64{3, 5}},
|
||||
{[]uint64{2, 3, 5}, []uint64{5, 3, 2}, []uint64{3, 2, 5}, []uint64{2, 3, 5}},
|
||||
{[]uint64{3, 2, 5}, []uint64{5, 3, 2}, []uint64{3, 2, 5}, []uint64{2, 3, 5}},
|
||||
{[]uint64{3, 3, 5}, []uint64{5, 3, 2}, []uint64{3, 2, 5}, []uint64{3, 5}},
|
||||
{[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{2, 3, 5}},
|
||||
{[]uint64{2, 3, 5}, []uint64{}, []uint64{}, []uint64{}},
|
||||
{[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{}, []uint64{}},
|
||||
{[]uint64{2, 3}, []uint64{2, 3, 5}, []uint64{5}, []uint64{}},
|
||||
{[]uint64{2, 2, 2}, []uint64{2, 2, 2}, []uint64{}, []uint64{}},
|
||||
{[]uint64{}, []uint64{2, 3, 5}, []uint64{}, []uint64{}},
|
||||
{[]uint64{}, []uint64{}, []uint64{}, []uint64{}},
|
||||
{[]uint64{1}, []uint64{1}, []uint64{}, []uint64{}},
|
||||
{[]uint64{1, 1, 1}, []uint64{1, 1}, []uint64{1, 2, 3}, []uint64{1}},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
setA := append([]uint64{}, tt.setA...)
|
||||
setB := append([]uint64{}, tt.setB...)
|
||||
setC := append([]uint64{}, tt.setC...)
|
||||
result := slice.Intersection[uint64](setA, setB, setC)
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i] < result[j]
|
||||
})
|
||||
if !reflect.DeepEqual(result, tt.out) {
|
||||
t.Errorf("got %d, want %d", result, tt.out)
|
||||
}
|
||||
if !reflect.DeepEqual(setA, tt.setA) {
|
||||
t.Errorf("slice modified, got %v, want %v", setA, tt.setA)
|
||||
}
|
||||
if !reflect.DeepEqual(setB, tt.setB) {
|
||||
t.Errorf("slice modified, got %v, want %v", setB, tt.setB)
|
||||
}
|
||||
if !reflect.DeepEqual(setC, tt.setC) {
|
||||
t.Errorf("slice modified, got %v, want %v", setC, tt.setC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSorted(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
out bool
|
||||
@@ -94,6 +162,24 @@ func TestIsSortedUint64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSorted_Generic(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
out bool
|
||||
}{
|
||||
{[]uint64{1, 2, 3}, true},
|
||||
{[]uint64{3, 1, 3}, false},
|
||||
{[]uint64{1}, true},
|
||||
{[]uint64{}, true},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := slice.IsSorted[uint64](tt.setA)
|
||||
if result != tt.out {
|
||||
t.Errorf("got %v, want %v", result, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntersectionInt64(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []int64
|
||||
@@ -205,6 +291,39 @@ func TestUnionInt64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnion_Generic(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
setB []uint64
|
||||
out []uint64
|
||||
}{
|
||||
{[]uint64{2, 3, 5}, []uint64{4, 6}, []uint64{2, 3, 5, 4, 6}},
|
||||
{[]uint64{2, 3, 5}, []uint64{3, 5}, []uint64{2, 3, 5}},
|
||||
{[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{2, 3, 5}},
|
||||
{[]uint64{2, 3, 5}, []uint64{}, []uint64{2, 3, 5}},
|
||||
{[]uint64{}, []uint64{2, 3, 5}, []uint64{2, 3, 5}},
|
||||
{[]uint64{}, []uint64{}, []uint64{}},
|
||||
{[]uint64{1}, []uint64{1}, []uint64{1}},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := slice.Union[uint64](tt.setA, tt.setB)
|
||||
if !reflect.DeepEqual(result, tt.out) {
|
||||
t.Errorf("got %d, want %d", result, tt.out)
|
||||
}
|
||||
|
||||
}
|
||||
items := [][]uint64{
|
||||
{3, 4, 5},
|
||||
{6, 7, 8},
|
||||
{9, 10, 11},
|
||||
}
|
||||
variadicResult := slice.Union[uint64](items...)
|
||||
want := []uint64{3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
if !reflect.DeepEqual(want, variadicResult) {
|
||||
t.Errorf("Received %v, wanted %v", variadicResult, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanUint64(t *testing.T) {
|
||||
testCases := []struct {
|
||||
in []uint64
|
||||
@@ -225,6 +344,26 @@ func TestCleanUint64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUniq_Generic(t *testing.T) {
|
||||
testCases := []struct {
|
||||
in []uint64
|
||||
out []uint64
|
||||
}{
|
||||
{[]uint64{2, 4, 4, 6, 6}, []uint64{2, 4, 6}},
|
||||
{[]uint64{3, 5, 5}, []uint64{3, 5}},
|
||||
{[]uint64{2, 2, 2}, []uint64{2}},
|
||||
{[]uint64{1, 4, 5, 9, 9}, []uint64{1, 4, 5, 9}},
|
||||
{[]uint64{}, []uint64{}},
|
||||
{[]uint64{1}, []uint64{1}},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := slice.Uniq[uint64](tt.in)
|
||||
if !reflect.DeepEqual(result, tt.out) {
|
||||
t.Errorf("got %d, want %d", result, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotUint64(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
@@ -247,6 +386,28 @@ func TestNotUint64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotIn_Generic(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []uint64
|
||||
setB []uint64
|
||||
out []uint64
|
||||
}{
|
||||
{[]uint64{4, 6}, []uint64{2, 3, 5, 4, 6}, []uint64{2, 3, 5}},
|
||||
{[]uint64{3, 5}, []uint64{2, 3, 5}, []uint64{2}},
|
||||
{[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{}},
|
||||
{[]uint64{2}, []uint64{2, 3, 5}, []uint64{3, 5}},
|
||||
{[]uint64{}, []uint64{2, 3, 5}, []uint64{2, 3, 5}},
|
||||
{[]uint64{}, []uint64{}, []uint64{}},
|
||||
{[]uint64{1}, []uint64{1}, []uint64{}},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := slice.NotIn[uint64](tt.setA, tt.setB)
|
||||
if !reflect.DeepEqual(result, tt.out) {
|
||||
t.Errorf("got %d, want %d", result, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotInt64(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA []int64
|
||||
@@ -309,6 +470,26 @@ func TestIsInInt64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsIn_Generic(t *testing.T) {
|
||||
testCases := []struct {
|
||||
a uint64
|
||||
b []uint64
|
||||
result bool
|
||||
}{
|
||||
{0, []uint64{}, false},
|
||||
{0, []uint64{0}, true},
|
||||
{4, []uint64{2, 3, 5, 4, 6}, true},
|
||||
{100, []uint64{2, 3, 5, 4, 6}, false},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := slice.IsIn[uint64](tt.a, tt.b)
|
||||
if result != tt.result {
|
||||
t.Errorf("IsIn(%d, %v)=%v, wanted: %v",
|
||||
tt.a, tt.b, result, tt.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnionByteSlices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
setA [][]byte
|
||||
@@ -587,3 +768,81 @@ func TestIsInSlots(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIntersection_Specific(b *testing.B) {
|
||||
b.StopTimer()
|
||||
sets := setupSlices()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
slice.IntersectionUint64(sets...)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIntersection_Generic(b *testing.B) {
|
||||
b.StopTimer()
|
||||
sets := setupSlices()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
slice.Intersection[uint64](sets...)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnion_Specific(b *testing.B) {
|
||||
b.StopTimer()
|
||||
sets := setupSlices()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
slice.UnionUint64(sets...)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnion_Generic(b *testing.B) {
|
||||
b.StopTimer()
|
||||
sets := setupSlices()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
slice.Union[uint64](sets...)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUniq_Specific(b *testing.B) {
|
||||
b.StopTimer()
|
||||
input := make([]uint64, 0, 1000)
|
||||
gen := rand.NewGenerator()
|
||||
for i := 0; i < 1000; i++ {
|
||||
n := gen.Uint64()
|
||||
input = append(input, n, n)
|
||||
}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
slice.SetUint64(input)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUniq_Generic(b *testing.B) {
|
||||
b.StopTimer()
|
||||
input := make([]uint64, 0, 1000)
|
||||
gen := rand.NewGenerator()
|
||||
for i := 0; i < 1000; i++ {
|
||||
n := gen.Uint64()
|
||||
input = append(input, n, n)
|
||||
}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
slice.Uniq[uint64](input)
|
||||
}
|
||||
}
|
||||
|
||||
func setupSlices() [][]uint64 {
|
||||
sets := make([][]uint64, 1000)
|
||||
gen := rand.NewGenerator()
|
||||
for i := 0; i < len(sets); i++ {
|
||||
setSize := gen.Intn(100)
|
||||
set := make([]uint64, setSize)
|
||||
for j := 0; j < setSize; j++ {
|
||||
set[j] = uint64(j)
|
||||
}
|
||||
sets[i] = set
|
||||
}
|
||||
return sets
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ func web3SignerConfig(cliCtx *cli.Context) (*remote_web3signer.SetupConfig, erro
|
||||
func feeRecipientConfig(cliCtx *cli.Context) (*validatorServiceConfig.FeeRecipientConfig, error) {
|
||||
var fileConfig *validatorServiceConfig.FeeRecipientFileConfig
|
||||
if cliCtx.IsSet(flags.FeeRecipientConfigFileFlag.Name) && cliCtx.IsSet(flags.FeeRecipientConfigURLFlag.Name) {
|
||||
return nil, errors.New("cannot specify both --validators-proposer-fileConfig-dir and --validators-proposer-fileConfig-url")
|
||||
return nil, fmt.Errorf("cannot specify both --%s and --%s", flags.FeeRecipientConfigFileFlag.Name, flags.FeeRecipientConfigURLFlag.Name)
|
||||
}
|
||||
if cliCtx.IsSet(flags.FeeRecipientConfigFileFlag.Name) {
|
||||
if err := unmarshalFromFile(cliCtx.Context, cliCtx.String(flags.FeeRecipientConfigFileFlag.Name), &fileConfig); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user