decred.org/dcrdex@v1.0.5/dex/txfee/feefetcher_test.go (about) 1 package txfee 2 3 import ( 4 "testing" 5 "time" 6 7 "decred.org/dcrdex/dex" 8 ) 9 10 func TestGroupedSources(t *testing.T) { 11 log := dex.StdOutLogger("T", dex.LevelTrace) 12 checkSort := func(sources []*SourceConfig, groupSizes ...int) { 13 t.Helper() 14 groups := groupedSources(sources, log) 15 if len(groups) != len(groupSizes) { 16 t.Fatalf("expected %d groups, got %d", len(groupSizes), len(groups)) 17 } 18 for i, group := range groups { 19 if len(group) != groupSizes[i] { 20 t.Fatalf("%d'th group has %d members. expected %d", i, len(group), groupSizes[i]) 21 } 22 } 23 } 24 sources := func(ranks ...uint) (srcs []*SourceConfig) { 25 for _, rank := range ranks { 26 srcs = append(srcs, &SourceConfig{Rank: rank}) 27 } 28 return 29 } 30 checkSort(sources(1, 1), 2) 31 checkSort(sources(1, 2), 1, 1) 32 checkSort(sources(1, 1, 2), 2, 1) 33 checkSort(sources(4, 4, 4, 2, 1, 1), 2, 1, 3) 34 } 35 36 func TestPrioritizedFeeRate(t *testing.T) { 37 feeFetchers := func(priorityRates [][2]uint) [][]*feeFetchSource { 38 sources := make([]*feeFetchSource, len(priorityRates)) 39 for i, rr := range priorityRates { 40 rank, rate := rr[0], rr[1] 41 sources[i] = &feeFetchSource{ 42 SourceConfig: &SourceConfig{Rank: rank}, 43 rate: uint64(rate), 44 stamp: time.Now(), 45 } 46 } 47 return groupSources(sources) 48 } 49 50 var fetchers [][]*feeFetchSource 51 checkRate := func(expRate uint64) { 52 t.Helper() 53 if r := prioritizedFeeRate(fetchers); r != expRate { 54 t.Fatalf("expected rate %d, got %d", expRate, r) 55 } 56 } 57 58 // just one 59 fetchers = feeFetchers([][2]uint{ 60 {1, 10}, 61 }) 62 checkRate(10) 63 64 // good until expired 65 f0 := fetchers[0][0] 66 f0.stamp = time.Now().Add(-feeExpiration + time.Second*10) 67 checkRate(10) 68 // expired 69 f0.stamp = time.Now().Add(-feeExpiration) 70 checkRate(0) 71 72 // two at different priorities 73 fetchers = feeFetchers([][2]uint{ 74 {1, 10}, 75 {2, 20}, 76 }) 77 // Only first is considered if not expired or failed. 78 checkRate(10) 79 // expire first 80 f0, f1 := fetchers[0][0], fetchers[1][0] 81 f0.stamp = time.Now().Add(-feeExpiration) 82 checkRate(20) 83 // first failed 84 f0.stamp = time.Now() 85 f0.failUntil = time.Now() 86 checkRate(20) 87 // both failed 88 f1.failUntil = time.Now() 89 checkRate(0) 90 91 // first group has multiple 92 fetchers = feeFetchers([][2]uint{ 93 {1, 10}, {1, 30}, 94 {2, 250}, 95 }) 96 checkRate(20) 97 // expire second from group 1 98 f0, f1 = fetchers[0][0], fetchers[0][1] 99 f1.failUntil = time.Now() 100 checkRate(10) 101 // second from group 1 half-decayed 102 f1.failUntil = time.Time{} 103 f1.stamp = time.Now().Add(-1 * (feeFetchFullValidityPeriod + (feeFetchValidityDecayPeriod / 2))) 104 checkRate(17) // (10 + (0.5 * 30)) / 1.5 = 16.6666 105 // first from group 1 decayed by 75% 106 f1.stamp = time.Now() 107 f0.stamp = time.Now().Add(-1 * (feeFetchFullValidityPeriod + (feeFetchValidityDecayPeriod * 3 / 4))) 108 checkRate(26) // (30 + (0.25 * 10)) / 1.25 = 26 109 // group 1 unusable 110 f0.failUntil = time.Now() 111 f1.failUntil = time.Now() 112 checkRate(250) 113 }