mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-03 16:37:39 +00:00
5aac06f04e
* begin move * use same import path * imports * regen protos * regen * no rename * generate ssz * gaz * fmt * edit build file * imports * modify * remove generated files * remove protos * edit imports in prysm * beacon chain all builds * edit script * add generated pbs * add replace rules * license for ethereumapis protos * change visibility * fmt * update build files to gaz ignore * use proper form * edit imports * wrap block * revert scripts * revert go mod
431 lines
18 KiB
Go
431 lines
18 KiB
Go
package validator
|
|
|
|
import (
|
|
"bytes"
|
|
"sort"
|
|
"testing"
|
|
|
|
types "github.com/prysmaticlabs/eth2-types"
|
|
"github.com/prysmaticlabs/go-bitfield"
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
|
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
|
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
|
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
|
)
|
|
|
|
func TestProposer_ProposerAtts_sortByProfitability(t *testing.T) {
|
|
atts := proposerAtts([]*ethpb.Attestation{
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 4}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b11000000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 4}, AggregationBits: bitfield.Bitlist{0b11110000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b11000000}}),
|
|
})
|
|
want := proposerAtts([]*ethpb.Attestation{
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 4}, AggregationBits: bitfield.Bitlist{0b11110000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 4}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b11000000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
|
testutil.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b11000000}}),
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
}
|
|
|
|
func TestProposer_ProposerAtts_sortByProfitabilityUsingMaxCover(t *testing.T) {
|
|
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{
|
|
ProposerAttsSelectionUsingMaxCover: true,
|
|
})
|
|
defer resetCfg()
|
|
|
|
type testData struct {
|
|
slot types.Slot
|
|
bits bitfield.Bitlist
|
|
}
|
|
getAtts := func(data []testData) proposerAtts {
|
|
var atts proposerAtts
|
|
for _, att := range data {
|
|
atts = append(atts, testutil.HydrateAttestation(ðpb.Attestation{
|
|
Data: ðpb.AttestationData{Slot: att.slot}, AggregationBits: att.bits}))
|
|
}
|
|
return atts
|
|
}
|
|
|
|
t.Run("no atts", func(t *testing.T) {
|
|
atts := getAtts([]testData{})
|
|
want := getAtts([]testData{})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
|
|
t.Run("single att", func(t *testing.T) {
|
|
atts := getAtts([]testData{
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
})
|
|
want := getAtts([]testData{
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
|
|
t.Run("single att per slot", func(t *testing.T) {
|
|
atts := getAtts([]testData{
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
})
|
|
want := getAtts([]testData{
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
|
|
t.Run("two atts on one of the slots", func(t *testing.T) {
|
|
atts := getAtts([]testData{
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{4, bitfield.Bitlist{0b11110000, 0b1}},
|
|
})
|
|
want := getAtts([]testData{
|
|
{4, bitfield.Bitlist{0b11110000, 0b1}},
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
|
|
t.Run("compare to native sort", func(t *testing.T) {
|
|
// The naive sort will end up with 0b11001000 being selected second (which is not optimal
|
|
// as it only contains a single unknown bit).
|
|
// The max-cover based approach will select 0b00001100 instead, despite lower bit count
|
|
// (since it has two new/unknown bits).
|
|
t.Run("naive", func(t *testing.T) {
|
|
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{
|
|
ProposerAttsSelectionUsingMaxCover: false,
|
|
})
|
|
defer resetCfg()
|
|
|
|
atts := getAtts([]testData{
|
|
{1, bitfield.Bitlist{0b11000011, 0b1}},
|
|
{1, bitfield.Bitlist{0b11001000, 0b1}},
|
|
{1, bitfield.Bitlist{0b00001100, 0b1}},
|
|
})
|
|
want := getAtts([]testData{
|
|
{1, bitfield.Bitlist{0b11000011, 0b1}},
|
|
{1, bitfield.Bitlist{0b11001000, 0b1}},
|
|
{1, bitfield.Bitlist{0b00001100, 0b1}},
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
t.Run("max-cover", func(t *testing.T) {
|
|
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{
|
|
ProposerAttsSelectionUsingMaxCover: true,
|
|
})
|
|
defer resetCfg()
|
|
|
|
atts := getAtts([]testData{
|
|
{1, bitfield.Bitlist{0b11000011, 0b1}},
|
|
{1, bitfield.Bitlist{0b11001000, 0b1}},
|
|
{1, bitfield.Bitlist{0b00001100, 0b1}},
|
|
})
|
|
want := getAtts([]testData{
|
|
{1, bitfield.Bitlist{0b11000011, 0b1}},
|
|
{1, bitfield.Bitlist{0b00001100, 0b1}},
|
|
{1, bitfield.Bitlist{0b11001000, 0b1}},
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
})
|
|
|
|
t.Run("multiple slots", func(t *testing.T) {
|
|
atts := getAtts([]testData{
|
|
{2, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
{4, bitfield.Bitlist{0b11110000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{3, bitfield.Bitlist{0b11000000, 0b1}},
|
|
})
|
|
want := getAtts([]testData{
|
|
{4, bitfield.Bitlist{0b11110000, 0b1}},
|
|
{4, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{3, bitfield.Bitlist{0b11000000, 0b1}},
|
|
{2, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
|
|
t.Run("selected and non selected atts sorted by bit count", func(t *testing.T) {
|
|
// Items at slot 4, must be first split into two lists by max-cover, with
|
|
// 0b10000011 scoring higher (as it provides more info in addition to already selected
|
|
// attestations) than 0b11100001 (despite naive bit count suggesting otherwise). Then,
|
|
// both selected and non-selected attestations must be additionally sorted by bit count.
|
|
atts := getAtts([]testData{
|
|
{4, bitfield.Bitlist{0b00000001, 0b1}},
|
|
{4, bitfield.Bitlist{0b11100001, 0b1}},
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
{2, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{4, bitfield.Bitlist{0b10000011, 0b1}},
|
|
{4, bitfield.Bitlist{0b11111000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{3, bitfield.Bitlist{0b11000000, 0b1}},
|
|
})
|
|
want := getAtts([]testData{
|
|
{4, bitfield.Bitlist{0b11111000, 0b1}},
|
|
{4, bitfield.Bitlist{0b10000011, 0b1}},
|
|
{4, bitfield.Bitlist{0b11100001, 0b1}},
|
|
{4, bitfield.Bitlist{0b00000001, 0b1}},
|
|
{3, bitfield.Bitlist{0b11000000, 0b1}},
|
|
{2, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11100000, 0b1}},
|
|
{1, bitfield.Bitlist{0b11000000, 0b1}},
|
|
})
|
|
atts = atts.sortByProfitability()
|
|
require.DeepEqual(t, want, atts)
|
|
})
|
|
}
|
|
|
|
func TestProposer_ProposerAtts_dedup(t *testing.T) {
|
|
data1 := testutil.HydrateAttestationData(ðpb.AttestationData{
|
|
Slot: 4,
|
|
})
|
|
data2 := testutil.HydrateAttestationData(ðpb.AttestationData{
|
|
Slot: 5,
|
|
})
|
|
tests := []struct {
|
|
name string
|
|
atts proposerAtts
|
|
want proposerAtts
|
|
}{
|
|
{
|
|
name: "nil list",
|
|
atts: nil,
|
|
want: proposerAtts(nil),
|
|
},
|
|
{
|
|
name: "empty list",
|
|
atts: proposerAtts{},
|
|
want: proposerAtts{},
|
|
},
|
|
{
|
|
name: "single item",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{AggregationBits: bitfield.Bitlist{}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{AggregationBits: bitfield.Bitlist{}},
|
|
},
|
|
},
|
|
{
|
|
name: "two items no duplicates",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10111110, 0x01}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01111111, 0x01}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01111111, 0x01}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10111110, 0x01}},
|
|
},
|
|
},
|
|
{
|
|
name: "two items with duplicates",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0xba, 0x01}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0xba, 0x01}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0xba, 0x01}},
|
|
},
|
|
},
|
|
{
|
|
name: "sorted no duplicates",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00101011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10100000, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00010000, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00101011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10100000, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00010000, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "sorted with duplicates",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000001, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "all equal",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "unsorted no duplicates",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00100010, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10100101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00010000, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10100101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00100010, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00010000, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "unsorted with duplicates",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10100101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10100101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000001, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000001, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10100101, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "no proper subset (same root)",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10000001, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00011001, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00011001, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b10000001, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "proper subset (same root)",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000001, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000001, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "no proper subset (different root)",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000101, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b10000001, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b00011001, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b00011001, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b10000001, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000101, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "proper subset (different root 1)",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000001, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b00000011, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00000001, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b01101101, 0b1}},
|
|
},
|
|
},
|
|
{
|
|
name: "proper subset (different root 2)",
|
|
atts: proposerAtts{
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b00001111, 0b1}},
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
},
|
|
want: proposerAtts{
|
|
ðpb.Attestation{Data: data2, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
ðpb.Attestation{Data: data1, AggregationBits: bitfield.Bitlist{0b11001111, 0b1}},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
atts := tt.atts.dedup()
|
|
sort.Slice(atts, func(i, j int) bool {
|
|
if atts[i].AggregationBits.Count() == atts[j].AggregationBits.Count() {
|
|
if atts[i].Data.Slot == atts[j].Data.Slot {
|
|
return bytes.Compare(atts[i].AggregationBits, atts[j].AggregationBits) <= 0
|
|
}
|
|
return atts[i].Data.Slot > atts[j].Data.Slot
|
|
}
|
|
return atts[i].AggregationBits.Count() > atts[j].AggregationBits.Count()
|
|
})
|
|
assert.DeepEqual(t, tt.want, atts)
|
|
})
|
|
}
|
|
}
|