Skip to content

Commit eee522c

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 21b4380 commit eee522c

25 files changed

+417
-345
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
@@ -635,7 +635,7 @@ func ManualMintSimpleAsset(t *harnessTest, lndNode *node.HarnessNode,
635635
[]byte{txscript.OP_1, txscript.OP_DATA_32},
636636
bytes.Repeat([]byte{0x00}, 32)...,
637637
)
638-
txTemplate := wire.NewMsgTx(2)
638+
txTemplate := wire.NewMsgTx(3)
639639
txTemplate.AddTxOut(&wire.TxOut{
640640
Value: int64(btcutil.Amount(1000)),
641641
PkScript: bytes.Clone(genesisDummyScript),

proof/proof_test.go

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

214214
// Build a minimal block with a single transaction so RandProof can
215215
// anchor the proof.
216-
tx := wire.NewMsgTx(2)
216+
tx := wire.NewMsgTx(3)
217217
tx.AddTxOut(&wire.TxOut{Value: 1})
218218
block := wire.MsgBlock{
219219
Transactions: []*wire.MsgTx{tx},

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
@@ -201,7 +201,7 @@ func addRandomManagedUTXO(t *testing.T, ctx context.Context,
201201
_, err = rand.Read(blockHash[:])
202202
require.NoError(t, err)
203203

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

tapdb/assets_store.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ func dbAssetsToChainAssets(dbAssets []ConfirmedAsset, witnesses assetWitnesses,
781781
}
782782
}
783783

784-
anchorTx := wire.NewMsgTx(2)
784+
anchorTx := wire.NewMsgTx(3)
785785
err = anchorTx.Deserialize(bytes.NewBuffer(sprout.AnchorTx))
786786
if err != nil {
787787
return nil, fmt.Errorf("unable to decode tx: %w", err)
@@ -3765,7 +3765,7 @@ func (a *AssetStore) queryParcelsWithFilters(ctx context.Context,
37653765
"%w", err)
37663766
}
37673767

3768-
anchorTx := wire.NewMsgTx(2)
3768+
anchorTx := wire.NewMsgTx(3)
37693769
err = anchorTx.Deserialize(bytes.NewReader(
37703770
dbAnchorTx.RawTx,
37713771
))

0 commit comments

Comments
 (0)