-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sweep: prepare for sweeper #1978
Conversation
49685bf
to
b569192
Compare
9c1cca0
to
158b97a
Compare
a168546
to
58c8813
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solid PR! The commit structure makes the set of changes very easy to review. The only comment re the commits, is that we typically like to add additional context to the commits themselves using the message body provided. We find that this helps to make the git history more detailed as each commit has a small body that explains the changes/rationale within it, and may also extend to the commits proceeding it as well (assuming we always work to retain commit order).
@@ -849,10 +849,6 @@ func (bo *breachedOutput) BuildWitness(signer lnwallet.Signer, txn *wire.MsgTx, | |||
return bo.witnessFunc(txn, hashCache, txinIdx) | |||
} | |||
|
|||
// Add compile-time constraint ensuring breachedOutput implements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rationale behind this change? Seems better from the PoV of unit tests, that we can feed in this interface into various methods in his file. After all, we may eventually extract this into the contractcourt
package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the interface because it was not used anywhere. But indeed, I can also see the breacharbiter
use an (its own) instance of the sweeper. Converted to Input
types.
sweep/sweeper.go
Outdated
Signer lnwallet.Signer | ||
} | ||
|
||
// NewSweeper returns a new Sweeper instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can instead be sweep.New
as it's the primary external facing struct within the package (atm).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed. Not completely sure if I like it, because it'll be another rename when we found out we need another important external facing struct.
sweep/sweeper.go
Outdated
cfg *SweeperConfig | ||
} | ||
|
||
// SweeperConfig contains dependencies of Sweeper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a period at the end of the sentence.
utxonursery.go
Outdated
// Store provides access to and modification of the persistent state | ||
// maintained about the utxo nursery's incubating outputs. | ||
Store NurseryStore | ||
|
||
// Sweeper manages the sweeping of unlocked outputs for nursery. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well at this point it actually just constructs the sweeping transactions.
return nil, err | ||
} | ||
|
||
log.Debugf("%T(%v): using %v sat/kw for sweep tx", c, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change, we've lost the debug logging here. Also just realized that we don't have a way currently to signal to the sweeper what conf timing, or fee rate that we'd like when sweeping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved logging to sweeper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added TODO for configurable fee rate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before we merge we should be able to specify the fee rate. In distinct areas in the codebase, we use 3 or 6 depending on how quickly we want the transaction to enter the chain. Some cases (CLTV timeouts) are more time sensitive than others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
return nil, err | ||
} | ||
|
||
log.Debugf("%T(%x): using %v sat/kw to sweep htlc"+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment here re losing the debug logging.
sweep/input.go
Outdated
// BaseInput contains all the information needed to sweep a output. | ||
type BaseInput struct { | ||
// InputKit contains the base information needed to sweep an output. | ||
type InputKit struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be public seeing as it's mostly used as a mix-in struct (via composition) now?
sweep/input.go
Outdated
@@ -72,28 +70,61 @@ func MakeBaseInput(outpoint *wire.OutPoint, | |||
} | |||
|
|||
// Amount returns the number of satoshis contained in the breached output. | |||
func (bi *BaseInput) Amount() btcutil.Amount { | |||
func (bi *InputKit) Amount() btcutil.Amount { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might cause vet on Go 1.11 to complain re the name of the method target...
sweep/input.go
Outdated
return &bi.signDesc | ||
} | ||
|
||
// AbsoluteMaturity returns the absolute timelock. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the absolute and relative maturity need to be a part of this struct? With the changes in this commit, it now serves more or less as the base class (via composition tho), and most "base" inputs don't require a CSV or CLTV semantics at all. Also if we go with my suggestion to always use non-final sequence locks inputs (or even randomize them as eventually we can make all transactions look like commitment transactions being broadcast) and use the next block height as the lock time value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you propose:
- Always set tx locktime to current height + 1
- Remove AbsoluteMaturity() from the interface completely, as it is no longer needed on the input level
- Remove relativeMaturity from BaseInput
- Implement BlockToMaturity of BaseInput as always returning 0
- Create a new struct CsvInput that allows setting the relative lock time
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove them only on this new baseInput
struct. Yes to the rest!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, got it. Didn't create CsvInput
yet, as it is not needed in this PR.
22e8545
to
d42c27a
Compare
Commit message bodies added |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
19deaee
to
608a9db
Compare
sweep/input.go
Outdated
|
||
// SpendableOutput an interface which can be used by the breach arbiter to | ||
// construct a transaction spending from outputs we control. | ||
type SpendableOutput interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice commit structure 👍
sweep/input.go
Outdated
// MakeBaseInput assembles a new BaseInput that can be used to construct a | ||
// sweep transaction. | ||
func MakeBaseInput(outpoint *wire.OutPoint, | ||
func makeInputKit(outpoint *wire.OutPoint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can remove makeInputKit
and just populate the struct manually where needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First I didn't like the suggestion, because I'd need to duplicate the amount assignment in makeInputKit. But then I realized that whole field is redundant. Removed it completely.
// spends from them. This method also makes an accurate fee estimate before | ||
// generating the required witnesses. | ||
// | ||
// The value of currentBlockHeight argument will be set as the tx locktime. This |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the parameter be called locktime
instead? Since we are currently not passing the correct block height.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expected value is currentBlockHeight, otherwise the comments would not be valid. Because we are currently not passing the block height in the contract resolvers, I added todo comments there.
sweep/sweeper.go
Outdated
sweepTx.AddTxIn(&wire.TxIn{ | ||
PreviousOutPoint: *input.OutPoint(), | ||
Sequence: input.BlocksToMaturity(), | ||
}) | ||
} | ||
for _, input := range cltvInputs { | ||
sweepTx.AddTxIn(&wire.TxIn{ | ||
PreviousOutPoint: *input.OutPoint(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is only set FF if NewTxIn
is used, so I don't think this will change the existing behavior.
d0aebc4
to
121d030
Compare
Comments addressed. |
sweep/sweeper.go
Outdated
return nil, err | ||
} | ||
|
||
log.Debugf("Using %v sat/kw for sweep tx", int64(feePerKw)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we consider making this info?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a commit that restructures the functions in a imo more logical way and unites the log statements.
This commit moves the output structs to a new package as a preparation for moving more logic into that package.
Sweep txes are currently generated in multiple locations. Moving the sweep tx generation into a shared package will allow us to reuse that logic.
This commit introduces a common interface for sweep inputs. It eliminates the type checking from UtxoSweeper. Also the formerly present Amount() getter is removed. It was redundant because this value is present in SignDesc().Output.Value as well.
Removes duplicate sweep tx code from commit resolver and delegates generation to UtxoSweeper in the sweep package.
c431e4b
to
95bf858
Compare
Comments addressed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🦎
) | ||
|
||
default: | ||
log.Warnf("kindergarten output in nursery store "+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this is consistent with the current behavior, but currently we won't add any weight estimate for unknown witness types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i take that back, the prior version would properly filter unknown output types and not include them in the transaction. the new version will include them
weightEstimate.AddWitnessInput( | ||
lnwallet.OfferedHtlcSuccessWitnessSize, | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing cltvCount++
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah wait, this is a new type that wasn't included before, nvm
} | ||
|
||
log.Infof("Creating sweep transaction for %v inputs (%v CSV, %v CLTV) "+ | ||
"using %v sat/kw", len(inputs), csvCount, cltvCount, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first argument should be len(inputs)-csvCount-cltvCount
, or len(inputs)-len(csvInputs)-len(cltvOutputs)
if getWeightEstimate
is modified to return slices of filtered inputs.
Added a small commit to restore prior behavior that filters unknown witness types #2062 |
Oh, good catch. I introduced that already in a commit before that last refactor commit. |
This PR makes changes that prepare for the new Sweeper struct.
A follow PR is #1960, which builds the sweeper around the sweep tx generation and uses that from
utxonursery
.