github.com/decred/dcrlnd@v0.7.6/autopilot/agent_constraints_test.go (about)

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