Skip to content

Commit 16580e8

Browse files
committed
tapfreighter: extract functions
1 parent e919548 commit 16580e8

File tree

1 file changed

+69
-37
lines changed

1 file changed

+69
-37
lines changed

tapfreighter/fund.go

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,56 @@ func createFundedPacketWithInputs(ctx context.Context, exporter proof.Exporter,
6767
return nil, err
6868
}
6969

70+
// Make sure we'll recognize local script keys in the virtual packet
71+
// later on in the process by annotating them with the full descriptor
72+
// information.
73+
if err := annotateLocalScriptKeys(ctx, vPkt, addrBook); err != nil {
74+
return nil, err
75+
}
76+
77+
// If we don't spend the full value, we need to create a change output.
78+
changeAmount := totalInputAmt - fundDesc.Amount
79+
err = createChangeOutput(ctx, vPkt, keyRing, fullValue, changeAmount)
80+
if err != nil {
81+
return nil, err
82+
}
83+
84+
// Before we can prepare output assets for our send, we need to generate
85+
// a new internal key for the anchor outputs. We assume any output that
86+
// hasn't got an internal key set is going to a local anchor, and we
87+
// provide the internal key for that.
88+
for idx := range vPkt.Outputs {
89+
vOut := vPkt.Outputs[idx]
90+
if vOut.AnchorOutputInternalKey != nil {
91+
continue
92+
}
93+
94+
newInternalKey, err := keyRing.DeriveNextKey(
95+
ctx, asset.TaprootAssetsKeyFamily,
96+
)
97+
if err != nil {
98+
return nil, err
99+
}
100+
vOut.SetAnchorInternalKey(
101+
newInternalKey, vPkt.ChainParams.HDCoinType,
102+
)
103+
}
104+
105+
if err := tapsend.PrepareOutputAssets(ctx, vPkt); err != nil {
106+
return nil, fmt.Errorf("unable to prepare outputs: %w", err)
107+
}
108+
109+
return &FundedVPacket{
110+
VPackets: []*tappsbt.VPacket{vPkt},
111+
InputCommitments: inputCommitments,
112+
}, nil
113+
}
114+
115+
// annotateLocalScriptKeys annotates the local script keys in the given virtual
116+
// packet with the full descriptor information.
117+
func annotateLocalScriptKeys(ctx context.Context, vPkt *tappsbt.VPacket,
118+
addrBook AddrBook) error {
119+
70120
// We want to know if we are sending to ourselves. We detect that by
71121
// looking at the key descriptor of the script key. Because that is not
72122
// part of addresses and might not be specified by the user through the
@@ -90,14 +140,24 @@ func createFundedPacketWithInputs(ctx context.Context, exporter proof.Exporter,
90140
continue
91141

92142
default:
93-
return nil, fmt.Errorf("cannot fetch script key: %w",
94-
err)
143+
return fmt.Errorf("cannot fetch script key: %w", err)
95144
}
96145
}
97146

147+
return nil
148+
}
149+
150+
// createChangeOutput creates a change output for the given virtual packet if
151+
// it isn't fully spent.
152+
func createChangeOutput(ctx context.Context, vPkt *tappsbt.VPacket,
153+
keyRing KeyRing, fullValue bool, changeAmount uint64) error {
154+
98155
// We expect some change back, or have passive assets to commit to, so
99156
// let's make sure we create a transfer output.
100-
var changeOut *tappsbt.VOutput
157+
var (
158+
changeOut *tappsbt.VOutput
159+
err error
160+
)
101161
if !fullValue {
102162
// Do we need to add a change output?
103163
changeOut, err = vPkt.SplitRootOutput()
@@ -127,15 +187,15 @@ func createFundedPacketWithInputs(ctx context.Context, exporter proof.Exporter,
127187
// to attach the passive assets to.
128188
unSpendable, err := changeOut.ScriptKey.IsUnSpendable()
129189
if err != nil {
130-
return nil, fmt.Errorf("cannot determine if script "+
131-
"key is spendable: %w", err)
190+
return fmt.Errorf("cannot determine if script key is "+
191+
"spendable: %w", err)
132192
}
133-
if unSpendable && !fullValue {
193+
if unSpendable {
134194
changeScriptKey, err := keyRing.DeriveNextKey(
135195
ctx, asset.TaprootAssetsKeyFamily,
136196
)
137197
if err != nil {
138-
return nil, err
198+
return err
139199
}
140200

141201
// We'll assume BIP-0086 everywhere, and use the tweaked
@@ -148,7 +208,7 @@ func createFundedPacketWithInputs(ctx context.Context, exporter proof.Exporter,
148208
// For existing change outputs, we'll just update the amount
149209
// since we might not have known what coin would've been
150210
// selected and how large the change would turn out to be.
151-
changeOut.Amount = totalInputAmt - fundDesc.Amount
211+
changeOut.Amount = changeAmount
152212

153213
// The asset version of the output should be the max of the set
154214
// of input versions. We need to set this now as in
@@ -170,35 +230,7 @@ func createFundedPacketWithInputs(ctx context.Context, exporter proof.Exporter,
170230
changeOut.AssetVersion = fn.Reduce(vPkt.Inputs, maxVersion)
171231
}
172232

173-
// Before we can prepare output assets for our send, we need to generate
174-
// a new internal key for the anchor outputs. We assume any output that
175-
// hasn't got an internal key set is going to a local anchor, and we
176-
// provide the internal key for that.
177-
for idx := range vPkt.Outputs {
178-
vOut := vPkt.Outputs[idx]
179-
if vOut.AnchorOutputInternalKey != nil {
180-
continue
181-
}
182-
183-
newInternalKey, err := keyRing.DeriveNextKey(
184-
ctx, asset.TaprootAssetsKeyFamily,
185-
)
186-
if err != nil {
187-
return nil, err
188-
}
189-
vOut.SetAnchorInternalKey(
190-
newInternalKey, vPkt.ChainParams.HDCoinType,
191-
)
192-
}
193-
194-
if err := tapsend.PrepareOutputAssets(ctx, vPkt); err != nil {
195-
return nil, fmt.Errorf("unable to prepare outputs: %w", err)
196-
}
197-
198-
return &FundedVPacket{
199-
VPackets: []*tappsbt.VPacket{vPkt},
200-
InputCommitments: inputCommitments,
201-
}, nil
233+
return nil
202234
}
203235

204236
// setVPacketInputs sets the inputs of the given vPkt to the given send eligible

0 commit comments

Comments
 (0)