Skip to content

Commit db6356f

Browse files
committed
itest: manually broadcast anchor tx in testPsbtExternalCommit
Update testPsbtExternalCommit to manually broadcast the anchor transaction. We ensure that tapd skips broadcasting the anchor transaction itself.
1 parent 64388e1 commit db6356f

File tree

1 file changed

+69
-4
lines changed

1 file changed

+69
-4
lines changed

itest/psbt_test.go

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ import (
77
"fmt"
88
"net/url"
99
"testing"
10+
"time"
1011

1112
"github.com/btcsuite/btcd/btcec/v2/schnorr"
1213
"github.com/btcsuite/btcd/btcutil"
1314
"github.com/btcsuite/btcd/btcutil/hdkeychain"
1415
"github.com/btcsuite/btcd/btcutil/psbt"
16+
"github.com/btcsuite/btcd/chaincfg/chainhash"
1517
"github.com/btcsuite/btcd/txscript"
18+
"github.com/btcsuite/btcd/wire"
1619
"github.com/btcsuite/btcwallet/waddrmgr"
1720
"github.com/davecgh/go-spew/spew"
1821
"github.com/lightninglabs/taproot-assets/address"
@@ -2611,18 +2614,80 @@ func testPsbtExternalCommit(t *harnessTest) {
26112614

26122615
btcPacket = signPacket(t.t, aliceLnd, btcPacket)
26132616
btcPacket = FinalizePacket(t.t, aliceLnd.RPC, btcPacket)
2617+
2618+
transferLabel := "itest-psbt-external-commit"
2619+
2620+
// Subscribe to the send event stream so we can verify the sender's
2621+
// state transitions during this test.
2622+
ctx, streamCancel := context.WithCancel(ctxb)
2623+
stream, err := aliceTapd.SubscribeSendEvents(
2624+
ctx, &taprpc.SubscribeSendEventsRequest{
2625+
FilterLabel: transferLabel,
2626+
},
2627+
)
2628+
require.NoError(t.t, err)
2629+
sendEvents := &EventSubscription[*taprpc.SendEvent]{
2630+
ClientEventStream: stream,
2631+
Cancel: streamCancel,
2632+
}
2633+
2634+
// Execute the transfer but skip anchor transaction broadcast. This
2635+
// simulates a packaging workflow where broadcasting is handled
2636+
// externally.
26142637
sendResp := PublishAndLogTransfer(
26152638
t.t, aliceTapd, btcPacket, activeAssets, passiveAssets,
2616-
commitResp,
2639+
commitResp, withSkipAnchorTxBroadcast(),
2640+
withLabel(transferLabel),
26172641
)
26182642

2643+
// Assert that the state machine transitions directly to waiting for
2644+
// tx confirmation, skipping the broadcast state.
2645+
require.Eventually(t.t, func() bool {
2646+
isMatchingState := func(msg *taprpc.SendEvent) bool {
2647+
lastState := tapfreighter.SendStateStorePreBroadcast
2648+
nextState := tapfreighter.SendStateWaitTxConf
2649+
2650+
return msg.SendState == lastState.String() &&
2651+
msg.NextSendState == nextState.String()
2652+
}
2653+
2654+
for {
2655+
msg, err := sendEvents.Recv()
2656+
if err != nil {
2657+
return false
2658+
}
2659+
2660+
return isMatchingState(msg)
2661+
}
2662+
}, defaultWaitTimeout, time.Second)
2663+
2664+
// Unmarshal the anchor transaction.
2665+
var anchorTx wire.MsgTx
2666+
reader := bytes.NewReader(sendResp.Transfer.AnchorTx)
2667+
err = anchorTx.Deserialize(reader)
2668+
require.NoError(t.t, err)
2669+
2670+
// Ensure that the anchor PSBT matches the returned anchor
2671+
// transaction.
2672+
require.Equal(t.t, anchorTx.TxHash(), btcPacket.UnsignedTx.TxHash())
2673+
2674+
// Assert that the anchor transaction is not in the mempool.
2675+
miner := t.lndHarness.Miner()
2676+
miner.AssertTxnsNotInMempool([]chainhash.Hash{
2677+
anchorTx.TxHash(),
2678+
})
2679+
2680+
// Add the anchor transaction to the mempool and mine.
2681+
miner.MineBlockWithTx(&anchorTx)
2682+
2683+
// Assert that the transfer has the correct number of outputs.
26192684
expectedAmounts := []uint64{
26202685
targetAsset.Amount - assetsToSend, assetsToSend,
26212686
}
2622-
ConfirmAndAssertOutboundTransferWithOutputs(
2687+
AssertAssetOutboundTransferWithOutputs(
26232688
t.t, t.lndHarness.Miner().Client, aliceTapd,
2624-
sendResp, targetAssetGenesis.AssetId, expectedAmounts,
2625-
0, 1, len(expectedAmounts),
2689+
sendResp.Transfer, targetAssetGenesis.AssetId, expectedAmounts,
2690+
0, 1, len(expectedAmounts), false,
26262691
)
26272692

26282693
// And now the event should be completed on both sides.

0 commit comments

Comments
 (0)