diff --git a/txpool/pool.go b/txpool/pool.go index afef2a9cd..16022c3bc 100644 --- a/txpool/pool.go +++ b/txpool/pool.go @@ -19,6 +19,7 @@ package txpool import ( "container/heap" "context" + "fmt" "sync" "time" @@ -154,19 +155,33 @@ func (p *SubPool) Worst() *MetaTx { return (*p.worst)[len(*p.worst)-1] } func (p *SubPool) PopBest() *MetaTx { - i := p.best.Pop().(*MetaTx) + i := heap.Pop(p.best).(*MetaTx) + if i.worstIndex != 0 { + panic("why?") + } heap.Remove(p.worst, i.worstIndex) return i } func (p *SubPool) PopWorst() *MetaTx { - i := p.worst.Pop().(*MetaTx) + i := heap.Pop(p.worst).(*MetaTx) + if i.bestIndex != 0 { + panic("why?") + } heap.Remove(p.best, i.bestIndex) return i } func (p *SubPool) Len() int { return p.best.Len() } func (p *SubPool) Add(i *MetaTx) { - heap.Push(p.worst, i) heap.Push(p.best, i) + heap.Push(p.worst, i) +} +func (p *SubPool) DebugPrint() { + for i := range *p.best { + fmt.Printf("best: %b\n", (*p.best)[i].SubPool) + } + for i := range *p.worst { + fmt.Printf("worst: %b\n", (*p.worst)[i].SubPool) + } } const PendingSubPoolLimit = 1024 diff --git a/txpool/pool_fuzz_test.go b/txpool/pool_fuzz_test.go index 52ea90f73..4fdcb132a 100644 --- a/txpool/pool_fuzz_test.go +++ b/txpool/pool_fuzz_test.go @@ -1,9 +1,12 @@ +//go:build gofuzzbeta // +build gofuzzbeta package txpool import ( "testing" + + "github.com/stretchr/testify/require" ) // https://blog.golang.org/fuzz-beta @@ -15,44 +18,56 @@ import ( // gotip test -trimpath -v -fuzz=Fuzz -fuzztime=10s ./txpool +func FuzzTwoQueue(f *testing.F) { + f.Add([]uint8{0b11000, 0b00101, 0b000111}) + f.Fuzz(func(t *testing.T, in []uint8) { + t.Parallel() + sub := NewSubPool() + for _, i := range in { + sub.Add(&MetaTx{SubPool: SubPoolMarker(i & 0b11111)}) + } + for sub.Len() > 0 { + require.Equal(t, (*sub.worst)[0].SubPool, sub.Best().SubPool) + require.Equal(t, (*sub.best)[0].SubPool, sub.Worst().SubPool) + sub.PopBest() + } + }) +} + func FuzzPromoteStep(f *testing.F) { f.Add([]uint8{0b11111, 0b10001, 0b10101, 0b00001, 0b00000}, []uint8{0b11111, 0b10001, 0b10101, 0b00001, 0b00000}, []uint8{0b11111, 0b10001, 0b10101, 0b00001, 0b00000}) f.Add([]uint8{0b11111}, []uint8{0b11111}, []uint8{0b11110, 0b0, 0b1010}) + f.Add([]uint8{0b11000, 0b00101, 0b000111}, []uint8{0b11000, 0b00101, 0b000111}, []uint8{0b11000, 0b00101, 0b000111}) f.Fuzz(func(t *testing.T, s1, s2, s3 []uint8) { t.Parallel() - pending := NewSubPool() - for i := range s1 { - s1[i] &= 0b11111 - pending.Add(&MetaTx{SubPool: SubPoolMarker(s1[i])}) + pending, baseFee, queued := NewSubPool(), NewSubPool(), NewSubPool() + for _, i := range s1 { + pending.Add(&MetaTx{SubPool: SubPoolMarker(i & 0b11111)}) } - baseFee := NewSubPool() - for i := range s2 { - s2[i] &= 0b11111 - baseFee.Add(&MetaTx{SubPool: SubPoolMarker(s2[i])}) + for _, i := range s2 { + baseFee.Add(&MetaTx{SubPool: SubPoolMarker(i & 0b11111)}) } - queue := NewSubPool() - for i := range s3 { - s3[i] &= 0b11111 - queue.Add(&MetaTx{SubPool: SubPoolMarker(s3[i])}) + for _, i := range s3 { + queued.Add(&MetaTx{SubPool: SubPoolMarker(i & 0b11111)}) } - PromoteStep(pending, baseFee, queue) + PromoteStep(pending, baseFee, queued) best, worst := pending.Best(), pending.Worst() _ = best if worst != nil && worst.SubPool < 0b01111 { - t.Fatalf("Pending worst too small %b, input: %b,%b,%b", worst.SubPool, s1, s2, s3) + t.Fatalf("pending worst too small %b, input: \n%x\n%x\n%x", worst.SubPool, s1, s2, s3) } best, worst = baseFee.Best(), baseFee.Worst() _ = best if worst != nil && worst.SubPool < 0b01111 { - t.Fatalf("Pending worst too small %b, input: %b,%b,%b", worst.SubPool, s1, s2, s3) + t.Fatalf("baseFee worst too small %b, input: \n%x\n%x\n%x", worst.SubPool, s1, s2, s3) } - best, worst = queue.Best(), queue.Worst() + best, worst = queued.Best(), queued.Worst() _ = best if worst != nil && worst.SubPool < 0b01111 { - t.Fatalf("Pending worst too small %b, input: %b,%b,%b", worst.SubPool, s1, s2, s3) + t.Fatalf("queued worst too small %b, input: \n%x\n%x\n%x", worst.SubPool, s1, s2, s3) } })