bitcoin-dumpwallet 0.1.16-alpha.0

persist wallet to and from disk
Documentation
crate::ix!();

pub fn create_from_dump(
    name:        &String,
    wallet_path: &Path,
    error:       &mut BilingualStr,
    warnings:    &mut Vec<BilingualStr>) -> bool {

    todo!();
        /*
            // Get the dumpfile
        std::string dump_filename = gArgs.GetArg("-dumpfile", "");
        if (dump_filename.empty()) {
            error = _("No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided.");
            return false;
        }

        fs::path dump_path = fs::PathFromString(dump_filename);
        dump_path = fs::absolute(dump_path);
        if (!fs::exists(dump_path)) {
            error = strprintf(_("Dump file %s does not exist."), fs::PathToString(dump_path));
            return false;
        }
        fsbridge::ifstream dump_file(dump_path);

        // Compute the checksum
        CHashWriter hasher(0, 0);
        uint256 checksum;

        // Check the magic and version
        std::string magic_key;
        std::getline(dump_file, magic_key, ',');
        std::string version_value;
        std::getline(dump_file, version_value, '\n');
        if (magic_key != DUMP_MAGIC) {
            error = strprintf(_("Error: Dumpfile identifier record is incorrect. Got \"%s\", expected \"%s\"."), magic_key, DUMP_MAGIC);
            dump_file.close();
            return false;
        }
        // Check the version number (value of first record)
        uint32_t ver;
        if (!ParseUInt32(version_value, &ver)) {
            error =strprintf(_("Error: Unable to parse version %u as a uint32_t"), version_value);
            dump_file.close();
            return false;
        }
        if (ver != DUMP_VERSION) {
            error = strprintf(_("Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s"), version_value);
            dump_file.close();
            return false;
        }
        std::string magic_hasher_line = strprintf("%s,%s\n", magic_key, version_value);
        hasher.write(magic_hasher_line.data(), magic_hasher_line.size());

        // Get the stored file format
        std::string format_key;
        std::getline(dump_file, format_key, ',');
        std::string format_value;
        std::getline(dump_file, format_value, '\n');
        if (format_key != "format") {
            error = strprintf(_("Error: Dumpfile format record is incorrect. Got \"%s\", expected \"format\"."), format_key);
            dump_file.close();
            return false;
        }
        // Get the data file format with format_value as the default
        std::string file_format = gArgs.GetArg("-format", format_value);
        if (file_format.empty()) {
            error = _("No wallet file format provided. To use createfromdump, -format=<format> must be provided.");
            return false;
        }
        DatabaseFormat data_format;
        if (file_format == "bdb") {
            data_format = DatabaseFormat::BERKELEY;
        } else if (file_format == "sqlite") {
            data_format = DatabaseFormat::SQLITE;
        } else {
            error = strprintf(_("Unknown wallet file format \"%s\" provided. Please provide one of \"bdb\" or \"sqlite\"."), file_format);
            return false;
        }
        if (file_format != format_value) {
            warnings.push_back(strprintf(_("Warning: Dumpfile wallet format \"%s\" does not match command line specified format \"%s\"."), format_value, file_format));
        }
        std::string format_hasher_line = strprintf("%s,%s\n", format_key, format_value);
        hasher.write(format_hasher_line.data(), format_hasher_line.size());

        DatabaseOptions options;
        DatabaseStatus status;
        options.require_create = true;
        options.require_format = data_format;
        std::unique_ptr<WalletDatabase> database = MakeDatabase(wallet_path, options, status, error);
        if (!database) return false;

        // dummy chain interface
        bool ret = true;
        std::shared_ptr<CWallet> wallet(new CWallet(nullptr /* chain */, name, std::move(database)), WalletToolReleaseWallet);
        {
            LOCK(wallet->cs_wallet);
            DBErrors load_wallet_ret = wallet->LoadWallet();
            if (load_wallet_ret != DBErrors::LOAD_OK) {
                error = strprintf(_("Error creating %s"), name);
                return false;
            }

            // Get the database handle
            WalletDatabase& db = wallet->GetDatabase();
            std::unique_ptr<DatabaseBatch> batch = db.MakeBatch();
            batch->TxnBegin();

            // Read the records from the dump file and write them to the database
            while (dump_file.good()) {
                std::string key;
                std::getline(dump_file, key, ',');
                std::string value;
                std::getline(dump_file, value, '\n');

                if (key == "checksum") {
                    std::vector<unsigned char> parsed_checksum = ParseHex(value);
                    std::copy(parsed_checksum.begin(), parsed_checksum.end(), checksum.begin());
                    break;
                }

                std::string line = strprintf("%s,%s\n", key, value);
                hasher.write(line.data(), line.size());

                if (key.empty() || value.empty()) {
                    continue;
                }

                if (!IsHex(key)) {
                    error = strprintf(_("Error: Got key that was not hex: %s"), key);
                    ret = false;
                    break;
                }
                if (!IsHex(value)) {
                    error = strprintf(_("Error: Got value that was not hex: %s"), value);
                    ret = false;
                    break;
                }

                std::vector<unsigned char> k = ParseHex(key);
                std::vector<unsigned char> v = ParseHex(value);

                DataStream ss_key(k, SER_DISK, CLIENT_VERSION);
                DataStream ss_value(v, SER_DISK, CLIENT_VERSION);

                if (!batch->Write(ss_key, ss_value)) {
                    error = strprintf(_("Error: Unable to write record to new wallet"));
                    ret = false;
                    break;
                }
            }

            if (ret) {
                uint256 comp_checksum = hasher.GetHash();
                if (checksum.IsNull()) {
                    error = _("Error: Missing checksum");
                    ret = false;
                } else if (checksum != comp_checksum) {
                    error = strprintf(_("Error: Dumpfile checksum does not match. Computed %s, expected %s"), HexStr(comp_checksum), HexStr(checksum));
                    ret = false;
                }
            }

            if (ret) {
                batch->TxnCommit();
            } else {
                batch->TxnAbort();
            }

            batch.reset();

            dump_file.close();
        }
        wallet.reset(); // The pointer deleter will close the wallet for us.

        // Remove the wallet dir if we have a failure
        if (!ret) {
            fs::remove_all(wallet_path);
        }

        return ret;
        */
}