Skip to content

Conversation

@TheBlueMatt
Copy link
Contributor

This is an alternative version of #10184. As @jonasschnelli points out there, the performance regressions are pretty minimal, but given that this is a pretty simple, mechanical change, its probably worth doing.

@jonasschnelli
Copy link
Contributor

Concept ACK.
Ideally we should have been implemented this in the first place, but the code diff was already huge without this.

@TheBlueMatt TheBlueMatt force-pushed the 2017-04-wallet-more-keypool-cache branch 2 times, most recently from 2db2acd to 4a526d9 Compare April 20, 2017 03:21
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can also remove this one completely

Copy link
Contributor Author

Choose a reason for hiding this comment

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

rpcwallet uses it? Might as well leave it.

@NicolasDorier
Copy link
Contributor

NicolasDorier commented Apr 20, 2017

I really like this PR. This is simpler than before, utACK. You should remove KeypoolCountExternalKeys() though.

@NicolasDorier
Copy link
Contributor

@jonasschnelli the line count is almost the same. But it was better to not break the reviews, this was already a big PR.

Copy link
Contributor

@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.

(These review comments are actually from Tuesday. Apparently I forgot to press the submit button.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Having both internal and fInternal variables in the same scope with slightly different meanings seems error prone. Consider renaming one or both. I might go with requestedInternal and actuallyInternal.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could use iterator version of erase to avoid another lookup

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe assert !setKeyPool.empty()

Copy link
Contributor

Choose a reason for hiding this comment

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

This new code doesn't seem equivalent to the old code. Previously, if HD_SPLIT were true but there were 0 internal keys, it would return current timestamp now. Now it will return oldest external key time. Also vice versa (swapping internal/external).

@TheBlueMatt TheBlueMatt force-pushed the 2017-04-wallet-more-keypool-cache branch from 4a526d9 to f4390a7 Compare May 5, 2017 21:48
@TheBlueMatt
Copy link
Contributor Author

Addressed @ryanofsky's comments and rebased.

Copy link
Contributor

@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.

utACK f4390a7c11d7bdaf772b2fd44ee11fdbc1b85d86. Changes since previous review: rebase, fInternal variable renames, iterator erase call, GetOldestKeyPoolTime bugfix.

Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Track keypool entries as internal vs external in memory"

The previous name GetOldestKeyPoolTime might be better name for this since it is returning a time.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe GetOldestKeyBirthdayInPool or GetOldestKeyTimeInPool

Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Track keypool entries as internal vs external in memory"

You could initialize this to GetOldest(external) to save a line of code and get rid of the -1 magic value.

@ryanofsky
Copy link
Contributor

@jonasschnelli, do you want to review this? It seems like it simplifies some things and could interact nicely with #10240 and #10238.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: amountExternal is not longer required, setExternalKeyPool.size() can be used directly at L2991+.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally setKeyPool.erase() happens after the DB read and HaveKey/fInternal check? No?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If there are any issues with that key, best to get it out of the pool so that future calls succeed (though, really, those should be fatal StartShutdown() issues, not just runtime_errors that the RPC interface will return).

@jonasschnelli
Copy link
Contributor

Reviewed.
utACK f4390a7c11d7bdaf772b2fd44ee11fdbc1b85d86 modulo nits (although merge seems okay at this stage).

@TheBlueMatt TheBlueMatt force-pushed the 2017-04-wallet-more-keypool-cache branch from f4390a7 to 435c272 Compare June 21, 2017 15:41
@TheBlueMatt
Copy link
Contributor Author

Rebased and addressed all the comments, I believe.

@NicolasDorier
Copy link
Contributor

utACK 435c272

Copy link
Contributor

@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.

utACK 435c272. Rebased and has the 3 suggested changes.

@TheBlueMatt
Copy link
Contributor Author

Would be nice to get this for 15 to avoid some minor performance regressions.

@ryanofsky
Copy link
Contributor

Would be nice to get this for 15 to avoid some minor performance regressions.

This seems like it could be merged now. I don't see anything that would hold it up.

nEnd = *(--setInternalKeyPool.end()) + 1;
}
if (!setExternalKeyPool.empty()) {
nEnd = std::max(nEnd, *(--setExternalKeyPool.end()) + 1);
Copy link
Member

Choose a reason for hiding this comment

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

This looks really strange, why the infix subtract to an iterator here?

@TheBlueMatt TheBlueMatt force-pushed the 2017-04-wallet-more-keypool-cache branch 2 times, most recently from 022b557 to 1ee8c0f Compare July 11, 2017 16:08
Copy link
Contributor

@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.

utACK 1ee8c0f1868c8e5ba2f22549ba8965e212867ff1, but IMO the new commit makes the code worse. Before you could clearly see what TopUpKeyPool was doing if either of the sets were empty. Now you have to look inside the definition of a dodgy GetHighestSetElement function in another part of the code to find out what it returns when a set is empty and what implications that has for the max value. Would be better to drop this commit and just replace *--end() with *rbegin() in the original code, I think.

Only change since last review is the new commit.

Copy link
Contributor

@ryanofsky ryanofsky Jul 11, 2017

Choose a reason for hiding this comment

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

s/uint64_t/int64_t/

@TheBlueMatt TheBlueMatt force-pushed the 2017-04-wallet-more-keypool-cache branch from 1ee8c0f to bdf6ba8 Compare July 11, 2017 22:28
@TheBlueMatt
Copy link
Contributor Author

@ryanofsky OK, I restored it closer to where it was. That code goes away in #10795 anyway.

Copy link
Contributor

@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.

utACK bdf6ba8. Last commit now just switches --end to rbegin.

@morcos
Copy link
Contributor

morcos commented Jul 12, 2017

utACK bdf6ba8
assuming we also merge #10795

} else {
setExternalKeyPool.insert(nEnd);
}
LogPrintf("keypool added key %d, size=%u, internal=%d\n", nEnd, setInternalKeyPool.size() + setExternalKeyPool.size(), internal);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: print external and internal sizes or only size for keypool you're adding to

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@sipa
Copy link
Member

