mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-29 18:10:48 +02:00
watchtower: uses P2TR for sweep, delivery, and reward addresses
In this commit, we modify the watch tower to use P2TR addrs for just about anything sweep related. One eye sore in this diff are the changes to `backup_task_internal_test.go`. All the values are hard coded, and now either differ by a value of 48, or needed to be modified to account for the new assumptions propagated to rewards values and fees.
This commit is contained in:
2
lnd.go
2
lnd.go
@ -458,7 +458,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg,
|
|||||||
Net: cfg.net,
|
Net: cfg.net,
|
||||||
NewAddress: func() (btcutil.Address, error) {
|
NewAddress: func() (btcutil.Address, error) {
|
||||||
return activeChainControl.Wallet.NewAddress(
|
return activeChainControl.Wallet.NewAddress(
|
||||||
lnwallet.WitnessPubKey, false,
|
lnwallet.TaprootPubkey, false,
|
||||||
lnwallet.DefaultAccountName,
|
lnwallet.DefaultAccountName,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/btcutil/txsort"
|
"github.com/btcsuite/btcd/btcutil/txsort"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||||
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
||||||
@ -228,8 +229,8 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64,
|
|||||||
i := inputIndex[inp.outPoint]
|
i := inputIndex[inp.outPoint]
|
||||||
justiceTxn.TxIn[i].Witness = inp.witness
|
justiceTxn.TxIn[i].Witness = inp.witness
|
||||||
|
|
||||||
// Validate the reconstructed witnesses to ensure they are valid
|
// Validate the reconstructed witnesses to ensure they are
|
||||||
// for the breached inputs.
|
// valid for the breached inputs.
|
||||||
vm, err := txscript.NewEngine(
|
vm, err := txscript.NewEngine(
|
||||||
inp.txOut.PkScript, justiceTxn, i,
|
inp.txOut.PkScript, justiceTxn, i,
|
||||||
txscript.StandardVerifyFlags,
|
txscript.StandardVerifyFlags,
|
||||||
@ -239,7 +240,9 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := vm.Execute(); err != nil {
|
if err := vm.Execute(); err != nil {
|
||||||
return nil, err
|
log.Debugf("Failed to validate justice transaction: %s",
|
||||||
|
spew.Sdump(justiceTxn))
|
||||||
|
return nil, fmt.Errorf("error validating TX: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +303,9 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) {
|
|||||||
|
|
||||||
sweepInputs = append(sweepInputs, toLocalInput)
|
sweepInputs = append(sweepInputs, toLocalInput)
|
||||||
|
|
||||||
|
log.Debugf("Found to local witness output=%#v, stack=%v",
|
||||||
|
toLocalInput.txOut, toLocalInput.witness)
|
||||||
|
|
||||||
// If the justice kit specifies that we have to sweep the to-remote
|
// If the justice kit specifies that we have to sweep the to-remote
|
||||||
// output, we'll also try to assemble the output and add it to weight
|
// output, we'll also try to assemble the output and add it to weight
|
||||||
// estimate if successful.
|
// estimate if successful.
|
||||||
@ -310,6 +316,9 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) {
|
|||||||
}
|
}
|
||||||
sweepInputs = append(sweepInputs, toRemoteInput)
|
sweepInputs = append(sweepInputs, toRemoteInput)
|
||||||
|
|
||||||
|
log.Debugf("Found to remote witness output=%#v, stack=%v",
|
||||||
|
toRemoteInput.txOut, toRemoteInput.witness)
|
||||||
|
|
||||||
if p.JusticeKit.BlobType.IsAnchorChannel() {
|
if p.JusticeKit.BlobType.IsAnchorChannel() {
|
||||||
weightEstimate.AddWitnessInput(input.ToRemoteConfirmedWitnessSize)
|
weightEstimate.AddWitnessInput(input.ToRemoteConfirmedWitnessSize)
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/btcec/v2"
|
"github.com/btcsuite/btcd/btcec/v2"
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/btcsuite/btcd/btcutil/txsort"
|
"github.com/btcsuite/btcd/btcutil/txsort"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
@ -151,6 +152,42 @@ func (t *backupTask) inputs() map[wire.OutPoint]input.Input {
|
|||||||
return inputs
|
return inputs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addrType returns the type of an address after parsing it and matching it to
|
||||||
|
// the set of known script templates.
|
||||||
|
func addrType(pkScript []byte) txscript.ScriptClass {
|
||||||
|
// We pass in a set of dummy chain params here as they're only needed
|
||||||
|
// to make the address struct, which we're ignoring anyway (scripts are
|
||||||
|
// always the same, it's addresses that change across chains).
|
||||||
|
scriptClass, _, _, _ := txscript.ExtractPkScriptAddrs(
|
||||||
|
pkScript, &chaincfg.MainNetParams,
|
||||||
|
)
|
||||||
|
|
||||||
|
return scriptClass
|
||||||
|
}
|
||||||
|
|
||||||
|
// addScriptWeight parses the passed pkScript and adds the computed weight cost
|
||||||
|
// were the script to be added to the justice transaction.
|
||||||
|
func addScriptWeight(weightEstimate *input.TxWeightEstimator,
|
||||||
|
pkScript []byte) error {
|
||||||
|
|
||||||
|
switch addrType(pkScript) { //nolint: whitespace
|
||||||
|
|
||||||
|
case txscript.WitnessV0PubKeyHashTy:
|
||||||
|
weightEstimate.AddP2WKHOutput()
|
||||||
|
|
||||||
|
case txscript.WitnessV0ScriptHashTy:
|
||||||
|
weightEstimate.AddP2WSHOutput()
|
||||||
|
|
||||||
|
case txscript.WitnessV1TaprootTy:
|
||||||
|
weightEstimate.AddP2TROutput()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid addr type: %v", addrType(pkScript))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// bindSession determines if the backupTask is compatible with the passed
|
// bindSession determines if the backupTask is compatible with the passed
|
||||||
// SessionInfo's policy. If no error is returned, the task has been bound to the
|
// SessionInfo's policy. If no error is returned, the task has been bound to the
|
||||||
// session and can be queued to upload to the tower. Otherwise, the bind failed
|
// session and can be queued to upload to the tower. Otherwise, the bind failed
|
||||||
@ -192,13 +229,19 @@ func (t *backupTask) bindSession(session *wtdb.ClientSessionBody) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All justice transactions have a p2wkh output paying to the victim.
|
// All justice transactions will either use segwit v0 (p2wkh + p2wsh)
|
||||||
weightEstimate.AddP2WKHOutput()
|
// or segwit v1 (p2tr).
|
||||||
|
if err := addScriptWeight(&weightEstimate, t.sweepPkScript); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// If the justice transaction has a reward output, add the output's
|
// If the justice transaction has a reward output, add the output's
|
||||||
// contribution to the weight estimate.
|
// contribution to the weight estimate.
|
||||||
if session.Policy.BlobType.Has(blob.FlagReward) {
|
if session.Policy.BlobType.Has(blob.FlagReward) {
|
||||||
weightEstimate.AddP2WKHOutput()
|
err := addScriptWeight(&weightEstimate, session.RewardPkScript)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.chanType.HasAnchors() != session.Policy.IsAnchorChannel() {
|
if t.chanType.HasAnchors() != session.Policy.IsAnchorChannel() {
|
||||||
|
@ -247,7 +247,7 @@ func genTaskTest(
|
|||||||
RewardPkScript: rewardScript,
|
RewardPkScript: rewardScript,
|
||||||
},
|
},
|
||||||
bindErr: bindErr,
|
bindErr: bindErr,
|
||||||
expSweepScript: makeAddrSlice(22),
|
expSweepScript: sweepAddr,
|
||||||
signer: signer,
|
signer: signer,
|
||||||
chanType: chanType,
|
chanType: chanType,
|
||||||
}
|
}
|
||||||
@ -259,10 +259,18 @@ var (
|
|||||||
blobTypeCommitReward = (blob.FlagCommitOutputs | blob.FlagReward).Type()
|
blobTypeCommitReward = (blob.FlagCommitOutputs | blob.FlagReward).Type()
|
||||||
|
|
||||||
addr, _ = btcutil.DecodeAddress(
|
addr, _ = btcutil.DecodeAddress(
|
||||||
"mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", &chaincfg.TestNet3Params,
|
"tb1pw8gzj8clt3v5lxykpgacpju5n8xteskt7gxhmudu6pa70nwfhe6s3unsyk",
|
||||||
|
&chaincfg.TestNet3Params,
|
||||||
)
|
)
|
||||||
|
|
||||||
addrScript, _ = txscript.PayToAddrScript(addr)
|
addrScript, _ = txscript.PayToAddrScript(addr)
|
||||||
|
|
||||||
|
sweepAddrScript, _ = btcutil.DecodeAddress(
|
||||||
|
"tb1qs3jyc9sf5kak3x0w99cav9u605aeu3t600xxx0",
|
||||||
|
&chaincfg.TestNet3Params,
|
||||||
|
)
|
||||||
|
|
||||||
|
sweepAddr, _ = txscript.PayToAddrScript(sweepAddrScript)
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestBackupTaskBind tests the initialization and binding of a backupTask to a
|
// TestBackupTaskBind tests the initialization and binding of a backupTask to a
|
||||||
@ -297,9 +305,9 @@ func TestBackupTask(t *testing.T) {
|
|||||||
expSweepCommitNoRewardBoth int64 = 299241
|
expSweepCommitNoRewardBoth int64 = 299241
|
||||||
expSweepCommitNoRewardLocal int64 = 199514
|
expSweepCommitNoRewardLocal int64 = 199514
|
||||||
expSweepCommitNoRewardRemote int64 = 99561
|
expSweepCommitNoRewardRemote int64 = 99561
|
||||||
expSweepCommitRewardBoth int64 = 296117
|
expSweepCommitRewardBoth int64 = 296069
|
||||||
expSweepCommitRewardLocal int64 = 197390
|
expSweepCommitRewardLocal int64 = 197342
|
||||||
expSweepCommitRewardRemote int64 = 98437
|
expSweepCommitRewardRemote int64 = 98389
|
||||||
sweepFeeRateNoRewardRemoteDust chainfee.SatPerKWeight = 227500
|
sweepFeeRateNoRewardRemoteDust chainfee.SatPerKWeight = 227500
|
||||||
sweepFeeRateRewardRemoteDust chainfee.SatPerKWeight = 175350
|
sweepFeeRateRewardRemoteDust chainfee.SatPerKWeight = 175350
|
||||||
)
|
)
|
||||||
@ -307,9 +315,9 @@ func TestBackupTask(t *testing.T) {
|
|||||||
expSweepCommitNoRewardBoth = 299236
|
expSweepCommitNoRewardBoth = 299236
|
||||||
expSweepCommitNoRewardLocal = 199513
|
expSweepCommitNoRewardLocal = 199513
|
||||||
expSweepCommitNoRewardRemote = 99557
|
expSweepCommitNoRewardRemote = 99557
|
||||||
expSweepCommitRewardBoth = 296112
|
expSweepCommitRewardBoth = 296064
|
||||||
expSweepCommitRewardLocal = 197389
|
expSweepCommitRewardLocal = 197341
|
||||||
expSweepCommitRewardRemote = 98433
|
expSweepCommitRewardRemote = 98385
|
||||||
sweepFeeRateNoRewardRemoteDust = 225400
|
sweepFeeRateNoRewardRemoteDust = 225400
|
||||||
sweepFeeRateRewardRemoteDust = 174100
|
sweepFeeRateRewardRemoteDust = 174100
|
||||||
}
|
}
|
||||||
@ -436,7 +444,7 @@ func TestBackupTask(t *testing.T) {
|
|||||||
"commit reward, to-remote output only, creates dust",
|
"commit reward, to-remote output only, creates dust",
|
||||||
1, // stateNum
|
1, // stateNum
|
||||||
0, // toLocalAmt
|
0, // toLocalAmt
|
||||||
100000, // toRemoteAmt
|
108221, // toRemoteAmt
|
||||||
blobTypeCommitReward, // blobType
|
blobTypeCommitReward, // blobType
|
||||||
sweepFeeRateRewardRemoteDust, // sweepFeeRate
|
sweepFeeRateRewardRemoteDust, // sweepFeeRate
|
||||||
addrScript, // rewardScript
|
addrScript, // rewardScript
|
||||||
|
@ -58,7 +58,8 @@ var (
|
|||||||
|
|
||||||
// addr is the server's reward address given to watchtower clients.
|
// addr is the server's reward address given to watchtower clients.
|
||||||
addr, _ = btcutil.DecodeAddress(
|
addr, _ = btcutil.DecodeAddress(
|
||||||
"mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", &chaincfg.TestNet3Params,
|
"tb1pw8gzj8clt3v5lxykpgacpju5n8xteskt7gxhmudu6pa70nwfhe6s3unsyk",
|
||||||
|
&chaincfg.TestNet3Params,
|
||||||
)
|
)
|
||||||
|
|
||||||
addrScript, _ = txscript.PayToAddrScript(addr)
|
addrScript, _ = txscript.PayToAddrScript(addr)
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||||
@ -156,7 +155,7 @@ func (p Policy) Validate() error {
|
|||||||
// of the justice transaction and subtracting an amount that satisfies the
|
// of the justice transaction and subtracting an amount that satisfies the
|
||||||
// policy's fee rate.
|
// policy's fee rate.
|
||||||
func (p *Policy) ComputeAltruistOutput(totalAmt btcutil.Amount,
|
func (p *Policy) ComputeAltruistOutput(totalAmt btcutil.Amount,
|
||||||
txWeight int64) (btcutil.Amount, error) {
|
txWeight int64, sweepScript []byte) (btcutil.Amount, error) {
|
||||||
|
|
||||||
txFee := p.SweepFeeRate.FeeForWeight(txWeight)
|
txFee := p.SweepFeeRate.FeeForWeight(txWeight)
|
||||||
if txFee > totalAmt {
|
if txFee > totalAmt {
|
||||||
@ -165,10 +164,9 @@ func (p *Policy) ComputeAltruistOutput(totalAmt btcutil.Amount,
|
|||||||
|
|
||||||
sweepAmt := totalAmt - txFee
|
sweepAmt := totalAmt - txFee
|
||||||
|
|
||||||
// TODO(conner): replace w/ configurable dust limit
|
// Check that the created outputs won't be dusty. We'll base the dust
|
||||||
// Check that the created outputs won't be dusty. The sweep pkscript is
|
// computation on the type of the script itself.
|
||||||
// currently a p2wpkh, so we'll use that script's dust limit.
|
if sweepAmt < lnwallet.DustLimitForSize(len(sweepScript)) {
|
||||||
if sweepAmt < lnwallet.DustLimitForSize(input.P2WPKHSize) {
|
|
||||||
return 0, ErrCreatesDust
|
return 0, ErrCreatesDust
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +178,8 @@ func (p *Policy) ComputeAltruistOutput(totalAmt btcutil.Amount,
|
|||||||
// and reward rate. The reward to he tower is subtracted first, before
|
// and reward rate. The reward to he tower is subtracted first, before
|
||||||
// splitting the remaining balance amongst the victim and fees.
|
// splitting the remaining balance amongst the victim and fees.
|
||||||
func (p *Policy) ComputeRewardOutputs(totalAmt btcutil.Amount,
|
func (p *Policy) ComputeRewardOutputs(totalAmt btcutil.Amount,
|
||||||
txWeight int64) (btcutil.Amount, btcutil.Amount, error) {
|
txWeight int64,
|
||||||
|
rewardScript []byte) (btcutil.Amount, btcutil.Amount, error) {
|
||||||
|
|
||||||
txFee := p.SweepFeeRate.FeeForWeight(txWeight)
|
txFee := p.SweepFeeRate.FeeForWeight(txWeight)
|
||||||
if txFee > totalAmt {
|
if txFee > totalAmt {
|
||||||
@ -198,10 +197,9 @@ func (p *Policy) ComputeRewardOutputs(totalAmt btcutil.Amount,
|
|||||||
// input value.
|
// input value.
|
||||||
sweepAmt := totalAmt - rewardAmt - txFee
|
sweepAmt := totalAmt - rewardAmt - txFee
|
||||||
|
|
||||||
// TODO(conner): replace w/ configurable dust limit
|
// Check that the created outputs won't be dusty. We'll base the dust
|
||||||
// Check that the created outputs won't be dusty. The sweep pkscript is
|
// computation on the type of the script itself.
|
||||||
// currently a p2wpkh, so we'll use that script's dust limit.
|
if sweepAmt < lnwallet.DustLimitForSize(len(rewardScript)) {
|
||||||
if sweepAmt < lnwallet.DustLimitForSize(input.P2WPKHSize) {
|
|
||||||
return 0, 0, ErrCreatesDust
|
return 0, 0, ErrCreatesDust
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,15 +229,16 @@ func ComputeRewardAmount(total btcutil.Amount, base, rate uint32) btcutil.Amount
|
|||||||
return rewardBase + proportional
|
return rewardBase + proportional
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComputeJusticeTxOuts constructs the justice transaction outputs for the given
|
// ComputeJusticeTxOuts constructs the justice transaction outputs for the
|
||||||
// policy. If the policy specifies a reward for the tower, there will be two
|
// given policy. If the policy specifies a reward for the tower, there will be
|
||||||
// outputs paying to the victim and the tower. Otherwise there will be a single
|
// two outputs paying to the victim and the tower. Otherwise there will be a
|
||||||
// output sweeping funds back to the victim. The totalAmt should be the sum of
|
// single output sweeping funds back to the victim. The totalAmt should be the
|
||||||
// any inputs used in the transaction. The passed txWeight should include the
|
// sum of any inputs used in the transaction. The passed txWeight should
|
||||||
// weight of the outputs for the justice transaction, which is dependent on
|
// include the weight of the outputs for the justice transaction, which is
|
||||||
// whether the justice transaction has a reward. The sweepPkScript should be the
|
// dependent on whether the justice transaction has a reward. The sweepPkScript
|
||||||
// pkScript of the victim to which funds will be recovered. The rewardPkScript
|
// should be the pkScript of the victim to which funds will be recovered. The
|
||||||
// is the pkScript of the tower where its reward will be deposited, and will be
|
// rewardPkScript is the pkScript of the tower where its reward will be
|
||||||
|
// deposited, and will be
|
||||||
// ignored if the blob type does not specify a reward.
|
// ignored if the blob type does not specify a reward.
|
||||||
func (p *Policy) ComputeJusticeTxOuts(totalAmt btcutil.Amount, txWeight int64,
|
func (p *Policy) ComputeJusticeTxOuts(totalAmt btcutil.Amount, txWeight int64,
|
||||||
sweepPkScript, rewardPkScript []byte) ([]*wire.TxOut, error) {
|
sweepPkScript, rewardPkScript []byte) ([]*wire.TxOut, error) {
|
||||||
@ -247,19 +246,19 @@ func (p *Policy) ComputeJusticeTxOuts(totalAmt btcutil.Amount, txWeight int64,
|
|||||||
var outputs []*wire.TxOut
|
var outputs []*wire.TxOut
|
||||||
|
|
||||||
// If the policy specifies a reward for the tower, compute a split of
|
// If the policy specifies a reward for the tower, compute a split of
|
||||||
// the funds based on the policy's parameters. Otherwise, we will use an
|
// the funds based on the policy's parameters. Otherwise, we will use
|
||||||
// the altruist output computation and sweep as much of the funds back
|
// the altruist output computation and sweep as much of the funds
|
||||||
// to the victim as possible.
|
// back to the victim as possible.
|
||||||
if p.BlobType.Has(blob.FlagReward) {
|
if p.BlobType.Has(blob.FlagReward) {
|
||||||
// Using the total input amount and the transaction's weight,
|
// Using the total input amount and the transaction's weight,
|
||||||
// compute the sweep and reward amounts. This corresponds to the
|
// compute the sweep and reward amounts. This corresponds to
|
||||||
// amount returned to the victim and the amount paid to the
|
// the amount returned to the victim and the amount paid to the
|
||||||
// tower, respectively. To do so, the required transaction fee
|
// tower, respectively. To do so, the required transaction fee
|
||||||
// is subtracted from the total, and the remaining amount is
|
// is subtracted from the total, and the remaining amount is
|
||||||
// divided according to the prenegotiated reward rate from the
|
// divided according to the pre negotiated reward rate from the
|
||||||
// client's session info.
|
// client's session info.
|
||||||
sweepAmt, rewardAmt, err := p.ComputeRewardOutputs(
|
sweepAmt, rewardAmt, err := p.ComputeRewardOutputs(
|
||||||
totalAmt, txWeight,
|
totalAmt, txWeight, rewardPkScript,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -280,7 +279,7 @@ func (p *Policy) ComputeJusticeTxOuts(totalAmt btcutil.Amount, txWeight int64,
|
|||||||
// returned to the victim. To do so, the required transaction
|
// returned to the victim. To do so, the required transaction
|
||||||
// fee is subtracted from the total input amount.
|
// fee is subtracted from the total input amount.
|
||||||
sweepAmt, err := p.ComputeAltruistOutput(
|
sweepAmt, err := p.ComputeAltruistOutput(
|
||||||
totalAmt, txWeight,
|
totalAmt, txWeight, sweepPkScript,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -22,7 +22,8 @@ import (
|
|||||||
var (
|
var (
|
||||||
// addr is the server's reward address given to watchtower clients.
|
// addr is the server's reward address given to watchtower clients.
|
||||||
addr, _ = btcutil.DecodeAddress(
|
addr, _ = btcutil.DecodeAddress(
|
||||||
"mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", &chaincfg.TestNet3Params,
|
"tb1pw8gzj8clt3v5lxykpgacpju5n8xteskt7gxhmudu6pa70nwfhe6s3unsyk",
|
||||||
|
&chaincfg.TestNet3Params,
|
||||||
)
|
)
|
||||||
|
|
||||||
addrScript, _ = txscript.PayToAddrScript(addr)
|
addrScript, _ = txscript.PayToAddrScript(addr)
|
||||||
|
Reference in New Issue
Block a user