Replace account ID with ZIP-0032 key path in listaddresses output.
Account ID information is insufficiently granular to identify separate pools of spend authority.
This commit is contained in:
parent
dc2c07bbde
commit
ebab190fdf
|
@ -534,7 +534,7 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equihash"
|
name = "equihash"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -543,7 +543,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "f4jumble"
|
name = "f4jumble"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
]
|
]
|
||||||
|
@ -1896,7 +1896,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_address"
|
name = "zcash_address"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bech32",
|
"bech32",
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
|
@ -1908,7 +1908,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_encoding"
|
name = "zcash_encoding"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"nonempty",
|
"nonempty",
|
||||||
|
@ -1917,7 +1917,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_history"
|
name = "zcash_history"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bigint",
|
"bigint",
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
|
@ -1927,7 +1927,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_note_encryption"
|
name = "zcash_note_encryption"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -1942,7 +1942,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_primitives"
|
name = "zcash_primitives"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"bip0039",
|
"bip0039",
|
||||||
|
@ -1976,7 +1976,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_proofs"
|
name = "zcash_proofs"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/nuttycom/librustzcash.git?rev=86d4affe739170ab5ed9e69f5123938d12973fde#86d4affe739170ab5ed9e69f5123938d12973fde"
|
source = "git+https://github.com/zcash/librustzcash.git?rev=3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12#3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bellman",
|
"bellman",
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -71,8 +71,8 @@ codegen-units = 1
|
||||||
ed25519-zebra = { git = "https://github.com/ZcashFoundation/ed25519-zebra.git", rev = "d3512400227a362d08367088ffaa9bd4142a69c7" }
|
ed25519-zebra = { git = "https://github.com/ZcashFoundation/ed25519-zebra.git", rev = "d3512400227a362d08367088ffaa9bd4142a69c7" }
|
||||||
incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "b7bd6246122a6e9ace8edb51553fbf5228906cbb" }
|
incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "b7bd6246122a6e9ace8edb51553fbf5228906cbb" }
|
||||||
orchard = { git = "https://github.com/zcash/orchard.git", rev = "2c8241f25b943aa05203eacf9905db117c69bd29" }
|
orchard = { git = "https://github.com/zcash/orchard.git", rev = "2c8241f25b943aa05203eacf9905db117c69bd29" }
|
||||||
zcash_address = { git = "https://github.com/nuttycom/librustzcash.git", rev = "86d4affe739170ab5ed9e69f5123938d12973fde" }
|
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12" }
|
||||||
zcash_history = { git = "https://github.com/nuttycom/librustzcash.git", rev = "86d4affe739170ab5ed9e69f5123938d12973fde" }
|
zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12" }
|
||||||
zcash_note_encryption = { git = "https://github.com/nuttycom/librustzcash.git", rev = "86d4affe739170ab5ed9e69f5123938d12973fde" }
|
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12" }
|
||||||
zcash_primitives = { git = "https://github.com/nuttycom/librustzcash.git", rev = "86d4affe739170ab5ed9e69f5123938d12973fde" }
|
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12" }
|
||||||
zcash_proofs = { git = "https://github.com/nuttycom/librustzcash.git", rev = "86d4affe739170ab5ed9e69f5123938d12973fde" }
|
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "3d7b9dc9aa14ecc8f95ed338b2d7876fac12fd12" }
|
||||||
|
|
|
@ -135,3 +135,21 @@ TEST(ZIP32, TestVectors) {
|
||||||
m_1_2hv_3.DefaultAddress().d,
|
m_1_2hv_3.DefaultAddress().d,
|
||||||
testing::ElementsAreArray({ 0x03, 0x0f, 0xfb, 0x26, 0x3a, 0x93, 0x9e, 0x23, 0x0e, 0x96, 0xdd }));
|
testing::ElementsAreArray({ 0x03, 0x0f, 0xfb, 0x26, 0x3a, 0x93, 0x9e, 0x23, 0x0e, 0x96, 0xdd }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ZIP32, ParseZip32KeypathAccount) {
|
||||||
|
std::string sAccount = "m/32'/1234'/5'";
|
||||||
|
EXPECT_TRUE(libzcash::ParseZip32KeypathAccount(sAccount).has_value());
|
||||||
|
EXPECT_EQ(libzcash::ParseZip32KeypathAccount(sAccount).value(), 5);
|
||||||
|
|
||||||
|
sAccount = "m/32'/1234'/50'";
|
||||||
|
EXPECT_TRUE(libzcash::ParseZip32KeypathAccount(sAccount).has_value());
|
||||||
|
EXPECT_EQ(libzcash::ParseZip32KeypathAccount(sAccount).value(), 50);
|
||||||
|
|
||||||
|
sAccount = "m/32'/1234'/5'/0";
|
||||||
|
EXPECT_TRUE(libzcash::ParseZip32KeypathAccount(sAccount).has_value());
|
||||||
|
EXPECT_EQ(libzcash::ParseZip32KeypathAccount(sAccount).value(), 5);
|
||||||
|
|
||||||
|
sAccount = "m/32'/133'/2147483646'/1";
|
||||||
|
EXPECT_TRUE(libzcash::ParseZip32KeypathAccount(sAccount).has_value());
|
||||||
|
EXPECT_EQ(libzcash::ParseZip32KeypathAccount(sAccount).value(), 2147483646);
|
||||||
|
}
|
||||||
|
|
|
@ -334,7 +334,7 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
|
||||||
" },\n"
|
" },\n"
|
||||||
" \"sapling\": [ -- each element in this list represents a set of diversified addresses derived from a single IVK. \n"
|
" \"sapling\": [ -- each element in this list represents a set of diversified addresses derived from a single IVK. \n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" \"zip32AccountId\": 0, -- optional field, not present for imported/watchonly sources,\n"
|
" \"zip32KeyPath\": \"m/32'/133'/0'\", -- optional field, not present for imported/watchonly sources,\n"
|
||||||
" \"addresses\": [\n"
|
" \"addresses\": [\n"
|
||||||
" \"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\",\n"
|
" \"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\",\n"
|
||||||
" ...\n"
|
" ...\n"
|
||||||
|
@ -477,12 +477,10 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
UniValue sapling_obj(UniValue::VOBJ);
|
UniValue sapling_obj(UniValue::VOBJ);
|
||||||
|
|
||||||
if (source == LegacyHDSeed) {
|
if (source == LegacyHDSeed || source == MnemonicHDSeed) {
|
||||||
std::string hdKeypath = pwalletMain->mapSaplingZKeyMetadata[ivk].hdKeypath;
|
std::string hdKeyPath = pwalletMain->mapSaplingZKeyMetadata[ivk].hdKeypath;
|
||||||
std::optional<unsigned long> accountId = libzcash::ParseZip32KeypathAccount(hdKeypath);
|
if (hdKeyPath != "") {
|
||||||
|
sapling_obj.pushKV("zip32KeyPath", hdKeyPath);
|
||||||
if (accountId.has_value()) {
|
|
||||||
sapling_obj.pushKV("zip32AccountId", (uint64_t) accountId.value());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -831,34 +831,34 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_getnewaddress) {
|
||||||
auto listarr = list.get_array();
|
auto listarr = list.get_array();
|
||||||
bool sproutCountMatch = false;
|
bool sproutCountMatch = false;
|
||||||
bool saplingExtfvksMatch = false;
|
bool saplingExtfvksMatch = false;
|
||||||
bool saplingAccount0 = false;
|
bool saplingSpendAuth0 = false;
|
||||||
bool saplingAccount1 = false;
|
bool saplingSpendAuth1 = false;
|
||||||
bool saplingCountMismatch = true;
|
bool saplingCountMismatch = true;
|
||||||
for (auto a : listarr.getValues()) {
|
for (auto a : listarr.getValues()) {
|
||||||
auto source = find_value(a.get_obj(), "source");
|
auto source = find_value(a.get_obj(), "source");
|
||||||
if (source.get_str() == "legacy_random") {
|
if (source.get_str() == "legacy_random") {
|
||||||
auto sprout_obj = find_value(a.get_obj(), "sprout").get_obj();
|
auto sproutObj = find_value(a.get_obj(), "sprout").get_obj();
|
||||||
auto sprout_addrs = find_value(sprout_obj, "addresses").get_array();
|
auto sproutAddrs = find_value(sproutObj, "addresses").get_array();
|
||||||
sproutCountMatch = (sprout_addrs.size() == 1);
|
sproutCountMatch = (sproutAddrs.size() == 1);
|
||||||
}
|
}
|
||||||
if (source.get_str() == "legacy_hdseed") {
|
if (source.get_str() == "legacy_hdseed") {
|
||||||
auto sapling_addr_sets = find_value(a.get_obj(), "sapling").get_array();
|
auto sapling_addr_sets = find_value(a.get_obj(), "sapling").get_array();
|
||||||
saplingExtfvksMatch = (sapling_addr_sets.size() == 2);
|
saplingExtfvksMatch = (sapling_addr_sets.size() == 2);
|
||||||
|
|
||||||
for (auto sapling_obj : sapling_addr_sets.getValues()) {
|
for (auto saplingObj : sapling_addr_sets.getValues()) {
|
||||||
auto sapling_account = find_value(sapling_obj, "zip32AccountId").get_int();
|
auto keypath = find_value(saplingObj, "zip32KeyPath").get_str();
|
||||||
saplingAccount0 |= (sapling_account == 0);
|
saplingSpendAuth0 |= (keypath == "m/32'/133'/2147483646'/0");
|
||||||
saplingAccount1 |= (sapling_account == 1);
|
saplingSpendAuth1 |= (keypath == "m/32'/133'/2147483646'/1");
|
||||||
auto sapling_addrs = find_value(sapling_obj, "addresses").get_array();
|
auto saplingAddrs = find_value(saplingObj, "addresses").get_array();
|
||||||
saplingCountMismatch &= (sapling_addrs.size() != 1);
|
saplingCountMismatch &= (saplingAddrs.size() != 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_CHECK(sproutCountMatch);
|
BOOST_CHECK(sproutCountMatch);
|
||||||
BOOST_CHECK(saplingExtfvksMatch);
|
BOOST_CHECK(saplingExtfvksMatch);
|
||||||
BOOST_CHECK(!saplingCountMismatch);
|
BOOST_CHECK(!saplingCountMismatch);
|
||||||
BOOST_CHECK(saplingAccount0);
|
BOOST_CHECK(saplingSpendAuth0);
|
||||||
BOOST_CHECK(saplingAccount1);
|
BOOST_CHECK(saplingSpendAuth1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,10 +124,10 @@ std::optional<SaplingPaymentAddress> CWallet::GenerateNewLegacySaplingZKey() {
|
||||||
auto seedOpt = GetMnemonicSeed();
|
auto seedOpt = GetMnemonicSeed();
|
||||||
if (seedOpt.has_value()) {
|
if (seedOpt.has_value()) {
|
||||||
auto seed = seedOpt.value();
|
auto seed = seedOpt.value();
|
||||||
if (!legacyHDChain.has_value()) {
|
if (!mnemonicHDChain.has_value()) {
|
||||||
legacyHDChain = CHDChain(seed.Fingerprint(), GetTime());
|
mnemonicHDChain = CHDChain(seed.Fingerprint(), GetTime());
|
||||||
}
|
}
|
||||||
CHDChain& hdChain = legacyHDChain.value();
|
CHDChain& hdChain = mnemonicHDChain.value();
|
||||||
|
|
||||||
// loop until we find an unused address index
|
// loop until we find an unused address index
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -249,8 +249,12 @@ std::optional<CPubKey> CWallet::GenerateNewKey()
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
auto seedOpt = GetMnemonicSeed();
|
auto seedOpt = GetMnemonicSeed();
|
||||||
CHDChain& hdChain = mnemonicHDChain.value();
|
|
||||||
if (seedOpt.has_value()) {
|
if (seedOpt.has_value()) {
|
||||||
|
if (!mnemonicHDChain.has_value()) {
|
||||||
|
mnemonicHDChain = CHDChain(seedOpt.value().Fingerprint(), GetTime());
|
||||||
|
}
|
||||||
|
CHDChain& hdChain = mnemonicHDChain.value();
|
||||||
|
|
||||||
// All mnemonic seeds are checked at construction to ensure that we can obtain
|
// All mnemonic seeds are checked at construction to ensure that we can obtain
|
||||||
// a valid spending key for the account ZCASH_LEGACY_ACCOUNT;
|
// a valid spending key for the account ZCASH_LEGACY_ACCOUNT;
|
||||||
// therefore, the `value()` call here is safe.
|
// therefore, the `value()` call here is safe.
|
||||||
|
|
|
@ -378,7 +378,7 @@ std::optional<ZcashdUnifiedAddress> UnifiedFullViewingKey::Address(diversifier_i
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<unsigned long> ParseZip32KeypathAccount(const std::string& keyPath) {
|
std::optional<unsigned long> ParseZip32KeypathAccount(const std::string& keyPath) {
|
||||||
std::regex pattern("m/32'/[0-9]+'/([0-9]+)'");
|
std::regex pattern("m/32'/[0-9]+'/([0-9]+)'.*");
|
||||||
std::smatch matches;
|
std::smatch matches;
|
||||||
if (std::regex_match(keyPath, matches, pattern)) {
|
if (std::regex_match(keyPath, matches, pattern)) {
|
||||||
return stoul(matches[1]);
|
return stoul(matches[1]);
|
||||||
|
|
Loading…
Reference in New Issue