Skip to content

Conversation

ryanofsky
Copy link
Contributor

@ryanofsky ryanofsky commented Feb 3, 2017

Require timestamps for importmulti keys

Additionally, accept a "now" timestamp, to allow avoiding rescans for keys
which are known never to have been used.

Note that the behavior when "now" is specified is slightly different than the
previous behavior when no timestamp was specified at all. Previously, when no
timestamp was specified, it would avoid rescanning during the importmulti call,
but set the key's nCreateTime value to 1, which would not prevent future block
reads in later ScanForWalletTransactions calls. With this change, passing a
"now" timestamp will set the key's nCreateTime to the current block time
instead of 1.

Fixes #9491

@TheBlueMatt
Copy link
Contributor

Needs 0.14 tag.

@@ -970,13 +984,16 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
" [ (array of json objects)\n"
" {\n"
" \"scriptPubKey\": \"<script>\" | { \"address\":\"<address>\" }, (string / json, required) Type of scriptPubKey (string for script, json for address)\n"
" \"timestamp\": 1454686740 | \"now\" , (integer / string) Integer timestamp, or the string \"now\" to substitute the current synced\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should say whether it is required or optional

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are at this, why do we have the number 1454686740 here? Can't we just say <timestamp>?

Copy link
Contributor Author

@ryanofsky ryanofsky Feb 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in af06509. Personally I think "timestamp": 1454686740 is more informative than "timestamp": <timestamp>, but made the requested change anyway.

@fanquake fanquake added this to the 0.14.0 milestone Feb 4, 2017
@gmaxwell
Copy link
Contributor

gmaxwell commented Feb 4, 2017

Concept ACK but people with more opinions (and knowledge about json rpc norms) should comment on the type of the timestamp argument being variable.

@jonasschnelli
Copy link
Contributor

Concept ACK, will test.

I liked the idea from @sipa where he mentioned that "unknown" as timestamp for avoiding rescans seems to be the better choice (instead of "now"). "Now" would imply that the key was generated during import which is (almost) impossible.

@maflcko
Copy link
Member

maflcko commented Feb 5, 2017 via email

@laanwj
Copy link
Member

laanwj commented Feb 6, 2017

Concept ACK

Concept ACK but people with more opinions (and knowledge about json rpc norms) should comment on the type of the timestamp argument being variable.

It's hard to wrap in bindings for statically typed languages - could be worked around with an extra flag that specifies how to handle the timestamp.

ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 6, 2017
@ryanofsky
Copy link
Contributor Author

Added RPC test to verify that this is correctly interpreting the "now" value and saving the current time as the key creation time in 2cd875a.

@ryanofsky
Copy link
Contributor Author

Squashed 2cd875a -> c07ebb6 (multinow.3 -> multinow.4)

@@ -1015,6 +1032,12 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();

// Verify all timestamps are present before importing any keys.
const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetBlockTime() : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the MTP here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to MTP in dc402a4

@TheBlueMatt
Copy link
Contributor

TheBlueMatt commented Feb 7, 2017

utACK c07ebb6 if we switch to using MTP for the "now" timestamp. Did not review tests.

Copy link
Contributor Author

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now using MTP in dc402a4

@@ -1015,6 +1032,12 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();

// Verify all timestamps are present before importing any keys.
const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetBlockTime() : 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to MTP in dc402a4

@TheBlueMatt
Copy link
Contributor

utACK dc402a4

@laanwj
Copy link
Member

laanwj commented Feb 9, 2017

I liked the idea from @sipa where he mentioned that "unknown" as timestamp for avoiding rescans seems to be the better choice (instead of "now"). "Now" would imply that the key was generated during import which is (almost) impossible.
sipa proposed timestamp: "unused" instead of "now".

A "unused" flag makes sense, however that is not a property of the timestamp.

@kallewoof
Copy link
Contributor

Timestamp = unused sounds strange to me as well. Timestamp = now makes more sense.

Copy link
Contributor

@kallewoof kallewoof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK, did not review tests

src/rpc/misc.cpp Outdated
@@ -167,6 +167,7 @@ UniValue validateaddress(const JSONRPCRequest& request)
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
" \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
" \"timestamp\" : <timestamp>, (number, optional) The creation time of the key if available\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Non-string arguments tend to be represented as simply name, not <name>, e.g. https://github.com/bitcoin/bitcoin/blame/master/src/rpc/blockchain.cpp#L649

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 38c01b5

@@ -640,7 +640,8 @@ UniValue dumpwallet(const JSONRPCRequest& request)
}


