Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
Add importmulti RPC call #7551
Conversation
laanwj
added
the
Wallet
label
Feb 17, 2016
|
Concept ACK |
laanwj
added
the
Feature
label
Feb 17, 2016
promag
and 1 other
commented on an outdated diff
Feb 17, 2016
| + const string& strValue = data["value"].get_str(); | ||
| + string strLabel = data.exists("label") ? data["label"].get_str() : ""; | ||
| + | ||
| + if (strType == "privkey") | ||
| + ImportPrivateKey(strValue, strLabel); | ||
| + else if (strType == "pubkey") | ||
| + ImportPublicKey(strValue, strLabel); | ||
| + else if (strType == "address") { | ||
| + bool fP2SH = data.exists("p2sh") ? data["p2sh"].get_bool() : false; | ||
| + ImportAddressKey(strValue, strLabel, fP2SH); | ||
| + } else | ||
| + throw; | ||
| + | ||
| + result.pushKV("result", UniValue(true)); | ||
| + fRunScan = true; | ||
| + } catch (...) { |
pedrobranco
Contributor
|
promag
and 1 other
commented on an outdated diff
Feb 17, 2016
| + HelpExampleCli("importmulti", "'[ { \"type\":\"privkey\", \"value\":\"<my private key>\", \"timestamp\":1455191478 }," | ||
| + "{ \"type\":\"pubkey\", \"value\":\"<my public key>\", \"label\":\"example 1\", \"timestamp\":1455191480 } ]' true") + | ||
| + HelpExampleCli("importmulti", "'[{ \"type\":\"pubkey\", \"value\":\"<my public key>\", \"label\":\"example 1\", \"timestamp\":1455191464 } ]' false") + HelpExampleRpc("importmulti", "[ { \"type\":\"privkey\", \"value\":\"<my private key>\" }," | ||
| + "{ \"type\":\"pubkey\", \"value\":\"<my public key>\", \"label\":\"example 1\", \"timestamp\":1455191480 } ], true") + | ||
| + HelpExampleRpc("importmulti", "'[{ \"type\":\"pubkey\", \"value\":\"<my public key>\", \"label\":\"example 1\", \"timestamp\":1455191464 } ]', false") + | ||
| + | ||
| + "\nResponse is an array with the same size as the input that has the execution result :\n" | ||
| + " [ { \"result\": true | false } , ... ]\n"); | ||
| + | ||
| + if (!EnsureWalletIsAvailable(fHelp)) | ||
| + return NullUniValue; | ||
| + | ||
| + if (params.size() == 1) | ||
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)); | ||
| + else | ||
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VBOOL)); |
promag
Contributor
|
promag
commented on an outdated diff
Feb 17, 2016
| @@ -510,3 +534,105 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) | ||
| file.close(); | ||
| return NullUniValue; | ||
| } | ||
| + | ||
| + | ||
| +UniValue importmulti(const UniValue& params, bool fHelp) | ||
| +{ | ||
| + if (fHelp || params.size() < 1 || params.size() > 2) | ||
| + throw runtime_error( | ||
| + "importmulti '[{\"type\":\"privkey\",\"value\":\"mkjjX...\"},...]' (rescan) \n\n" |
promag
Contributor
|
promag
commented on an outdated diff
Feb 17, 2016
| @@ -72,6 +73,40 @@ std::string DecodeDumpString(const std::string &str) { | ||
| return ret.str(); | ||
| } | ||
| +bool ImportPrivateKey(const string& strPrivkey, const string& strLabel) |
promag
Contributor
|
|
concept ACK I have implemented a method to also simply just import an spv proof + transaction rather than rescan. Would be nice to include that in this as well. (need to add tests and PR...) |
|
Concept ACK. |
instagibbs
and 1 other
commented on an outdated diff
Feb 18, 2016
| @@ -0,0 +1,143 @@ | ||
| +#!/usr/bin/env python2 | ||
| +# Copyright (c) 2014-2016 The Bitcoin Core developers | ||
| +# Distributed under the MIT software license, see the accompanying | ||
| +# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
| + | ||
| +from test_framework.test_framework import BitcoinTestFramework | ||
| +from test_framework.util import * | ||
| + | ||
| +class ImportMultiTest (BitcoinTestFramework): | ||
| + | ||
| + def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size): |
|
|
I agree. Though I've done a similar thing in #7552. Use positional arguments only for the 'essential' arguments, and an associative array for everything optional or future-extensible. Much less hassle and confusing than APIs with tons of positional arguments, especially optional ones. |
|
@jonasschnelli there is also #7518 that accepts options as a JSON object. |
promag
referenced this pull request
Feb 25, 2016
Closed
Add option to specify rescan starting timestamp to RPC import calls #6570
|
GBT also uses an options Object |
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Feb 25, 2016
|
concept ACK |
|
Replaced the output result from [ { "result": true } , ... ] to [ { "success": true } , ... ]. In case of giving a exception should we show any information of the reason in the result? Something like: |
|
Passing along error messages would be hugely helpful, yes. |
|
Another thing, currently we match the input to the output status by the order given of the input array. Example: input = [ { type: "address", value: "myaddress1"}, { type: "address", value: "myaddress2"}, ... ] to something like: input = [ { type: "address", value: "myaddress1"}, { type: "address", value: "myaddress2"}, ... ] Or maybe include in the reference the complete input node . In this case when the user calls the importmulti it can pass any type of extra information that later can be useful to take some action. |
|
I'll have to defer to others on the value of that. I don't see much value-add personally but unsure. |
mrbandrews
commented on an outdated diff
Mar 17, 2016
| @@ -0,0 +1,144 @@ | ||
| +#!/usr/bin/env python2 | ||
| +# Copyright (c) 2014-2016 The Bitcoin Core developers | ||
| +# Distributed under the MIT software license, see the accompanying | ||
| +# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
| + | ||
| +from test_framework.test_framework import BitcoinTestFramework | ||
| +from test_framework.util import * | ||
| + | ||
| +class ImportMultiTest (BitcoinTestFramework): | ||
| + def setup_chain(self): | ||
| + print("Initializing test directory "+self.options.tmpdir) | ||
| + initialize_chain_clean(self.options.tmpdir, 4) | ||
| + |
|
|
mrbandrews
commented on an outdated diff
Mar 17, 2016
| +#!/usr/bin/env python2 | ||
| +# Copyright (c) 2014-2016 The Bitcoin Core developers | ||
| +# Distributed under the MIT software license, see the accompanying | ||
| +# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
| + | ||
| +from test_framework.test_framework import BitcoinTestFramework | ||
| +from test_framework.util import * | ||
| + | ||
| +class ImportMultiTest (BitcoinTestFramework): | ||
| + def setup_chain(self): | ||
| + print("Initializing test directory "+self.options.tmpdir) | ||
| + initialize_chain_clean(self.options.tmpdir, 4) | ||
| + | ||
| + def setup_network(self, split=False): | ||
| + self.nodes = start_nodes(2, self.options.tmpdir) | ||
| + connect_nodes_bi(self.nodes,0,1) |
mrbandrews
Contributor
|
mrbandrews
commented on an outdated diff
Mar 17, 2016
| +# Distributed under the MIT software license, see the accompanying | ||
| +# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
| + | ||
| +from test_framework.test_framework import BitcoinTestFramework | ||
| +from test_framework.util import * | ||
| + | ||
| +class ImportMultiTest (BitcoinTestFramework): | ||
| + def setup_chain(self): | ||
| + print("Initializing test directory "+self.options.tmpdir) | ||
| + initialize_chain_clean(self.options.tmpdir, 4) | ||
| + | ||
| + def setup_network(self, split=False): | ||
| + self.nodes = start_nodes(2, self.options.tmpdir) | ||
| + connect_nodes_bi(self.nodes,0,1) | ||
| + self.is_network_split=False | ||
| + self.sync_all() |
|
|
mrbandrews
commented on an outdated diff
Mar 17, 2016
| + # pubkey | ||
| + address2 = self.nodes[0].getnewaddress() | ||
| + address2_pubkey = self.nodes[0].validateaddress(address2)['pubkey'] # Using pubkey | ||
| + # privkey | ||
| + address3 = self.nodes[0].getnewaddress() | ||
| + address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey | ||
| + # scriptPubKey | ||
| + address4 = self.nodes[0].getnewaddress() | ||
| + address4_scriptpubkey = self.nodes[0].validateaddress(address4)['scriptPubKey'] # Using scriptpubkey | ||
| + | ||
| + | ||
| + #Check only one address | ||
| + address_info = self.nodes[0].validateaddress(address1) | ||
| + assert_equal(address_info['ismine'], True) | ||
| + | ||
| + self.sync_all() |
|
|
|
Lightly tested ACK. |
|
@mrbandrews Test added. |
MarcoFalke
and 1 other
commented on an outdated diff
Mar 28, 2016
| + { "type": ADDRESS_KEY, "value": self.nodes[0].getnewaddress() , "label":"random account" } , | ||
| + { "type": PUB_KEY, "value": self.nodes[0].validateaddress(self.nodes[0].getnewaddress())['pubkey'] } , | ||
| + { "type": SCRIPT_KEY, "value": self.nodes[0].validateaddress(self.nodes[0].getnewaddress())['scriptPubKey'] }, | ||
| + ], { "rescan":False } ) | ||
| + | ||
| + # all succeed | ||
| + assert_equal(result2[0]['success'], True) | ||
| + assert_equal(result2[1]['success'], True) | ||
| + assert_equal(result2[2]['success'], True) | ||
| + assert_equal(result2[3]['success'], True) | ||
| + assert_equal(result2[4]['success'], True) | ||
| + | ||
| + # empty json case | ||
| + try: | ||
| + self.nodes[1].importmulti() | ||
| + raise |
MarcoFalke
Member
|
MarcoFalke
commented on an outdated diff
Mar 28, 2016
| + except: | ||
| + pass | ||
| + | ||
| + # parcial success case | ||
| + result3 = self.nodes[1].importmulti( [ | ||
| + { "type": ADDRESS_KEY, "value": self.nodes[0].getnewaddress() }, | ||
| + { "type": PUB_KEY }, | ||
| + { "type": PUB_KEY , "value": "123456789"}, | ||
| + ] ) | ||
| + | ||
| + assert_equal(result3[0]['success'], True) | ||
| + try: #JSON field "error" doesn't exist in success:true | ||
| + result3[0]['error'] | ||
| + raise | ||
| + except: | ||
| + pass |
|
|
|
Concept ACK |
|
Needs rebase after #7558 |
@MarcoFalke What do you suggest? @laanwj Rebased. |
|
@laanwj Are you considering merging this soon? |
|
Sorry for the very late response here, but I think it's undesirable to have the "p2sh" flag in this call. The fact that it's present in importscript is historical, but quite confusing I think (see #7687). Here is what happens:
will mark scriptPubKeys that exactly match script as ismine, but without the ability to spend them, and there is no address added to the wallet (so it will likely be treated as change by the wallet, though show up in listunspent).
Will do the same as the call above, AND also add script as a known script to the keystore, meaning that it will start treating scriptPubKeys that send to P2SH(script) as ismine too, AND in addition associate the passed label with that P2SH address (but not with the raw script).
Will mark scriptPubKeys that match the exact script corresponding to address as ismine, AND associate the passed label with it. There is a much cleaner distinction here, where importing of scripts and importing of addresses is completely separate. That would mean that where you'd use import script p2sh=true, instead, you'd import both a script and an address. |
jonasschnelli
commented on an outdated diff
Apr 14, 2016
| + // clang-format off | ||
| + if (fHelp || params.size() < 1 || params.size() > 2) | ||
| + throw runtime_error( | ||
| + "importmulti '[{\"type\":\"privkey\",\"value\":\"mkjjX...\"},...]' (rescan) \n\n" | ||
| + "Import several types of addresses (private and public keys, transaction addresses/scripts) with only one rescan\n" | ||
| + | ||
| + "Arguments:\n" | ||
| + "1. json request array (json, required) Data to be imported\n" | ||
| + " [ (json array of json objects)\n" | ||
| + " {\n" | ||
| + " \"type\": \"privkey | pubkey | address | script\", (string, required) Type of address\n" | ||
| + " \"value\": \"...\", (string, required) Value of the address\n" | ||
| + " \"timestamp\": 1454686740, (integer, optional) Timestamp\n" | ||
| + " \"label\": \"...\" (string, optional) Label\n" | ||
| + " \"p2sh\": true | false (bool, optional, default=false) Value is a P2SH (type=script only)\n" | ||
| + " }\n" |
jonasschnelli
Member
|
|
To add some more background: ultimately, there are 3 internal calls that can be issued:
So right now, importaddress "script" p2sh=true calls AddWatchOnly(script), AddCScript(script), SetAddressBook(P2SH(script)). This is a bit inconsistent, as it has effects on outputs. paying to script directly and through P2SH |
|
concept ACK |
sipa
referenced this pull request
Apr 18, 2016
Closed
Fix help text around importaddress and rename it to importscript #7903
|
@sipa Thanks for the explanation. I've added p2sh support only because |
|
Maybe I'm misunderstanding this, but I think the type should fully specify what kind of object is imported:
This makes an extra P2SH flag redundant. |
|
script is ambiguous: it can mean "i'm importing this script, so that when it is used as a P2SH redeemscript, the client knows how to sign it", or "i want outputs spending to this exact script to be counting towards my balance and listunspent". |
|
Then add a different type for either case? |
|
eh, the "i'm importing this script, so that when it is used as a P2SH redeemscript, the client knows how to sign it" case probably doesn't belong here at all, as it relates to signing and doesn't affect the balance/rescan? |
|
@laanwj It does, because if that script itself uses keys that are known to the wallet, it will make such outputs be considered spendable. |
|
I'm sorry for just mentioning some background and complaints, and not offering a good solution. But I think we have a mess that is caused by having half a dozen different ways through which a script can be considered spendable/solvable/ismine, and having magic import commands with many edge cases (like importaddress now) that just try to do as much as possible, and we should not maintain that in newer APIs. One solution is to break it down to the lowest-level CKeyStore changes, and providing a means to individually add:
However, it would be highly inconvenient to use (you'd sometimes need 3 separate entries to get the behaviour of a single call now). Here is a proposal, but it's quite a bit different from the existing design: the input is a list of Objects, each of which has the following keys:
This is a bit redundant and less convenient (it always requires specifying a script or address, and either keys), but I think it allows for very accurate error messages whenever the behaviour wouldn't match the user's expectations. It also makes it obvious where the current codebase's restrictions are (you can't make a non-standard scriptPubKey non-internal, only individual keys can be assigned a birth time, ...), which can be loosened in future iterations if those restrictions are solved. Open for discussion of course! |
MarcoFalke
referenced this pull request
May 1, 2016
Closed
Optional parameter for rescans to start at a specified height #7984
|
@sipa replace |
|
@promag I considered that, but if it's an address, it's not really a scriptPubKey (especially if there is ever support for things like stealth addresses (which contain cryptographic information that never actually directly ends up in the scriptPubKey). Perhaps there should be two separate fields, address or scriptPubKey, and you're required to exactly provide one of them. |
|
@sipa ACK and thanks for the proposal. Also, when calling with the private keys and |
MarcoFalke
and 1 other
commented on an outdated diff
May 6, 2016
@sipa maybe we could go with:
It's scalable and unambiguous. WDYT? |
|
@arowser this is still work in progress. |
|
@promag Looks good to me. |
laanwj
added this to the 0.13.0 milestone
Jun 8, 2016
|
As this is very often requested functionality I'd really like to get this in for 0.13. Note that the deadline for features for 0.13 is June 16, so that would mean we'll have to get it to a mergeable state in a week. Is that realistic? |
|
@laanwj Yes, i think is realistic. |
|
Ping... |
|
@laanwj We have a partial solution but is not complete:
We've made a major refactor and unfortunately we think we are late for the 0.13 milestone. |
MarcoFalke
and 1 other
commented on an outdated diff
Jun 15, 2016
| @@ -0,0 +1,214 @@ | ||
| +#!/usr/bin/env python3 | ||
| +# Copyright (c) 2014-2016 The Bitcoin Core developers | ||
| +# Distributed under the MIT software license, see the accompanying | ||
| +# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
| + | ||
| +from test_framework.test_framework import BitcoinTestFramework | ||
| +from test_framework.util import * | ||
| + | ||
| +class ImportMultiTest (BitcoinTestFramework): | ||
| + def setup_chain(self): | ||
| + print("Initializing test directory "+self.options.tmpdir) | ||
| + initialize_chain_clean(self.options.tmpdir, 2) |
MarcoFalke
Member
|
MarcoFalke
commented on an outdated diff
Jun 16, 2016
MarcoFalke
commented on an outdated diff
Jun 16, 2016
| +# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
| + | ||
| +from test_framework.test_framework import BitcoinTestFramework | ||
| +from test_framework.util import * | ||
| + | ||
| +class ImportMultiTest (BitcoinTestFramework): | ||
| + def setup_chain(self): | ||
| + print("Initializing test directory "+self.options.tmpdir) | ||
| + initialize_chain_clean(self.options.tmpdir, 2) | ||
| + | ||
| + def setup_network(self, split=False): | ||
| + self.nodes = start_nodes(2, self.options.tmpdir) | ||
| + self.is_network_split=False | ||
| + | ||
| + def run_test (self): | ||
| + import time |
|
|
|
Looks good to me - utACK d72a886
Seems acceptable for a first version, it's not documented either so that's consistent.
I'm afraid so too, if we would merge it now it would be very last-minute, I don't think this code is well-tested enough. Code does get more testing on master, but so close to a release it's more risky, we don't want to release with something broken. |
I totally agree. Still we need help on how to implement internal mode and watch-only, and the consistency checking (technical doubts, so we'll need to do some researching). |
|
I promise to help with this (nag me if I forget), but after 0.13 is
branched off.
|
Thanks for the support. I have some doubts about the expected result in some situations:
About the internal concept I'm a bit confused on how it should work. |
|
@pedrobranco Removing the 0.13 milestone then - thanks for your patience! |
MarcoFalke
removed this from the 0.13.0 milestone
Jun 21, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Jun 28, 2016
|
I think if private keys are given and watchonly, you should fail. The reason for the watchonly option is to indicate that you intentionally are not providing a private key, and are not expecting the ability to spend. It's there so that if someone just forgets to provide a private key (as opposed to making it intentionally watch-only), the call can warn them by failing. The internal concept is similar to watchonly. When it is present, you're not adding the address to the addressbook (so no label, not even an empty label). This makes it incompatible with the label option. But also for example, when the scriptPubKey is given in hex form and not in a standard type that can be internally converted to a CTxDestination, internal must be set, as there would be no way to add it to the address book (at this point). |
|
@sipa ACK. |
|
Consistency check added + internal + watchonly. |
jonasschnelli
referenced this pull request
Jul 20, 2016
Merged
[Wallet] Add RPC call "rescanblockchain <startheight> <stopheight>" #7061
|
Can someone please review the PR? |
|
Will test today. |
jonasschnelli
commented on an outdated diff
Jul 28, 2016
| @@ -61,6 +61,20 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { | ||
| return pindex; | ||
| } | ||
| + | ||
| +struct SmallerThanTimestamp { | ||
| + bool operator()(CBlockIndex* pBlock, const int64_t& time) const | ||
| + { | ||
| + return pBlock->GetBlockTime() < time; | ||
| + } | ||
| +}; | ||
| + | ||
| +CBlockIndex* CChain::FindLatestBefore(int64_t nTime) const | ||
| +{ | ||
| + std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime, SmallerThanTimestamp()); |
jonasschnelli
Member
|
jonasschnelli
and 1 other
commented on an outdated diff
Jul 28, 2016
| + int64_t nLowestTimestamp = 0; | ||
| + | ||
| + if (fRescan && chainActive.Tip()) | ||
| + nLowestTimestamp = chainActive.Tip()->GetBlockTime(); | ||
| + else | ||
| + fRescan = false; | ||
| + | ||
| + UniValue response(UniValue::VARR); | ||
| + | ||
| + BOOST_FOREACH (const UniValue& data, request.getValues()) { | ||
| + const UniValue result = processImport(data); | ||
| + response.push_back(result); | ||
| + } | ||
| + | ||
| + if (fRescan && fRunScan && request.size()) { | ||
| + CBlockIndex* pindex = nLowestTimestamp > 0 ? chainActive.FindLatestBefore(nLowestTimestamp) : chainActive.Genesis(); |
jonasschnelli
Member
|
jonasschnelli
commented on an outdated diff
Jul 28, 2016
| + | ||
| + LOCK2(cs_main, pwalletMain->cs_wallet); | ||
| + EnsureWalletIsUnlocked(); | ||
| + | ||
| + bool fRunScan = false; | ||
| + int64_t nLowestTimestamp = 0; | ||
| + | ||
| + if (fRescan && chainActive.Tip()) | ||
| + nLowestTimestamp = chainActive.Tip()->GetBlockTime(); | ||
| + else | ||
| + fRescan = false; | ||
| + | ||
| + UniValue response(UniValue::VARR); | ||
| + | ||
| + BOOST_FOREACH (const UniValue& data, request.getValues()) { | ||
| + const UniValue result = processImport(data); |
jonasschnelli
Member
|
jonasschnelli
commented on an outdated diff
Jul 28, 2016
| + | ||
| + CKey key = vchSecret.GetKey(); | ||
| + | ||
| + if (!key.IsValid()) | ||
| + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); | ||
| + | ||
| + CPubKey pubkey = key.GetPubKey(); | ||
| + assert(key.VerifyPubKey(pubkey)); | ||
| + | ||
| + CKeyID vchAddress = pubkey.GetID(); | ||
| + pwalletMain->MarkDirty(); | ||
| + pwalletMain->SetAddressBook(vchAddress, label, "receive"); | ||
| + | ||
| + if (pwalletMain->HaveKey(vchAddress)) | ||
| + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Already have this key"); | ||
| + ; |
jonasschnelli
Member
|
jonasschnelli
commented on the diff
Jul 28, 2016
| + | ||
| + const UniValue& request = params[0]; | ||
| + | ||
| + //Default options | ||
| + bool fRescan = true; | ||
| + | ||
| + if (params.size() > 1) { | ||
| + const UniValue& options = params[1]; | ||
| + if (options.exists("rescan")) | ||
| + fRescan = options["rescan"].get_bool(); | ||
| + } | ||
| + | ||
| + LOCK2(cs_main, pwalletMain->cs_wallet); | ||
| + EnsureWalletIsUnlocked(); | ||
| + | ||
| + bool fRunScan = false; |
jonasschnelli
Member
|
|
The rescan behavior seems not to work, I'm happy to test again once this is fixed. |
jonasschnelli
added this to the
0.14 milestone
Jul 28, 2016
|
@jonasschnelli Can you please test the rescan behavior? |
jonasschnelli
commented on an outdated diff
Aug 4, 2016
| + | ||
| + // If at least one request was successful then allow rescan. | ||
| + if (result["success"].get_bool()) { | ||
| + fRunScan = true; | ||
| + } | ||
| + | ||
| + // Get the lowest timestamp. | ||
| + const int64_t& timestamp = data.exists("timestamp") && data["timestamp"].get_int64() > 1 ? data["timestamp"].get_int64() : 1; | ||
| + | ||
| + if (timestamp > 1 && timestamp < nLowestTimestamp) { | ||
| + nLowestTimestamp = timestamp; | ||
| + } | ||
| + } | ||
| + | ||
| + if (fRescan && fRunScan && request.size()) { | ||
| + CBlockIndex* pindex = nLowestTimestamp > 0 ? chainActive.FindLatestBefore(nLowestTimestamp) : chainActive.Genesis(); |
|
|
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Aug 7, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Aug 9, 2016
luke-jr
referenced this pull request
Sep 6, 2016
Open
Feature Request: -rescan pruned blockchain #8668
|
What needs to be done here? |
Maybe add some tests for the rescan feature. |
|
Personally, I don't know the opinion of others, I'd really like to move forward and merge this if the base functionality is agreed on. There is still enough time before 0.14 to fix problems, add tests, add features etc. |
| + int64_t nLowestTimestamp; | ||
| + | ||
| + if (fRescan && chainActive.Tip()) { | ||
| + nLowestTimestamp = chainActive.Tip()->GetBlockTime(); |
jonasschnelli
Sep 28, 2016
Member
nit: using chainActive.Tip()s blocktime with the later FindLatestBefore(nLowestTimestamp) will probably always result in re-scaning a couple 1-2 blocks when importing with a timestamp in future.
pedrobranco
Sep 28, 2016
•
Contributor
We can prevent rescanning if nLowestTimestamp is in the future:
if (fRescan && fRunScan && request.size() && nLowestTimestamp <= chainActive.Tip()->GetBlockTime()) {
(...)| + nLowestTimestamp = chainActive.Tip()->GetBlockTime(); | ||
| + } else { | ||
| + fRescan = false; | ||
| + } |
jonasschnelli
Sep 28, 2016
Member
This else should be removed because it can only set a already false fRescan again to false.
jonasschnelli
Sep 28, 2016
Member
Argh. Your right. Got fooled by fRunScan, fRescan.
Nevermind then.
jonasschnelli
approved these changes
Sep 28, 2016
Tested ACK 1bcc021
(trivial rebase issue [only rpc-tests.py] can be done during merging), nits can be addresses after merging.
|
Rebased and nits addressed. |
| + pwalletMain->SetAddressBook(pubKeyAddress.Get(), label, "receive"); | ||
| + } | ||
| + | ||
| + // TODO Is this necessary? |
laanwj
Oct 5, 2016
Owner
It looks like you're doing the IsMine/HaveWatchOnly/AddWatchOnly dance twice here. Why?
pedrobranco
Oct 6, 2016
•
Contributor
I was wondering the same when I checked the RPC call importpubkey, which calls the same dance in here.
In doubt, and since I did want to change the behavior of importing pub keys, I've added the TODO mark for revision of this part of the code.
|
Needs (easy) rebase in rpcwallet.cpp after #8788 |
pedrobranco
added some commits
Jun 16, 2016
|
Rebased. |
|
Re-Tested ACK 215caba |
laanwj
merged commit 215caba
into
bitcoin:master
Oct 20, 2016
1 check passed
added a commit
that referenced
this pull request
Oct 20, 2016
Yes, agreed. The code is self-contained so the risk of regressions is minimal. The |
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Oct 20, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Oct 20, 2016
|
bisect identifies cb08fdb as the commit that causes the compile to fail with:-
I am confused as to how this tested ok and got merged when it doesn't compile.. |
| + CPubKey pubkey = key.GetPubKey(); | ||
| + assert(key.VerifyPubKey(pubkey)); | ||
| + | ||
| + CKeyID vchAddress = pubkey.GetID(); |
|
This has not given any compile issues for anyone else besides a boost issue which was fixed later ( #8980).
If you are trying to merge this into some other code base do not complain here if the build breaks. |
pedrobranco commentedFeb 17, 2016
As discussed in PR #6570 this is a new rpc call
importmultithat receives an array of JSON objects representing the intention of importing a public key, a private key, an address and script/p2sh:and rescans (if not disabled in second argument) the chain from the block that has a timestamp lowest than the lowest timestamp found in all requests, preventing scanning from genesis.
The output is an array with the status of each request:
Arguments:
Some notes:
Edit: As suggested by @promag i've replaced the second argument (optional)
boolto JSON to be easier specify new options and added a newtype="script"to support only script values, so cantype="address"work only with addresses.