Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions asset/asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,16 @@ func (a *Asset) IsBurn() bool {
return IsBurnKey(a.ScriptKey.PubKey, a.PrevWitnesses[0])
}

// IsTombstone returns true if an asset uses the NUMS script key and has zero
// value.
func (a *Asset) IsTombstone() bool {
if a.ScriptKey.PubKey == nil {
return false
}

return a.Amount == 0 && a.ScriptKey.PubKey.IsEqual(NUMSPubKey)
}

// PrimaryPrevID returns the primary prev ID of an asset. This is the prev ID of
// the first witness, unless the first witness is a split-commitment witness,
// in which case it is the prev ID of the first witness of the root asset.
Expand Down
4 changes: 4 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ type Config struct {

ChainPorter tapfreighter.Porter

// SweepOrphanUtxos toggles sweeping orphaned UTXOs into anchor
// transactions for sends and burns.
SweepOrphanUtxos bool

// FsmDaemonAdapters is a set of adapters that allow a state machine to
// interact with external daemons.
FsmDaemonAdapters *lndservices.LndFsmDaemonAdapters
Expand Down
6 changes: 6 additions & 0 deletions docs/release-notes/release-notes-0.8.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@

## Functional Updates

- [Garbage collection of orphaned UTXOs](https://github.com/lightninglabs/taproot-assets/pull/1832)
by sweeping tombstones and burn outputs when executing onchain transactions.
Garbage collection will be executed on every burn, transfer or call to
`AnchorVirtualPsbts`. A new configuration is available to control the sweeping
via the flag `wallet.sweep-orphan-utxos`.

## RPC Updates

- [PR#1841](https://github.com/lightninglabs/taproot-assets/pull/1841): Remove
Expand Down
20 changes: 3 additions & 17 deletions itest/assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1276,10 +1276,6 @@ func AssertAssetOutboundTransferWithOutputs(t *testing.T,
scripts[string(o.ScriptKey)] = struct{}{}
}

sendRespJSON, err := formatProtoJSON(transfer)
require.NoError(t, err)
t.Logf("Got response from sending assets: %v", sendRespJSON)

// Mine a block to force the send event to complete (confirm on-chain).
var newBlock *wire.MsgBlock
if confirm {
Expand Down Expand Up @@ -1325,16 +1321,6 @@ func AssertAssetOutboundTransferWithOutputs(t *testing.T,
return slices.Contains(actualInputAssetIDs, id)
})
}, defaultTimeout, wait.PollInterval)
require.NoError(t, err)

transferResp, err := sender.ListTransfers(
ctxb, &taprpc.ListTransfersRequest{},
)
require.NoError(t, err)

transferRespJSON, err := formatProtoJSON(transferResp)
require.NoError(t, err)
t.Logf("Got response from list transfers: %v", transferRespJSON)

return newBlock
}
Expand Down Expand Up @@ -2410,7 +2396,7 @@ func AssertBalances(t *testing.T, client taprpc.TaprootAssetsClient,
actualBalance := balanceSum(resp, false)
if balance != actualBalance {
return fmt.Errorf("asset balance, wanted %d, "+
"got: %v", balance, toJSON(t, resp))
"got: %v", balance, actualBalance)
}

// If we query for grouped asset balances too, it means
Expand Down Expand Up @@ -2528,7 +2514,7 @@ func AssertBalances(t *testing.T, client taprpc.TaprootAssetsClient,
}
if balance != totalBalance {
return fmt.Errorf("ListAssets balance, wanted %d, "+
"got: %v", balance, toJSON(t, resp))
"got: %v", balance, totalBalance)
}

// The number of UTXOs means asset outputs in this case. We
Expand Down Expand Up @@ -2605,7 +2591,7 @@ func AssertBalances(t *testing.T, client taprpc.TaprootAssetsClient,

if balance != totalBalance {
return fmt.Errorf("ListUtxos balance, wanted %d, "+
"got: %v", balance, toJSON(t, resp))
"got: %v", balance, totalBalance)
}

