|
|
@ -101,6 +101,8 @@ UniValue importprivkey(const JSONRPCRequest& request) |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool fRescan = true; |
|
|
|
|
|
|
|
{ |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
|
|
|
|
|
|
|
|
EnsureWalletIsUnlocked(pwallet); |
|
|
|
EnsureWalletIsUnlocked(pwallet); |
|
|
@ -111,7 +113,6 @@ UniValue importprivkey(const JSONRPCRequest& request) |
|
|
|
strLabel = request.params[1].get_str(); |
|
|
|
strLabel = request.params[1].get_str(); |
|
|
|
|
|
|
|
|
|
|
|
// Whether to perform rescan after import
|
|
|
|
// Whether to perform rescan after import
|
|
|
|
bool fRescan = true; |
|
|
|
|
|
|
|
if (!request.params[2].isNull()) |
|
|
|
if (!request.params[2].isNull()) |
|
|
|
fRescan = request.params[2].get_bool(); |
|
|
|
fRescan = request.params[2].get_bool(); |
|
|
|
|
|
|
|
|
|
|
@ -131,7 +132,6 @@ UniValue importprivkey(const JSONRPCRequest& request) |
|
|
|
CKeyID vchAddress = pubkey.GetID(); |
|
|
|
CKeyID vchAddress = pubkey.GetID(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
pwallet->MarkDirty(); |
|
|
|
pwallet->MarkDirty(); |
|
|
|
|
|
|
|
|
|
|
|
// We don't know which corresponding address will be used; label them all
|
|
|
|
// We don't know which corresponding address will be used; label them all
|
|
|
|
for (const auto& dest : GetAllDestinationsForKey(pubkey)) { |
|
|
|
for (const auto& dest : GetAllDestinationsForKey(pubkey)) { |
|
|
|
pwallet->SetAddressBook(dest, strLabel, "receive"); |
|
|
|
pwallet->SetAddressBook(dest, strLabel, "receive"); |
|
|
@ -142,20 +142,19 @@ UniValue importprivkey(const JSONRPCRequest& request) |
|
|
|
return NullUniValue; |
|
|
|
return NullUniValue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// whenever a key is imported, we need to scan the whole chain
|
|
|
|
|
|
|
|
pwallet->UpdateTimeFirstKey(1); |
|
|
|
pwallet->mapKeyMetadata[vchAddress].nCreateTime = 1; |
|
|
|
pwallet->mapKeyMetadata[vchAddress].nCreateTime = 1; |
|
|
|
|
|
|
|
|
|
|
|
if (!pwallet->AddKeyPubKey(key, pubkey)) { |
|
|
|
if (!pwallet->AddKeyPubKey(key, pubkey)) { |
|
|
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); |
|
|
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); |
|
|
|
} |
|
|
|
} |
|
|
|
pwallet->LearnAllRelatedScripts(pubkey); |
|
|
|
pwallet->LearnAllRelatedScripts(pubkey); |
|
|
|
|
|
|
|
} |
|
|
|
// whenever a key is imported, we need to scan the whole chain
|
|
|
|
} |
|
|
|
pwallet->UpdateTimeFirstKey(1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fRescan) { |
|
|
|
if (fRescan) { |
|
|
|
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); |
|
|
|
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NullUniValue; |
|
|
|
return NullUniValue; |
|
|
|
} |
|
|
|
} |
|
|
@ -268,6 +267,7 @@ UniValue importaddress(const JSONRPCRequest& request) |
|
|
|
if (!request.params[3].isNull()) |
|
|
|
if (!request.params[3].isNull()) |
|
|
|
fP2SH = request.params[3].get_bool(); |
|
|
|
fP2SH = request.params[3].get_bool(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
|
|
|
|
|
|
|
|
CTxDestination dest = DecodeDestination(request.params[0].get_str()); |
|
|
|
CTxDestination dest = DecodeDestination(request.params[0].get_str()); |
|
|
@ -282,7 +282,7 @@ UniValue importaddress(const JSONRPCRequest& request) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); |
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if (fRescan) |
|
|
|
if (fRescan) |
|
|
|
{ |
|
|
|
{ |
|
|
|
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); |
|
|
|
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); |
|
|
@ -436,6 +436,7 @@ UniValue importpubkey(const JSONRPCRequest& request) |
|
|
|
if (!pubKey.IsFullyValid()) |
|
|
|
if (!pubKey.IsFullyValid()) |
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); |
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
|
|
|
|
|
|
|
|
for (const auto& dest : GetAllDestinationsForKey(pubKey)) { |
|
|
|
for (const auto& dest : GetAllDestinationsForKey(pubKey)) { |
|
|
@ -443,7 +444,7 @@ UniValue importpubkey(const JSONRPCRequest& request) |
|
|
|
} |
|
|
|
} |
|
|
|
ImportScript(pwallet, GetScriptForRawPubKey(pubKey), strLabel, false); |
|
|
|
ImportScript(pwallet, GetScriptForRawPubKey(pubKey), strLabel, false); |
|
|
|
pwallet->LearnAllRelatedScripts(pubKey); |
|
|
|
pwallet->LearnAllRelatedScripts(pubKey); |
|
|
|
|
|
|
|
} |
|
|
|
if (fRescan) |
|
|
|
if (fRescan) |
|
|
|
{ |
|
|
|
{ |
|
|
|
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); |
|
|
|
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */); |
|
|
@ -479,18 +480,19 @@ UniValue importwallet(const JSONRPCRequest& request) |
|
|
|
if (fPruneMode) |
|
|
|
if (fPruneMode) |
|
|
|
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode"); |
|
|
|
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int64_t nTimeBegin = 0; |
|
|
|
|
|
|
|
bool fGood = true; |
|
|
|
|
|
|
|
{ |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
|
|
|
|
|
|
|
|
EnsureWalletIsUnlocked(pwallet); |
|
|
|
EnsureWalletIsUnlocked(pwallet); |
|
|
|
|
|
|
|
|
|
|
|
std::ifstream file; |
|
|
|
std::ifstream file; |
|
|
|
file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); |
|
|
|
file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); |
|
|
|
if (!file.is_open()) |
|
|
|
if (!file.is_open()) { |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); |
|
|
|
|
|
|
|
} |
|
|
|
int64_t nTimeBegin = chainActive.Tip()->GetBlockTime(); |
|
|
|
nTimeBegin = chainActive.Tip()->GetBlockTime(); |
|
|
|
|
|
|
|
|
|
|
|
bool fGood = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg()); |
|
|
|
int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg()); |
|
|
|
file.seekg(0, file.beg); |
|
|
|
file.seekg(0, file.beg); |
|
|
@ -563,6 +565,7 @@ UniValue importwallet(const JSONRPCRequest& request) |
|
|
|
file.close(); |
|
|
|
file.close(); |
|
|
|
pwallet->ShowProgress("", 100); // hide progress dialog in GUI
|
|
|
|
pwallet->ShowProgress("", 100); // hide progress dialog in GUI
|
|
|
|
pwallet->UpdateTimeFirstKey(nTimeBegin); |
|
|
|
pwallet->UpdateTimeFirstKey(nTimeBegin); |
|
|
|
|
|
|
|
} |
|
|
|
pwallet->RescanFromTime(nTimeBegin, false /* update */); |
|
|
|
pwallet->RescanFromTime(nTimeBegin, false /* update */); |
|
|
|
pwallet->MarkDirty(); |
|
|
|
pwallet->MarkDirty(); |
|
|
|
|
|
|
|
|
|
|
@ -1135,18 +1138,21 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int64_t now = 0; |
|
|
|
|
|
|
|
bool fRunScan = false; |
|
|
|
|
|
|
|
int64_t nLowestTimestamp = 0; |
|
|
|
|
|
|
|
UniValue response(UniValue::VARR); |
|
|
|
|
|
|
|
{ |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
LOCK2(cs_main, pwallet->cs_wallet); |
|
|
|
EnsureWalletIsUnlocked(pwallet); |
|
|
|
EnsureWalletIsUnlocked(pwallet); |
|
|
|
|
|
|
|
|
|
|
|
// Verify all timestamps are present before importing any keys.
|
|
|
|
// Verify all timestamps are present before importing any keys.
|
|
|
|
const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; |
|
|
|
now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; |
|
|
|
for (const UniValue& data : requests.getValues()) { |
|
|
|
for (const UniValue& data : requests.getValues()) { |
|
|
|
GetImportTimestamp(data, now); |
|
|
|
GetImportTimestamp(data, now); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool fRunScan = false; |
|
|
|
|
|
|
|
const int64_t minimumTimestamp = 1; |
|
|
|
const int64_t minimumTimestamp = 1; |
|
|
|
int64_t nLowestTimestamp = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fRescan && chainActive.Tip()) { |
|
|
|
if (fRescan && chainActive.Tip()) { |
|
|
|
nLowestTimestamp = chainActive.Tip()->GetBlockTime(); |
|
|
|
nLowestTimestamp = chainActive.Tip()->GetBlockTime(); |
|
|
@ -1154,8 +1160,6 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) |
|
|
|
fRescan = false; |
|
|
|
fRescan = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
UniValue response(UniValue::VARR); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const UniValue& data : requests.getValues()) { |
|
|
|
for (const UniValue& data : requests.getValues()) { |
|
|
|
const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp); |
|
|
|
const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp); |
|
|
|
const UniValue result = ProcessImport(pwallet, data, timestamp); |
|
|
|
const UniValue result = ProcessImport(pwallet, data, timestamp); |
|
|
@ -1175,7 +1179,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) |
|
|
|
nLowestTimestamp = timestamp; |
|
|
|
nLowestTimestamp = timestamp; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if (fRescan && fRunScan && requests.size()) { |
|
|
|
if (fRescan && fRunScan && requests.size()) { |
|
|
|
int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, true /* update */); |
|
|
|
int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, true /* update */); |
|
|
|
pwallet->ReacceptWalletTransactions(); |
|
|
|
pwallet->ReacceptWalletTransactions(); |
|
|
|