@@ -212,9 +212,9 @@ func newSupplyCommitTestHarness(t *testing.T) *supplyCommitTestHarness {
212
212
}
213
213
214
214
// addTestMintAnchorUniCommitment inserts a mint_anchor_uni_commitments record
215
- // using harness data.
215
+ // using harness data and returns both the commitment ID and the outpoint .
216
216
func (h * supplyCommitTestHarness ) addTestMintAnchorUniCommitment (
217
- batchKeyBytes []byte , spentBy sql.NullInt64 ) int64 {
217
+ batchKeyBytes []byte , spentBy sql.NullInt64 , mintTxid chainhash. Hash ) ( int64 , wire. OutPoint ) {
218
218
219
219
h .t .Helper ()
220
220
@@ -228,7 +228,16 @@ func (h *supplyCommitTestHarness) addTestMintAnchorUniCommitment(
228
228
)
229
229
require .NoError (h .t , err )
230
230
231
- txOutputIndex := int32 (test .RandInt [uint32 ]() % 100 )
231
+ txOutputIndex := int32 (test .RandInt [uint32 ]())
232
+
233
+ outpoint := wire.OutPoint {
234
+ Hash : mintTxid ,
235
+ Index : uint32 (txOutputIndex ),
236
+ }
237
+
238
+ var outpointBuf bytes.Buffer
239
+ err = wire .WriteOutPoint (& outpointBuf , 0 , 0 , & outpoint )
240
+ require .NoError (h .t , err )
232
241
233
242
anchorCommitID , err := h .db .UpsertMintAnchorUniCommitment (
234
243
h .ctx , sqlc.UpsertMintAnchorUniCommitmentParams {
@@ -237,11 +246,12 @@ func (h *supplyCommitTestHarness) addTestMintAnchorUniCommitment(
237
246
TaprootInternalKeyID : internalKeyID ,
238
247
GroupKey : h .groupKeyBytes ,
239
248
SpentBy : spentBy ,
249
+ Outpoint : outpointBuf .Bytes (),
240
250
},
241
251
)
242
252
require .NoError (h .t , err )
243
253
244
- return anchorCommitID
254
+ return anchorCommitID , outpoint
245
255
}
246
256
247
257
// currentState fetches the current state of the state machine via FetchState.
@@ -687,7 +697,8 @@ func (h *supplyCommitTestHarness) confirmChainTx(txID int64, txidBytes,
687
697
// list of updates applied, the generated keys, the commit TX, and the simulated
688
698
// chain proof details for assertion purposes.
689
699
func (h * supplyCommitTestHarness ) performSingleTransition (
690
- updates []supplycommit.SupplyUpdateEvent ) stateTransitionOutput {
700
+ updates []supplycommit.SupplyUpdateEvent ,
701
+ preCommitOutpoints []wire.OutPoint ) stateTransitionOutput {
691
702
692
703
h .t .Helper ()
693
704
@@ -709,6 +720,13 @@ func (h *supplyCommitTestHarness) performSingleTransition(
709
720
// Next, we'll generate a new "fake" commitment transaction along with
710
721
// sample internal and output keys.
711
722
commitTx := randTx (h .t , 1 )
723
+ // Add inputs to the transaction that spend the pre-commitment outputs.
724
+ for _ , outpoint := range preCommitOutpoints {
725
+ commitTx .TxIn = append (commitTx .TxIn , & wire.TxIn {
726
+ PreviousOutPoint : outpoint ,
727
+ })
728
+ }
729
+
712
730
internalKey , _ := test .RandKeyDesc (h .t )
713
731
outputKey := test .RandPubKey (h .t )
714
732
@@ -1255,7 +1273,8 @@ func TestBindDanglingUpdatesToTransition(t *testing.T) {
1255
1273
// To create dangling updates, we first need a state machine and a
1256
1274
// finalized transition.
1257
1275
updates1 := []supplycommit.SupplyUpdateEvent {h .randMintEvent ()}
1258
- stateTransition1 := h .performSingleTransition (updates1 )
1276
+ // Pass empty outpoints since this test doesn't need pre-commitments
1277
+ stateTransition1 := h .performSingleTransition (updates1 , []wire.OutPoint {})
1259
1278
h .assertTransitionApplied (stateTransition1 )
1260
1279
1261
1280
// Now, with the machine in DefaultState, we'll manually insert some
@@ -1640,6 +1659,46 @@ func TestSupplyCommitApplyStateTransition(t *testing.T) {
1640
1659
1641
1660
h := newSupplyCommitTestHarness (t )
1642
1661
1662
+ // First, let's create some pre-commitments that should be spent
1663
+ // when we apply the state transition. We'll create mint transactions
1664
+ // and track their outpoints.
1665
+ batchKeyBytes1 , _ , _ , mintTxidBytes1 , _ := h .addTestMintingBatch ()
1666
+ var mintTxid1 chainhash.Hash
1667
+ copy (mintTxid1 [:], mintTxidBytes1 )
1668
+ _ , outpoint1 := h .addTestMintAnchorUniCommitment (
1669
+ batchKeyBytes1 , sql.NullInt64 {}, mintTxid1 ,
1670
+ )
1671
+ batchKeyBytes2 , _ , _ , mintTxidBytes2 , _ := h .addTestMintingBatch ()
1672
+ var mintTxid2 chainhash.Hash
1673
+ copy (mintTxid2 [:], mintTxidBytes2 )
1674
+ _ , outpoint2 := h .addTestMintAnchorUniCommitment (
1675
+ batchKeyBytes2 , sql.NullInt64 {}, mintTxid2 ,
1676
+ )
1677
+
1678
+ // Create an additional pre-commitment that should NOT be spent
1679
+ // This tests that we're only marking the specific pre-commitments
1680
+ // referenced in the transaction inputs as spent.
1681
+ batchKeyBytesExtra , _ , _ , mintTxidBytesExtra , _ := h .addTestMintingBatch ()
1682
+ var mintTxidExtra chainhash.Hash
1683
+ copy (mintTxidExtra [:], mintTxidBytesExtra )
1684
+ _ , outpointExtra := h .addTestMintAnchorUniCommitment (
1685
+ batchKeyBytesExtra , sql.NullInt64 {}, mintTxidExtra ,
1686
+ )
1687
+
1688
+ // Collect only the first two outpoints for the transaction inputs
1689
+ // The extra one should remain unspent
1690
+ preCommitOutpoints := []wire.OutPoint {outpoint1 , outpoint2 }
1691
+
1692
+ // Verify we have all three unspent pre-commitments before the
1693
+ // transition.
1694
+ precommitsRes := h .commitMachine .UnspentPrecommits (h .ctx , h .assetSpec )
1695
+ precommits , err := precommitsRes .Unpack ()
1696
+ require .NoError (t , err )
1697
+ require .Len (
1698
+ t , precommits , 3 , "should have 3 unspent pre-commitments " +
1699
+ "before transition" ,
1700
+ )
1701
+
1643
1702
// To kick off our test, we'll perform a single state transition. This
1644
1703
// entails: adding a set of pending updates, committing the signed
1645
1704
// commit tx, and finally applying the state transition. After
@@ -1649,17 +1708,70 @@ func TestSupplyCommitApplyStateTransition(t *testing.T) {
1649
1708
updates1 := []supplycommit.SupplyUpdateEvent {
1650
1709
h .randMintEvent (), h .randBurnEvent (),
1651
1710
}
1652
- stateTransition1 := h .performSingleTransition (updates1 )
1711
+ stateTransition1 := h .performSingleTransition (updates1 , preCommitOutpoints )
1653
1712
h .assertTransitionApplied (stateTransition1 )
1654
1713
1714
+ // After the first transition, only the two pre-commitments that were
1715
+ // included in the transaction inputs should be marked as spent.
1716
+ // The extra pre-commitment should remain unspent.
1717
+ precommitsRes = h .commitMachine .UnspentPrecommits (h .ctx , h .assetSpec )
1718
+ precommits , err = precommitsRes .Unpack ()
1719
+ require .NoError (t , err )
1720
+ require .Len (
1721
+ t , precommits , 1 , "should have 1 unspent pre-commitment after " +
1722
+ "first transition (the one not included in tx inputs)" ,
1723
+ )
1724
+
1725
+ // Verify that the remaining unspent pre-commitment is the extra one
1726
+ // by checking its outpoint
1727
+ remainingPrecommit := precommits [0 ]
1728
+ remainingOutpoint := wire.OutPoint {
1729
+ Hash : remainingPrecommit .MintingTxn .TxHash (),
1730
+ Index : remainingPrecommit .OutIdx ,
1731
+ }
1732
+
1733
+ require .Equal (
1734
+ t , outpointExtra , remainingOutpoint ,
1735
+ "the remaining unspent pre-commitment should be the extra one" ,
1736
+ )
1737
+
1738
+ // Now create new pre-commitments for the second transition.
1739
+ batchKeyBytes3 , _ , _ , mintTxidBytes3 , _ := h .addTestMintingBatch ()
1740
+ var mintTxid3 chainhash.Hash
1741
+ copy (mintTxid3 [:], mintTxidBytes3 )
1742
+ _ , outpoint3 := h .addTestMintAnchorUniCommitment (
1743
+ batchKeyBytes3 , sql.NullInt64 {}, mintTxid3 ,
1744
+ )
1745
+
1746
+ // Verify we have the extra one from before plus the new one.
1747
+ precommitsRes = h .commitMachine .UnspentPrecommits (h .ctx , h .assetSpec )
1748
+ precommits , err = precommitsRes .Unpack ()
1749
+ require .NoError (t , err )
1750
+ require .Len (
1751
+ t , precommits , 2 , "should have 2 unspent pre-commitments " +
1752
+ "before second transition (extra from first + new one)" ,
1753
+ )
1754
+
1655
1755
// To ensure that we can perform multiple transitions, we'll now do
1656
1756
// another one, with a new set of events, and then assert that it's been
1657
- // applied properly.
1757
+ // applied properly. This time we'll spend both the extra pre-commitment
1758
+ // from the first round and the new one.
1658
1759
updates2 := []supplycommit.SupplyUpdateEvent {
1659
1760
h .randMintEvent (), h .randIgnoreEvent (),
1660
1761
}
1661
- stateTransition2 := h .performSingleTransition (updates2 )
1762
+ preCommitOutpoints2 := []wire.OutPoint {outpointExtra , outpoint3 }
1763
+ stateTransition2 := h .performSingleTransition (updates2 , preCommitOutpoints2 )
1662
1764
h .assertTransitionApplied (stateTransition2 )
1765
+
1766
+ // After the second transition, the new pre-commitment should also be spent.
1767
+ // Finally, verify that no unspent pre-commitments remain.
1768
+ precommitsRes = h .commitMachine .UnspentPrecommits (h .ctx , h .assetSpec )
1769
+ precommits , err = precommitsRes .Unpack ()
1770
+ require .NoError (t , err )
1771
+ require .Empty (
1772
+ t , precommits , "should have no unspent pre-commitments after " +
1773
+ "all transitions" ,
1774
+ )
1663
1775
}
1664
1776
1665
1777
// TestSupplyCommitUnspentPrecommits tests the UnspentPrecommits method.
@@ -1681,8 +1793,10 @@ func TestSupplyCommitUnspentPrecommits(t *testing.T) {
1681
1793
require .Empty (t , precommits )
1682
1794
1683
1795
// Next, we'll add a new minting batch, and a pre-commit along with it.
1684
- batchKeyBytes , _ , mintTx1 , _ , _ := h .addTestMintingBatch ()
1685
- _ = h .addTestMintAnchorUniCommitment (batchKeyBytes , sql.NullInt64 {})
1796
+ batchKeyBytes , _ , mintTx1 , mintTxidBytes , _ := h .addTestMintingBatch ()
1797
+ var mintTxid chainhash.Hash
1798
+ copy (mintTxid [:], mintTxidBytes )
1799
+ _ , _ = h .addTestMintAnchorUniCommitment (batchKeyBytes , sql.NullInt64 {}, mintTxid )
1686
1800
1687
1801
// At this point, we should find a single pre commitment on disk.
1688
1802
precommitsRes = h .commitMachine .UnspentPrecommits (h .ctx , spec )
@@ -1694,12 +1808,14 @@ func TestSupplyCommitUnspentPrecommits(t *testing.T) {
1694
1808
// Next, we'll add another pre commitment, and this time associate it
1695
1809
// (spend it) by a supply commitment.
1696
1810
//nolint:lll
1697
- batchKeyBytes , commitTxDbID2 , _ , commitTxid2 , commitRawTx2 :=
1811
+ batchKeyBytes , commitTxDbID2 , _ , commitTxidBytes2 , commitRawTx2 :=
1698
1812
h .addTestMintingBatch ()
1813
+ var commitTxid2 chainhash.Hash
1814
+ copy (commitTxid2 [:], commitTxidBytes2 )
1699
1815
commitID2 := h .addTestSupplyCommitment (
1700
- commitTxDbID2 , commitTxid2 , commitRawTx2 , false ,
1816
+ commitTxDbID2 , commitTxidBytes2 , commitRawTx2 , false ,
1701
1817
)
1702
- _ = h .addTestMintAnchorUniCommitment (batchKeyBytes , sqlInt64 (commitID2 ))
1818
+ _ , _ = h .addTestMintAnchorUniCommitment (batchKeyBytes , sqlInt64 (commitID2 ), commitTxid2 )
1703
1819
1704
1820
// We should now find two pre-commitments.
1705
1821
precommitsRes = h .commitMachine .UnspentPrecommits (h .ctx , spec )
@@ -1713,7 +1829,7 @@ func TestSupplyCommitUnspentPrecommits(t *testing.T) {
1713
1829
blockHeight := sqlInt32 (123 )
1714
1830
txIndex := sqlInt32 (1 )
1715
1831
_ , err = h .db .UpsertChainTx (h .ctx , sqlc.UpsertChainTxParams {
1716
- Txid : commitTxid2 ,
1832
+ Txid : commitTxid2 [:] ,
1717
1833
RawTx : commitRawTx2 ,
1718
1834
ChainFees : 0 ,
1719
1835
BlockHash : blockHash ,
0 commit comments