Skip to content
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: create sweeper #1960

Merged
merged 13 commits into from
Dec 19, 2018
Merged
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ _testmain.go
/lnd-debug
/lncli
/lncli-debug
/lnd-itest
/lncli-itest

# Integration test log files
output*.log
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ build:
$(GOBUILD) -tags="$(DEV_TAGS)" -o lnd-debug $(LDFLAGS) $(PKG)
$(GOBUILD) -tags="$(DEV_TAGS)" -o lncli-debug $(LDFLAGS) $(PKG)/cmd/lncli

build-itest:
joostjager marked this conversation as resolved.
Show resolved Hide resolved
@$(call print, "Building itest lnd and lncli.")
$(GOBUILD) -tags="$(ITEST_TAGS)" -o lnd-itest $(LDFLAGS) $(PKG)
$(GOBUILD) -tags="$(ITEST_TAGS)" -o lncli-itest $(LDFLAGS) $(PKG)/cmd/lncli

install:
@$(call print, "Installing lnd and lncli.")
$(GOINSTALL) -tags="${tags}" $(LDFLAGS) $(PKG)
Expand All @@ -118,7 +123,7 @@ itest-only:
@$(call print, "Running integration tests.")
$(ITEST)

itest: btcd build itest-only
itest: btcd build-itest itest-only

unit: btcd
@$(call print, "Running unit tests.")
Expand Down Expand Up @@ -181,6 +186,7 @@ rpc:
clean:
@$(call print, "Cleaning source.$(NC)")
$(RM) ./lnd-debug ./lncli-debug
$(RM) ./lnd-itest ./lncli-itest
$(RM) -r ./vendor .vendor-new


Expand Down
20 changes: 16 additions & 4 deletions breacharbiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,7 @@ type breachedOutput struct {
outpoint wire.OutPoint
witnessType lnwallet.WitnessType
signDesc lnwallet.SignDescriptor
confHeight uint32

secondLevelWitnessScript []byte

Expand All @@ -768,7 +769,8 @@ type breachedOutput struct {
func makeBreachedOutput(outpoint *wire.OutPoint,
witnessType lnwallet.WitnessType,
secondLevelScript []byte,
signDescriptor *lnwallet.SignDescriptor) breachedOutput {
signDescriptor *lnwallet.SignDescriptor,
confHeight uint32) breachedOutput {

amount := signDescriptor.Output.Value

Expand All @@ -778,6 +780,7 @@ func makeBreachedOutput(outpoint *wire.OutPoint,
secondLevelWitnessScript: secondLevelScript,
witnessType: witnessType,
signDesc: *signDescriptor,
confHeight: confHeight,
}
}

Expand Down Expand Up @@ -831,6 +834,12 @@ func (bo *breachedOutput) BlocksToMaturity() uint32 {
return 0
}

// HeightHint returns the minimum height at which a confirmed spending tx can
// occur.
func (bo *breachedOutput) HeightHint() uint32 {
return bo.confHeight
}

// Add compile-time constraint ensuring breachedOutput implements the Input
// interface.
var _ sweep.Input = (*breachedOutput)(nil)
Expand Down Expand Up @@ -878,7 +887,8 @@ func newRetributionInfo(chanPoint *wire.OutPoint,
// No second level script as this is a commitment
// output.
nil,
breachInfo.LocalOutputSignDesc)
breachInfo.LocalOutputSignDesc,
breachInfo.BreachHeight)

breachedOutputs = append(breachedOutputs, localOutput)
}
Expand All @@ -895,7 +905,8 @@ func newRetributionInfo(chanPoint *wire.OutPoint,
// No second level script as this is a commitment
// output.
nil,
breachInfo.RemoteOutputSignDesc)
breachInfo.RemoteOutputSignDesc,
breachInfo.BreachHeight)

breachedOutputs = append(breachedOutputs, remoteOutput)
}
Expand All @@ -919,7 +930,8 @@ func newRetributionInfo(chanPoint *wire.OutPoint,
&breachInfo.HtlcRetributions[i].OutPoint,
htlcWitnessType,
breachInfo.HtlcRetributions[i].SecondLevelWitnessScript,
&breachInfo.HtlcRetributions[i].SignDesc)
&breachInfo.HtlcRetributions[i].SignDesc,
breachInfo.BreachHeight)