if config.numAnchorUtxos > 0 {
Expand Down
5 changes: 0 additions & 5 deletions itest/burn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,6 @@ func testBurnAssets(t *harnessTest) {
WithScriptKeyType(asset.ScriptKeyBurn),
)

_, err = t.tapd.ListAssets(ctxt, &taprpc.ListAssetRequest{
IncludeSpent: true,
})
require.NoError(t.t, err)

// Test case 4: Burn some units of a grouped asset. We start by making
// sure we still have the full balance before burning.
AssertBalanceByID(
Expand Down
2 changes: 1 addition & 1 deletion itest/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func TestTaprootAssetsDaemon(t *testing.T) {
// assure no state is taken over between runs.
tapdHarness, uniHarness, proofCourier := setupHarnesses(
t1, ht, lndHarness, uniServerLndHarness,
testCase.proofCourierType,
testCase.proofCourierType, testCase.tapdOptions...,
)

ht := ht.newHarnessTest(
Expand Down
8 changes: 8 additions & 0 deletions itest/tapd_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ type harnessOpts struct {
// verification should only occur for commitments submitted by peers,
// not via on-chain spend detection.
disableSupplyVerifierChainWatch bool

// sweepOrphanUtxos indicates whether orphaned anchor UTXOs should be
// swept into anchor transactions.
sweepOrphanUtxos bool
}

type harnessOption func(*harnessOpts)
Expand Down Expand Up @@ -256,6 +260,10 @@ func newTapdHarness(t *testing.T, ht *harnessTest, cfg tapdConfig,
// nolint: lll
tapCfg.Universe.DisableSupplyVerifierChainWatch = opts.disableSupplyVerifierChainWatch

// Pass through the sweep orphan UTXOs flag. If the option was not set,
// this will be false, which is the default.
tapCfg.Wallet.SweepOrphanUtxos = opts.sweepOrphanUtxos

switch {
case len(opts.oracleServerAddress) > 0:
tapCfg.Experimental.Rfq.PriceOracleAddress =
Expand Down
23 changes: 19 additions & 4 deletions itest/test_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type testCase struct {
name string
test func(t *harnessTest)
proofCourierType proof.CourierType
tapdOptions []Option
}

// harnessTest wraps a regular testing.T providing enhanced error detection
Expand Down Expand Up @@ -270,7 +271,7 @@ func (h *harnessTest) addFederationServer(host string, target *tapdHarness) {
// to each other through an in-memory gRPC connection.
func setupHarnesses(t *testing.T, ht *harnessTest,
lndHarness *lntest.HarnessTest, uniServerLndHarness *node.HarnessNode,
proofCourierType proof.CourierType) (*tapdHarness,
proofCourierType proof.CourierType, tapdOpts ...Option) (*tapdHarness,
*universeServerHarness, proof.CourierHarness) {

// Create a new universe server harness and start it.
Expand Down Expand Up @@ -306,10 +307,11 @@ func setupHarnesses(t *testing.T, ht *harnessTest,
alice := lndHarness.NewNodeWithCoins("Alice", nil)

// Create a tapd that uses Alice and connect it to the universe server.
tapdOptions := append(tapdOpts, func(params *tapdHarnessParams) {
params.proofCourier = proofCourier
})
tapdHarness := setupTapdHarness(
t, ht, alice, universeServer, func(params *tapdHarnessParams) {
params.proofCourier = proofCourier
},
t, ht, alice, universeServer, tapdOptions...,
)
return tapdHarness, universeServer, proofCourier
}
Expand Down Expand Up @@ -372,6 +374,10 @@ type tapdHarnessParams struct {
// sendPriceHint indicates whether the tapd should send price hints from
// the local oracle to the counterparty when requesting a quote.
sendPriceHint bool

// sweepOrphanUtxos indicates whether orphaned UTXOs should be swept
// into anchor transactions.
sweepOrphanUtxos bool
}

// Option is a tapd harness option.
Expand Down Expand Up @@ -400,6 +406,14 @@ func WithSendPriceHint() Option {
}
}

// WithSweepOrphanUtxos enables sweeping zero-value anchor UTXOs for
// the tapd harness created with this option.
func WithSweepOrphanUtxos() Option {
return func(th *tapdHarnessParams) {
th.sweepOrphanUtxos = true
}
}

// setupTapdHarness creates a new tapd that connects to the given lnd node
// and to the given universe server.
func setupTapdHarness(t *testing.T, ht *harnessTest,
Expand Down Expand Up @@ -434,6 +448,7 @@ func setupTapdHarness(t *testing.T, ht *harnessTest,
ho.disableSyncCache = params.disableSyncCache
ho.oracleServerAddress = params.oracleServerAddress
ho.sendPriceHint = params.sendPriceHint
ho.sweepOrphanUtxos = params.sweepOrphanUtxos
}

tapdCfg := tapdConfig{
Expand Down
11 changes: 11 additions & 0 deletions itest/test_list_on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@ var allTestCases = []*testCase{
name: "min relay fee bump",
test: testMinRelayFeeBump,
},
{
name: "zero value anchor sweep",
test: testZeroValueAnchorSweep,
tapdOptions: []Option{
WithSweepOrphanUtxos(),
},
},
{
name: "zero value anchor accumulation",
test: testZeroValueAnchorAccumulation,
},
{
name: "restart receiver check balance",
test: testRestartReceiverCheckBalance,
Expand Down
Loading
Loading