Skip to content

Commit

Permalink
Add BIP352 test vectors as unit tests
Browse files Browse the repository at this point in the history
Use the test vectors to test sending and receiving. A few cases are not
covered here, namely anything that requires testing specific to the
wallet. For example:

* Taproot script path spending is not tested, as that is better tested in
  a wallets coin selection / signing logic
* Re-computing outputs during RBF is not tested, as that is better
  tested in a wallets RBF logic

The unit tests are written in such a way that adding new test cases is
as easy as updating the JSON file.
  • Loading branch information
josibake committed Jan 19, 2024
1 parent 23df115 commit 53630a3
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 5 deletions.
124 changes: 123 additions & 1 deletion src/test/data/bip352_send_and_receive_vectors.json
Original file line number Diff line number Diff line change
Expand Up @@ -2035,5 +2035,127 @@
}
}
]
},
{
"comment": "Single receipient: taproot input with NUMS point",
"sending": [
{
"given": {
"vin": [
{
"txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
"vout": 0,
"scriptSig": "",
"txinwitness": "0440c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b22205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5ac41c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0e6adf06419fc5d335d5e6a34f160304d78ff7356343aa0e6a79a3a715725f4440150",
"prevout": {
"scriptPubKey": {
"hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
}
},
"private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
},
{
"txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
"vout": 0,
"scriptSig": "",
"txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1",
"prevout": {
"scriptPubKey": {
"hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338"
}
},
"private_key": "fc8716a97a48ba9a05a98ae47b5cd201a25a7fd5d8b73c203c5f7b6b6b3b6ad7"
},
{
"txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
"vout": 1,
"scriptSig": "",
"txinwitness": "0340268d31a9276f6380107d5321cafa6d9e8e5ea39204318fdc8206b31507c891c3bbcea3c99e2208d73bd127a8e8c5f1e45a54f1bd217205414ddb566ab7eda0092220e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85dac41c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0e6adf06419fc5d335d5e6a34f160304d78ff7356343aa0e6a79a3a715725f444",
"prevout": {
"scriptPubKey": {
"hex": "5120e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d"
}
},
"private_key": "8d4751f6e8a3586880fb66c19ae277969bd5aa06f61c4ee2f1e2486efdf666d3"
}
],
"recipients": [
[
"sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
1.0
]
]
},
"expected": {
"outputs": [
[
"79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d",
1.0
]
]
}
}
],
"receiving": [
{
"given": {
"vin": [
{
"txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
"vout": 0,
"scriptSig": "",
"txinwitness": "0440c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b22205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5ac41c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0e6adf06419fc5d335d5e6a34f160304d78ff7356343aa0e6a79a3a715725f4440150",
"prevout": {
"scriptPubKey": {
"hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
}
}
},
{
"txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
"vout": 0,
"scriptSig": "",
"txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1",
"prevout": {
"scriptPubKey": {
"hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338"
}
}
},
{
"txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
"vout": 1,
"scriptSig": "",
"txinwitness": "0340268d31a9276f6380107d5321cafa6d9e8e5ea39204318fdc8206b31507c891c3bbcea3c99e2208d73bd127a8e8c5f1e45a54f1bd217205414ddb566ab7eda0092220e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85dac41c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0e6adf06419fc5d335d5e6a34f160304d78ff7356343aa0e6a79a3a715725f444",
"prevout": {
"scriptPubKey": {
"hex": "5120e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d"
}
}
}
],
"outputs": [
"79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d"
],
"key_material": {
"spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
"scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
},
"labels": []
},
"expected": {
"addresses": [
"sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
],
"outputs": [
{
"pub_key": "79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d",
"priv_key_tweak": "3ddec3232609d348d6b8b53123b4f40f6d4f5398ca586f087b0416ec3b851496",
"signature": "d7d06e3afb68363031e4eb18035c46ceae41bdbebe7888a4754bc9848c596436869aeaecff0527649a1f458b71c9ceecec10b535c09d01d720229aa228547706"
}
]
}
}
]
}
]
]
24 changes: 20 additions & 4 deletions src/wallet/test/silentpayment_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,28 @@ BOOST_AUTO_TEST_CASE(bip352_send_and_receive_test_vectors)
std::vector<COutPoint> outpoints;
std::vector<std::pair<CKey, bool>> sender_secret_keys;
for (const auto& input : given["vin"].getValues()) {
outpoints.emplace_back(TxidFromString(input["txid"].get_str()), input["vout"].getInt<uint32_t>());
COutPoint outpoint{TxidFromString(input["txid"].get_str()), input["vout"].getInt<uint32_t>()};
outpoints.push_back(outpoint);
const auto& spk_bytes = ParseHex(input["prevout"]["scriptPubKey"]["hex"].get_str());
CScript spk = CScript(spk_bytes.begin(), spk_bytes.end());
std::vector<std::vector<unsigned char>> solutions;
TxoutType type = Solver(spk, solutions);
sender_secret_keys.emplace_back(ParseHexToCKey(input["private_key"].get_str()), (type == TxoutType::WITNESS_V1_TAPROOT));
const auto& script_sig_bytes = ParseHex(input["scriptSig"].get_str());
CScript script_sig = CScript(script_sig_bytes.begin(), script_sig_bytes.end());
CTxIn txin{outpoint, script_sig};
CScriptWitness witness;
// read the field txWitness as a stream and write txWitness >> witness.stack;
auto witness_str = ParseHex(input["txinwitness"].get_str());
if (!witness_str.empty()) {
SpanReader(witness_str) >> witness.stack;
txin.scriptWitness = witness;
}

// check if this is a silent payment input by trying to extract the public key
auto pubkey = ExtractPubKeyFromInput(txin, spk);
if (pubkey.has_value()) {
std::vector<std::vector<unsigned char>> solutions;
TxoutType type = Solver(spk, solutions);
sender_secret_keys.emplace_back(ParseHexToCKey(input["private_key"].get_str()), (type == TxoutType::WITNESS_V1_TAPROOT));
}
}

std::vector<CRecipient> silent_payment_addresses;
Expand Down

0 comments on commit 53630a3

Please sign in to comment.