Skip to content

Commit ca22445

Browse files
committed
multi: make all new txes v3
This commit changes all new Bitcoin transactions from version 2 to version 3 (TRUC - Topologically Restricted Until Confirmed) as defined in BIP 431. Version 3 transactions provide better fee-bumping and pinning protection, which is beneficial for Taproot Assets anchor transactions.
1 parent 5b165ff commit ca22445

24 files changed

+416
-344
lines changed

asset/group_key_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func TestNonSpendableLeafScript(t *testing.T) {
333333

334334
// Finally, we'll make the dummy spend transaction, and
335335
// the output script that we'll attempt to spend.
336-
spendTx := wire.NewMsgTx(1)
336+
spendTx := wire.NewMsgTx(3)
337337
spendTx.AddTxIn(&wire.TxIn{})
338338

339339
leafScript, err := txscript.PayToTaprootScript(

asset/mock.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,11 @@ func virtualGenesisTx(newAsset *Asset) (*wire.MsgTx, error) {
313313

314314
// With our single input and output mapped, we're ready to construct our
315315
// virtual transaction.
316+
//
317+
// IMPORTANT: The virtual transaction version must remain at v2 for
318+
// backwards compatibility. Changing the version would invalidate all
319+
// existing asset witness signatures. Only the anchor (real Bitcoin)
320+
// transactions use v3.
316321
virtualTx := wire.NewMsgTx(2)
317322
virtualTx.AddTxIn(txIn)
318323
virtualTx.AddTxOut(txOut)

itest/round_trip_send_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func testRoundTripSend(t *harnessTest) {
163163
estimatedWeight := estimator.Weight()
164164
requiredFee := feeRate.FeeForWeight(estimatedWeight)
165165

166-
tx := wire.NewMsgTx(2)
166+
tx := wire.NewMsgTx(3)
167167
tx.TxIn = []*wire.TxIn{{
168168
PreviousOutPoint: *outpoint,
169169
}}

itest/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ func ManualMintSimpleAsset(t *harnessTest, lndNode *node.HarnessNode,
632632
[]byte{txscript.OP_1, txscript.OP_DATA_32},
633633
bytes.Repeat([]byte{0x00}, 32)...,
634634
)
635-
txTemplate := wire.NewMsgTx(2)
635+
txTemplate := wire.NewMsgTx(3)
636636
txTemplate.AddTxOut(&wire.TxOut{
637637
Value: int64(btcutil.Amount(1000)),
638638
PkScript: bytes.Clone(genesisDummyScript),

proof/verifier_test.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package proof
22

33
import (
4+
"bytes"
5+
"encoding/hex"
6+
"os"
47
"slices"
8+
"strings"
59
"testing"
610

711
"github.com/btcsuite/btcd/btcec/v2"
@@ -155,7 +159,7 @@ func makeV0InclusionProof(t *testing.T, opts ...createProofOpt) ([]*Proof,
155159

156160
internalKey := test.RandPubKey(t)
157161

158-
anchorTx := wire.NewMsgTx(2)
162+
anchorTx := wire.NewMsgTx(3)
159163
anchorTx.TxOut = make([]*wire.TxOut, len(tapCommitments))
160164

161165
indexes := maps.Keys(tapCommitments)
@@ -1157,3 +1161,53 @@ func TestVerifyV1ExclusionProof(t *testing.T) {
11571161
})
11581162
}
11591163
}
1164+
1165+
// TestTransactionVersionInProofSystem verifies that the current codebase
1166+
// creates v3 transactions.
1167+
func TestTransactionVersionInProofSystem(t *testing.T) {
1168+
t.Parallel()
1169+
1170+
proofs, _ := makeV0InclusionProof(t)
1171+
require.Len(t, proofs, 1)
1172+
proof := proofs[0]
1173+
1174+
require.Equal(t, int32(3), proof.AnchorTx.Version,
1175+
"Post-commit b3562461: all new transactions should be v3")
1176+
}
1177+
1178+
// TestBackwardsCompatibilityWithExistingProofs tests that existing proof files
1179+
// (which contain v2 transactions) can still be loaded and verified by the
1180+
// current v3-enabled codebase.
1181+
func TestBackwardsCompatibilityWithExistingProofs(t *testing.T) {
1182+
t.Parallel()
1183+
1184+
const fileName = "testdata/proof-file.hex"
1185+
1186+
// Load the existing proof file (created pre-v3).
1187+
proofHex, err := os.ReadFile(fileName)
1188+
require.NoError(t, err, "Failed to load %s", fileName)
1189+
1190+
proofBytes, err := hex.DecodeString(
1191+
strings.TrimSpace(string(proofHex)),
1192+
)
1193+
require.NoError(t, err)
1194+
1195+
// Decode the proof file.
1196+
var proofFile File
1197+
err = proofFile.Decode(bytes.NewReader(proofBytes))
1198+
require.NoError(t, err, "v3-enabled code must decode existing proofs")
1199+
1200+
// Get the last proof from the file.
1201+
lastProof, err := proofFile.LastProof()
1202+
require.NoError(t, err)
1203+
1204+
t.Logf("Proof file %s uses tx version: %d",
1205+
fileName, lastProof.AnchorTx.Version)
1206+
1207+
require.Equal(t, int32(2), lastProof.AnchorTx.Version)
1208+
1209+
_, err = lastProof.verifyExclusionProofs()
1210+
require.NoError(
1211+
t, err, "v3-enabled code must verify existing v2 proofs",
1212+
)
1213+
}

tapchannel/commitment.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@ func CreateSecondLevelHtlcTx(chanState lnwallet.AuxChanState,
14921492
func FakeCommitTx(fundingOutpoint wire.OutPoint,
14931493
allocations []*tapsend.Allocation) (*wire.MsgTx, error) {
14941494

1495-
fakeCommitTx := wire.NewMsgTx(2)
1495+
fakeCommitTx := wire.NewMsgTx(3)
14961496
fakeCommitTx.TxIn = []*wire.TxIn{
14971497
{
14981498
PreviousOutPoint: fundingOutpoint,

tapdb/addrs_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func confirmTx(tx *lndclient.Transaction) {
4747

4848
func randWalletTx() *lndclient.Transaction {
4949
tx := &lndclient.Transaction{
50-
Tx: wire.NewMsgTx(2),
50+
Tx: wire.NewMsgTx(3),
5151
Timestamp: time.Now(),
5252
BlockHeight: rand.Int31n(700_000),
5353
BlockHash: test.RandHash().String(),

tapdb/asset_minting_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func addRandomManagedUTXO(t *testing.T, ctx context.Context,
200200
_, err = rand.Read(blockHash[:])
201201
require.NoError(t, err)
202202

203-
anchorTx := wire.NewMsgTx(2)
203+
anchorTx := wire.NewMsgTx(3)
204204
anchorTx.AddTxIn(&wire.TxIn{})
205205
anchorTx.AddTxOut(&wire.TxOut{
206206
PkScript: bytes.Repeat([]byte{0x01}, 34),

tapdb/assets_store.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ func dbAssetsToChainAssets(dbAssets []ConfirmedAsset, witnesses assetWitnesses,
772772
}
773773
}
774774

775-
anchorTx := wire.NewMsgTx(2)
775+
anchorTx := wire.NewMsgTx(3)
776776
err = anchorTx.Deserialize(bytes.NewBuffer(sprout.AnchorTx))
777777
if err != nil {
778778
return nil, fmt.Errorf("unable to decode tx: %w", err)
@@ -3592,7 +3592,7 @@ func (a *AssetStore) queryParcelsWithFilters(ctx context.Context,
35923592
"%w", err)
35933593
}
35943594

3595-
anchorTx := wire.NewMsgTx(2)
3595+
anchorTx := wire.NewMsgTx(3)
35963596
err = anchorTx.Deserialize(bytes.NewReader(
35973597
dbAnchorTx.RawTx,
35983598
))

tapdb/assets_store_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ func TestImportAssetProof(t *testing.T) {
375375
// We now add a second proof for the same script key but a different
376376
// outpoint and expect that to be stored and retrieved correctly.
377377
oldOutpoint := testProof.AssetSnapshot.OutPoint
378-
newChainTx := wire.NewMsgTx(2)
378+
newChainTx := wire.NewMsgTx(3)
379379
newChainTx.TxIn = []*wire.TxIn{{
380380
PreviousOutPoint: test.RandOp(t),
381381
}}
@@ -1577,7 +1577,7 @@ func TestAssetExportLog(t *testing.T) {
15771577
require.Len(t, utxos, 1)
15781578
require.Equal(t, assetGen.anchorPoints[0], utxos[0].OutPoint)
15791579

1580-
newAnchorTx := wire.NewMsgTx(2)
1580+
newAnchorTx := wire.NewMsgTx(3)
15811581
newAnchorTx.AddTxIn(&wire.TxIn{})
15821582
newAnchorTx.TxIn[0].SignatureScript = []byte{}
15831583
newAnchorTx.AddTxOut(&wire.TxOut{
@@ -2377,7 +2377,7 @@ func TestTransferOutputProofDeliveryStatus(t *testing.T) {
23772377
// of the first transfer output.
23782378
//
23792379
// First, we'll generate a new anchor transaction for use in the parcel.
2380-
newAnchorTx := wire.NewMsgTx(2)
2380+
newAnchorTx := wire.NewMsgTx(3)
23812381
newAnchorTx.AddTxIn(&wire.TxIn{})
23822382
newAnchorTx.TxIn[0].SignatureScript = []byte{}
23832383
newAnchorTx.AddTxOut(&wire.TxOut{
@@ -2670,7 +2670,7 @@ func TestQueryAssetBurns(t *testing.T) {
26702670
// of the first transfer output.
26712671
//
26722672
// First, we'll generate a new anchor transaction for use in the parcel.
2673-
newAnchorTx := wire.NewMsgTx(2)
2673+
newAnchorTx := wire.NewMsgTx(3)
26742674
newAnchorTx.AddTxIn(&wire.TxIn{})
26752675
newAnchorTx.TxIn[0].SignatureScript = []byte{}
26762676
newAnchorTx.AddTxOut(&wire.TxOut{
@@ -3257,7 +3257,7 @@ func createTestProofWithAnchor(t *testing.T, testAsset *asset.Asset,
32573257
_, err := rand.Read(blockHash[:])
32583258
require.NoError(t, err)
32593259

3260-
anchorTx := wire.NewMsgTx(2)
3260+
anchorTx := wire.NewMsgTx(3)
32613261
anchorTx.AddTxIn(&wire.TxIn{})
32623262

32633263
// Add enough outputs to cover the requested index

0 commit comments

Comments
 (0)