throwaway: loop out works! (mostly)

pull/471/head
Harsha Goli 2 years ago
parent e5e51b065e
commit 2de6c18ede
No known key found for this signature in database
GPG Key ID: 90E00CCB1C74C611

@ -216,12 +216,10 @@ func testResume(t *testing.T, confs uint32, expired, preimageRevealed,
}
_, senderPubKey := test.CreateKey(1)
var senderKey [33]byte
copy(senderKey[:], senderPubKey.SerializeCompressed())
senderKey := senderPubKey.SerializeCompressed()
_, receiverPubKey := test.CreateKey(2)
var receiverKey [33]byte
copy(receiverKey[:], receiverPubKey.SerializeCompressed())
receiverKey := receiverPubKey.SerializeCompressed()
update := loopdb.LoopEvent{
SwapStateData: loopdb.SwapStateData{

@ -211,26 +211,54 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (
if failureReason != clientrpc.FailureReason_FAILURE_REASON_NONE {
state = clientrpc.SwapState_FAILED
}
scriptVer := loop.GetHtlcScriptVersion(loopSwap.ProtocolVersion)
var swapType clientrpc.SwapType
var htlcAddress, htlcAddressP2WSH, htlcAddressNP2WSH string
var htlcAddress, htlcAddressP2WSH, htlcAddressP2TR, htlcAddressNP2WSH string
switch loopSwap.SwapType {
case swap.TypeIn:
swapType = clientrpc.SwapType_LOOP_IN
htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress()
// Determine which address to set depending on script version.
// If the loop in is external, we'll default to v1
if loopSwap.ExternalHtlc {
htlcAddressNP2WSH = loopSwap.HtlcAddressNP2WSH.EncodeAddress()
htlcAddress = htlcAddressNP2WSH
} else {
}
switch scriptVer {
case swap.HtlcV1:
htlcAddressNP2WSH = loopSwap.HtlcAddressNP2WSH.EncodeAddress()
htlcAddress = htlcAddressNP2WSH
case swap.HtlcV2:
htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress()
htlcAddress = htlcAddressP2WSH
case swap.HtlcV3:
htlcAddressP2TR = loopSwap.HtlcAddressP2TR.EncodeAddress()
htlcAddress = htlcAddressP2TR
default:
return nil, errors.New("unknown script version")
}
case swap.TypeOut:
swapType = clientrpc.SwapType_LOOP_OUT
htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress()
htlcAddress = htlcAddressP2WSH
switch scriptVer {
case swap.HtlcV2:
htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress()
htlcAddress = htlcAddressP2WSH
case swap.HtlcV3:
htlcAddressP2TR = loopSwap.HtlcAddressP2TR.EncodeAddress()
htlcAddress = htlcAddressP2TR
default:
return nil, errors.New("unknown script version")
}
default:
return nil, errors.New("unknown swap type")
@ -245,6 +273,7 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (
InitiationTime: loopSwap.InitiationTime.UnixNano(),
LastUpdateTime: loopSwap.LastUpdate.UnixNano(),
HtlcAddress: htlcAddress,
HtlcAddressP2Tr: htlcAddressP2TR,
HtlcAddressP2Wsh: htlcAddressP2WSH,
HtlcAddressNp2Wsh: htlcAddressNP2WSH,
Type: swapType,

@ -24,6 +24,7 @@ func TestProtocolVersionSanity(t *testing.T) {
ProtocolVersionLoopOutCancel,
ProtocolVersionProbe,
ProtocolVersionRoutingPlugin,
ProtocolVersionTaproot,
}
rpcVersions := [...]looprpc.ProtocolVersion{
@ -37,6 +38,7 @@ func TestProtocolVersionSanity(t *testing.T) {
looprpc.ProtocolVersion_LOOP_OUT_CANCEL,
looprpc.ProtocolVersion_PROBE,
looprpc.ProtocolVersion_ROUTING_PLUGIN,
looprpc.ProtocolVersion_TAPROOT,
}
require.Equal(t, len(versions), len(rpcVersions))

@ -58,6 +58,8 @@ type loopInSwap struct {
htlc *swap.Htlc
htlcP2TR *swap.Htlc
htlcP2WSH *swap.Htlc
htlcNP2WSH *swap.Htlc
@ -405,6 +407,11 @@ func validateLoopInContract(lnd *lndclient.LndServices,
// initHtlcs creates and updates the native and nested segwit htlcs
// of the loopInSwap.
func (s *loopInSwap) initHtlcs() error {
htlcP2TR, err := s.swapKit.getHtlc(swap.HtlcP2TR)
if err != nil {
return err
}
htlcP2WSH, err := s.swapKit.getHtlc(swap.HtlcP2WSH)
if err != nil {
return err
@ -418,7 +425,9 @@ func (s *loopInSwap) initHtlcs() error {
// Log htlc addresses for debugging.
s.swapKit.log.Infof("Htlc address (P2WSH): %v", htlcP2WSH.Address)
s.swapKit.log.Infof("Htlc address (NP2WSH): %v", htlcNP2WSH.Address)
s.swapKit.log.Infof("P2TR address (NP2WSH): %v", htlcP2TR.Address)
s.htlcP2TR = htlcP2TR
s.htlcP2WSH = htlcP2WSH
s.htlcNP2WSH = htlcNP2WSH
@ -432,6 +441,7 @@ func (s *loopInSwap) sendUpdate(ctx context.Context) error {
info.HtlcAddressP2WSH = s.htlcP2WSH.Address
info.HtlcAddressNP2WSH = s.htlcNP2WSH.Address
info.HtlcAddressP2TR = s.htlcP2TR.Address
info.ExternalHtlc = s.ExternalHtlc
select {
@ -600,15 +610,8 @@ func (s *loopInSwap) waitForHtlcConf(globalCtx context.Context) (
notifier := s.lnd.ChainNotifier
confChanP2WSH, confErrP2WSH, err := notifier.RegisterConfirmationsNtfn(
ctx, s.htlcTxHash, s.htlcP2WSH.PkScript, 1, s.InitiationHeight,
)
if err != nil {
return nil, err
}
confChanNP2WSH, confErrNP2WSH, err := notifier.RegisterConfirmationsNtfn(
ctx, s.htlcTxHash, s.htlcNP2WSH.PkScript, 1, s.InitiationHeight,
confChanP2TR, confErrP2TR, err := notifier.RegisterConfirmationsNtfn(
ctx, s.htlcTxHash, s.htlcP2TR.PkScript, 1, s.InitiationHeight,
)
if err != nil {
return nil, err
@ -618,22 +621,13 @@ func (s *loopInSwap) waitForHtlcConf(globalCtx context.Context) (
for conf == nil {
select {
// P2WSH htlc confirmed.
case conf = <-confChanP2WSH:
s.htlc = s.htlcP2WSH
s.log.Infof("P2WSH htlc confirmed")
// NP2WSH htlc confirmed.
case conf = <-confChanNP2WSH:
s.htlc = s.htlcNP2WSH
s.log.Infof("NP2WSH htlc confirmed")
// Conf ntfn error.
case err := <-confErrP2WSH:
return nil, err
// P2TR htlc confirmed.
case conf = <-confChanP2TR:
s.htlc = s.htlcP2TR
s.log.Infof("P2TR htlc confirmed")
// Conf ntfn error.
case err := <-confErrNP2WSH:
case err = <-confErrP2TR:
return nil, err
// Keep up with block height.
@ -692,10 +686,10 @@ func (s *loopInSwap) publishOnChainHtlc(ctx context.Context) (bool, error) {
s.log.Infof("Publishing on chain HTLC with fee rate %v", feeRate)
// Internal loop-in is always P2WSH.
// Internal loop-in is always P2TR.
tx, err := s.lnd.WalletKit.SendOutputs(
ctx, []*wire.TxOut{{
PkScript: s.htlcP2WSH.PkScript,
PkScript: s.htlcP2TR.PkScript,
Value: int64(s.LoopInContract.AmountRequested),
}}, feeRate, labels.LoopInHtlcLabel(swap.ShortHash(&s.hash)),
)
@ -944,10 +938,20 @@ func (s *loopInSwap) publishTimeoutTx(ctx context.Context,
return s.htlc.GenTimeoutWitness(sig), nil
}
// TODO(arshbot): replace with a more holistic Script func
var witnessScript []byte
var trHtlc *swap.HtlcScriptV3
trHtlc, ok := s.htlc.HtlcScript.(*swap.HtlcScriptV3)
if !ok {
witnessScript = s.htlc.Script()
} else {
witnessScript = trHtlc.TimeoutScript
}
sequence := uint32(0)
timeoutTx, err := s.sweeper.CreateSweepTx(
ctx, s.height, sequence, s.htlc, *htlcOutpoint, s.SenderKey,
witnessFunc, htlcValue, fee, s.timeoutAddr,
witnessScript, witnessFunc, htlcValue, fee, s.timeoutAddr,
)
if err != nil {
return 0, err

@ -345,8 +345,8 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool,
ctx := newLoopInTestContext(t)
cfg := newSwapConfig(&ctx.lnd.LndServices, ctx.store, ctx.server)
senderKey := [33]byte{4}
receiverKey := [33]byte{5}
senderKey := []byte{4}
receiverKey := []byte{5}
contract := &loopdb.LoopInContract{
HtlcConfTarget: 2,

@ -304,7 +304,7 @@ func (s *loopOutSwap) sendUpdate(ctx context.Context) error {
info := s.swapInfo()
s.log.Infof("Loop out swap state: %v", info.State)
info.HtlcAddressP2WSH = s.htlc.Address
info.HtlcAddressP2TR = s.htlc.Address
select {
case s.statusChan <- *info:
@ -488,6 +488,7 @@ func (s *loopOutSwap) executeSwap(globalCtx context.Context) error {
htlcOutpoint, htlcValue, err := swap.GetScriptOutput(
txConf.Tx, s.htlc.PkScript,
)
if err != nil {
return err
}
@ -857,6 +858,7 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
ctx, cancel := context.WithCancel(globalCtx)
defer cancel()
htlcConfChan, htlcErrChan, err :=
s.lnd.ChainNotifier.RegisterConfirmationsNtfn(
ctx, s.htlcTxHash, s.htlc.PkScript,
@ -950,6 +952,7 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
// Unexpected error on the confirm channel happened,
// abandon the swap.
case err := <-htlcErrChan:
s.log.Infof(err.Error())
return nil, err
// Htlc got confirmed, continue to sweeping.
@ -1284,10 +1287,20 @@ func (s *loopOutSwap) sweep(ctx context.Context,
}
}
// TODO(arshbot): replace with a more holistic Script func
var witnessScript []byte
var trHtlc *swap.HtlcScriptV3
trHtlc, ok := s.htlc.HtlcScript.(*swap.HtlcScriptV3)
if !ok {
witnessScript = s.htlc.Script()
} else {
witnessScript = trHtlc.ClaimScript
}
// Create sweep tx.
sweepTx, err := s.sweeper.CreateSweepTx(
ctx, s.height, s.htlc.SuccessSequence(), s.htlc, htlcOutpoint,
s.ReceiverKey, witnessFunc, htlcValue, fee, s.DestAddr,
s.ReceiverKey, witnessScript, witnessFunc, htlcValue, fee, s.DestAddr,
)
if err != nil {
return err

@ -71,7 +71,7 @@ func newServerMock(lnd *test.LndMockServices) *serverMock {
}
func (s *serverMock) NewLoopOutSwap(_ context.Context, swapHash lntypes.Hash,
amount btcutil.Amount, _ int32, _ [33]byte, _ time.Time,
amount btcutil.Amount, _ int32, _ []byte, _ time.Time,
_ string) (*newLoopOutResponse, error) {
_, senderKey := test.CreateKey(100)
@ -92,11 +92,8 @@ func (s *serverMock) NewLoopOutSwap(_ context.Context, swapHash lntypes.Hash,
return nil, err
}
var senderKeyArray [33]byte
copy(senderKeyArray[:], senderKey.SerializeCompressed())
return &newLoopOutResponse{
senderKey: senderKeyArray,
senderKey: senderKey.SerializeCompressed(),
swapInvoice: swapPayReqString,
prepayInvoice: prePayReqString,
}, nil

@ -215,7 +215,7 @@ func NewHtlc(version ScriptVersion, cltvExpiry int32,
// Generate a tapscript address from our tree
address, err = btcutil.NewAddressTaproot(
schnorr.SerializePubKey(trHtlc.taprootKey), chainParams,
schnorr.SerializePubKey(trHtlc.TaprootKey), chainParams,
)
if err != nil {
return nil, err
@ -239,24 +239,6 @@ func NewHtlc(version ScriptVersion, cltvExpiry int32,
Address: address,
SigScript: sigScript,
}, nil
/*
{
HtlcScript:
timeoutScript []byte
claimScript []byte
internalPubKey *secp.PublicKey
senderKey [33]byte
},
Hash: preimage,
Version: HtlcV3,
PkScript: p2trPkScript or nil
OutputType: HtlcP2WSH,
ChainParams: chainParams,
Address: tapScriptAddr,
SigScript: nil,
}
*/
}
// GenSuccessWitness returns the success script to spend this htlc with
@ -564,11 +546,11 @@ func (h *HtlcScriptV2) SuccessSequence() uint32 {
// HtlcScriptV2 encapsulates the htlc v2 script.
type HtlcScriptV3 struct {
timeoutScript []byte
claimScript []byte
taprootKey *secp.PublicKey
internalPubKey *secp.PublicKey
senderKey []byte
TimeoutScript []byte
ClaimScript []byte
TaprootKey *secp.PublicKey
InternalPubKey *secp.PublicKey
SenderKey []byte
}
func newHTLCScriptV3(
@ -634,18 +616,18 @@ func newHTLCScriptV3(
)
return &HtlcScriptV3{
timeoutScript: timeoutPathScript,
claimScript: claimPathScript,
taprootKey: taprootKey,
internalPubKey: internalPubKey,
senderKey: senderHtlcKey,
TimeoutScript: timeoutPathScript,
ClaimScript: claimPathScript,
TaprootKey: taprootKey,
InternalPubKey: internalPubKey,
SenderKey: senderHtlcKey,
}, nil
}
func (h *HtlcScriptV3) genControlBlock(leafScript []byte) ([]byte, error) {
var outputKeyYIsOdd bool
if h.taprootKey.SerializeCompressed()[0] == secp.PubKeyFormatCompressedOdd {
if h.TaprootKey.SerializeCompressed()[0] == secp.PubKeyFormatCompressedOdd {
outputKeyYIsOdd = true
}
@ -653,7 +635,7 @@ func (h *HtlcScriptV3) genControlBlock(leafScript []byte) ([]byte, error) {
proof := leaf.TapHash()
controlBlock := txscript.ControlBlock{
InternalKey: h.internalPubKey,
InternalKey: h.InternalPubKey,
OutputKeyYIsOdd: outputKeyYIsOdd,
LeafVersion: txscript.BaseLeafVersion,
InclusionProof: proof[:],
@ -668,23 +650,23 @@ func (h *HtlcScriptV3) genControlBlock(leafScript []byte) ([]byte, error) {
func (h *HtlcScriptV3) genSuccessWitness(signature []byte, preimage lntypes.Preimage) wire.TxWitness {
// TODO: Unsilence errors
controlBlockBytes, _ := h.genControlBlock(h.timeoutScript)
// TODO(arshbot): Unsilence errors
controlBlockBytes, _ := h.genControlBlock(h.TimeoutScript)
return wire.TxWitness{
preimage[:],
signature,
h.claimScript,
h.ClaimScript,
controlBlockBytes,
}
}
func (h *HtlcScriptV3) GenTimeoutWitness(senderSig []byte) wire.TxWitness {
// TODO: Unsilence errors
controlBlockBytes, _ := h.genControlBlock(h.claimScript)
// TODO(arshbot): Unsilence errors
controlBlockBytes, _ := h.genControlBlock(h.ClaimScript)
return wire.TxWitness{
senderSig,
h.timeoutScript,
h.TimeoutScript,
controlBlockBytes,
}
}
@ -706,5 +688,5 @@ func (h *HtlcScriptV3) MaxTimeoutWitnessSize() int {
}
func (h *HtlcScriptV3) SuccessSequence() uint32 {
return 10
return 1
}

@ -398,7 +398,7 @@ func TestHtlcV3(t *testing.T) {
require.True(t, ok)
sig := signTx(
tx, senderPrivKey, txscript.NewBaseTapLeaf(trHtlc.claimScript),
tx, senderPrivKey, txscript.NewBaseTapLeaf(trHtlc.ClaimScript),
)
return htlc.genSuccessWitness(sig, preimage)
@ -414,7 +414,7 @@ func TestHtlcV3(t *testing.T) {
require.True(t, ok)
sig := signTx(
tx, receiverPrivKey, txscript.NewBaseTapLeaf(trHtlc.timeoutScript),
tx, receiverPrivKey, txscript.NewBaseTapLeaf(trHtlc.TimeoutScript),
)
return htlc.GenTimeoutWitness(sig)

@ -23,7 +23,7 @@ type Sweeper struct {
func (s *Sweeper) CreateSweepTx(
globalCtx context.Context, height int32, sequence uint32,
htlc *swap.Htlc, htlcOutpoint wire.OutPoint,
keyBytes []byte,
keyBytes, witnessScript []byte,
witnessFunc func(sig []byte) (wire.TxWitness, error),
amount, fee btcutil.Amount,
destAddr btcutil.Address) (*wire.MsgTx, error) {
@ -52,18 +52,17 @@ func (s *Sweeper) CreateSweepTx(
})
// Generate a signature for the swap htlc transaction.
key, err := btcec.ParsePubKey(keyBytes)
if err != nil {
return nil, err
}
signDesc := lndclient.SignDescriptor{
WitnessScript: htlc.Script(),
WitnessScript: witnessScript,
Output: &wire.TxOut{
Value: int64(amount),
},
HashType: txscript.SigHashAll,
HashType: txscript.SigHashDefault,
InputIndex: 0,
KeyDesc: keychain.KeyDescriptor{
PubKey: key,

Loading…
Cancel
Save