agent_constraints_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package autopilot
  2. import (
  3. prand "math/rand"
  4. "testing"
  5. "time"
  6. "github.com/btcsuite/btcd/btcutil"
  7. "github.com/lightningnetwork/lnd/lnwire"
  8. )
  9. func TestConstraintsChannelBudget(t *testing.T) {
  10. t.Parallel()
  11. prand.Seed(time.Now().Unix())
  12. const (
  13. minChanSize = 0
  14. maxChanSize = btcutil.Amount(btcutil.SatoshiPerBitcoin)
  15. chanLimit = 3
  16. threshold = 0.5
  17. )
  18. constraints := NewConstraints(
  19. minChanSize,
  20. maxChanSize,
  21. chanLimit,
  22. 0,
  23. threshold,
  24. )
  25. randChanID := func() lnwire.ShortChannelID {
  26. return lnwire.NewShortChanIDFromInt(uint64(prand.Int63()))
  27. }
  28. testCases := []struct {
  29. channels []LocalChannel
  30. walletAmt btcutil.Amount
  31. needMore bool
  32. amtAvailable btcutil.Amount
  33. numMore uint32
  34. }{
  35. // Many available funds, but already have too many active open
  36. // channels.
  37. {
  38. []LocalChannel{
  39. {
  40. ChanID: randChanID(),
  41. Balance: btcutil.Amount(prand.Int31()),
  42. },
  43. {
  44. ChanID: randChanID(),
  45. Balance: btcutil.Amount(prand.Int31()),
  46. },
  47. {
  48. ChanID: randChanID(),
  49. Balance: btcutil.Amount(prand.Int31()),
  50. },
  51. },
  52. btcutil.Amount(btcutil.SatoshiPerBitcoin * 10),
  53. false,
  54. 0,
  55. 0,
  56. },
  57. // Ratio of funds in channels and total funds meets the
  58. // threshold.
  59. {
  60. []LocalChannel{
  61. {
  62. ChanID: randChanID(),
  63. Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin),
  64. },
  65. {
  66. ChanID: randChanID(),
  67. Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin),
  68. },
  69. },
  70. btcutil.Amount(btcutil.SatoshiPerBitcoin * 2),
  71. false,
  72. 0,
  73. 0,
  74. },
  75. // Ratio of funds in channels and total funds is below the
  76. // threshold. We have 10 BTC allocated amongst channels and
  77. // funds, atm. We're targeting 50%, so 5 BTC should be
  78. // allocated. Only 1 BTC is atm, so 4 BTC should be
  79. // recommended. We should also request 2 more channels as the
  80. // limit is 3.
  81. {
  82. []LocalChannel{
  83. {
  84. ChanID: randChanID(),
  85. Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin),
  86. },
  87. },
  88. btcutil.Amount(btcutil.SatoshiPerBitcoin * 9),
  89. true,
  90. btcutil.Amount(btcutil.SatoshiPerBitcoin * 4),
  91. 2,
  92. },
  93. // Ratio of funds in channels and total funds is below the
  94. // threshold. We have 14 BTC total amongst the wallet's
  95. // balance, and our currently opened channels. Since we're
  96. // targeting a 50% allocation, we should commit 7 BTC. The
  97. // current channels commit 4 BTC, so we should expected 3 BTC
  98. // to be committed. We should only request a single additional
  99. // channel as the limit is 3.
  100. {
  101. []LocalChannel{
  102. {
  103. ChanID: randChanID(),
  104. Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin),
  105. },
  106. {
  107. ChanID: randChanID(),
  108. Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin * 3),
  109. },
  110. },
  111. btcutil.Amount(btcutil.SatoshiPerBitcoin * 10),
  112. true,
  113. btcutil.Amount(btcutil.SatoshiPerBitcoin * 3),
  114. 1,
  115. },
  116. // Ratio of funds in channels and total funds is above the
  117. // threshold.
  118. {
  119. []LocalChannel{
  120. {
  121. ChanID: randChanID(),
  122. Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin),
  123. },
  124. {
  125. ChanID: randChanID(),
  126. Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin),
  127. },
  128. },
  129. btcutil.Amount(btcutil.SatoshiPerBitcoin),
  130. false,
  131. 0,
  132. 0,
  133. },
  134. }
  135. for i, testCase := range testCases {
  136. amtToAllocate, numMore := constraints.ChannelBudget(
  137. testCase.channels, testCase.walletAmt,
  138. )
  139. if amtToAllocate != testCase.amtAvailable {
  140. t.Fatalf("test #%v: expected %v, got %v",
  141. i, testCase.amtAvailable, amtToAllocate)
  142. }
  143. if numMore != testCase.numMore {
  144. t.Fatalf("test #%v: expected %v, got %v",
  145. i, testCase.numMore, numMore)
  146. }
  147. }
  148. }