mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-22 23:03:43 +02:00
itest: test BIP-0086 Taproot account+pubkey import
This commit is contained in:
parent
97dfc04117
commit
3a66a09d9d
@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/btcsuite/btcd/btcutil/hdkeychain"
|
"github.com/btcsuite/btcd/btcutil/hdkeychain"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
@ -31,7 +32,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// walletToLNAddrType maps walletrpc.AddressType to lnrpc.AddressType.
|
// walletToLNAddrType maps walletrpc.AddressType to lnrpc.AddressType.
|
||||||
func walletToLNAddrType(t *testing.T, addrType walletrpc.AddressType) lnrpc.AddressType {
|
func walletToLNAddrType(t *testing.T,
|
||||||
|
addrType walletrpc.AddressType) lnrpc.AddressType {
|
||||||
|
|
||||||
switch addrType {
|
switch addrType {
|
||||||
case walletrpc.AddressType_NESTED_WITNESS_PUBKEY_HASH,
|
case walletrpc.AddressType_NESTED_WITNESS_PUBKEY_HASH,
|
||||||
walletrpc.AddressType_HYBRID_NESTED_WITNESS_PUBKEY_HASH:
|
walletrpc.AddressType_HYBRID_NESTED_WITNESS_PUBKEY_HASH:
|
||||||
@ -41,6 +44,9 @@ func walletToLNAddrType(t *testing.T, addrType walletrpc.AddressType) lnrpc.Addr
|
|||||||
case walletrpc.AddressType_WITNESS_PUBKEY_HASH:
|
case walletrpc.AddressType_WITNESS_PUBKEY_HASH:
|
||||||
return lnrpc.AddressType_WITNESS_PUBKEY_HASH
|
return lnrpc.AddressType_WITNESS_PUBKEY_HASH
|
||||||
|
|
||||||
|
case walletrpc.AddressType_TAPROOT_PUBKEY:
|
||||||
|
return lnrpc.AddressType_TAPROOT_PUBKEY
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t.Fatalf("unhandled addr type %v", addrType)
|
t.Fatalf("unhandled addr type %v", addrType)
|
||||||
return 0
|
return 0
|
||||||
@ -65,8 +71,6 @@ func newExternalAddr(t *testing.T, funder, signer *lntest.HarnessNode,
|
|||||||
|
|
||||||
// Carol also needs to generate the address for the sake of this test to
|
// Carol also needs to generate the address for the sake of this test to
|
||||||
// be able to sign the channel funding input.
|
// be able to sign the channel funding input.
|
||||||
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
defer cancel()
|
|
||||||
signerResp, err := signer.NewAddress(ctxt, &lnrpc.NewAddressRequest{
|
signerResp, err := signer.NewAddress(ctxt, &lnrpc.NewAddressRequest{
|
||||||
Type: walletToLNAddrType(t, addrType),
|
Type: walletToLNAddrType(t, addrType),
|
||||||
})
|
})
|
||||||
@ -96,6 +100,9 @@ func assertExternalAddrType(t *testing.T, addrStr string,
|
|||||||
|
|
||||||
require.IsType(t, addr, &btcutil.AddressScriptHash{})
|
require.IsType(t, addr, &btcutil.AddressScriptHash{})
|
||||||
|
|
||||||
|
case walletrpc.AddressType_TAPROOT_PUBKEY:
|
||||||
|
require.IsType(t, addr, &btcutil.AddressTaproot{})
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t.Fatalf("unsupported account addr type %v", accountAddrType)
|
t.Fatalf("unsupported account addr type %v", accountAddrType)
|
||||||
}
|
}
|
||||||
@ -208,7 +215,9 @@ func psbtSendFromImportedAccount(t *harnessTest, srcNode, destNode,
|
|||||||
|
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
balanceResp, err := srcNode.WalletBalance(ctxt, &lnrpc.WalletBalanceRequest{})
|
balanceResp, err := srcNode.WalletBalance(
|
||||||
|
ctxt, &lnrpc.WalletBalanceRequest{},
|
||||||
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
require.Contains(t.t, balanceResp.AccountBalance, account)
|
require.Contains(t.t, balanceResp.AccountBalance, account)
|
||||||
confBalance := balanceResp.AccountBalance[account].ConfirmedBalance
|
confBalance := balanceResp.AccountBalance[account].ConfirmedBalance
|
||||||
@ -246,7 +255,9 @@ func psbtSendFromImportedAccount(t *harnessTest, srcNode, destNode,
|
|||||||
finalizeReq := &walletrpc.FinalizePsbtRequest{
|
finalizeReq := &walletrpc.FinalizePsbtRequest{
|
||||||
FundedPsbt: fundResp.FundedPsbt,
|
FundedPsbt: fundResp.FundedPsbt,
|
||||||
}
|
}
|
||||||
finalizeResp, err := signer.WalletKitClient.FinalizePsbt(ctxt, finalizeReq)
|
finalizeResp, err := signer.WalletKitClient.FinalizePsbt(
|
||||||
|
ctxt, finalizeReq,
|
||||||
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
|
|
||||||
// With the PSBT signed, we can broadcast the resulting transaction.
|
// With the PSBT signed, we can broadcast the resulting transaction.
|
||||||
@ -284,6 +295,18 @@ func psbtSendFromImportedAccount(t *harnessTest, srcNode, destNode,
|
|||||||
expTxFee = 164
|
expTxFee = 164
|
||||||
expChangeScriptType = txscript.WitnessV0PubKeyHashTy
|
expChangeScriptType = txscript.WitnessV0PubKeyHashTy
|
||||||
|
|
||||||
|
case walletrpc.AddressType_TAPROOT_PUBKEY:
|
||||||
|
if account != defaultImportedAccount {
|
||||||
|
expTxFee = 190
|
||||||
|
expChangeScriptType = txscript.WitnessV1TaprootTy
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spends from the default imported account fall back to a P2WKH
|
||||||
|
// change. We'll want to change that, but in a separate PR.
|
||||||
|
expTxFee = 221
|
||||||
|
expChangeScriptType = txscript.WitnessV0PubKeyHashTy
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t.Fatalf("unsupported addr type %v", accountAddrType)
|
t.Fatalf("unsupported addr type %v", accountAddrType)
|
||||||
}
|
}
|
||||||
@ -322,7 +345,9 @@ func fundChanAndCloseFromImportedAccount(t *harnessTest, srcNode, destNode,
|
|||||||
// on.
|
// on.
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
balanceResp, err := srcNode.WalletBalance(ctxt, &lnrpc.WalletBalanceRequest{})
|
balanceResp, err := srcNode.WalletBalance(
|
||||||
|
ctxt, &lnrpc.WalletBalanceRequest{},
|
||||||
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
require.Contains(t.t, balanceResp.AccountBalance, account)
|
require.Contains(t.t, balanceResp.AccountBalance, account)
|
||||||
accountConfBalance := balanceResp.
|
accountConfBalance := balanceResp.
|
||||||
@ -437,6 +462,18 @@ func fundChanAndCloseFromImportedAccount(t *harnessTest, srcNode, destNode,
|
|||||||
expChanTxFee = 176
|
expChanTxFee = 176
|
||||||
expChangeScriptType = txscript.WitnessV0PubKeyHashTy
|
expChangeScriptType = txscript.WitnessV0PubKeyHashTy
|
||||||
|
|
||||||
|
case walletrpc.AddressType_TAPROOT_PUBKEY:
|
||||||
|
if account != defaultImportedAccount {
|
||||||
|
expChanTxFee = 202
|
||||||
|
expChangeScriptType = txscript.WitnessV1TaprootTy
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spends from the default imported account fall back to a P2WKH
|
||||||
|
// change. We'll want to change that, but in a separate PR.
|
||||||
|
expChanTxFee = 233
|
||||||
|
expChangeScriptType = txscript.WitnessV0PubKeyHashTy
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t.Fatalf("unsupported addr type %v", accountAddrType)
|
t.Fatalf("unsupported addr type %v", accountAddrType)
|
||||||
}
|
}
|
||||||
@ -563,6 +600,10 @@ func testWalletImportAccount(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
name: "standard BIP-0084",
|
name: "standard BIP-0084",
|
||||||
addrType: walletrpc.AddressType_WITNESS_PUBKEY_HASH,
|
addrType: walletrpc.AddressType_WITNESS_PUBKEY_HASH,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "standard BIP-0086",
|
||||||
|
addrType: walletrpc.AddressType_TAPROOT_PUBKEY,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
@ -571,7 +612,9 @@ func testWalletImportAccount(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ht := newHarnessTest(tt, net)
|
ht := newHarnessTest(tt, net)
|
||||||
ht.RunTestCase(&testCase{
|
ht.RunTestCase(&testCase{
|
||||||
name: tc.name,
|
name: tc.name,
|
||||||
test: func(net1 *lntest.NetworkHarness, t1 *harnessTest) {
|
test: func(net1 *lntest.NetworkHarness,
|
||||||
|
t1 *harnessTest) {
|
||||||
|
|
||||||
testWalletImportAccountScenario(
|
testWalletImportAccountScenario(
|
||||||
net, t, tc.addrType,
|
net, t, tc.addrType,
|
||||||
)
|
)
|
||||||
@ -669,7 +712,9 @@ func runWalletImportAccountScenario(net *lntest.NetworkHarness, t *harnessTest,
|
|||||||
// some assertions we'll make later on.
|
// some assertions we'll make later on.
|
||||||
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
balanceResp, err := dave.WalletBalance(ctxt, &lnrpc.WalletBalanceRequest{})
|
balanceResp, err := dave.WalletBalance(
|
||||||
|
ctxt, &lnrpc.WalletBalanceRequest{},
|
||||||
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
require.Contains(t.t, balanceResp.AccountBalance, importedAccount)
|
require.Contains(t.t, balanceResp.AccountBalance, importedAccount)
|
||||||
confBalance := balanceResp.AccountBalance[importedAccount].ConfirmedBalance
|
confBalance := balanceResp.AccountBalance[importedAccount].ConfirmedBalance
|
||||||
@ -716,6 +761,10 @@ func testWalletImportPubKey(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
name: "BIP-0084",
|
name: "BIP-0084",
|
||||||
addrType: walletrpc.AddressType_WITNESS_PUBKEY_HASH,
|
addrType: walletrpc.AddressType_WITNESS_PUBKEY_HASH,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "BIP-0086",
|
||||||
|
addrType: walletrpc.AddressType_TAPROOT_PUBKEY,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
@ -724,7 +773,9 @@ func testWalletImportPubKey(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ht := newHarnessTest(tt, net)
|
ht := newHarnessTest(tt, net)
|
||||||
ht.RunTestCase(&testCase{
|
ht.RunTestCase(&testCase{
|
||||||
name: tc.name,
|
name: tc.name,
|
||||||
test: func(net1 *lntest.NetworkHarness, t1 *harnessTest) {
|
test: func(net1 *lntest.NetworkHarness,
|
||||||
|
t1 *harnessTest) {
|
||||||
|
|
||||||
testWalletImportPubKeyScenario(
|
testWalletImportPubKeyScenario(
|
||||||
net, t, tc.addrType,
|
net, t, tc.addrType,
|
||||||
)
|
)
|
||||||
@ -758,7 +809,9 @@ func testWalletImportPubKeyScenario(net *lntest.NetworkHarness, t *harnessTest,
|
|||||||
// We'll define a helper closure that we'll use throughout the test to
|
// We'll define a helper closure that we'll use throughout the test to
|
||||||
// generate a new address of the given type from Carol's perspective,
|
// generate a new address of the given type from Carol's perspective,
|
||||||
// import it into Dave's wallet, and fund it.
|
// import it into Dave's wallet, and fund it.
|
||||||
importPubKey := func(keyIndex uint32, prevConfBalance, prevUnconfBalance int64) {
|
importPubKey := func(keyIndex uint32, prevConfBalance,
|
||||||
|
prevUnconfBalance int64) {
|
||||||
|
|
||||||
// Retrieve Carol's account public key for the corresponding
|
// Retrieve Carol's account public key for the corresponding
|
||||||
// address type.
|
// address type.
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||||
@ -767,7 +820,9 @@ func testWalletImportPubKeyScenario(net *lntest.NetworkHarness, t *harnessTest,
|
|||||||
Name: "default",
|
Name: "default",
|
||||||
AddressType: addrType,
|
AddressType: addrType,
|
||||||
}
|
}
|
||||||
listResp, err := carol.WalletKitClient.ListAccounts(ctxt, listReq)
|
listResp, err := carol.WalletKitClient.ListAccounts(
|
||||||
|
ctxt, listReq,
|
||||||
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
require.Equal(t.t, len(listResp.Accounts), 1)
|
require.Equal(t.t, len(listResp.Accounts), 1)
|
||||||
p2wkhAccount := listResp.Accounts[0]
|
p2wkhAccount := listResp.Accounts[0]
|
||||||
@ -784,11 +839,19 @@ func testWalletImportPubKeyScenario(net *lntest.NetworkHarness, t *harnessTest,
|
|||||||
externalAddrPubKey, err := externalAddrExtKey.ECPubKey()
|
externalAddrPubKey, err := externalAddrExtKey.ECPubKey()
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
|
|
||||||
|
// Serialize as 32-byte x-only pubkey for Taproot addresses.
|
||||||
|
serializedPubKey := externalAddrPubKey.SerializeCompressed()
|
||||||
|
if addrType == walletrpc.AddressType_TAPROOT_PUBKEY {
|
||||||
|
serializedPubKey = schnorr.SerializePubKey(
|
||||||
|
externalAddrPubKey,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Import the public key into Dave.
|
// Import the public key into Dave.
|
||||||
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
importReq := &walletrpc.ImportPublicKeyRequest{
|
importReq := &walletrpc.ImportPublicKeyRequest{
|
||||||
PublicKey: externalAddrPubKey.SerializeCompressed(),
|
PublicKey: serializedPubKey,
|
||||||
AddressType: addrType,
|
AddressType: addrType,
|
||||||
}
|
}
|
||||||
_, err = dave.WalletKitClient.ImportPublicKey(ctxt, importReq)
|
_, err = dave.WalletKitClient.ImportPublicKey(ctxt, importReq)
|
||||||
@ -798,9 +861,11 @@ func testWalletImportPubKeyScenario(net *lntest.NetworkHarness, t *harnessTest,
|
|||||||
// required later when signing.
|
// required later when signing.
|
||||||
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
carolAddrResp, err := carol.NewAddress(ctxt, &lnrpc.NewAddressRequest{
|
carolAddrResp, err := carol.NewAddress(
|
||||||
Type: walletToLNAddrType(t.t, addrType),
|
ctxt, &lnrpc.NewAddressRequest{
|
||||||
})
|
Type: walletToLNAddrType(t.t, addrType),
|
||||||
|
},
|
||||||
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
|
|
||||||
// Send coins to Carol's address and confirm them, making sure
|
// Send coins to Carol's address and confirm them, making sure
|
||||||
@ -842,9 +907,13 @@ func testWalletImportPubKeyScenario(net *lntest.NetworkHarness, t *harnessTest,
|
|||||||
// import into Dave again.
|
// import into Dave again.
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
balanceResp, err := dave.WalletBalance(ctxt, &lnrpc.WalletBalanceRequest{})
|
balanceResp, err := dave.WalletBalance(
|
||||||
|
ctxt, &lnrpc.WalletBalanceRequest{},
|
||||||
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(t.t, err)
|
||||||
require.Contains(t.t, balanceResp.AccountBalance, defaultImportedAccount)
|
require.Contains(
|
||||||
|
t.t, balanceResp.AccountBalance, defaultImportedAccount,
|
||||||
|
)
|
||||||
confBalance := balanceResp.
|
confBalance := balanceResp.
|
||||||
AccountBalance[defaultImportedAccount].ConfirmedBalance
|
AccountBalance[defaultImportedAccount].ConfirmedBalance
|
||||||
importPubKey(1, confBalance, 0)
|
importPubKey(1, confBalance, 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user