channel_update.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package netann
  2. import (
  3. "bytes"
  4. "fmt"
  5. "time"
  6. "github.com/btcsuite/btcd/btcec/v2"
  7. "github.com/lightningnetwork/lnd/channeldb/models"
  8. "github.com/lightningnetwork/lnd/keychain"
  9. "github.com/lightningnetwork/lnd/lnwallet"
  10. "github.com/lightningnetwork/lnd/lnwire"
  11. )
  12. // ErrUnableToExtractChanUpdate is returned when a channel update cannot be
  13. // found for one of our active channels.
  14. var ErrUnableToExtractChanUpdate = fmt.Errorf("unable to extract ChannelUpdate")
  15. // ChannelUpdateModifier is a closure that makes in-place modifications to an
  16. // lnwire.ChannelUpdate.
  17. type ChannelUpdateModifier func(*lnwire.ChannelUpdate)
  18. // ChanUpdSetDisable is a functional option that sets the disabled channel flag
  19. // if disabled is true, and clears the bit otherwise.
  20. func ChanUpdSetDisable(disabled bool) ChannelUpdateModifier {
  21. return func(update *lnwire.ChannelUpdate) {
  22. if disabled {
  23. // Set the bit responsible for marking a channel as
  24. // disabled.
  25. update.ChannelFlags |= lnwire.ChanUpdateDisabled
  26. } else {
  27. // Clear the bit responsible for marking a channel as
  28. // disabled.
  29. update.ChannelFlags &= ^lnwire.ChanUpdateDisabled
  30. }
  31. }
  32. }
  33. // ChanUpdSetTimestamp is a functional option that sets the timestamp of the
  34. // update to the current time, or increments it if the timestamp is already in
  35. // the future.
  36. func ChanUpdSetTimestamp(update *lnwire.ChannelUpdate) {
  37. newTimestamp := uint32(time.Now().Unix())
  38. if newTimestamp <= update.Timestamp {
  39. // Increment the prior value to ensure the timestamp
  40. // monotonically increases, otherwise the update won't
  41. // propagate.
  42. newTimestamp = update.Timestamp + 1
  43. }
  44. update.Timestamp = newTimestamp
  45. }
  46. // SignChannelUpdate applies the given modifiers to the passed
  47. // lnwire.ChannelUpdate, then signs the resulting update. The provided update
  48. // should be the most recent, valid update, otherwise the timestamp may not
  49. // monotonically increase from the prior.
  50. //
  51. // NOTE: This method modifies the given update.
  52. func SignChannelUpdate(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator,
  53. update *lnwire.ChannelUpdate, mods ...ChannelUpdateModifier) error {
  54. // Apply the requested changes to the channel update.
  55. for _, modifier := range mods {
  56. modifier(update)
  57. }
  58. // Create the DER-encoded ECDSA signature over the message digest.
  59. sig, err := SignAnnouncement(signer, keyLoc, update)
  60. if err != nil {
  61. return err
  62. }
  63. // Parse the DER-encoded signature into a fixed-size 64-byte array.
  64. update.Signature, err = lnwire.NewSigFromSignature(sig)
  65. if err != nil {
  66. return err
  67. }
  68. return nil
  69. }
  70. // ExtractChannelUpdate attempts to retrieve a lnwire.ChannelUpdate message from
  71. // an edge's info and a set of routing policies.
  72. //
  73. // NOTE: The passed policies can be nil.
  74. func ExtractChannelUpdate(ownerPubKey []byte,
  75. info *models.ChannelEdgeInfo,
  76. policies ...*models.ChannelEdgePolicy) (
  77. *lnwire.ChannelUpdate, error) {
  78. // Helper function to extract the owner of the given policy.
  79. owner := func(edge *models.ChannelEdgePolicy) []byte {
  80. var pubKey *btcec.PublicKey
  81. if edge.ChannelFlags&lnwire.ChanUpdateDirection == 0 {
  82. pubKey, _ = info.NodeKey1()
  83. } else {
  84. pubKey, _ = info.NodeKey2()
  85. }
  86. // If pubKey was not found, just return nil.
  87. if pubKey == nil {
  88. return nil
  89. }
  90. return pubKey.SerializeCompressed()
  91. }
  92. // Extract the channel update from the policy we own, if any.
  93. for _, edge := range policies {
  94. if edge != nil && bytes.Equal(ownerPubKey, owner(edge)) {
  95. return ChannelUpdateFromEdge(info, edge)
  96. }
  97. }
  98. return nil, ErrUnableToExtractChanUpdate
  99. }
  100. // UnsignedChannelUpdateFromEdge reconstructs an unsigned ChannelUpdate from the
  101. // given edge info and policy.
  102. func UnsignedChannelUpdateFromEdge(info *models.ChannelEdgeInfo,
  103. policy *models.ChannelEdgePolicy) *lnwire.ChannelUpdate {
  104. return &lnwire.ChannelUpdate{
  105. ChainHash: info.ChainHash,
  106. ShortChannelID: lnwire.NewShortChanIDFromInt(policy.ChannelID),
  107. Timestamp: uint32(policy.LastUpdate.Unix()),
  108. ChannelFlags: policy.ChannelFlags,
  109. MessageFlags: policy.MessageFlags,
  110. TimeLockDelta: policy.TimeLockDelta,
  111. HtlcMinimumMsat: policy.MinHTLC,
  112. HtlcMaximumMsat: policy.MaxHTLC,
  113. BaseFee: uint32(policy.FeeBaseMSat),
  114. FeeRate: uint32(policy.FeeProportionalMillionths),
  115. ExtraOpaqueData: policy.ExtraOpaqueData,
  116. }
  117. }
  118. // ChannelUpdateFromEdge reconstructs a signed ChannelUpdate from the given edge
  119. // info and policy.
  120. func ChannelUpdateFromEdge(info *models.ChannelEdgeInfo,
  121. policy *models.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) {
  122. update := UnsignedChannelUpdateFromEdge(info, policy)
  123. var err error
  124. update.Signature, err = lnwire.NewSigFromECDSARawSignature(
  125. policy.SigBytes,
  126. )
  127. if err != nil {
  128. return nil, err
  129. }
  130. return update, nil
  131. }