sipa commented Jul 13, 2017

utACK bdf6ba8. I started reviewing the first commit, made two review comments, and your two further commits exactly fixed those issues :)

@TheBlueMatt TheBlueMatt force-pushed the 2017-04-wallet-more-keypool-cache branch from bdf6ba8 to 6734c07 Compare July 14, 2017 15:19
@TheBlueMatt TheBlueMatt force-pushed the 2017-04-wallet-more-keypool-cache branch from 6734c07 to d40a72c Compare July 15, 2017 01:25
@sipa
Copy link
Member

sipa commented Jul 15, 2017

utACK d40a72c, only change is the keypool size logging.

@morcos
Copy link
Contributor

morcos commented Jul 15, 2017

utACK d40a72c

@sipa sipa merged commit d40a72c into bitcoin:master Jul 15, 2017
sipa added a commit that referenced this pull request Jul 15, 2017
d40a72c Clarify *(--.end()) iterator semantics in CWallet::TopUpKeyPool (Matt Corallo)
28301b9 Meet code style on lines changed in the previous commit (Matt Corallo)
4a3fc35 Track keypool entries as internal vs external in memory (Matt Corallo)

Pull request description:

  This is an alternative version of #10184. As @jonasschnelli points out there, the performance regressions are pretty minimal, but given that this is a pretty simple, mechanical change, its probably worth doing.

Tree-SHA512: e83f9ebf2998f8164d1b2eebe5e6dcdeadea8c30b7612861f830758c08bf4093cd6a67b3bcfa9cfcb139e5e0b106fc8898a975fc69f334981aefc756568ab613
laanwj added a commit that referenced this pull request Jul 18, 2017
1fc8c3d No longer ever reuse keypool indexes (Matt Corallo)

Pull request description:

  This fixes an issue where you could reserve a keypool entry, then
  top up the keypool, writing out a new key at the given index, then
  return they key from the pool. This isnt likely to cause issues,
  but given there is no reason to ever re-use keypool indexes
  (they're 64 bits...), best to avoid it alltogether.

  Builds on #10235, should probably get a 15 tag.

Tree-SHA512: c13a18a90f1076fb74307f2d64e9d80149811524c6bda259698ff2c65adaf8c6c3f2a3a07a5f4bf03251bc942ba8f5fd33a4427aa4256748c40b062991682caf
@jonasschnelli
Copy link
Contributor

Post merge ACK

PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Sep 18, 2019
1fc8c3d No longer ever reuse keypool indexes (Matt Corallo)

Pull request description:

  This fixes an issue where you could reserve a keypool entry, then
  top up the keypool, writing out a new key at the given index, then
  return they key from the pool. This isnt likely to cause issues,
  but given there is no reason to ever re-use keypool indexes
  (they're 64 bits...), best to avoid it alltogether.

  Builds on bitcoin#10235, should probably get a 15 tag.

Tree-SHA512: c13a18a90f1076fb74307f2d64e9d80149811524c6bda259698ff2c65adaf8c6c3f2a3a07a5f4bf03251bc942ba8f5fd33a4427aa4256748c40b062991682caf
@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.

7 participants