fuzz example

This commit is contained in:
alex.sharov 2021-07-29 15:23:17 +07:00
parent 284ac68930
commit 8ca2c0cef4
3 changed files with 147 additions and 28 deletions

View File

@ -261,6 +261,94 @@ func PromoteStep(pending, baseFee, queued *SubPool) {
}
}
func CheckInvariants(pending, baseFee, queued *SubPool) {
//1. If top element in the worst green queue has SubPool != 0b1111 (binary), it needs to be removed from the green pool.
// If SubPool < 0b1000 (not satisfying minimum fee), discard.
// If SubPool == 0b1110, demote to the yellow pool, otherwise demote to the red pool.
for worst := pending.Worst(); pending.Len() > 0; worst = pending.Worst() {
if worst.SubPool >= 0b11110 {
break
}
if worst.SubPool >= 0b11100 {
baseFee.Add(pending.PopWorst())
continue
}
if worst.SubPool >= 0b11000 {
queued.Add(pending.PopWorst())
continue
}
pending.PopWorst()
}
//2. If top element in the worst green queue has SubPool == 0b1111, but there is not enough room in the pool, discard.
for worst := pending.Worst(); pending.Len() > PendingSubPoolLimit; worst = pending.Worst() {
if worst.SubPool >= 0b11110 { // TODO: here must 'SubPool == 0b1111' or 'SubPool <= 0b1111' ?
break
}
pending.PopWorst()
}
//3. If the top element in the best yellow queue has SubPool == 0b1111, promote to the green pool.
for best := baseFee.Best(); baseFee.Len() > 0; best = baseFee.Best() {
if best.SubPool < 0b11110 {
break
}
pending.Add(baseFee.PopWorst())
}
//4. If the top element in the worst yellow queue has SubPool != 0x1110, it needs to be removed from the yellow pool.
// If SubPool < 0b1000 (not satisfying minimum fee), discard. Otherwise, demote to the red pool.
for worst := baseFee.Worst(); baseFee.Len() > 0; worst = baseFee.Worst() {
if worst.SubPool >= 0b11100 {
break
}
if worst.SubPool >= 0b11000 {
queued.Add(baseFee.PopWorst())
continue
}
baseFee.PopWorst()
}
//5. If the top element in the worst yellow queue has SubPool == 0x1110, but there is not enough room in the pool, discard.
for worst := baseFee.Worst(); baseFee.Len() > BaseFeeSubPoolLimit; worst = baseFee.Worst() {
if worst.SubPool >= 0b11110 {
break
}
baseFee.PopWorst()
}
//6. If the top element in the best red queue has SubPool == 0x1110, promote to the yellow pool. If SubPool == 0x1111, promote to the green pool.
for best := queued.Best(); queued.Len() > 0; best = queued.Best() {
if best.SubPool < 0b11100 {
break
}
if best.SubPool < 0b11110 {
baseFee.Add(queued.PopWorst())
continue
}
pending.Add(queued.PopWorst())
}
//7. If the top element in the worst red queue has SubPool < 0b1000 (not satisfying minimum fee), discard.
for worst := queued.Worst(); queued.Len() > 0; worst = queued.Worst() {
if worst.SubPool >= 0b10000 {
break
}
queued.PopWorst()
}
//8. If the top element in the worst red queue has SubPool >= 0b100, but there is not enough room in the pool, discard.
for worst := queued.Worst(); queued.Len() > QueuedSubPoolLimit; worst = queued.Worst() {
if worst.SubPool >= 0b10000 {
break
}
queued.PopWorst()
}
}
// Below is a draft code, will convert it to Loop and LoopStep funcs later
type PoolImpl struct {

View File

@ -1,28 +0,0 @@
// +build gofuzzbeta
package txpool
// https://blog.golang.org/fuzz-beta
// golang.org/s/draft-fuzzing-design
//gotip doc testing
//gotip doc testing.F
//gotip doc testing.F.Add
//gotip doc testing.F.Fuzz
func FuzzParseQuery(f *testing.F) {
f.Add("x=1&y=2")
f.Fuzz(func(t *testing.T, queryStr string) {
query, err := url.ParseQuery(queryStr)
if err != nil {
t.Skip()
}
queryStr2 := query.Encode()
query2, err := url.ParseQuery(queryStr2)
if err != nil {
t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err)
}
if !reflect.DeepEqual(query, query2) {
t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2)
}
})
}

59
txpool/pool_fuzz_test.go Normal file
View File

@ -0,0 +1,59 @@
// +build gofuzzbeta
package txpool
import (
"testing"
)
// https://blog.golang.org/fuzz-beta
// golang.org/s/draft-fuzzing-design
//gotip doc testing
//gotip doc testing.F
//gotip doc testing.F.Add
//gotip doc testing.F.Fuzz
//func FuzzParseQuery(f *testing.F) {
// f.Add("x=1&y=2")
// f.Fuzz(func(t *testing.T, queryStr string) {
// query, err := url.ParseQuery(queryStr)
// if err != nil {
// t.Skip()
// }
// queryStr2 := query.Encode()
// query2, err := url.ParseQuery(queryStr2)
// if err != nil {
// t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err)
// }
// if !reflect.DeepEqual(query, query2) {
// t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2)
// }
// })
//}
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.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])})
}
baseFee := NewSubPool()
for i := range s2 {
s2[i] &= 0b11111
baseFee.Add(&MetaTx{SubPool: SubPoolMarker(s2[i])})
}
queue := NewSubPool()
for i := range s3 {
s3[i] &= 0b11111
queue.Add(&MetaTx{SubPool: SubPoolMarker(s3[i])})
}
PromoteStep(pending, baseFee, queue)
if pending.Best() != nil && pending.Best().SubPool < 0b11110 {
t.Fatalf("Pending best too small %b", pending.Best().SubPool)
}
})
}