breachedOutputs = append(breachedOutputs, htlcOutput)
}
Expand Down
4 changes: 2 additions & 2 deletions breacharbiter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@ func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent,
ba := newBreachArbiter(&BreachConfig{
CloseLink: func(_ *wire.OutPoint, _ htlcswitch.ChannelCloseType) {},
DB: db,
Estimator: &lnwallet.StaticFeeEstimator{FeePerKW: 12500},
Estimator: lnwallet.NewStaticFeeEstimator(12500, 0),
GenSweepScript: func() ([]byte, error) { return nil, nil },
ContractBreaches: contractBreaches,
Signer: signer,
Expand Down Expand Up @@ -1476,7 +1476,7 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa
return nil, nil, nil, err
}

estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 12500}
estimator := lnwallet.NewStaticFeeEstimator(12500, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
return nil, nil, nil, err
Expand Down
12 changes: 6 additions & 6 deletions chainregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,19 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
FeeRate: cfg.Bitcoin.FeeRate,
TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
}
cc.feeEstimator = lnwallet.StaticFeeEstimator{
FeePerKW: defaultBitcoinStaticFeePerKW,
}
cc.feeEstimator = lnwallet.NewStaticFeeEstimator(
defaultBitcoinStaticFeePerKW, 0,
)
case litecoinChain:
cc.routingPolicy = htlcswitch.ForwardingPolicy{
MinHTLC: cfg.Litecoin.MinHTLC,
BaseFee: cfg.Litecoin.BaseFee,
FeeRate: cfg.Litecoin.FeeRate,
TimeLockDelta: cfg.Litecoin.TimeLockDelta,
}
cc.feeEstimator = lnwallet.StaticFeeEstimator{
FeePerKW: defaultLitecoinStaticFeePerKW,
}
cc.feeEstimator = lnwallet.NewStaticFeeEstimator(
defaultLitecoinStaticFeePerKW, 0,
)
default:
return nil, nil, fmt.Errorf("Default routing policy for "+
"chain %v is unknown", registeredChains.PrimaryChain())
Expand Down
6 changes: 6 additions & 0 deletions contractcourt/contract_resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
&h.htlcResolution.ClaimOutpoint,
&h.htlcResolution.SweepSignDesc,
h.htlcResolution.Preimage[:],
h.broadcastHeight,
)

// With the input created, we can now generate the full
Expand All @@ -471,6 +472,8 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
// TODO: Set tx lock time to current block height
// instead of zero. Will be taken care of once sweeper
// implementation is complete.
//
// TODO: Use time-based sweeper and result chan.
var err error
h.sweepTx, err = h.Sweeper.CreateSweepTx(
[]sweep.Input{&input}, sweepConfTarget, 0,
Expand Down Expand Up @@ -1254,6 +1257,7 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) {
&c.commitResolution.SelfOutPoint,
lnwallet.CommitmentNoDelay,
&c.commitResolution.SelfOutputSignDesc,
c.broadcastHeight,
)

