-
Notifications
You must be signed in to change notification settings - Fork 492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove brain farts #12234
Remove brain farts #12234
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
a60a08e
to
eb2df20
Compare
To help me reviewing, can you explain why a version using only a Dictionary in the HdPubKeyCache is not good, or can change behavior? turbolay@b75679d |
Using only a dictionary is possible but the assumption in the code is that the |
Thank you this is exactly the answer I needed. I will review soon |
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using NBitcoin; | ||
|
||
namespace WalletWasabi.Blockchain.Keys; | ||
|
||
public class HdPubKeyCache : IEnumerable<HdPubKey> | ||
public class HdPubKeyCache : IEnumerable<HdPubKeyInfo> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to have at least a few unit tests for this class. There is no HdPubKeyCacheTests
file.
There we could verify the test scenario:
- Add 750 keys
- Add another 750 keys
- Verify that
HdPubKeyCache.Snapshot
for both previous states return the same first 750 keys (HdPubKeyInfo
defines the==
operator so it should be trivial)
This should work because ArraySegment
holds reference to _hdPubKeyInfos
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whatever we modify in the code has real consequences observable from the external world, otherwise why would someone modify code? This means that this should be observable through the KeyManager
. You should be able to request the keys, generate a new key and verify that the enumeration that you received before adding the key doesn't contain it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whatever we modify in the code has real consequences observable from the external world, otherwise why would someone modify code?
Lucas, you are good at arguing almost anything but we write tests1 for good reasons.
So would a test like this one https://github.com/kiminuo/WalletWasabi/tree/simplify-hdpkcache (kiminuo@6271bbf) hurt?
Personally, I would be also interested in
/// <summary>
/// Tests adding the same key twice.
/// </summary>
[Fact]
public void SameKeyTwiceTest()
{
KeyManager keyManager = ServiceFactory.CreateKeyManager(password: "password");
HdPubKey NewKey(string label) => keyManager.GenerateNewKey(label, KeyState.Used, isInternal: true);
HdPubKeyCache cache = new();
HdPubKey key = NewKey($"Key#1");
cache.AddKey(key, ScriptPubKeyType.Segwit);
cache.AddKey(key, ScriptPubKeyType.Segwit);
}
if this should throw an exception or not. I understand that it should not ever happen but in your implementation there is
_hdPubKeyIndexedByScriptPubKey[info.ScriptPubKey] = info.HdPubKey;
which does not throw.
Footnotes
-
Not as much as I would like lately but anyway. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. You are testing exactly as I suggested (testing the KeyManager). So, yes, except for the code added for testing only, which is not necessary.
The SameKeyTwiceTest
is not good because it assumes the cache must fail in case of duplicated keys but that is not a responsibility of the cache. In case the cache receives a duplicated key that means that we have a bug in the KeyManager and we need to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
SameKeyTwiceTest
is not good because it assumes the cache must fail in case of duplicated keys but that is not a responsibility of the cache. In case the cache receives a duplicated key that means that we have a bug in the KeyManager and we need to fix it.
Well, and that's precisely what I'm after. The test would make it clear that we don't expect to get the same key twice. I'm not sure why it's not responsibility of cache to throw an exception in such case because it looks to me that in this scenario the internal state of cache would get broken.
However, I guess you don't watch such test. Anyway, my goal here is basically to document expectations. But we don't document code mostly so the alternative is to write a test but if even test is not possible then ...
Looks like a great improvement to me. |
Co-authored-by: Kimi <58662979+kiminuo@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, and I tested and didn't find problems.
My 2 suggestions are just for cf
Co-authored-by: Turbolay <turbolay@zksnacks.com>
private Dictionary<Script, HdPubKey> HdPubKeysByScript { get; } = new(); | ||
private HashSet<HdPubKey> HdPubKeys { get; } = new(); | ||
private Dictionary<KeyPath, ScriptBytesHdPubKeyPair> ScriptBytesHdPubKeyPairByKeyPath { get; } = new(); | ||
private Dictionary<Script, HdPubKey> _hdPubKeyIndexedByScriptPubKey = new(1_000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific reason to break the code convention of "everything should be a property"?
{ | ||
ExtKey extKey = GetMasterExtKey(password); | ||
var extKeysAndPubs = new List<(ExtKey secret, HdPubKey pubKey)>(); | ||
var extKeysAndPubs = new List<ExtKey>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just extKeys?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete the file.
I loaded an old wallet and I got the following exc.
|
This PR is for simplifying the
HdPubKeyCache
that contains unnecessary complexities that make it slow (the idea behind whatever is named blahblahCache is to make things faster.The PR contains many things, changes and improvements all across the key management code because I think those are changes that we need to do anyway but by sure not all of them in the same PR.
One clear improvement in term of performance is in the
HdPubKeyCache::GetView
(a method that is called millions of times).master (results in microseconds)
PR (result in nanoseconds 1us = 1000 ns)
About the new brain fart involving
ArraySegment
, that's there to avoid changing behavior. I mean, I think it is absolutely unnecessary but it is to avoid thinking and testing.