fee_bumper.go 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. package sweep
  2. import (
  3. "errors"
  4. "fmt"
  5. "sync"
  6. "sync/atomic"
  7. "github.com/btcsuite/btcd/btcutil"
  8. "github.com/btcsuite/btcd/chaincfg/chainhash"
  9. "github.com/btcsuite/btcd/rpcclient"
  10. "github.com/btcsuite/btcd/txscript"
  11. "github.com/btcsuite/btcd/wire"
  12. "github.com/btcsuite/btcwallet/chain"
  13. "github.com/davecgh/go-spew/spew"
  14. "github.com/lightningnetwork/lnd/chainntnfs"
  15. "github.com/lightningnetwork/lnd/fn"
  16. "github.com/lightningnetwork/lnd/input"
  17. "github.com/lightningnetwork/lnd/labels"
  18. "github.com/lightningnetwork/lnd/lnutils"
  19. "github.com/lightningnetwork/lnd/lnwallet"
  20. "github.com/lightningnetwork/lnd/lnwallet/chainfee"
  21. )
  22. var (
  23. // ErrInvalidBumpResult is returned when the bump result is invalid.
  24. ErrInvalidBumpResult = errors.New("invalid bump result")
  25. // ErrNotEnoughBudget is returned when the fee bumper decides the
  26. // current budget cannot cover the fee.
  27. ErrNotEnoughBudget = errors.New("not enough budget")
  28. // ErrLocktimeImmature is returned when sweeping an input whose
  29. // locktime is not reached.
  30. ErrLocktimeImmature = errors.New("immature input")
  31. // ErrTxNoOutput is returned when an output cannot be created during tx
  32. // preparation, usually due to the output being dust.
  33. ErrTxNoOutput = errors.New("tx has no output")
  34. // ErrThirdPartySpent is returned when a third party has spent the
  35. // input in the sweeping tx.
  36. ErrThirdPartySpent = errors.New("third party spent the output")
  37. )
  38. // Bumper defines an interface that can be used by other subsystems for fee
  39. // bumping.
  40. type Bumper interface {
  41. // Broadcast is used to publish the tx created from the given inputs
  42. // specified in the request. It handles the tx creation, broadcasts it,
  43. // and monitors its confirmation status for potential fee bumping. It
  44. // returns a chan that the caller can use to receive updates about the
  45. // broadcast result and potential RBF attempts.
  46. Broadcast(req *BumpRequest) (<-chan *BumpResult, error)
  47. }
  48. // BumpEvent represents the event of a fee bumping attempt.
  49. type BumpEvent uint8
  50. const (
  51. // TxPublished is sent when the broadcast attempt is finished.
  52. TxPublished BumpEvent = iota
  53. // TxFailed is sent when the broadcast attempt fails.
  54. TxFailed
  55. // TxReplaced is sent when the original tx is replaced by a new one.
  56. TxReplaced
  57. // TxConfirmed is sent when the tx is confirmed.
  58. TxConfirmed
  59. // sentinalEvent is used to check if an event is unknown.
  60. sentinalEvent
  61. )
  62. // String returns a human-readable string for the event.
  63. func (e BumpEvent) String() string {
  64. switch e {
  65. case TxPublished:
  66. return "Published"
  67. case TxFailed:
  68. return "Failed"
  69. case TxReplaced:
  70. return "Replaced"
  71. case TxConfirmed:
  72. return "Confirmed"
  73. default:
  74. return "Unknown"
  75. }
  76. }
  77. // Unknown returns true if the event is unknown.
  78. func (e BumpEvent) Unknown() bool {
  79. return e >= sentinalEvent
  80. }
  81. // BumpRequest is used by the caller to give the Bumper the necessary info to
  82. // create and manage potential fee bumps for a set of inputs.
  83. type BumpRequest struct {
  84. // Budget givens the total amount that can be used as fees by these
  85. // inputs.
  86. Budget btcutil.Amount
  87. // Inputs is the set of inputs to sweep.
  88. Inputs []input.Input
  89. // DeadlineHeight is the block height at which the tx should be
  90. // confirmed.
  91. DeadlineHeight int32
  92. // DeliveryAddress is the script to send the change output to.
  93. DeliveryAddress []byte
  94. // MaxFeeRate is the maximum fee rate that can be used for fee bumping.
  95. MaxFeeRate chainfee.SatPerKWeight
  96. // StartingFeeRate is an optional parameter that can be used to specify
  97. // the initial fee rate to use for the fee function.
  98. StartingFeeRate fn.Option[chainfee.SatPerKWeight]
  99. }
  100. // MaxFeeRateAllowed returns the maximum fee rate allowed for the given
  101. // request. It calculates the feerate using the supplied budget and the weight,
  102. // compares it with the specified MaxFeeRate, and returns the smaller of the
  103. // two.
  104. func (r *BumpRequest) MaxFeeRateAllowed() (chainfee.SatPerKWeight, error) {
  105. // Get the size of the sweep tx, which will be used to calculate the
  106. // budget fee rate.
  107. size, err := calcSweepTxWeight(r.Inputs, r.DeliveryAddress)
  108. if err != nil {
  109. return 0, err
  110. }
  111. // Use the budget and MaxFeeRate to decide the max allowed fee rate.
  112. // This is needed as, when the input has a large value and the user
  113. // sets the budget to be proportional to the input value, the fee rate
  114. // can be very high and we need to make sure it doesn't exceed the max
  115. // fee rate.
  116. maxFeeRateAllowed := chainfee.NewSatPerKWeight(r.Budget, size)
  117. if maxFeeRateAllowed > r.MaxFeeRate {
  118. log.Debugf("Budget feerate %v exceeds MaxFeeRate %v, use "+
  119. "MaxFeeRate instead, txWeight=%v", maxFeeRateAllowed,
  120. r.MaxFeeRate, size)
  121. return r.MaxFeeRate, nil
  122. }
  123. log.Debugf("Budget feerate %v below MaxFeeRate %v, use budget feerate "+
  124. "instead, txWeight=%v", maxFeeRateAllowed, r.MaxFeeRate, size)
  125. return maxFeeRateAllowed, nil
  126. }
  127. // calcSweepTxWeight calculates the weight of the sweep tx. It assumes a
  128. // sweeping tx always has a single output(change).
  129. func calcSweepTxWeight(inputs []input.Input,
  130. outputPkScript []byte) (uint64, error) {
  131. // Use a const fee rate as we only use the weight estimator to
  132. // calculate the size.
  133. const feeRate = 1
  134. // Initialize the tx weight estimator with,
  135. // - nil outputs as we only have one single change output.
  136. // - const fee rate as we don't care about the fees here.
  137. // - 0 maxfeerate as we don't care about fees here.
  138. //
  139. // TODO(yy): we should refactor the weight estimator to not require a
  140. // fee rate and max fee rate and make it a pure tx weight calculator.
  141. _, estimator, err := getWeightEstimate(
  142. inputs, nil, feeRate, 0, outputPkScript,
  143. )
  144. if err != nil {
  145. return 0, err
  146. }
  147. return uint64(estimator.weight()), nil
  148. }
  149. // BumpResult is used by the Bumper to send updates about the tx being
  150. // broadcast.
  151. type BumpResult struct {
  152. // Event is the type of event that the result is for.
  153. Event BumpEvent
  154. // Tx is the tx being broadcast.
  155. Tx *wire.MsgTx
  156. // ReplacedTx is the old, replaced tx if a fee bump is attempted.
  157. ReplacedTx *wire.MsgTx
  158. // FeeRate is the fee rate used for the new tx.
  159. FeeRate chainfee.SatPerKWeight
  160. // Fee is the fee paid by the new tx.
  161. Fee btcutil.Amount
  162. // Err is the error that occurred during the broadcast.
  163. Err error
  164. // requestID is the ID of the request that created this record.
  165. requestID uint64
  166. }
  167. // Validate validates the BumpResult so it's safe to use.
  168. func (b *BumpResult) Validate() error {
  169. // Every result must have a tx.
  170. if b.Tx == nil {
  171. return fmt.Errorf("%w: nil tx", ErrInvalidBumpResult)
  172. }
  173. // Every result must have a known event.
  174. if b.Event.Unknown() {
  175. return fmt.Errorf("%w: unknown event", ErrInvalidBumpResult)
  176. }
  177. // If it's a replacing event, it must have a replaced tx.
  178. if b.Event == TxReplaced && b.ReplacedTx == nil {
  179. return fmt.Errorf("%w: nil replacing tx", ErrInvalidBumpResult)
  180. }
  181. // If it's a failed event, it must have an error.
  182. if b.Event == TxFailed && b.Err == nil {
  183. return fmt.Errorf("%w: nil error", ErrInvalidBumpResult)
  184. }
  185. // If it's a confirmed event, it must have a fee rate and fee.
  186. if b.Event == TxConfirmed && (b.FeeRate == 0 || b.Fee == 0) {
  187. return fmt.Errorf("%w: missing fee rate or fee",
  188. ErrInvalidBumpResult)
  189. }
  190. return nil
  191. }
  192. // TxPublisherConfig is the config used to create a new TxPublisher.
  193. type TxPublisherConfig struct {
  194. // Signer is used to create the tx signature.
  195. Signer input.Signer
  196. // Wallet is used primarily to publish the tx.
  197. Wallet Wallet
  198. // Estimator is used to estimate the fee rate for the new tx based on
  199. // its deadline conf target.
  200. Estimator chainfee.Estimator
  201. // Notifier is used to monitor the confirmation status of the tx.
  202. Notifier chainntnfs.ChainNotifier
  203. }
  204. // TxPublisher is an implementation of the Bumper interface. It utilizes the
  205. // `testmempoolaccept` RPC to bump the fee of txns it created based on
  206. // different fee function selected or configed by the caller. Its purpose is to
  207. // take a list of inputs specified, and create a tx that spends them to a
  208. // specified output. It will then monitor the confirmation status of the tx,
  209. // and if it's not confirmed within a certain time frame, it will attempt to
  210. // bump the fee of the tx by creating a new tx that spends the same inputs to
  211. // the same output, but with a higher fee rate. It will continue to do this
  212. // until the tx is confirmed or the fee rate reaches the maximum fee rate
  213. // specified by the caller.
  214. type TxPublisher struct {
  215. wg sync.WaitGroup
  216. // cfg specifies the configuration of the TxPublisher.
  217. cfg *TxPublisherConfig
  218. // currentHeight is the current block height.
  219. currentHeight atomic.Int32
  220. // records is a map keyed by the requestCounter and the value is the tx
  221. // being monitored.
  222. records lnutils.SyncMap[uint64, *monitorRecord]
  223. // requestCounter is a monotonically increasing counter used to keep
  224. // track of how many requests have been made.
  225. requestCounter atomic.Uint64
  226. // subscriberChans is a map keyed by the requestCounter, each item is
  227. // the chan that the publisher sends the fee bump result to.
  228. subscriberChans lnutils.SyncMap[uint64, chan *BumpResult]
  229. // quit is used to signal the publisher to stop.
  230. quit chan struct{}
  231. }
  232. // Compile-time constraint to ensure TxPublisher implements Bumper.
  233. var _ Bumper = (*TxPublisher)(nil)
  234. // NewTxPublisher creates a new TxPublisher.
  235. func NewTxPublisher(cfg TxPublisherConfig) *TxPublisher {
  236. return &TxPublisher{
  237. cfg: &cfg,
  238. records: lnutils.SyncMap[uint64, *monitorRecord]{},
  239. subscriberChans: lnutils.SyncMap[uint64, chan *BumpResult]{},
  240. quit: make(chan struct{}),
  241. }
  242. }
  243. // isNeutrinoBackend checks if the wallet backend is neutrino.
  244. func (t *TxPublisher) isNeutrinoBackend() bool {
  245. return t.cfg.Wallet.BackEnd() == "neutrino"
  246. }
  247. // Broadcast is used to publish the tx created from the given inputs. It will,
  248. // 1. init a fee function based on the given strategy.
  249. // 2. create an RBF-compliant tx and monitor it for confirmation.
  250. // 3. notify the initial broadcast result back to the caller.
  251. // The initial broadcast is guaranteed to be RBF-compliant unless the budget
  252. // specified cannot cover the fee.
  253. //
  254. // NOTE: part of the Bumper interface.
  255. func (t *TxPublisher) Broadcast(req *BumpRequest) (<-chan *BumpResult, error) {
  256. log.Tracef("Received broadcast request: %s", newLogClosure(
  257. func() string {
  258. return spew.Sdump(req)
  259. })())
  260. // Attempt an initial broadcast which is guaranteed to comply with the
  261. // RBF rules.
  262. result, err := t.initialBroadcast(req)
  263. if err != nil {
  264. log.Errorf("Initial broadcast failed: %v", err)
  265. return nil, err
  266. }
  267. // Create a chan to send the result to the caller.
  268. subscriber := make(chan *BumpResult, 1)
  269. t.subscriberChans.Store(result.requestID, subscriber)
  270. // Send the initial broadcast result to the caller.
  271. t.handleResult(result)
  272. return subscriber, nil
  273. }
  274. // initialBroadcast initializes a fee function, creates an RBF-compliant tx and
  275. // broadcasts it.
  276. func (t *TxPublisher) initialBroadcast(req *BumpRequest) (*BumpResult, error) {
  277. // Create a fee bumping algorithm to be used for future RBF.
  278. feeAlgo, err := t.initializeFeeFunction(req)
  279. if err != nil {
  280. return nil, fmt.Errorf("init fee function: %w", err)
  281. }
  282. // Create the initial tx to be broadcasted. This tx is guaranteed to
  283. // comply with the RBF restrictions.
  284. requestID, err := t.createRBFCompliantTx(req, feeAlgo)
  285. if err != nil {
  286. return nil, fmt.Errorf("create RBF-compliant tx: %w", err)
  287. }
  288. // Broadcast the tx and return the monitored record.
  289. result, err := t.broadcast(requestID)
  290. if err != nil {
  291. return nil, fmt.Errorf("broadcast sweep tx: %w", err)
  292. }
  293. return result, nil
  294. }
  295. // initializeFeeFunction initializes a fee function to be used for this request
  296. // for future fee bumping.
  297. func (t *TxPublisher) initializeFeeFunction(
  298. req *BumpRequest) (FeeFunction, error) {
  299. // Get the max allowed feerate.
  300. maxFeeRateAllowed, err := req.MaxFeeRateAllowed()
  301. if err != nil {
  302. return nil, err
  303. }
  304. // Get the initial conf target.
  305. confTarget := calcCurrentConfTarget(
  306. t.currentHeight.Load(), req.DeadlineHeight,
  307. )
  308. log.Debugf("Initializing fee function with conf target=%v, budget=%v, "+
  309. "maxFeeRateAllowed=%v", confTarget, req.Budget,
  310. maxFeeRateAllowed)
  311. // Initialize the fee function and return it.
  312. //
  313. // TODO(yy): return based on differet req.Strategy?
  314. return NewLinearFeeFunction(
  315. maxFeeRateAllowed, confTarget, t.cfg.Estimator,
  316. req.StartingFeeRate,
  317. )
  318. }
  319. // createRBFCompliantTx creates a tx that is compliant with RBF rules. It does
  320. // so by creating a tx, validate it using `TestMempoolAccept`, and bump its fee
  321. // and redo the process until the tx is valid, or return an error when non-RBF
  322. // related errors occur or the budget has been used up.
  323. func (t *TxPublisher) createRBFCompliantTx(req *BumpRequest,
  324. f FeeFunction) (uint64, error) {
  325. for {
  326. // Create a new tx with the given fee rate and check its
  327. // mempool acceptance.
  328. tx, fee, err := t.createAndCheckTx(req, f)
  329. switch {
  330. case err == nil:
  331. // The tx is valid, return the request ID.
  332. requestID := t.storeRecord(tx, req, f, fee)
  333. log.Infof("Created tx %v for %v inputs: feerate=%v, "+
  334. "fee=%v, inputs=%v", tx.TxHash(),
  335. len(req.Inputs), f.FeeRate(), fee,
  336. inputTypeSummary(req.Inputs))
  337. return requestID, nil
  338. // If the error indicates the fees paid is not enough, we will
  339. // ask the fee function to increase the fee rate and retry.
  340. case errors.Is(err, lnwallet.ErrMempoolFee):
  341. // We should at least start with a feerate above the
  342. // mempool min feerate, so if we get this error, it
  343. // means something is wrong earlier in the pipeline.
  344. log.Errorf("Current fee=%v, feerate=%v, %v", fee,
  345. f.FeeRate(), err)
  346. fallthrough
  347. // We are not paying enough fees so we increase it.
  348. case errors.Is(err, rpcclient.ErrInsufficientFee):
  349. increased := false
  350. // Keep calling the fee function until the fee rate is
  351. // increased or maxed out.
  352. for !increased {
  353. log.Debugf("Increasing fee for next round, "+
  354. "current fee=%v, feerate=%v", fee,
  355. f.FeeRate())
  356. // If the fee function tells us that we have
  357. // used up the budget, we will return an error
  358. // indicating this tx cannot be made. The
  359. // sweeper should handle this error and try to
  360. // cluster these inputs differetly.
  361. increased, err = f.Increment()
  362. if err != nil {
  363. return 0, err
  364. }
  365. }
  366. // TODO(yy): suppose there's only one bad input, we can do a
  367. // binary search to find out which input is causing this error
  368. // by recreating a tx using half of the inputs and check its
  369. // mempool acceptance.
  370. default:
  371. log.Debugf("Failed to create RBF-compliant tx: %v", err)
  372. return 0, err
  373. }
  374. }
  375. }
  376. // storeRecord stores the given record in the records map.
  377. func (t *TxPublisher) storeRecord(tx *wire.MsgTx, req *BumpRequest,
  378. f FeeFunction, fee btcutil.Amount) uint64 {
  379. // Increase the request counter.
  380. //
  381. // NOTE: this is the only place where we increase the
  382. // counter.
  383. requestID := t.requestCounter.Add(1)
  384. // Register the record.
  385. t.records.Store(requestID, &monitorRecord{
  386. tx: tx,
  387. req: req,
  388. feeFunction: f,
  389. fee: fee,
  390. })
  391. return requestID
  392. }
  393. // createAndCheckTx creates a tx based on the given inputs, change output
  394. // script, and the fee rate. In addition, it validates the tx's mempool
  395. // acceptance before returning a tx that can be published directly, along with
  396. // its fee.
  397. func (t *TxPublisher) createAndCheckTx(req *BumpRequest, f FeeFunction) (
  398. *wire.MsgTx, btcutil.Amount, error) {
  399. // Create the sweep tx with max fee rate of 0 as the fee function
  400. // guarantees the fee rate used here won't exceed the max fee rate.
  401. tx, fee, err := t.createSweepTx(
  402. req.Inputs, req.DeliveryAddress, f.FeeRate(),
  403. )
  404. if err != nil {
  405. return nil, fee, fmt.Errorf("create sweep tx: %w", err)
  406. }
  407. // Sanity check the budget still covers the fee.
  408. if fee > req.Budget {
  409. return nil, fee, fmt.Errorf("%w: budget=%v, fee=%v",
  410. ErrNotEnoughBudget, req.Budget, fee)
  411. }
  412. // Validate the tx's mempool acceptance.
  413. err = t.cfg.Wallet.CheckMempoolAcceptance(tx)
  414. // Exit early if the tx is valid.
  415. if err == nil {
  416. return tx, fee, nil
  417. }
  418. // Print an error log if the chain backend doesn't support the mempool
  419. // acceptance test RPC.
  420. if errors.Is(err, rpcclient.ErrBackendVersion) {
  421. log.Errorf("TestMempoolAccept not supported by backend, " +
  422. "consider upgrading it to a newer version")
  423. return tx, fee, nil
  424. }
  425. // We are running on a backend that doesn't implement the RPC
  426. // testmempoolaccept, eg, neutrino, so we'll skip the check.
  427. if errors.Is(err, chain.ErrUnimplemented) {
  428. log.Debug("Skipped testmempoolaccept due to not implemented")
  429. return tx, fee, nil
  430. }
  431. return nil, fee, fmt.Errorf("tx=%v failed mempool check: %w",
  432. tx.TxHash(), err)
  433. }
  434. // broadcast takes a monitored tx and publishes it to the network. Prior to the
  435. // broadcast, it will subscribe the tx's confirmation notification and attach
  436. // the event channel to the record. Any broadcast-related errors will not be
  437. // returned here, instead, they will be put inside the `BumpResult` and
  438. // returned to the caller.
  439. func (t *TxPublisher) broadcast(requestID uint64) (*BumpResult, error) {
  440. // Get the record being monitored.
  441. record, ok := t.records.Load(requestID)
  442. if !ok {
  443. return nil, fmt.Errorf("tx record %v not found", requestID)
  444. }
  445. txid := record.tx.TxHash()
  446. tx := record.tx
  447. log.Debugf("Publishing sweep tx %v, num_inputs=%v, height=%v",
  448. txid, len(tx.TxIn), t.currentHeight.Load())
  449. // Set the event, and change it to TxFailed if the wallet fails to
  450. // publish it.
  451. event := TxPublished
  452. // Publish the sweeping tx with customized label. If the publish fails,
  453. // this error will be saved in the `BumpResult` and it will be removed
  454. // from being monitored.
  455. err := t.cfg.Wallet.PublishTransaction(
  456. tx, labels.MakeLabel(labels.LabelTypeSweepTransaction, nil),
  457. )
  458. if err != nil {
  459. // NOTE: we decide to attach this error to the result instead
  460. // of returning it here because by the time the tx reaches
  461. // here, it should have passed the mempool acceptance check. If
  462. // it still fails to be broadcast, it's likely a non-RBF
  463. // related error happened. So we send this error back to the
  464. // caller so that it can handle it properly.
  465. //
  466. // TODO(yy): find out which input is causing the failure.
  467. log.Errorf("Failed to publish tx %v: %v", txid, err)
  468. event = TxFailed
  469. }
  470. result := &BumpResult{
  471. Event: event,
  472. Tx: record.tx,
  473. Fee: record.fee,
  474. FeeRate: record.feeFunction.FeeRate(),
  475. Err: err,
  476. requestID: requestID,
  477. }
  478. return result, nil
  479. }
  480. // notifyResult sends the result to the resultChan specified by the requestID.
  481. // This channel is expected to be read by the caller.
  482. func (t *TxPublisher) notifyResult(result *BumpResult) {
  483. id := result.requestID
  484. subscriber, ok := t.subscriberChans.Load(id)
  485. if !ok {
  486. log.Errorf("Result chan for id=%v not found", id)
  487. return
  488. }
  489. log.Debugf("Sending result for requestID=%v, tx=%v", id,
  490. result.Tx.TxHash())
  491. select {
  492. // Send the result to the subscriber.
  493. //
  494. // TODO(yy): Add timeout in case it's blocking?
  495. case subscriber <- result:
  496. case <-t.quit:
  497. log.Debug("Fee bumper stopped")
  498. }
  499. }
  500. // removeResult removes the tracking of the result if the result contains a
  501. // non-nil error, or the tx is confirmed, the record will be removed from the
  502. // maps.
  503. func (t *TxPublisher) removeResult(result *BumpResult) {
  504. id := result.requestID
  505. // Remove the record from the maps if there's an error. This means this
  506. // tx has failed its broadcast and cannot be retried. There are two
  507. // cases,
  508. // - when the budget cannot cover the fee.
  509. // - when a non-RBF related error occurs.
  510. switch result.Event {
  511. case TxFailed:
  512. log.Errorf("Removing monitor record=%v, tx=%v, due to err: %v",
  513. id, result.Tx.TxHash(), result.Err)
  514. case TxConfirmed:
  515. // Remove the record is the tx is confirmed.
  516. log.Debugf("Removing confirmed monitor record=%v, tx=%v", id,
  517. result.Tx.TxHash())
  518. // Do nothing if it's neither failed or confirmed.
  519. default:
  520. log.Tracef("Skipping record removal for id=%v, event=%v", id,
  521. result.Event)
  522. return
  523. }
  524. t.records.Delete(id)
  525. t.subscriberChans.Delete(id)
  526. }
  527. // handleResult handles the result of a tx broadcast. It will notify the
  528. // subscriber and remove the record if the tx is confirmed or failed to be
  529. // broadcast.
  530. func (t *TxPublisher) handleResult(result *BumpResult) {
  531. // Notify the subscriber.
  532. t.notifyResult(result)
  533. // Remove the record if it's failed or confirmed.
  534. t.removeResult(result)
  535. }
  536. // monitorRecord is used to keep track of the tx being monitored by the
  537. // publisher internally.
  538. type monitorRecord struct {
  539. // tx is the tx being monitored.
  540. tx *wire.MsgTx
  541. // req is the original request.
  542. req *BumpRequest
  543. // feeFunction is the fee bumping algorithm used by the publisher.
  544. feeFunction FeeFunction
  545. // fee is the fee paid by the tx.
  546. fee btcutil.Amount
  547. }
  548. // Start starts the publisher by subscribing to block epoch updates and kicking
  549. // off the monitor loop.
  550. func (t *TxPublisher) Start() error {
  551. log.Info("TxPublisher starting...")
  552. defer log.Debugf("TxPublisher started")
  553. blockEvent, err := t.cfg.Notifier.RegisterBlockEpochNtfn(nil)
  554. if err != nil {
  555. return fmt.Errorf("register block epoch ntfn: %w", err)
  556. }
  557. t.wg.Add(1)
  558. go t.monitor(blockEvent)
  559. return nil
  560. }
  561. // Stop stops the publisher and waits for the monitor loop to exit.
  562. func (t *TxPublisher) Stop() {
  563. log.Info("TxPublisher stopping...")
  564. defer log.Debugf("TxPublisher stopped")
  565. close(t.quit)
  566. t.wg.Wait()
  567. }
  568. // monitor is the main loop driven by new blocks. Whevenr a new block arrives,
  569. // it will examine all the txns being monitored, and check if any of them needs
  570. // to be bumped. If so, it will attempt to bump the fee of the tx.
  571. //
  572. // NOTE: Must be run as a goroutine.
  573. func (t *TxPublisher) monitor(blockEvent *chainntnfs.BlockEpochEvent) {
  574. defer blockEvent.Cancel()
  575. defer t.wg.Done()
  576. for {
  577. select {
  578. case epoch, ok := <-blockEvent.Epochs:
  579. if !ok {
  580. // We should stop the publisher before stopping
  581. // the chain service. Otherwise it indicates an
  582. // error.
  583. log.Error("Block epoch channel closed, exit " +
  584. "monitor")
  585. return
  586. }
  587. log.Debugf("TxPublisher received new block: %v",
  588. epoch.Height)
  589. // Update the best known height for the publisher.
  590. t.currentHeight.Store(epoch.Height)
  591. // Check all monitored txns to see if any of them needs
  592. // to be bumped.
  593. t.processRecords()
  594. case <-t.quit:
  595. log.Debug("Fee bumper stopped, exit monitor")
  596. return
  597. }
  598. }
  599. }
  600. // processRecords checks all the txns being monitored, and checks if any of
  601. // them needs to be bumped. If so, it will attempt to bump the fee of the tx.
  602. func (t *TxPublisher) processRecords() {
  603. // confirmedRecords stores a map of the records which have been
  604. // confirmed.
  605. confirmedRecords := make(map[uint64]*monitorRecord)
  606. // feeBumpRecords stores a map of the records which need to be bumped.
  607. feeBumpRecords := make(map[uint64]*monitorRecord)
  608. // failedRecords stores a map of the records which has inputs being
  609. // spent by a third party.
  610. //
  611. // NOTE: this is only used for neutrino backend.
  612. failedRecords := make(map[uint64]*monitorRecord)
  613. // visitor is a helper closure that visits each record and divides them
  614. // into two groups.
  615. visitor := func(requestID uint64, r *monitorRecord) error {
  616. log.Tracef("Checking monitor recordID=%v for tx=%v", requestID,
  617. r.tx.TxHash())
  618. // If the tx is already confirmed, we can stop monitoring it.
  619. if t.isConfirmed(r.tx.TxHash()) {
  620. confirmedRecords[requestID] = r
  621. // Move to the next record.
  622. return nil
  623. }
  624. // Check whether the inputs has been spent by a third party.
  625. //
  626. // NOTE: this check is only done for neutrino backend.
  627. if t.isThirdPartySpent(r.tx.TxHash(), r.req.Inputs) {
  628. failedRecords[requestID] = r
  629. // Move to the next record.
  630. return nil
  631. }
  632. feeBumpRecords[requestID] = r
  633. // Return nil to move to the next record.
  634. return nil
  635. }
  636. // Iterate through all the records and divide them into two groups.
  637. t.records.ForEach(visitor)
  638. // For records that are confirmed, we'll notify the caller about this
  639. // result.
  640. for requestID, r := range confirmedRecords {
  641. rec := r
  642. log.Debugf("Tx=%v is confirmed", r.tx.TxHash())
  643. t.wg.Add(1)
  644. go t.handleTxConfirmed(rec, requestID)
  645. }
  646. // Get the current height to be used in the following goroutines.
  647. currentHeight := t.currentHeight.Load()
  648. // For records that are not confirmed, we perform a fee bump if needed.
  649. for requestID, r := range feeBumpRecords {
  650. rec := r
  651. log.Debugf("Attempting to fee bump Tx=%v", r.tx.TxHash())
  652. t.wg.Add(1)
  653. go t.handleFeeBumpTx(requestID, rec, currentHeight)
  654. }
  655. // For records that are failed, we'll notify the caller about this
  656. // result.
  657. for requestID, r := range failedRecords {
  658. rec := r
  659. log.Debugf("Tx=%v has inputs been spent by a third party, "+
  660. "failing it now", r.tx.TxHash())
  661. t.wg.Add(1)
  662. go t.handleThirdPartySpent(rec, requestID)
  663. }
  664. }
  665. // handleTxConfirmed is called when a monitored tx is confirmed. It will
  666. // notify the subscriber then remove the record from the maps .
  667. //
  668. // NOTE: Must be run as a goroutine to avoid blocking on sending the result.
  669. func (t *TxPublisher) handleTxConfirmed(r *monitorRecord, requestID uint64) {
  670. defer t.wg.Done()
  671. // Create a result that will be sent to the resultChan which is
  672. // listened by the caller.
  673. result := &BumpResult{
  674. Event: TxConfirmed,
  675. Tx: r.tx,
  676. requestID: requestID,
  677. Fee: r.fee,
  678. FeeRate: r.feeFunction.FeeRate(),
  679. }
  680. // Notify that this tx is confirmed and remove the record from the map.
  681. t.handleResult(result)
  682. }
  683. // handleFeeBumpTx checks if the tx needs to be bumped, and if so, it will
  684. // attempt to bump the fee of the tx.
  685. //
  686. // NOTE: Must be run as a goroutine to avoid blocking on sending the result.
  687. func (t *TxPublisher) handleFeeBumpTx(requestID uint64, r *monitorRecord,
  688. currentHeight int32) {
  689. defer t.wg.Done()
  690. oldTxid := r.tx.TxHash()
  691. // Get the current conf target for this record.
  692. confTarget := calcCurrentConfTarget(currentHeight, r.req.DeadlineHeight)
  693. // Ask the fee function whether a bump is needed. We expect the fee
  694. // function to increase its returned fee rate after calling this
  695. // method.
  696. increased, err := r.feeFunction.IncreaseFeeRate(confTarget)
  697. if err != nil {
  698. // TODO(yy): send this error back to the sweeper so it can
  699. // re-group the inputs?
  700. log.Errorf("Failed to increase fee rate for tx %v at "+
  701. "height=%v: %v", oldTxid, t.currentHeight.Load(), err)
  702. return
  703. }
  704. // If the fee rate was not increased, there's no need to bump the fee.
  705. if !increased {
  706. log.Tracef("Skip bumping tx %v at height=%v", oldTxid,
  707. t.currentHeight.Load())
  708. return
  709. }
  710. // The fee function now has a new fee rate, we will use it to bump the
  711. // fee of the tx.
  712. resultOpt := t.createAndPublishTx(requestID, r)
  713. // If there's a result, we will notify the caller about the result.
  714. resultOpt.WhenSome(func(result BumpResult) {
  715. // Notify the new result.
  716. t.handleResult(&result)
  717. })
  718. }
  719. // handleThirdPartySpent is called when the inputs in an unconfirmed tx is
  720. // spent. It will notify the subscriber then remove the record from the maps
  721. // and send a TxFailed event to the subscriber.
  722. //
  723. // NOTE: Must be run as a goroutine to avoid blocking on sending the result.
  724. func (t *TxPublisher) handleThirdPartySpent(r *monitorRecord,
  725. requestID uint64) {
  726. defer t.wg.Done()
  727. // Create a result that will be sent to the resultChan which is
  728. // listened by the caller.
  729. //
  730. // TODO(yy): create a new state `TxThirdPartySpent` to notify the
  731. // sweeper to remove the input, hence moving the monitoring of inputs
  732. // spent inside the fee bumper.
  733. result := &BumpResult{
  734. Event: TxFailed,
  735. Tx: r.tx,
  736. requestID: requestID,
  737. Err: ErrThirdPartySpent,
  738. }
  739. // Notify that this tx is confirmed and remove the record from the map.
  740. t.handleResult(result)
  741. }
  742. // createAndPublishTx creates a new tx with a higher fee rate and publishes it
  743. // to the network. It will update the record with the new tx and fee rate if
  744. // successfully created, and return the result when published successfully.
  745. func (t *TxPublisher) createAndPublishTx(requestID uint64,
  746. r *monitorRecord) fn.Option[BumpResult] {
  747. // Fetch the old tx.
  748. oldTx := r.tx
  749. // Create a new tx with the new fee rate.
  750. //
  751. // NOTE: The fee function is expected to have increased its returned
  752. // fee rate after calling the SkipFeeBump method. So we can use it
  753. // directly here.
  754. tx, fee, err := t.createAndCheckTx(r.req, r.feeFunction)
  755. // If the error is fee related, we will return no error and let the fee
  756. // bumper retry it at next block.
  757. //
  758. // NOTE: we can check the RBF error here and ask the fee function to
  759. // recalculate the fee rate. However, this would defeat the purpose of
  760. // using a deadline based fee function:
  761. // - if the deadline is far away, there's no rush to RBF the tx.
  762. // - if the deadline is close, we expect the fee function to give us a
  763. // higher fee rate. If the fee rate cannot satisfy the RBF rules, it
  764. // means the budget is not enough.
  765. if errors.Is(err, rpcclient.ErrInsufficientFee) ||
  766. errors.Is(err, lnwallet.ErrMempoolFee) {
  767. log.Debugf("Failed to bump tx %v: %v", oldTx.TxHash(), err)
  768. return fn.None[BumpResult]()
  769. }
  770. // If the error is not fee related, we will return a `TxFailed` event
  771. // so this input can be retried.
  772. if err != nil {
  773. // If the tx doesn't not have enought budget, we will return a
  774. // result so the sweeper can handle it by re-clustering the
  775. // utxos.
  776. if errors.Is(err, ErrNotEnoughBudget) {
  777. log.Warnf("Fail to fee bump tx %v: %v", oldTx.TxHash(),
  778. err)
  779. } else {
  780. // Otherwise, an unexpected error occurred, we will
  781. // fail the tx and let the sweeper retry the whole
  782. // process.
  783. log.Errorf("Failed to bump tx %v: %v", oldTx.TxHash(),
  784. err)
  785. }
  786. return fn.Some(BumpResult{
  787. Event: TxFailed,
  788. Tx: oldTx,
  789. Err: err,
  790. requestID: requestID,
  791. })
  792. }
  793. // The tx has been created without any errors, we now register a new
  794. // record by overwriting the same requestID.
  795. t.records.Store(requestID, &monitorRecord{
  796. tx: tx,
  797. req: r.req,
  798. feeFunction: r.feeFunction,
  799. fee: fee,
  800. })
  801. // Attempt to broadcast this new tx.
  802. result, err := t.broadcast(requestID)
  803. if err != nil {
  804. log.Infof("Failed to broadcast replacement tx %v: %v",
  805. tx.TxHash(), err)
  806. return fn.None[BumpResult]()
  807. }
  808. // If the result error is fee related, we will return no error and let
  809. // the fee bumper retry it at next block.
  810. //
  811. // NOTE: we may get this error if we've bypassed the mempool check,
  812. // which means we are suing neutrino backend.
  813. if errors.Is(result.Err, rpcclient.ErrInsufficientFee) ||
  814. errors.Is(result.Err, lnwallet.ErrMempoolFee) {
  815. log.Debugf("Failed to bump tx %v: %v", oldTx.TxHash(), err)
  816. return fn.None[BumpResult]()
  817. }
  818. // A successful replacement tx is created, attach the old tx.
  819. result.ReplacedTx = oldTx
  820. // If the new tx failed to be published, we will return the result so
  821. // the caller can handle it.
  822. if result.Event == TxFailed {
  823. return fn.Some(*result)
  824. }
  825. log.Infof("Replaced tx=%v with new tx=%v", oldTx.TxHash(), tx.TxHash())
  826. // Otherwise, it's a successful RBF, set the event and return.
  827. result.Event = TxReplaced
  828. return fn.Some(*result)
  829. }
  830. // isConfirmed checks the btcwallet to see whether the tx is confirmed.
  831. func (t *TxPublisher) isConfirmed(txid chainhash.Hash) bool {
  832. details, err := t.cfg.Wallet.GetTransactionDetails(&txid)
  833. if err != nil {
  834. log.Warnf("Failed to get tx details for %v: %v", txid, err)
  835. return false
  836. }
  837. return details.NumConfirmations > 0
  838. }
  839. // isThirdPartySpent checks whether the inputs of the tx has already been spent
  840. // by a third party. When a tx is not confirmed, yet its inputs has been spent,
  841. // then it must be spent by a different tx other than the sweeping tx here.
  842. //
  843. // NOTE: this check is only performed for neutrino backend as it has no
  844. // reliable way to tell a tx has been replaced.
  845. func (t *TxPublisher) isThirdPartySpent(txid chainhash.Hash,
  846. inputs []input.Input) bool {
  847. // Skip this check for if this is not neutrino backend.
  848. if !t.isNeutrinoBackend() {
  849. return false
  850. }
  851. // Iterate all the inputs and check if they have been spent already.
  852. for _, inp := range inputs {
  853. op := inp.OutPoint()
  854. // For wallet utxos, the height hint is not set - we don't need
  855. // to monitor them for third party spend.
  856. heightHint := inp.HeightHint()
  857. if heightHint == 0 {
  858. log.Debugf("Skipped third party check for wallet "+
  859. "input %v", op)
  860. continue
  861. }
  862. // If the input has already been spent after the height hint, a
  863. // spend event is sent back immediately.
  864. spendEvent, err := t.cfg.Notifier.RegisterSpendNtfn(
  865. &op, inp.SignDesc().Output.PkScript, heightHint,
  866. )
  867. if err != nil {
  868. log.Criticalf("Failed to register spend ntfn for "+
  869. "input=%v: %v", op, err)
  870. return false
  871. }
  872. // Remove the subscription when exit.
  873. defer spendEvent.Cancel()
  874. // Do a non-blocking read to see if the output has been spent.
  875. select {
  876. case spend, ok := <-spendEvent.Spend:
  877. if !ok {
  878. log.Debugf("Spend ntfn for %v canceled", op)
  879. return false
  880. }
  881. spendingTxID := spend.SpendingTx.TxHash()
  882. // If the spending tx is the same as the sweeping tx
  883. // then we are good.
  884. if spendingTxID == txid {
  885. continue
  886. }
  887. log.Warnf("Detected third party spent of output=%v "+
  888. "in tx=%v", op, spend.SpendingTx.TxHash())
  889. return true
  890. // Move to the next input.
  891. default:
  892. }
  893. }
  894. return false
  895. }
  896. // calcCurrentConfTarget calculates the current confirmation target based on
  897. // the deadline height. The conf target is capped at 0 if the deadline has
  898. // already been past.
  899. func calcCurrentConfTarget(currentHeight, deadline int32) uint32 {
  900. var confTarget uint32
  901. // Calculate how many blocks left until the deadline.
  902. deadlineDelta := deadline - currentHeight
  903. // If we are already past the deadline, we will set the conf target to
  904. // be 1.
  905. if deadlineDelta < 0 {
  906. log.Warnf("Deadline is %d blocks behind current height %v",
  907. -deadlineDelta, currentHeight)
  908. confTarget = 0
  909. } else {
  910. confTarget = uint32(deadlineDelta)
  911. }
  912. return confTarget
  913. }
  914. // createSweepTx creates a sweeping tx based on the given inputs, change
  915. // address and fee rate.
  916. func (t *TxPublisher) createSweepTx(inputs []input.Input, changePkScript []byte,
  917. feeRate chainfee.SatPerKWeight) (*wire.MsgTx, btcutil.Amount, error) {
  918. // Validate and calculate the fee and change amount.
  919. txFee, changeAmtOpt, locktimeOpt, err := prepareSweepTx(
  920. inputs, changePkScript, feeRate, t.currentHeight.Load(),
  921. )
  922. if err != nil {
  923. return nil, 0, err
  924. }
  925. var (
  926. // Create the sweep transaction that we will be building. We
  927. // use version 2 as it is required for CSV.
  928. sweepTx = wire.NewMsgTx(2)
  929. // We'll add the inputs as we go so we know the final ordering
  930. // of inputs to sign.
  931. idxs []input.Input
  932. )
  933. // We start by adding all inputs that commit to an output. We do this
  934. // since the input and output index must stay the same for the
  935. // signatures to be valid.
  936. for _, o := range inputs {
  937. if o.RequiredTxOut() == nil {
  938. continue
  939. }
  940. idxs = append(idxs, o)
  941. sweepTx.AddTxIn(&wire.TxIn{
  942. PreviousOutPoint: o.OutPoint(),
  943. Sequence: o.BlocksToMaturity(),
  944. })
  945. sweepTx.AddTxOut(o.RequiredTxOut())
  946. }
  947. // Sum up the value contained in the remaining inputs, and add them to
  948. // the sweep transaction.
  949. for _, o := range inputs {
  950. if o.RequiredTxOut() != nil {
  951. continue
  952. }
  953. idxs = append(idxs, o)
  954. sweepTx.AddTxIn(&wire.TxIn{
  955. PreviousOutPoint: o.OutPoint(),
  956. Sequence: o.BlocksToMaturity(),
  957. })
  958. }
  959. // If there's a change amount, add it to the transaction.
  960. changeAmtOpt.WhenSome(func(changeAmt btcutil.Amount) {
  961. sweepTx.AddTxOut(&wire.TxOut{
  962. PkScript: changePkScript,
  963. Value: int64(changeAmt),
  964. })
  965. })
  966. // We'll default to using the current block height as locktime, if none
  967. // of the inputs commits to a different locktime.
  968. sweepTx.LockTime = uint32(locktimeOpt.UnwrapOr(t.currentHeight.Load()))
  969. prevInputFetcher, err := input.MultiPrevOutFetcher(inputs)
  970. if err != nil {
  971. return nil, 0, fmt.Errorf("error creating prev input fetcher "+
  972. "for hash cache: %v", err)
  973. }
  974. hashCache := txscript.NewTxSigHashes(sweepTx, prevInputFetcher)
  975. // With all the inputs in place, use each output's unique input script
  976. // function to generate the final witness required for spending.
  977. addInputScript := func(idx int, tso input.Input) error {
  978. inputScript, err := tso.CraftInputScript(
  979. t.cfg.Signer, sweepTx, hashCache, prevInputFetcher, idx,
  980. )
  981. if err != nil {
  982. return err
  983. }
  984. sweepTx.TxIn[idx].Witness = inputScript.Witness
  985. if len(inputScript.SigScript) == 0 {
  986. return nil
  987. }
  988. sweepTx.TxIn[idx].SignatureScript = inputScript.SigScript
  989. return nil
  990. }
  991. for idx, inp := range idxs {
  992. if err := addInputScript(idx, inp); err != nil {
  993. return nil, 0, err
  994. }
  995. }
  996. log.Debugf("Created sweep tx %v for %v inputs", sweepTx.TxHash(),
  997. len(inputs))
  998. return sweepTx, txFee, nil
  999. }
  1000. // prepareSweepTx returns the tx fee, an optional change amount and an optional
  1001. // locktime after a series of validations:
  1002. // 1. check the locktime has been reached.
  1003. // 2. check the locktimes are the same.
  1004. // 3. check the inputs cover the outputs.
  1005. //
  1006. // NOTE: if the change amount is below dust, it will be added to the tx fee.
  1007. func prepareSweepTx(inputs []input.Input, changePkScript []byte,
  1008. feeRate chainfee.SatPerKWeight, currentHeight int32) (
  1009. btcutil.Amount, fn.Option[btcutil.Amount], fn.Option[int32], error) {
  1010. noChange := fn.None[btcutil.Amount]()
  1011. noLocktime := fn.None[int32]()
  1012. // Creating a weight estimator with nil outputs and zero max fee rate.
  1013. // We don't allow adding customized outputs in the sweeping tx, and the
  1014. // fee rate is already being managed before we get here.
  1015. inputs, estimator, err := getWeightEstimate(
  1016. inputs, nil, feeRate, 0, changePkScript,
  1017. )
  1018. if err != nil {
  1019. return 0, noChange, noLocktime, err
  1020. }
  1021. txFee := estimator.fee()
  1022. var (
  1023. // Track whether any of the inputs require a certain locktime.
  1024. locktime = int32(-1)
  1025. // We keep track of total input amount, and required output
  1026. // amount to use for calculating the change amount below.
  1027. totalInput btcutil.Amount
  1028. requiredOutput btcutil.Amount
  1029. )
  1030. // Go through each input and check if the required lock times have
  1031. // reached and are the same.
  1032. for _, o := range inputs {
  1033. // If the input has a required output, we'll add it to the
  1034. // required output amount.
  1035. if o.RequiredTxOut() != nil {
  1036. requiredOutput += btcutil.Amount(
  1037. o.RequiredTxOut().Value,
  1038. )
  1039. }
  1040. // Update the total input amount.
  1041. totalInput += btcutil.Amount(o.SignDesc().Output.Value)
  1042. lt, ok := o.RequiredLockTime()
  1043. // Skip if the input doesn't require a lock time.
  1044. if !ok {
  1045. continue
  1046. }
  1047. // Check if the lock time has reached
  1048. if lt > uint32(currentHeight) {
  1049. return 0, noChange, noLocktime, ErrLocktimeImmature
  1050. }
  1051. // If another input commits to a different locktime, they
  1052. // cannot be combined in the same transaction.
  1053. if locktime != -1 && locktime != int32(lt) {
  1054. return 0, noChange, noLocktime, ErrLocktimeConflict
  1055. }
  1056. // Update the locktime for next iteration.
  1057. locktime = int32(lt)
  1058. }
  1059. // Make sure total output amount is less than total input amount.
  1060. if requiredOutput+txFee > totalInput {
  1061. return 0, noChange, noLocktime, fmt.Errorf("insufficient "+
  1062. "input to create sweep tx: input_sum=%v, "+
  1063. "output_sum=%v", totalInput, requiredOutput+txFee)
  1064. }
  1065. // The value remaining after the required output and fees is the
  1066. // change output.
  1067. changeAmt := totalInput - requiredOutput - txFee
  1068. changeAmtOpt := fn.Some(changeAmt)
  1069. // We'll calculate the dust limit for the given changePkScript since it
  1070. // is variable.
  1071. changeFloor := lnwallet.DustLimitForSize(len(changePkScript))
  1072. // If the change amount is dust, we'll move it into the fees.
  1073. if changeAmt < changeFloor {
  1074. log.Infof("Change amt %v below dustlimit %v, not adding "+
  1075. "change output", changeAmt, changeFloor)
  1076. // If there's no required output, and the change output is a
  1077. // dust, it means we are creating a tx without any outputs. In
  1078. // this case we'll return an error. This could happen when
  1079. // creating a tx that has an anchor as the only input.
  1080. if requiredOutput == 0 {
  1081. return 0, noChange, noLocktime, ErrTxNoOutput
  1082. }
  1083. // The dust amount is added to the fee.
  1084. txFee += changeAmt
  1085. // Set the change amount to none.
  1086. changeAmtOpt = fn.None[btcutil.Amount]()
  1087. }
  1088. // Optionally set the locktime.
  1089. locktimeOpt := fn.Some(locktime)
  1090. if locktime == -1 {
  1091. locktimeOpt = noLocktime
  1092. }
  1093. log.Debugf("Creating sweep tx for %v inputs (%s) using %v, "+
  1094. "tx_weight=%v, tx_fee=%v, locktime=%v, parents_count=%v, "+
  1095. "parents_fee=%v, parents_weight=%v, current_height=%v",
  1096. len(inputs), inputTypeSummary(inputs), feeRate,
  1097. estimator.weight(), txFee, locktimeOpt, len(estimator.parents),
  1098. estimator.parentsFee, estimator.parentsWeight, currentHeight)
  1099. return txFee, changeAmtOpt, locktimeOpt, nil
  1100. }