lnwallet+funding: sanitize upfront_shutdown_script
Otherwise, we would get non-standard txn's and fail to broadcast them when cooperatively closing a channel. This wouldn't affect funds security as no HTLCs would be active to steal. This is just a safety measure as we should only generate standard txn's.
This commit is contained in:
2 files changed
+199
No files matched your search
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
@@ -1255,6 +1256,16 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
pendingReservation.Lock()
|
||||
defer pendingReservation.Unlock()
|
||||
|
||||
// If UpfrontShutdownScript is set, validate that it is a valid script.
|
||||
shutdown := req.contribution.UpfrontShutdown
|
||||
if len(shutdown) > 0 {
|
||||
// Validate the shutdown script.
|
||||
if !validateUpfrontShutdown(shutdown, &l.Cfg.NetParams) {
|
||||
req.err <- fmt.Errorf("invalid shutdown script")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Some temporary variables to cut down on the resolution verbosity.
|
||||
pendingReservation.theirContribution = req.contribution
|
||||
theirContribution := req.contribution
|
||||
@@ -1561,6 +1572,17 @@ func (l *LightningWallet) handleSingleContribution(req *addSingleContributionMsg
|
||||
// TODO(roasbeef): verify sanity of remote party's parameters, fail if
|
||||
// disagree
|
||||
|
||||
// Validate that the remote's UpfrontShutdownScript is a valid script
|
||||
// if it's set.
|
||||
shutdown := req.contribution.UpfrontShutdown
|
||||
if len(shutdown) > 0 {
|
||||
// Validate the shutdown script.
|
||||
if !validateUpfrontShutdown(shutdown, &l.Cfg.NetParams) {
|
||||
req.err <- fmt.Errorf("invalid shutdown script")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Simply record the counterparty's contribution into the pending
|
||||
// reservation data as they'll be solely funding the channel entirely.
|
||||
pendingReservation.theirContribution = req.contribution
|
||||
@@ -2132,3 +2154,26 @@ func (s *shimKeyRing) DeriveNextKey(keyFam keychain.KeyFamily) (keychain.KeyDesc
|
||||
|
||||
return *fundingKeys.LocalKey, nil
|
||||
}
|
||||
|
||||
// validateUpfrontShutdown checks whether the provided upfront_shutdown_script
|
||||
// is of a valid type that we accept.
|
||||
func validateUpfrontShutdown(shutdown lnwire.DeliveryAddress,
|
||||
params *chaincfg.Params) bool {
|
||||
|
||||
// We don't need to worry about a large UpfrontShutdownScript since it
|
||||
// was already checked in lnwire when decoding from the wire.
|
||||
scriptClass, _, _, _ := txscript.ExtractPkScriptAddrs(shutdown, params)
|
||||
|
||||
switch scriptClass {
|
||||
case txscript.PubKeyHashTy,
|
||||
txscript.WitnessV0PubKeyHashTy,
|
||||
txscript.ScriptHashTy,
|
||||
txscript.WitnessV0ScriptHashTy:
|
||||
// The above four types are permitted according to BOLT#02.
|
||||
// Everything else is disallowed.
|
||||
return true
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user