Repository: dogecoin/dogecoin
File: src/wallet/walletdb.cpp (C++)

Code before:
                    std::vector<uint32_t> path;
                    if (keyMeta.has_key_origin) {
                        // We have a key origin, so pull it from its path vector
                        path = keyMeta.key_origin.path;
                    } else {
                        // No key origin, have to parse the string
                        if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
                            strErr = "Error reading wallet database: keymeta with invalid HD keypath";
                            return false;
                        }
                    }

                    // Extract the index and internal from the path
                    // Path string is m/0'/k'/i'
                    // Path vector is [0', k', i'] (but as ints OR'd with the hardened bit
                    // k == 0 for external, 1 for internal. i is the index
                    if (path.size() != 3) {
                        strErr = "Error reading wallet database: keymeta found with unexpected path";
                        return false;
                    }
                    if (path[0] != 0x80000000) {
                        strErr = strprintf("Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
                        return false;
                    }
                    if (path[1] != 0x80000003 && path[1] != (1 | 0x80000000)) {
                        strErr = strprintf("Unexpected path index of 0x%08x (expected 0x80000003 or 0x80000001) for the element at index 1", path[1]);
                        return false;
                    }
                    if ((path[2] & 0x80000000) == 0) {
                        strErr = strprintf("Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
                        return false;
                    }
                    internal = path[1] == (1 | 0x80000000);
                    index = path[2] & ~0x80000000;
                }

                // Insert a new CHDChain, or get the one that already exists
                auto ins = wss.m_hd_chains.emplace(keyMeta.hd_seed_id, CHDChain());
                CHDChain& chain = ins.first->second;
                if (ins.second) {
                    // For new chains, we want to default to VERSION_HD_BASE until we see an internal
                    chain.nVersion = CHDChain::VERSION_HD_BASE;
                    chain.seed_id = keyMeta.hd_seed_id;
                }
                if (internal) {
                    chain.nVersion = CHDChain::VERSION_HD_CHAIN_SPLIT;
                    chain.nInternalChainCounter = std::max(chain.nInternalChainCounter, index);
                } else {
                    chain.nExternalChainCounter = std::max(chain.nExternalChainCounter, index);
                }
            }

Review comment (suggestion):
Per your earlier comment, these lines need to be adapted to allow both `0x80000003` and `0x80000000`.

Code after:
                    std::vector<uint32_t> path;
                    if (keyMeta.has_key_origin) {
                        // We have a key origin, so pull it from its path vector
                        path = keyMeta.key_origin.path;
                    } else {
                        // No key origin, have to parse the string
                        if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
                            strErr = "Error reading wallet database: keymeta with invalid HD keypath";
                            return false;
                        }
                    }

                    // Extract the index and internal from the path
                    // Path string is m/0'/k'/i'
                    // Path vector is [0', k', i'] (but as ints OR'd with the hardened bit
                    // k == 0 for external, 1 for internal. i is the index
                    if (path.size() != 3) {
                        strErr = "Error reading wallet database: keymeta found with unexpected path";
                        return false;
                    }
                    if (path[0] != 0x80000000) {
                        strErr = strprintf("Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
                        return false;
                    }
                    if (path[1] != 0x80000000 && path[1] != 0x80000003 && path[1] != (1 | 0x80000000)) {
                        strErr = strprintf("Unexpected path index of 0x%08x (expected 0x80000000, 0x80000003 or 0x80000001) for the element at index 1", path[1]);
                        return false;
                    }
                    if ((path[2] & 0x80000000) == 0) {
                        strErr = strprintf("Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
                        return false;
                    }
                    internal = path[1] == (1 | 0x80000000);
                    index = path[2] & ~0x80000000;
                }

                // Insert a new CHDChain, or get the one that already exists
                auto ins = wss.m_hd_chains.emplace(keyMeta.hd_seed_id, CHDChain());
                CHDChain& chain = ins.first->second;
                if (ins.second) {
                    // For new chains, we want to default to VERSION_HD_BASE until we see an internal
                    chain.nVersion = CHDChain::VERSION_HD_BASE;
                    chain.seed_id = keyMeta.hd_seed_id;
                }
                if (internal) {
                    chain.nVersion = CHDChain::VERSION_HD_CHAIN_SPLIT;
                    chain.nInternalChainCounter = std::max(chain.nInternalChainCounter, index);
                } else {
                    chain.nExternalChainCounter = std::max(chain.nExternalChainCounter, index);
                }
            }