lnwallet: integrate obfuscated state hints into funding workflow
This commit finalizes the implementation of #58 by integrating passing around the obfuscate state hints into the funding workflow of the wallet, and also the daemon’s funding manager. In order to amend the tests, the functions to set and receive the state hints are now publicly exported.
This commit is contained in:
6 files changed
+147
-34
No files matched your search
+70
-2
@@ -6,6 +6,7 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/btcsuite/fastsha256"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
@@ -197,10 +198,14 @@ type addSingleFunderSigsMsg struct {
|
||||
// construct for them.
|
||||
revokeKey *btcec.PublicKey
|
||||
|
||||
// This should be 1/2 of the signatures needed to succesfully spend our
|
||||
// version of the commitment transaction.
|
||||
// theirCommitmentSig are the 1/2 of the signatures needed to
|
||||
// succesfully spend our version of the commitment transaction.
|
||||
theirCommitmentSig []byte
|
||||
|
||||
// obsfucator is the bytes to be used to obsfucate the state hints on
|
||||
// the commitment transaction.
|
||||
obsfucator [StateHintSize]byte
|
||||
|
||||
// NOTE: In order to avoid deadlocks, this channel MUST be buffered.
|
||||
err chan error
|
||||
}
|
||||
@@ -782,6 +787,24 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
// With both commitment transactions constructed, generate the state
|
||||
// obsfucator then use it to encode the current state number withi both
|
||||
// commitment transactions.
|
||||
// TODO(roasbeef): define obsfucator scheme for dual funder
|
||||
var stateObsfucator [StateHintSize]byte
|
||||
if pendingReservation.partialState.IsInitiator {
|
||||
stateObsfucator, err = deriveStateHintObsfucator(elkremSender)
|
||||
if err != nil {
|
||||
req.err <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
err = initStateHints(ourCommitTx, theirCommitTx, stateObsfucator)
|
||||
if err != nil {
|
||||
req.err <- err
|
||||
return
|
||||
}
|
||||
|
||||
// Sort both transactions according to the agreed upon cannonical
|
||||
// ordering. This lets us skip sending the entire transaction over,
|
||||
// instead we'll just send signatures.
|
||||
@@ -801,6 +824,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
pendingReservation.partialState.TheirCommitKey = theirCommitKey
|
||||
pendingReservation.partialState.TheirMultiSigKey = theirContribution.MultiSigKey
|
||||
pendingReservation.partialState.OurCommitTx = ourCommitTx
|
||||
pendingReservation.partialState.StateHintObsfucator = stateObsfucator
|
||||
pendingReservation.ourContribution.RevocationKey = ourRevokeKey
|
||||
|
||||
// Generate a signature for their version of the initial commitment
|
||||
@@ -1047,6 +1071,7 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
|
||||
pendingReservation.partialState.FundingOutpoint = req.fundingOutpoint
|
||||
pendingReservation.partialState.TheirCurrentRevocation = req.revokeKey
|
||||
pendingReservation.partialState.ChanID = req.fundingOutpoint
|
||||
pendingReservation.partialState.StateHintObsfucator = req.obsfucator
|
||||
fundingTxIn := wire.NewTxIn(req.fundingOutpoint, nil, nil)
|
||||
|
||||
// Now that we have the funding outpoint, we can generate both versions
|
||||
@@ -1071,6 +1096,15 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
// With both commitment transactions constructed, generate the state
|
||||
// obsfucator then use it to encode the current state number within
|
||||
// both commitment transactions.
|
||||
err = initStateHints(ourCommitTx, theirCommitTx, req.obsfucator)
|
||||
if err != nil {
|
||||
req.err <- err
|
||||
return
|
||||
}
|
||||
|
||||
// Sort both transactions according to the agreed upon cannonical
|
||||
// ordering. This ensures that both parties sign the same sighash
|
||||
// without further synchronization.
|
||||
@@ -1291,6 +1325,40 @@ func (l *LightningWallet) deriveMasterElkremRoot() (*btcec.PrivateKey, error) {
|
||||
return masterElkremRoot.ECPrivKey()
|
||||
}
|
||||
|
||||
// deriveStateHintObsfucator derives the bytes to be used for obsfucatating the
|
||||
// state hints from the elkerem root to be used for a new channel. The
|
||||
// obsfucator is generated by performing an additional sha256 hash of the first
|
||||
// child derived from the elkrem root. The leading 4 bytes are used for the
|
||||
// obsfucator.
|
||||
func deriveStateHintObsfucator(elkremRoot *elkrem.ElkremSender) ([StateHintSize]byte, error) {
|
||||
var obsfucator [StateHintSize]byte
|
||||
|
||||
firstChild, err := elkremRoot.AtIndex(0)
|
||||
if err != nil {
|
||||
return obsfucator, err
|
||||
}
|
||||
|
||||
grandChild := fastsha256.Sum256(firstChild[:])
|
||||
copy(obsfucator[:], grandChild[:])
|
||||
|
||||
return obsfucator, nil
|
||||
}
|
||||
|
||||
// initStateHints properly sets the obsfucated state ints ob both commitment
|
||||
// transactions using the passed obsfucator.
|
||||
func initStateHints(commit1, commit2 *wire.MsgTx,
|
||||
obsfucator [StateHintSize]byte) error {
|
||||
|
||||
if err := SetStateNumHint(commit1, 0, obsfucator); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := SetStateNumHint(commit2, 0, obsfucator); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// selectInputs selects a slice of inputs necessary to meet the specified
|
||||
// selection amount. If input selection is unable to suceed to to insuffcient
|
||||
// funds, a non-nil error is returned. Additionally, the total amount of the
|
||||
|
||||
Reference in new issue
Block a user