// With out input constructed, we'll now request that the
Expand All @@ -1263,6 +1267,8 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) {
// TODO: Set tx lock time to current block height instead of
// zero. Will be taken care of once sweeper implementation is
// complete.
//
// TODO: Use time-based sweeper and result chan.
c.sweepTx, err = c.Sweeper.CreateSweepTx(
[]sweep.Input{&input}, sweepConfTarget, 0,
)
Expand Down
6 changes: 4 additions & 2 deletions fundingmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
addr *lnwire.NetAddress, tempTestDir string) (*testNode, error) {

netParams := activeNetParams.Params
estimator := lnwallet.StaticFeeEstimator{FeePerKW: 62500}
estimator := lnwallet.NewStaticFeeEstimator(62500, 0)

chainNotifier := &mockNotifier{
oneConfChannel: make(chan *chainntnfs.TxConfirmation, 1),
Expand All @@ -250,7 +250,9 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
signer := &mockSigner{
key: alicePrivKey,
}
bio := &mockChainIO{}
bio := &mockChainIO{
bestHeight: fundingBroadcastHeight,
}

dbDir := filepath.Join(tempTestDir, "cdb")
cdb, err := channeldb.Open(dbDir)
Expand Down
10 changes: 5 additions & 5 deletions htlcswitch/link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1795,7 +1795,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) {
coreLink.cfg.HodlMask = hodl.MaskFromFlags(hodl.ExitSettle)
coreLink.cfg.DebugHTLC = true

estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
t.Fatalf("unable to query fee estimator: %v", err)
Expand Down Expand Up @@ -2206,7 +2206,7 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) {
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
)

estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
t.Fatalf("unable to query fee estimator: %v", err)
Expand Down Expand Up @@ -2453,7 +2453,7 @@ func TestChannelLinkTrimCircuitsPending(t *testing.T) {

// Compute the static fees that will be used to determine the
// correctness of Alice's bandwidth when forwarding HTLCs.
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
t.Fatalf("unable to query fee estimator: %v", err)
Expand Down Expand Up @@ -2731,7 +2731,7 @@ func TestChannelLinkTrimCircuitsNoCommit(t *testing.T) {

// Compute the static fees that will be used to determine the
// correctness of Alice's bandwidth when forwarding HTLCs.
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
t.Fatalf("unable to query fee estimator: %v", err)
Expand Down Expand Up @@ -2989,7 +2989,7 @@ func TestChannelLinkBandwidthChanReserve(t *testing.T) {
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
)

estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
t.Fatalf("unable to query fee estimator: %v", err)
Expand Down
4 changes: 4 additions & 0 deletions htlcswitch/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ func (m *mockFeeEstimator) EstimateFeePerKW(
}
}

func (m *mockFeeEstimator) RelayFeePerKW() lnwallet.SatPerKWeight {
return 1e3
}

func (m *mockFeeEstimator) Start() error {
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion htlcswitch/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte,
return nil, nil, nil, nil, err
}

estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
return nil, nil, nil, nil, err
Expand Down
2 changes: 1 addition & 1 deletion lntest/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func (hn *HarnessNode) start(lndError chan<- error) error {

args := hn.cfg.genArgs()
args = append(args, fmt.Sprintf("--profile=%d", 9000+hn.NodeID))
hn.cmd = exec.Command("./lnd-debug", args...)
hn.cmd = exec.Command("./lnd-itest", args...)

// Redirect stderr output to buffer
var errb bytes.Buffer
Expand Down
2 changes: 1 addition & 1 deletion lnwallet/channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,7 @@ func TestHTLCSigNumber(t *testing.T) {
}

// Calculate two values that will be below and above Bob's dust limit.
estimator := &StaticFeeEstimator{FeePerKW: 6000}
estimator := NewStaticFeeEstimator(6000, 0)
feePerKw, err := estimator.EstimateFeePerKW(1)
if err != nil {
t.Fatalf("unable to get fee: %v", err)
Expand Down
52 changes: 48 additions & 4 deletions lnwallet/fee_estimator.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,50 @@ type FeeEstimator interface {
// Stop stops any spawned goroutines and cleans up the resources used
// by the fee estimator.
Stop() error

// RelayFeePerKW returns the minimum fee rate required for transactions
// to be relayed. This is also the basis for calculation of the dust
// limit.
RelayFeePerKW() SatPerKWeight
}

// StaticFeeEstimator will return a static value for all fee calculation
// requests. It is designed to be replaced by a proper fee calculation
// implementation.
// implementation. The fees are not accessible directly, because changing them
// would not be thread safe.
type StaticFeeEstimator struct {
// FeePerKW is the static fee rate in satoshis-per-vbyte that will be
// feePerKW is the static fee rate in satoshis-per-vbyte that will be
// returned by this fee estimator.
FeePerKW SatPerKWeight
feePerKW SatPerKWeight

// relayFee is the minimum fee rate required for transactions to be
// relayed.
relayFee SatPerKWeight
}

// NewStaticFeeEstimator returns a new static fee estimator instance.
func NewStaticFeeEstimator(feePerKW,
relayFee SatPerKWeight) *StaticFeeEstimator {

return &StaticFeeEstimator{
feePerKW: feePerKW,
relayFee: relayFee,
}
}

// EstimateFeePerKW will return a static value for fee calculations.
//
// NOTE: This method is part of the FeeEstimator interface.
func (e StaticFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
return e.FeePerKW, nil
return e.feePerKW, nil
}

// RelayFeePerKW returns the minimum fee rate required for transactions to be
// relayed.
//
// NOTE: This method is part of the FeeEstimator interface.
func (e StaticFeeEstimator) RelayFeePerKW() SatPerKWeight {
return e.relayFee
}

// Start signals the FeeEstimator to start any processes or goroutines
Expand Down Expand Up @@ -206,6 +234,14 @@ func (b *BtcdFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, er
return feeEstimate, nil
}

// RelayFeePerKW returns the minimum fee rate required for transactions to be
// relayed.
//
// NOTE: This method is part of the FeeEstimator interface.
func (b *BtcdFeeEstimator) RelayFeePerKW() SatPerKWeight {
return b.minFeePerKW
}

// fetchEstimate returns a fee estimate for a transaction to be confirmed in
// confTarget blocks. The estimate is returned in sat/kw.
func (b *BtcdFeeEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, error) {
Expand Down Expand Up @@ -359,6 +395,14 @@ func (b *BitcoindFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight
return feeEstimate, nil
}

// RelayFeePerKW returns the minimum fee rate required for transactions to be
// relayed.
//
// NOTE: This method is part of the FeeEstimator interface.
func (b *BitcoindFeeEstimator) RelayFeePerKW() SatPerKWeight {
return b.minFeePerKW
}

// fetchEstimate returns a fee estimate for a transaction to be confirmed in
// confTarget blocks. The estimate is returned in sat/kw.
func (b *BitcoindFeeEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, error) {
Expand Down
4 changes: 1 addition & 3 deletions lnwallet/fee_estimator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ func TestStaticFeeEstimator(t *testing.T) {

const feePerKw = lnwallet.FeePerKwFloor

feeEstimator := &lnwallet.StaticFeeEstimator{
FeePerKW: feePerKw,
}
feeEstimator := lnwallet.NewStaticFeeEstimator(feePerKw, 0)
if err := feeEstimator.Start(); err != nil {
t.Fatalf("unable to start fee estimator: %v", err)
}
Expand Down
Loading