mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 11:32:09 +00:00
acc307b959
* add max/min span visualisation tool cli * go mod tidy * lint imports * remove typo * fix epoch table value * fix deepsource * add dep to bazel * fix dep import order * change command name from span to slasher-span-display * change command args style using - instead of _ * sed s/CONFIGURATION/SLASHER PARAMS// * change double neg to double pos condition * remove unused anonymous func * better function naming * add range condition * [deepsource] Fix Empty slice literal used to declare a variable GO-W1027 * correct typo * do not show incorrect epochs due to round robin * fix import --------- Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
541 lines
12 KiB
Go
541 lines
12 KiB
Go
package slasher
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
ssz "github.com/prysmaticlabs/fastssz"
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
|
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
|
)
|
|
|
|
func TestDefaultParams(t *testing.T) {
|
|
def := DefaultParams()
|
|
assert.Equal(t, true, def.chunkSize > 0)
|
|
assert.Equal(t, true, def.validatorChunkSize > 0)
|
|
assert.Equal(t, true, def.historyLength > 0)
|
|
}
|
|
|
|
func TestParams_cellIndex(t *testing.T) {
|
|
type args struct {
|
|
validatorIndex primitives.ValidatorIndex
|
|
epoch primitives.Epoch
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields *Parameters
|
|
args args
|
|
want uint64
|
|
}{
|
|
{
|
|
name: "epoch 0 and validator index 0",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
},
|
|
args: args{
|
|
validatorIndex: 0,
|
|
epoch: 0,
|
|
},
|
|
want: 0,
|
|
},
|
|
{
|
|
// val0 val1 val2
|
|
// | | |
|
|
// { } { } { }
|
|
// [2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
// |-> epoch 1, validator 2
|
|
name: "epoch < chunkSize and validatorIndex < validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
},
|
|
args: args{
|
|
validatorIndex: 2,
|
|
epoch: 1,
|
|
},
|
|
want: 7,
|
|
},
|
|
{
|
|
// val0 val1 val2
|
|
// | | |
|
|
// { } { } { }
|
|
// [2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
// |-> epoch 4, validator 2 (wrap around)
|
|
name: "epoch > chunkSize and validatorIndex < validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
},
|
|
args: args{
|
|
validatorIndex: 2,
|
|
epoch: 4,
|
|
},
|
|
want: 7,
|
|
},
|
|
{
|
|
// val0 val1 val2
|
|
// | | |
|
|
// { } { } { }
|
|
// [2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
// |-> epoch 3, validator 2 (wrap around)
|
|
name: "epoch = chunkSize and validatorIndex < validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
},
|
|
args: args{
|
|
validatorIndex: 2,
|
|
epoch: 3,
|
|
},
|
|
want: 6,
|
|
},
|
|
{
|
|
// val0 val1 val2
|
|
// | | |
|
|
// { } { } { }
|
|
// [2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
// |-> epoch 0, validator 3 (wrap around)
|
|
name: "epoch < chunkSize and validatorIndex = validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
},
|
|
args: args{
|
|
validatorIndex: 3,
|
|
epoch: 0,
|
|
},
|
|
want: 0,
|
|
},
|
|
{
|
|
// val0 val1 val2
|
|
// | | |
|
|
// { } { } { }
|
|
// [2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
// |-> epoch 0, validator 4 (wrap around)
|
|
name: "epoch < chunkSize and validatorIndex > validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
},
|
|
args: args{
|
|
validatorIndex: 4,
|
|
epoch: 0,
|
|
},
|
|
want: 3,
|
|
},
|
|
{
|
|
// val0 val1 val2
|
|
// | | |
|
|
// { } { } { }
|
|
// [2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
// |-> epoch 3, validator 3 (wrap around)
|
|
name: "epoch = chunkSize and validatorIndex = validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
},
|
|
args: args{
|
|
validatorIndex: 3,
|
|
epoch: 3,
|
|
},
|
|
want: 0,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &Parameters{
|
|
chunkSize: tt.fields.chunkSize,
|
|
validatorChunkSize: tt.fields.validatorChunkSize,
|
|
historyLength: tt.fields.historyLength,
|
|
}
|
|
if got := c.cellIndex(tt.args.validatorIndex, tt.args.epoch); got != tt.want {
|
|
t.Errorf("cellIndex() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParams_chunkIndex(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fields *Parameters
|
|
epoch primitives.Epoch
|
|
want uint64
|
|
}{
|
|
{
|
|
name: "epoch 0",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
historyLength: 3,
|
|
},
|
|
epoch: 0,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "epoch < historyLength, epoch < chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
historyLength: 3,
|
|
},
|
|
epoch: 2,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "epoch = historyLength, epoch < chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 4,
|
|
historyLength: 3,
|
|
},
|
|
epoch: 3,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "epoch > historyLength, epoch < chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 5,
|
|
historyLength: 3,
|
|
},
|
|
epoch: 4,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "epoch < historyLength, epoch < chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
historyLength: 3,
|
|
},
|
|
epoch: 2,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "epoch = historyLength, epoch < chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 4,
|
|
historyLength: 3,
|
|
},
|
|
epoch: 3,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "epoch < historyLength, epoch = chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 2,
|
|
historyLength: 3,
|
|
},
|
|
epoch: 2,
|
|
want: 1,
|
|
},
|
|
{
|
|
name: "epoch < historyLength, epoch > chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 2,
|
|
historyLength: 4,
|
|
},
|
|
epoch: 3,
|
|
want: 1,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &Parameters{
|
|
chunkSize: tt.fields.chunkSize,
|
|
historyLength: tt.fields.historyLength,
|
|
}
|
|
if got := c.chunkIndex(tt.epoch); got != tt.want {
|
|
t.Errorf("chunkIndex() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParams_flatSliceID(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fields *Parameters
|
|
validatorChunkIndex uint64
|
|
chunkIndex uint64
|
|
want uint64
|
|
}{
|
|
{
|
|
name: "Proper disk key for 0, 0",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
historyLength: 6,
|
|
},
|
|
chunkIndex: 0,
|
|
validatorChunkIndex: 0,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "Proper disk key for epoch < historyLength, validator < validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
historyLength: 6,
|
|
},
|
|
chunkIndex: 1,
|
|
validatorChunkIndex: 1,
|
|
want: 3,
|
|
},
|
|
{
|
|
name: "Proper disk key for epoch > historyLength, validator > validatorChunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
validatorChunkSize: 3,
|
|
historyLength: 6,
|
|
},
|
|
chunkIndex: 10,
|
|
validatorChunkIndex: 10,
|
|
want: 30,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &Parameters{
|
|
chunkSize: tt.fields.chunkSize,
|
|
validatorChunkSize: tt.fields.validatorChunkSize,
|
|
historyLength: tt.fields.historyLength,
|
|
}
|
|
got := c.flatSliceID(tt.validatorChunkIndex, tt.chunkIndex)
|
|
decoded := ssz.UnmarshallUint64(got)
|
|
if decoded != tt.want {
|
|
t.Errorf("diskKey() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParams_validatorChunkIndex(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fields *Parameters
|
|
validatorIndex primitives.ValidatorIndex
|
|
want uint64
|
|
}{
|
|
{
|
|
name: "validator index < validatorChunkSize",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 3,
|
|
},
|
|
validatorIndex: 2,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "validator index = validatorChunkSize",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 3,
|
|
},
|
|
validatorIndex: 3,
|
|
want: 1,
|
|
},
|
|
{
|
|
name: "validator index > validatorChunkSize",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 3,
|
|
},
|
|
validatorIndex: 99,
|
|
want: 33,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &Parameters{
|
|
validatorChunkSize: tt.fields.validatorChunkSize,
|
|
}
|
|
if got := c.validatorChunkIndex(tt.validatorIndex); got != tt.want {
|
|
t.Errorf("validatorChunkIndex() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParams_chunkOffset(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fields *Parameters
|
|
epoch primitives.Epoch
|
|
want uint64
|
|
}{
|
|
{
|
|
name: "epoch < chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
},
|
|
epoch: 2,
|
|
want: 2,
|
|
},
|
|
{
|
|
name: "epoch = chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
},
|
|
epoch: 3,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "epoch > chunkSize",
|
|
fields: &Parameters{
|
|
chunkSize: 3,
|
|
},
|
|
epoch: 5,
|
|
want: 2,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &Parameters{
|
|
chunkSize: tt.fields.chunkSize,
|
|
}
|
|
if got := c.chunkOffset(tt.epoch); got != tt.want {
|
|
t.Errorf("chunkOffset() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParams_validatorOffset(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fields *Parameters
|
|
validatorIndex primitives.ValidatorIndex
|
|
want uint64
|
|
}{
|
|
{
|
|
name: "validatorIndex < validatorChunkSize",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 3,
|
|
},
|
|
validatorIndex: 2,
|
|
want: 2,
|
|
},
|
|
{
|
|
name: "validatorIndex = validatorChunkSize",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 3,
|
|
},
|
|
validatorIndex: 3,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "validatorIndex > validatorChunkSize",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 3,
|
|
},
|
|
validatorIndex: 5,
|
|
want: 2,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &Parameters{
|
|
validatorChunkSize: tt.fields.validatorChunkSize,
|
|
}
|
|
if got := c.validatorOffset(tt.validatorIndex); got != tt.want {
|
|
t.Errorf("validatorOffset() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParams_validatorIndicesInChunk(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fields *Parameters
|
|
validatorChunkIdx uint64
|
|
want []primitives.ValidatorIndex
|
|
}{
|
|
{
|
|
name: "Returns proper indices",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 3,
|
|
},
|
|
validatorChunkIdx: 2,
|
|
want: []primitives.ValidatorIndex{6, 7, 8},
|
|
},
|
|
{
|
|
name: "0 validator chunk size returns empty",
|
|
fields: &Parameters{
|
|
validatorChunkSize: 0,
|
|
},
|
|
validatorChunkIdx: 100,
|
|
want: []primitives.ValidatorIndex{},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &Parameters{
|
|
validatorChunkSize: tt.fields.validatorChunkSize,
|
|
}
|
|
if got := c.ValidatorIndexesInChunk(tt.validatorChunkIdx); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("validatorIndicesInChunk() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParameters_firstEpoch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
params *Parameters
|
|
chunkIndex uint64
|
|
want primitives.Epoch
|
|
}{
|
|
{
|
|
name: "first epoch of chunk 0 is 0",
|
|
params: DefaultParams(),
|
|
chunkIndex: 0,
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "with chunk_size = 3, first epoch of chunk 1 is 3",
|
|
params: &Parameters{
|
|
chunkSize: 3,
|
|
},
|
|
chunkIndex: 1,
|
|
want: 3,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := tt.params.firstEpoch(tt.chunkIndex); got != tt.want {
|
|
t.Errorf("firstEpoch() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParameters_lastEpoch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
params *Parameters
|
|
chunkIndex uint64
|
|
want primitives.Epoch
|
|
}{
|
|
{
|
|
name: "with chunk_size = 3, last epoch of chunk 0 is 2",
|
|
params: &Parameters{
|
|
chunkSize: 3,
|
|
},
|
|
chunkIndex: 0,
|
|
want: 2,
|
|
},
|
|
{
|
|
name: "with chunk_size = 3, last epoch of chunk 1 is 5",
|
|
params: &Parameters{
|
|
chunkSize: 3,
|
|
},
|
|
chunkIndex: 1,
|
|
want: 5,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := tt.params.lastEpoch(tt.chunkIndex); got != tt.want {
|
|
t.Errorf("lastEpoch() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|