UniValue processImport(const UniValue& data) {
UniValue processImport(const UniValue& data, int64_t timestamp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: const int64_t timestamp
Nit 2 / coding standard: Functions in Bitcoin generally start with a capital letter, i.e. ProcessImport here. (Exception being the RPC commands, which match the CLI command names.) I know you didn't name this one, but it coincides with the new function below (getImportTimestamp). Renaming this one should not be a big issue, as it is used in one place only.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6524d40

@@ -958,6 +958,20 @@ UniValue processImport(const UniValue& data) {
}
}

int64_t getImportTimestamp(const UniValue& data, int64_t now)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit / coding standard / repeat: GetImportTimestamp (see above)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6524d40

@@ -970,13 +984,16 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
" [ (array of json objects)\n"
" {\n"
" \"scriptPubKey\": \"<script>\" | { \"address\":\"<address>\" }, (string / json, required) Type of scriptPubKey (string for script, json for address)\n"
" \"timestamp\": <timestamp> | \"now\" , (integer / string, required) Integer timestamp, or the string \"now\" to substitute the current synced\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit / repeat: <timestamp> -> timestamp (see above comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6524d40

@@ -1015,6 +1032,12 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();

// Verify all timestamps are present before importing any keys.
const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if 0 is a good default for now, but it doesn't seem harmful either. I wonder if the function shouldn't simply throw a runtime_exception if !chainActive.Tip() saying to sync up first..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be ok with that change, but prefer the current behavior of not aborting just to give a notification that the chain is not synced when the outcome is safe either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, yeah I think a notification would be useful.

" \"timestamp\": <timestamp> | \"now\" , (integer / string, required) Integer timestamp, or the string \"now\" to substitute the current synced\n"
" blockchain time. The timestamp of the oldest key will determine how far back blockchain rescans\n"
" for missing wallet transactions need to begin. \"now\" can be specified to bypass scanning, for\n"
" keys which are known to never have been used, and 0 can be specified to scan the entire blockchain.\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Language: "The timestamp of the oldest key will determine how far back blockchain rescans need to begin for finding missing wallet transactions." maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6524d40

ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 9, 2017
Fix validateaddress timestamp argument documentation as suggested
bitcoin#9682 (comment)
ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 9, 2017
@ryanofsky
Copy link
Contributor Author

Squashed 6524d40 -> 715f05d (multinow.6 -> multinow.7)

Copy link
Contributor

@jonasschnelli jonasschnelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested ACK 715f05d

Additionally, accept a "now" timestamp, to allow avoiding rescans for keys
which are known never to have been used.

Note that the behavior when "now" is specified is slightly different than the
previous behavior when no timestamp was specified at all. Previously, when no
timestamp was specified, it would avoid rescanning during the importmulti call,
but set the key's nCreateTime value to 1, which would not prevent future block
reads in later ScanForWalletTransactions calls. With this change, passing a
"now" timestamp will set the key's nCreateTime to the current block time
instead of 1.

Fixes bitcoin#9491
Easiest way to test this was to expose the timestamp via the validateaddress
RPC (which was already looking up and returning key metadata).
@ryanofsky
Copy link
Contributor Author

Rebased 715f05d -> 266a811 (multinow.7 -> multinow.8) following the #9227 merge.

This PR didn't conflict with #9227, but I'm about to rebase #9108 on top of this, and #9108 did conflict with #9227.

@morcos
Copy link
Contributor

morcos commented Feb 13, 2017

utACK 266a811

@laanwj laanwj merged commit 266a811 into bitcoin:master Feb 14, 2017
laanwj added a commit that referenced this pull request Feb 14, 2017
266a811 Use MTP for importmulti "now" timestamps (Russell Yanofsky)
3cf9917 Add test to check new importmulti "now" value (Russell Yanofsky)
442887f Require timestamps for importmulti keys (Russell Yanofsky)
laanwj added a commit that referenced this pull request Feb 15, 2017
… (on top of #9682)

a80f98b Use importmulti timestamp when importing watch only keys (Russell Yanofsky)
a58370e Dedup nTimeFirstKey update logic (Russell Yanofsky)
codablock pushed a commit to codablock/dash that referenced this pull request Feb 1, 2018
266a811 Use MTP for importmulti "now" timestamps (Russell Yanofsky)
3cf9917 Add test to check new importmulti "now" value (Russell Yanofsky)
442887f Require timestamps for importmulti keys (Russell Yanofsky)
codablock pushed a commit to codablock/dash that referenced this pull request Feb 1, 2018
…ly keys (on top of bitcoin#9682)

a80f98b Use importmulti timestamp when importing watch only keys (Russell Yanofsky)
a58370e Dedup nTimeFirstKey update logic (Russell Yanofsky)
HashUnlimited pushed a commit to chaincoin/chaincoin that referenced this pull request Feb 27, 2018
andvgal pushed a commit to energicryptocurrency/gen2-energi that referenced this pull request Jan 6, 2019
266a811 Use MTP for importmulti "now" timestamps (Russell Yanofsky)
3cf9917 Add test to check new importmulti "now" value (Russell Yanofsky)
442887f Require timestamps for importmulti keys (Russell Yanofsky)
andvgal pushed a commit to energicryptocurrency/gen2-energi that referenced this pull request Jan 6, 2019
…ly keys (on top of bitcoin#9682)

a80f98b Use importmulti timestamp when importing watch only keys (Russell Yanofsky)
a58370e Dedup nTimeFirstKey update logic (Russell Yanofsky)
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Feb 28, 2019
266a811 Use MTP for importmulti "now" timestamps (Russell Yanofsky)
3cf9917 Add test to check new importmulti "now" value (Russell Yanofsky)
442887f Require timestamps for importmulti keys (Russell Yanofsky)
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Feb 28, 2019
…ly keys (on top of bitcoin#9682)

a80f98b Use importmulti timestamp when importing watch only keys (Russell Yanofsky)
a58370e Dedup nTimeFirstKey update logic (Russell Yanofsky)
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Mar 2, 2019
266a811 Use MTP for importmulti "now" timestamps (Russell Yanofsky)
3cf9917 Add test to check new importmulti "now" value (Russell Yanofsky)
442887f Require timestamps for importmulti keys (Russell Yanofsky)
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Mar 2, 2019
…ly keys (on top of bitcoin#9682)

a80f98b Use importmulti timestamp when importing watch only keys (Russell Yanofsky)
a58370e Dedup nTimeFirstKey update logic (Russell Yanofsky)
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Importmulti api is confusing in a way that could lead to funds loss.
10 participants