channel_update_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package netann_test
  2. import (
  3. "errors"
  4. "testing"
  5. "time"
  6. "github.com/btcsuite/btcd/btcec/v2"
  7. "github.com/btcsuite/btcd/btcec/v2/ecdsa"
  8. "github.com/lightningnetwork/lnd/keychain"
  9. "github.com/lightningnetwork/lnd/lnwallet"
  10. "github.com/lightningnetwork/lnd/lnwire"
  11. "github.com/lightningnetwork/lnd/netann"
  12. "github.com/lightningnetwork/lnd/routing"
  13. )
  14. type mockSigner struct {
  15. err error
  16. }
  17. func (m *mockSigner) SignMessage(_ keychain.KeyLocator,
  18. _ []byte, _ bool) (*ecdsa.Signature, error) {
  19. if m.err != nil {
  20. return nil, m.err
  21. }
  22. return nil, nil
  23. }
  24. var _ lnwallet.MessageSigner = (*mockSigner)(nil)
  25. var (
  26. privKey, _ = btcec.NewPrivateKey()
  27. privKeySigner = keychain.NewPrivKeyMessageSigner(privKey, testKeyLoc)
  28. pubKey = privKey.PubKey()
  29. errFailedToSign = errors.New("unable to sign message")
  30. )
  31. type updateDisableTest struct {
  32. name string
  33. startEnabled bool
  34. disable bool
  35. startTime time.Time
  36. signer lnwallet.MessageSigner
  37. expErr error
  38. }
  39. var updateDisableTests = []updateDisableTest{
  40. {
  41. name: "working signer enabled to disabled",
  42. startEnabled: true,
  43. disable: true,
  44. startTime: time.Now(),
  45. signer: netann.NewNodeSigner(privKeySigner),
  46. },
  47. {
  48. name: "working signer enabled to enabled",
  49. startEnabled: true,
  50. disable: false,
  51. startTime: time.Now(),
  52. signer: netann.NewNodeSigner(privKeySigner),
  53. },
  54. {
  55. name: "working signer disabled to enabled",
  56. startEnabled: false,
  57. disable: false,
  58. startTime: time.Now(),
  59. signer: netann.NewNodeSigner(privKeySigner),
  60. },
  61. {
  62. name: "working signer disabled to disabled",
  63. startEnabled: false,
  64. disable: true,
  65. startTime: time.Now(),
  66. signer: netann.NewNodeSigner(privKeySigner),
  67. },
  68. {
  69. name: "working signer future monotonicity",
  70. startEnabled: true,
  71. disable: true,
  72. startTime: time.Now().Add(time.Hour), // must increment
  73. signer: netann.NewNodeSigner(privKeySigner),
  74. },
  75. {
  76. name: "failing signer",
  77. startTime: time.Now(),
  78. signer: &mockSigner{err: errFailedToSign},
  79. expErr: errFailedToSign,
  80. },
  81. {
  82. name: "invalid sig from signer",
  83. startTime: time.Now(),
  84. signer: &mockSigner{}, // returns a nil signature
  85. expErr: errors.New("cannot decode empty signature"),
  86. },
  87. }
  88. // TestUpdateDisableFlag checks the behavior of UpdateDisableFlag, asserting
  89. // that the proper channel flags are set, the timestamp always increases
  90. // monotonically, and that the correct errors are returned in the event that the
  91. // signer is unable to produce a signature.
  92. func TestUpdateDisableFlag(t *testing.T) {
  93. t.Parallel()
  94. for _, tc := range updateDisableTests {
  95. tc := tc
  96. t.Run(tc.name, func(t *testing.T) {
  97. // Create the initial update, the only fields we are
  98. // concerned with in this test are the timestamp and the
  99. // channel flags.
  100. ogUpdate := &lnwire.ChannelUpdate{
  101. Timestamp: uint32(tc.startTime.Unix()),
  102. }
  103. if !tc.startEnabled {
  104. ogUpdate.ChannelFlags |= lnwire.ChanUpdateDisabled
  105. }
  106. // Create new update to sign using the same fields as
  107. // the original. UpdateDisableFlag will mutate the
  108. // passed channel update, so we keep the old one to test
  109. // against.
  110. newUpdate := &lnwire.ChannelUpdate{
  111. Timestamp: ogUpdate.Timestamp,
  112. ChannelFlags: ogUpdate.ChannelFlags,
  113. }
  114. // Attempt to update and sign the new update, specifying
  115. // disabled or enabled as prescribed in the test case.
  116. err := netann.SignChannelUpdate(
  117. tc.signer, testKeyLoc, newUpdate,
  118. netann.ChanUpdSetDisable(tc.disable),
  119. netann.ChanUpdSetTimestamp,
  120. )
  121. var fail bool
  122. switch {
  123. // Both nil, pass.
  124. case tc.expErr == nil && err == nil:
  125. // Both non-nil, compare error strings since some
  126. // methods don't return concrete error types.
  127. case tc.expErr != nil && err != nil:
  128. if err.Error() != tc.expErr.Error() {
  129. fail = true
  130. }
  131. // Otherwise, one is nil and one is non-nil.
  132. default:
  133. fail = true
  134. }
  135. if fail {
  136. t.Fatalf("expected error: %v, got %v",
  137. tc.expErr, err)
  138. }
  139. // Exit early if the test expected a failure.
  140. if tc.expErr != nil {
  141. return
  142. }
  143. // Verify that the timestamp has increased from the
  144. // original update.
  145. if newUpdate.Timestamp <= ogUpdate.Timestamp {
  146. t.Fatalf("update timestamp should be "+
  147. "monotonically increasing, "+
  148. "original: %d, new %d",
  149. ogUpdate.Timestamp, newUpdate.Timestamp)
  150. }
  151. // Verify that the disabled flag is properly set.
  152. disabled := newUpdate.ChannelFlags&
  153. lnwire.ChanUpdateDisabled != 0
  154. if disabled != tc.disable {
  155. t.Fatalf("expected disable:%v, found:%v",
  156. tc.disable, disabled)
  157. }
  158. // Finally, validate the signature using the router's
  159. // verification logic.
  160. err = routing.VerifyChannelUpdateSignature(
  161. newUpdate, pubKey,
  162. )
  163. if err != nil {
  164. t.Fatalf("channel update failed to "+
  165. "validate: %v", err)
  166. }
  167. })
  168. }
  169. }