mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-23 03:51:29 +00:00
5a66807989
* First take at updating everything to v5 * Patch gRPC gateway to use prysm v5 Fix patch * Update go ssz --------- Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
209 lines
6.8 KiB
Go
209 lines
6.8 KiB
Go
package backfill
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
|
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
|
)
|
|
|
|
func TestBatcherBefore(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
b batcher
|
|
upTo []primitives.Slot
|
|
expect []batch
|
|
}{
|
|
{
|
|
name: "size 10",
|
|
b: batcher{min: 0, size: 10},
|
|
upTo: []primitives.Slot{33, 30, 10, 6},
|
|
expect: []batch{
|
|
{begin: 23, end: 33, state: batchInit},
|
|
{begin: 20, end: 30, state: batchInit},
|
|
{begin: 0, end: 10, state: batchInit},
|
|
{begin: 0, end: 6, state: batchInit},
|
|
},
|
|
},
|
|
{
|
|
name: "size 4",
|
|
b: batcher{min: 0, size: 4},
|
|
upTo: []primitives.Slot{33, 6, 4},
|
|
expect: []batch{
|
|
{begin: 29, end: 33, state: batchInit},
|
|
{begin: 2, end: 6, state: batchInit},
|
|
{begin: 0, end: 4, state: batchInit},
|
|
},
|
|
},
|
|
{
|
|
name: "trigger end",
|
|
b: batcher{min: 20, size: 10},
|
|
upTo: []primitives.Slot{33, 30, 25, 21, 20, 19},
|
|
expect: []batch{
|
|
{begin: 23, end: 33, state: batchInit},
|
|
{begin: 20, end: 30, state: batchInit},
|
|
{begin: 20, end: 25, state: batchInit},
|
|
{begin: 20, end: 21, state: batchInit},
|
|
{begin: 20, end: 20, state: batchEndSequence},
|
|
{begin: 19, end: 19, state: batchEndSequence},
|
|
},
|
|
},
|
|
}
|
|
for _, c := range cases {
|
|
for i := range c.upTo {
|
|
upTo := c.upTo[i]
|
|
expect := c.expect[i]
|
|
t.Run(fmt.Sprintf("%s upTo %d", c.name, upTo), func(t *testing.T) {
|
|
got := c.b.before(upTo)
|
|
require.Equal(t, expect.begin, got.begin)
|
|
require.Equal(t, expect.end, got.end)
|
|
require.Equal(t, expect.state, got.state)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBatchSequencer(t *testing.T) {
|
|
var min, max, size primitives.Slot
|
|
seqLen := 8
|
|
min = 0
|
|
max = 11235
|
|
size = 64
|
|
seq := newBatchSequencer(seqLen, min, max, size)
|
|
expected := []batch{
|
|
{begin: 11171, end: 11235},
|
|
{begin: 11107, end: 11171},
|
|
{begin: 11043, end: 11107},
|
|
{begin: 10979, end: 11043},
|
|
{begin: 10915, end: 10979},
|
|
{begin: 10851, end: 10915},
|
|
{begin: 10787, end: 10851},
|
|
{begin: 10723, end: 10787},
|
|
}
|
|
got, err := seq.sequence()
|
|
require.Equal(t, seqLen, len(got))
|
|
for i := 0; i < seqLen; i++ {
|
|
g := got[i]
|
|
exp := expected[i]
|
|
require.NoError(t, err)
|
|
require.Equal(t, exp.begin, g.begin)
|
|
require.Equal(t, exp.end, g.end)
|
|
require.Equal(t, batchSequenced, g.state)
|
|
}
|
|
// This should give us the error indicating there are too many outstanding batches.
|
|
_, err = seq.sequence()
|
|
require.ErrorIs(t, err, errMaxBatches)
|
|
|
|
// mark the last batch completed so we can call sequence again.
|
|
last := seq.seq[len(seq.seq)-1]
|
|
// With this state, the batch should get served back to us as the next batch.
|
|
last.state = batchErrRetryable
|
|
seq.update(last)
|
|
nextS, err := seq.sequence()
|
|
require.Equal(t, 1, len(nextS))
|
|
next := nextS[0]
|
|
require.NoError(t, err)
|
|
require.Equal(t, last.begin, next.begin)
|
|
require.Equal(t, last.end, next.end)
|
|
// sequence() should replace the batchErrRetryable state with batchSequenced.
|
|
require.Equal(t, batchSequenced, next.state)
|
|
|
|
// No batches have been marked importable.
|
|
require.Equal(t, 0, len(seq.importable()))
|
|
|
|
// Mark our batch importable and make sure it shows up in the list of importable batches.
|
|
next.state = batchImportable
|
|
seq.update(next)
|
|
require.Equal(t, 0, len(seq.importable()))
|
|
first := seq.seq[0]
|
|
first.state = batchImportable
|
|
seq.update(first)
|
|
require.Equal(t, 1, len(seq.importable()))
|
|
require.Equal(t, len(seq.seq), seqLen)
|
|
// change the last element back to batchInit so that the importable test stays simple
|
|
last = seq.seq[len(seq.seq)-1]
|
|
last.state = batchInit
|
|
seq.update(last)
|
|
// ensure that the number of importable elements grows as the list is marked importable
|
|
for i := 0; i < len(seq.seq); i++ {
|
|
seq.seq[i].state = batchImportable
|
|
require.Equal(t, i+1, len(seq.importable()))
|
|
}
|
|
// reset everything to init
|
|
for i := 0; i < len(seq.seq); i++ {
|
|
seq.seq[i].state = batchInit
|
|
require.Equal(t, 0, len(seq.importable()))
|
|
}
|
|
// loop backwards and make sure importable is zero until the first element is importable
|
|
for i := len(seq.seq) - 1; i > 0; i-- {
|
|
seq.seq[i].state = batchImportable
|
|
require.Equal(t, 0, len(seq.importable()))
|
|
}
|
|
seq.seq[0].state = batchImportable
|
|
require.Equal(t, len(seq.seq), len(seq.importable()))
|
|
|
|
// reset everything to init again
|
|
for i := 0; i < len(seq.seq); i++ {
|
|
seq.seq[i].state = batchInit
|
|
require.Equal(t, 0, len(seq.importable()))
|
|
}
|
|
// set first 3 elements to importable. we should see them in the result for importable()
|
|
// and be able to use update to cycle them away.
|
|
seq.seq[0].state, seq.seq[1].state, seq.seq[2].state = batchImportable, batchImportable, batchImportable
|
|
require.Equal(t, 3, len(seq.importable()))
|
|
a, b, c, z := seq.seq[0], seq.seq[1], seq.seq[2], seq.seq[3]
|
|
require.NotEqual(t, z.begin, seq.seq[2].begin)
|
|
require.NotEqual(t, z.begin, seq.seq[1].begin)
|
|
require.NotEqual(t, z.begin, seq.seq[0].begin)
|
|
a.state, b.state, c.state = batchImportComplete, batchImportComplete, batchImportComplete
|
|
seq.update(a)
|
|
|
|
// follow z as it moves down the chain to the first spot
|
|
require.Equal(t, z.begin, seq.seq[2].begin)
|
|
require.NotEqual(t, z.begin, seq.seq[1].begin)
|
|
require.NotEqual(t, z.begin, seq.seq[0].begin)
|
|
seq.update(b)
|
|
require.NotEqual(t, z.begin, seq.seq[2].begin)
|
|
require.Equal(t, z.begin, seq.seq[1].begin)
|
|
require.NotEqual(t, z.begin, seq.seq[0].begin)
|
|
seq.update(c)
|
|
require.NotEqual(t, z.begin, seq.seq[2].begin)
|
|
require.NotEqual(t, z.begin, seq.seq[1].begin)
|
|
require.Equal(t, z.begin, seq.seq[0].begin)
|
|
|
|
// Check integrity of begin/end alignment across the sequence.
|
|
// Also update all the states to sequenced for the convenience of the next test.
|
|
for i := 1; i < len(seq.seq); i++ {
|
|
require.Equal(t, seq.seq[i].end, seq.seq[i-1].begin)
|
|
// won't touch the first element, which is fine because it is marked complete below.
|
|
seq.seq[i].state = batchSequenced
|
|
}
|
|
|
|
// set the min for the batcher close to the lowest slot. This will force the next batch to be partial and the batch
|
|
// after that to be the final batch.
|
|
newMin := seq.seq[len(seq.seq)-1].begin - 30
|
|
seq.batcher.min = newMin
|
|
first = seq.seq[0]
|
|
first.state = batchImportComplete
|
|
// update() with a complete state will cause the sequence to be extended with an additional batch
|
|
seq.update(first)
|
|
lastS, err := seq.sequence()
|
|
last = lastS[0]
|
|
require.NoError(t, err)
|
|
require.Equal(t, newMin, last.begin)
|
|
require.Equal(t, seq.seq[len(seq.seq)-2].begin, last.end)
|
|
|
|
// Mark first batch done again, this time check that sequence() gives errEndSequence.
|
|
first = seq.seq[0]
|
|
first.state = batchImportComplete
|
|
// update() with a complete state will cause the sequence to be extended with an additional batch
|
|
seq.update(first)
|
|
endExp, err := seq.sequence()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(endExp))
|
|
end := endExp[0]
|
|
//require.ErrorIs(t, err, errEndSequence)
|
|
require.Equal(t, batchEndSequence, end.state)
|
|
}
|