github.com/decred/dcrlnd@v0.7.6/funding/commitment_type_negotiation_test.go (about)

     1  package funding
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/decred/dcrlnd/lnwallet"
     7  	"github.com/decred/dcrlnd/lnwire"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  // TestCommitmentTypeNegotiation tests all of the possible paths of a channel
    12  // commitment type negotiation.
    13  func TestCommitmentTypeNegotiation(t *testing.T) {
    14  	t.Parallel()
    15  
    16  	testCases := []struct {
    17  		name              string
    18  		mustBeExplicit    bool
    19  		channelFeatures   *lnwire.RawFeatureVector
    20  		localFeatures     *lnwire.RawFeatureVector
    21  		remoteFeatures    *lnwire.RawFeatureVector
    22  		expectsCommitType lnwallet.CommitmentType
    23  		expectsChanType   lnwire.ChannelType
    24  		expectsErr        error
    25  	}{
    26  		{
    27  			name: "explicit missing remote negotiation feature",
    28  			channelFeatures: lnwire.NewRawFeatureVector(
    29  				lnwire.StaticRemoteKeyRequired,
    30  				lnwire.AnchorsZeroFeeHtlcTxRequired,
    31  			),
    32  			localFeatures: lnwire.NewRawFeatureVector(
    33  				lnwire.StaticRemoteKeyOptional,
    34  				lnwire.AnchorsZeroFeeHtlcTxOptional,
    35  				lnwire.ExplicitChannelTypeOptional,
    36  			),
    37  			remoteFeatures: lnwire.NewRawFeatureVector(
    38  				lnwire.StaticRemoteKeyOptional,
    39  				lnwire.AnchorsZeroFeeHtlcTxOptional,
    40  			),
    41  			expectsCommitType: lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx,
    42  			expectsChanType: lnwire.ChannelType(*lnwire.NewRawFeatureVector(
    43  				lnwire.StaticRemoteKeyRequired,
    44  				lnwire.AnchorsZeroFeeHtlcTxRequired,
    45  			)),
    46  			expectsErr: nil,
    47  		},
    48  		{
    49  			name: "local funder wants explicit, remote doesn't " +
    50  				"support so fall back",
    51  			mustBeExplicit: true,
    52  			channelFeatures: lnwire.NewRawFeatureVector(
    53  				lnwire.StaticRemoteKeyRequired,
    54  				lnwire.AnchorsZeroFeeHtlcTxRequired,
    55  			),
    56  			localFeatures: lnwire.NewRawFeatureVector(
    57  				lnwire.StaticRemoteKeyOptional,
    58  				lnwire.AnchorsZeroFeeHtlcTxOptional,
    59  				lnwire.ExplicitChannelTypeOptional,
    60  			),
    61  			remoteFeatures: lnwire.NewRawFeatureVector(
    62  				lnwire.StaticRemoteKeyOptional,
    63  				lnwire.AnchorsZeroFeeHtlcTxOptional,
    64  			),
    65  			expectsErr: errUnsupportedExplicitNegotiation,
    66  		},
    67  		{
    68  			name: "explicit missing remote commitment feature",
    69  			channelFeatures: lnwire.NewRawFeatureVector(
    70  				lnwire.StaticRemoteKeyRequired,
    71  				lnwire.AnchorsZeroFeeHtlcTxRequired,
    72  			),
    73  			localFeatures: lnwire.NewRawFeatureVector(
    74  				lnwire.StaticRemoteKeyOptional,
    75  				lnwire.AnchorsZeroFeeHtlcTxOptional,
    76  				lnwire.ExplicitChannelTypeOptional,
    77  			),
    78  			remoteFeatures: lnwire.NewRawFeatureVector(
    79  				lnwire.StaticRemoteKeyOptional,
    80  				lnwire.ExplicitChannelTypeOptional,
    81  			),
    82  			expectsErr: errUnsupportedChannelType,
    83  		},
    84  		{
    85  			name: "explicit anchors",
    86  			channelFeatures: lnwire.NewRawFeatureVector(
    87  				lnwire.StaticRemoteKeyRequired,
    88  				lnwire.AnchorsZeroFeeHtlcTxRequired,
    89  			),
    90  			localFeatures: lnwire.NewRawFeatureVector(
    91  				lnwire.StaticRemoteKeyOptional,
    92  				lnwire.AnchorsZeroFeeHtlcTxOptional,
    93  				lnwire.ExplicitChannelTypeOptional,
    94  			),
    95  			remoteFeatures: lnwire.NewRawFeatureVector(
    96  				lnwire.StaticRemoteKeyOptional,
    97  				lnwire.AnchorsZeroFeeHtlcTxOptional,
    98  				lnwire.ExplicitChannelTypeOptional,
    99  			),
   100  			expectsCommitType: lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx,
   101  			expectsChanType: lnwire.ChannelType(*lnwire.NewRawFeatureVector(
   102  				lnwire.StaticRemoteKeyRequired,
   103  				lnwire.AnchorsZeroFeeHtlcTxRequired,
   104  			)),
   105  			expectsErr: nil,
   106  		},
   107  		{
   108  			name: "explicit tweakless",
   109  			channelFeatures: lnwire.NewRawFeatureVector(
   110  				lnwire.StaticRemoteKeyRequired,
   111  			),
   112  			localFeatures: lnwire.NewRawFeatureVector(
   113  				lnwire.StaticRemoteKeyOptional,
   114  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   115  				lnwire.ExplicitChannelTypeOptional,
   116  			),
   117  			remoteFeatures: lnwire.NewRawFeatureVector(
   118  				lnwire.StaticRemoteKeyOptional,
   119  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   120  				lnwire.ExplicitChannelTypeOptional,
   121  			),
   122  			expectsCommitType: lnwallet.CommitmentTypeTweakless,
   123  			expectsChanType: lnwire.ChannelType(*lnwire.NewRawFeatureVector(
   124  				lnwire.StaticRemoteKeyRequired,
   125  			)),
   126  			expectsErr: nil,
   127  		},
   128  		{
   129  			name:            "explicit legacy",
   130  			channelFeatures: lnwire.NewRawFeatureVector(),
   131  			localFeatures: lnwire.NewRawFeatureVector(
   132  				lnwire.StaticRemoteKeyOptional,
   133  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   134  				lnwire.ExplicitChannelTypeOptional,
   135  			),
   136  			remoteFeatures: lnwire.NewRawFeatureVector(
   137  				lnwire.StaticRemoteKeyOptional,
   138  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   139  				lnwire.ExplicitChannelTypeOptional,
   140  			),
   141  			expectsCommitType: lnwallet.CommitmentTypeLegacy,
   142  			expectsChanType:   lnwire.ChannelType(*lnwire.NewRawFeatureVector()),
   143  			expectsErr:        nil,
   144  		},
   145  		// Both sides signal the explicit chan type bit, so we expect
   146  		// that we return the corresponding chan type feature bits,
   147  		// even though we didn't set an explicit channel type.
   148  		{
   149  			name:            "implicit anchors",
   150  			channelFeatures: nil,
   151  			localFeatures: lnwire.NewRawFeatureVector(
   152  				lnwire.StaticRemoteKeyOptional,
   153  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   154  				lnwire.ExplicitChannelTypeOptional,
   155  			),
   156  			remoteFeatures: lnwire.NewRawFeatureVector(
   157  				lnwire.StaticRemoteKeyOptional,
   158  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   159  				lnwire.ExplicitChannelTypeOptional,
   160  			),
   161  			expectsCommitType: lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx,
   162  			expectsChanType: lnwire.ChannelType(*lnwire.NewRawFeatureVector(
   163  				lnwire.StaticRemoteKeyRequired,
   164  				lnwire.AnchorsZeroFeeHtlcTxRequired,
   165  			)),
   166  			expectsErr: nil,
   167  		},
   168  		{
   169  			name:            "implicit tweakless",
   170  			channelFeatures: nil,
   171  			localFeatures: lnwire.NewRawFeatureVector(
   172  				lnwire.StaticRemoteKeyOptional,
   173  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   174  			),
   175  			remoteFeatures: lnwire.NewRawFeatureVector(
   176  				lnwire.StaticRemoteKeyOptional,
   177  			),
   178  			expectsCommitType: lnwallet.CommitmentTypeTweakless,
   179  			expectsChanType: lnwire.ChannelType(*lnwire.NewRawFeatureVector(
   180  				lnwire.StaticRemoteKeyRequired,
   181  			)),
   182  			expectsErr: nil,
   183  		},
   184  		{
   185  			name:            "implicit legacy",
   186  			channelFeatures: nil,
   187  			localFeatures:   lnwire.NewRawFeatureVector(),
   188  			remoteFeatures: lnwire.NewRawFeatureVector(
   189  				lnwire.StaticRemoteKeyOptional,
   190  				lnwire.AnchorsZeroFeeHtlcTxOptional,
   191  			),
   192  			expectsCommitType: lnwallet.CommitmentTypeLegacy,
   193  			expectsChanType:   lnwire.ChannelType(*lnwire.NewRawFeatureVector()),
   194  			expectsErr:        nil,
   195  		},
   196  	}
   197  
   198  	for _, testCase := range testCases {
   199  		testCase := testCase
   200  		ok := t.Run(testCase.name, func(t *testing.T) {
   201  			localFeatures := lnwire.NewFeatureVector(
   202  				testCase.localFeatures, lnwire.Features,
   203  			)
   204  			remoteFeatures := lnwire.NewFeatureVector(
   205  				testCase.remoteFeatures, lnwire.Features,
   206  			)
   207  
   208  			var channelType *lnwire.ChannelType
   209  			if testCase.channelFeatures != nil {
   210  				channelType = new(lnwire.ChannelType)
   211  				*channelType = lnwire.ChannelType(
   212  					*testCase.channelFeatures,
   213  				)
   214  			}
   215  			_, localChanType, localCommitType, err := negotiateCommitmentType(
   216  				channelType, localFeatures, remoteFeatures,
   217  				testCase.mustBeExplicit,
   218  			)
   219  			require.Equal(t, testCase.expectsErr, err)
   220  
   221  			_, remoteChanType, remoteCommitType, err := negotiateCommitmentType(
   222  				channelType, remoteFeatures, localFeatures,
   223  				testCase.mustBeExplicit,
   224  			)
   225  			require.Equal(t, testCase.expectsErr, err)
   226  
   227  			if testCase.expectsErr != nil {
   228  				return
   229  			}
   230  
   231  			require.Equal(
   232  				t, testCase.expectsCommitType, localCommitType,
   233  				testCase.name,
   234  			)
   235  			require.Equal(
   236  				t, testCase.expectsCommitType, remoteCommitType,
   237  				testCase.name,
   238  			)
   239  
   240  			require.Equal(
   241  				t, testCase.expectsChanType, *localChanType,
   242  				testCase.name,
   243  			)
   244  			require.Equal(
   245  				t, testCase.expectsChanType, *remoteChanType,
   246  				testCase.name,
   247  			)
   248  		})
   249  		if !ok {
   250  			return
   251  		}
   252  	}
   253  }