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