Skip to content

Commit b47fe32

Browse files
committed
tapfreighter: simplify createChangeOutput function
1 parent 08d0354 commit b47fe32

File tree

1 file changed

+73
-68
lines changed

1 file changed

+73
-68
lines changed

tapfreighter/fund.go

+73-68
Original file line numberDiff line numberDiff line change
@@ -152,83 +152,88 @@ func annotateLocalScriptKeys(ctx context.Context, vPkt *tappsbt.VPacket,
152152
func createChangeOutput(ctx context.Context, vPkt *tappsbt.VPacket,
153153
keyRing KeyRing, fullValue bool, changeAmount uint64) error {
154154

155+
// If we're spending the full value, we don't need a change output. We
156+
// currently assume that if it's a full-value non-interactive spend that
157+
// the packet was created with the correct function in the tappsbt
158+
// packet that adds the NUMS script key output for the tombstone. If
159+
// the user doesn't set that, then an error will be returned from the
160+
// tapsend.PrepareOutputAssets function. But we should probably change
161+
// that and allow the user to specify a minimum packet template and add
162+
// whatever else is needed to it automatically.
163+
if fullValue {
164+
return nil
165+
}
166+
155167
// We expect some change back, or have passive assets to commit to, so
156168
// let's make sure we create a transfer output.
157-
var (
158-
changeOut *tappsbt.VOutput
159-
err error
160-
)
161-
if !fullValue {
162-
// Do we need to add a change output?
163-
changeOut, err = vPkt.SplitRootOutput()
164-
if err != nil {
165-
lastOut := vPkt.Outputs[len(vPkt.Outputs)-1]
166-
splitOutIndex := lastOut.AnchorOutputIndex + 1
167-
changeOut = &tappsbt.VOutput{
168-
Type: tappsbt.TypeSplitRoot,
169-
Interactive: lastOut.Interactive,
170-
AnchorOutputIndex: splitOutIndex,
171-
172-
// We want to handle deriving a real key in a
173-
// generic manner, so we'll do that just below.
174-
ScriptKey: asset.NUMSScriptKey,
175-
}
176-
177-
vPkt.Outputs = append(vPkt.Outputs, changeOut)
169+
changeOut, err := vPkt.SplitRootOutput()
170+
if err != nil {
171+
lastOut := vPkt.Outputs[len(vPkt.Outputs)-1]
172+
splitOutIndex := lastOut.AnchorOutputIndex + 1
173+
changeOut = &tappsbt.VOutput{
174+
Type: tappsbt.TypeSplitRoot,
175+
Interactive: lastOut.Interactive,
176+
AnchorOutputIndex: splitOutIndex,
177+
178+
// We want to handle deriving a real key in a
179+
// generic manner, so we'll do that just below.
180+
ScriptKey: asset.NUMSScriptKey,
178181
}
179182

180-
// Since we know we're going to receive some change back, we
181-
// need to make sure it is going to an address that we control.
182-
// This should only be the case where we create the default
183-
// change output with the NUMS key to avoid deriving too many
184-
// keys prematurely. We don't need to derive a new key if we
185-
// only have passive assets to commit to, since they all have
186-
// their own script key and the output is more of a placeholder
187-
// to attach the passive assets to.
188-
unSpendable, err := changeOut.ScriptKey.IsUnSpendable()
183+
vPkt.Outputs = append(vPkt.Outputs, changeOut)
184+
}
185+
186+
// Since we know we're going to receive some change back, we
187+
// need to make sure it is going to an address that we control.
188+
// This should only be the case where we create the default
189+
// change output with the NUMS key to avoid deriving too many
190+
// keys prematurely. We don't need to derive a new key if we
191+
// only have passive assets to commit to, since they all have
192+
// their own script key and the output is more of a placeholder
193+
// to attach the passive assets to.
194+
unSpendable, err := changeOut.ScriptKey.IsUnSpendable()
195+
if err != nil {
196+
return fmt.Errorf("cannot determine if script key is "+
197+
"spendable: %w", err)
198+
}
199+
if unSpendable {
200+
changeScriptKey, err := keyRing.DeriveNextKey(
201+
ctx, asset.TaprootAssetsKeyFamily,
202+
)
189203
if err != nil {
190-
return fmt.Errorf("cannot determine if script key is "+
191-
"spendable: %w", err)
192-
}
193-
if unSpendable {
194-
changeScriptKey, err := keyRing.DeriveNextKey(
195-
ctx, asset.TaprootAssetsKeyFamily,
196-
)
197-
if err != nil {
198-
return err
199-
}
200-
201-
// We'll assume BIP-0086 everywhere, and use the tweaked
202-
// key from here on out.
203-
changeOut.ScriptKey = asset.NewScriptKeyBip86(
204-
changeScriptKey,
205-
)
204+
return err
206205
}
207206

208-
// For existing change outputs, we'll just update the amount
209-
// since we might not have known what coin would've been
210-
// selected and how large the change would turn out to be.
211-
changeOut.Amount = changeAmount
212-
213-
// The asset version of the output should be the max of the set
214-
// of input versions. We need to set this now as in
215-
// PrepareOutputAssets locators are created which includes the
216-
// version from the vOut. If we don't set it here, a v1 asset
217-
// spent that becomes change will be a v0 if combined with such
218-
// inputs.
219-
//
220-
// TODO(roasbeef): remove as not needed?
221-
maxVersion := func(maxVersion asset.Version,
222-
vInput *tappsbt.VInput) asset.Version {
223-
224-
if vInput.Asset().Version > maxVersion {
225-
return vInput.Asset().Version
226-
}
227-
228-
return maxVersion
207+
// We'll assume BIP-0086 everywhere, and use the tweaked
208+
// key from here on out.
209+
changeOut.ScriptKey = asset.NewScriptKeyBip86(
210+
changeScriptKey,
211+
)
212+
}
213+
214+
// For existing change outputs, we'll just update the amount
215+
// since we might not have known what coin would've been
216+
// selected and how large the change would turn out to be.
217+
changeOut.Amount = changeAmount
218+
219+
// The asset version of the output should be the max of the set
220+
// of input versions. We need to set this now as in
221+
// PrepareOutputAssets locators are created which includes the
222+
// version from the vOut. If we don't set it here, a v1 asset
223+
// spent that becomes change will be a v0 if combined with such
224+
// inputs.
225+
//
226+
// TODO(roasbeef): remove as not needed?
227+
maxVersion := func(maxVersion asset.Version,
228+
vInput *tappsbt.VInput) asset.Version {
229+
230+
if vInput.Asset().Version > maxVersion {
231+
return vInput.Asset().Version
229232
}
230-
changeOut.AssetVersion = fn.Reduce(vPkt.Inputs, maxVersion)
233+
234+
return maxVersion
231235
}
236+
changeOut.AssetVersion = fn.Reduce(vPkt.Inputs, maxVersion)
232237

233238
return nil
234239
}

0 commit comments

Comments
 (0)