From 1f7c1a6f217372c65daa47e676d0ab00c3baeba3 Mon Sep 17 00:00:00 2001 From: benaadams Date: Mon, 11 Dec 2023 16:18:11 +0000 Subject: [PATCH 1/6] Use TryGetValue to halve Dictionary lookups --- .../Nethermind.Cli/Modules/CliModuleLoader.cs | 7 +++--- src/Nethermind/Nethermind.Cli/NodeManager.cs | 7 +++--- .../SnapshotManager.cs | 17 +++++++------ .../HintBasedCache.cs | 18 +++++++------- .../Collections/LinkedHashSet.cs | 10 ++++---- .../Tracing/ParityStyle/ParityLikeTxTracer.cs | 24 +++++++++---------- .../Nethermind.Network/P2P/Session.cs | 7 +++--- .../Framework/TestBuilder.cs | 7 +++--- .../PersistentStorageProvider.cs | 8 +++---- .../Proofs/AccountProofCollector.cs | 9 +++---- .../FastBlocks/FastHeadersSyncFeed.cs | 2 +- .../FastSync/TreeSync.cs | 7 +++--- .../Nethermind.Wallet/DevKeyStoreWallet.cs | 8 +++---- src/Nethermind/Nethermind.Wallet/DevWallet.cs | 4 ++-- 14 files changed, 71 insertions(+), 64 deletions(-) diff --git a/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs b/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs index 21ac2e6079e..695854077c0 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs @@ -93,14 +93,15 @@ private void LoadModule(CliModuleBase module) } ObjectInstance instance; - if (!_objects.ContainsKey(objectName)) + if (!_objects.TryGetValue(objectName, out ObjectInstance? value)) { instance = _engine.JintEngine.Object.Construct(Arguments.Empty); _engine.JintEngine.SetValue(objectName, instance); - _objects[objectName] = instance; + value = instance; + _objects[objectName] = value; } - instance = _objects[objectName]; + instance = value; var @delegate = CreateDelegate(methodInfo, module); DelegateWrapper nativeDelegate = new DelegateWrapper(_engine.JintEngine, @delegate); diff --git a/src/Nethermind/Nethermind.Cli/NodeManager.cs b/src/Nethermind/Nethermind.Cli/NodeManager.cs index e326dd637c1..f6b90dbb4d3 100644 --- a/src/Nethermind/Nethermind.Cli/NodeManager.cs +++ b/src/Nethermind/Nethermind.Cli/NodeManager.cs @@ -44,12 +44,13 @@ public NodeManager(ICliEngine cliEngine, IJsonSerializer serializer, ICliConsole public void SwitchUri(Uri uri) { CurrentUri = uri.ToString(); - if (!_clients.ContainsKey(uri)) + if (!_clients.TryGetValue(uri, out IJsonRpcClient? value)) { - _clients[uri] = new BasicJsonRpcClient(uri, _serializer, _logManager); + value = new BasicJsonRpcClient(uri, _serializer, _logManager); + _clients[uri] = value; } - _currentClient = _clients[uri]; + _currentClient = value; } public void SwitchClient(IJsonRpcClient client) diff --git a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs index 5474bc8e533..85723f5e35b 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs @@ -274,8 +274,8 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch // Resolve the authorization key and check against signers Address signer = header.Author; - if (!snapshot.Signers.ContainsKey(signer)) throw new InvalidOperationException("Unauthorized signer"); - if (HasSignedRecently(snapshot, number, signer)) throw new InvalidOperationException($"Recently signed (trying to sign {number} when last signed {snapshot.Signers[signer]} with {snapshot.Signers.Count} signers)"); + if (!snapshot.Signers.TryGetValue(signer, out var value)) throw new InvalidOperationException("Unauthorized signer"); + if (HasSignedRecently(snapshot, number, signer)) throw new InvalidOperationException($"Recently signed (trying to sign {number} when last signed {value} with {snapshot.Signers.Count} signers)"); snapshot.Signers[signer] = number; @@ -353,25 +353,24 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch private bool Cast(Snapshot snapshot, Address address, bool authorize) { - if (!snapshot.Tally.ContainsKey(address)) + if (!snapshot.Tally.TryGetValue(address, out Tally? value)) { - snapshot.Tally[address] = new Tally(authorize); + value = new Tally(authorize); + snapshot.Tally[address] = value; } // Ensure the vote is meaningful if (!IsValidVote(snapshot, address, authorize)) return false; - - // Cast the vote into tally - snapshot.Tally[address].Votes++; + value.Votes++; return true; } private bool Uncast(Snapshot snapshot, Address address, bool authorize) { // If there's no tally, it's a dangling vote, just drop - if (!snapshot.Tally.ContainsKey(address)) return true; + if (!snapshot.Tally.TryGetValue(address, out Tally? value)) return true; - Tally tally = snapshot.Tally[address]; + Tally tally = value; // Ensure we only revert counted votes if (tally.Authorize != authorize) return false; diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs index bf9f0a42f21..b24aadeb45d 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs @@ -55,12 +55,13 @@ public void Hint(Guid guid, long start, long end) throw new InvalidOperationException("Hint too wide"); } - if (!_epochsPerGuid.ContainsKey(guid)) + if (!_epochsPerGuid.TryGetValue(guid, out HashSet? value)) { - _epochsPerGuid[guid] = new HashSet(); + value = new HashSet(); + _epochsPerGuid[guid] = value; } - HashSet epochForGuid = _epochsPerGuid[guid]; + HashSet epochForGuid = value; uint currentMin = uint.MaxValue; uint currentMax = 0; foreach (uint alreadyCachedEpoch in epochForGuid.ToList()) @@ -78,12 +79,12 @@ public void Hint(Guid guid, long start, long end) if (alreadyCachedEpoch < startEpoch || alreadyCachedEpoch > endEpoch) { epochForGuid.Remove(alreadyCachedEpoch); - if (!_epochRefs.ContainsKey(alreadyCachedEpoch)) + if (!_epochRefs.TryGetValue(alreadyCachedEpoch, out var value)) { throw new InvalidAsynchronousStateException("Epoch ref missing"); } - _epochRefs[alreadyCachedEpoch] = _epochRefs[alreadyCachedEpoch] - 1; + _epochRefs[alreadyCachedEpoch] = value - 1; if (_epochRefs[alreadyCachedEpoch] == 0) { // _logger.Warn($"Removing data set for epoch {alreadyCachedEpoch}"); @@ -102,12 +103,13 @@ public void Hint(Guid guid, long start, long end) if (!epochForGuid.Contains(epoch)) { epochForGuid.Add(epoch); - if (!_epochRefs.ContainsKey(epoch)) + if (!_epochRefs.TryGetValue(epoch, out var value)) { - _epochRefs[epoch] = 0; + value = 0; + _epochRefs[epoch] = value; } - _epochRefs[epoch] = _epochRefs[epoch] + 1; + _epochRefs[epoch] = value + 1; if (_epochRefs[epoch] == 1) { // _logger.Warn($"Building data set for epoch {epoch}"); diff --git a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs index a98ef4efd75..69d986c2913 100644 --- a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs +++ b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs @@ -10,7 +10,7 @@ namespace Nethermind.Core.Collections { public class LinkedHashSet : ISet, IReadOnlySet where T : notnull { - private readonly IDictionary> _dict; + private readonly Dictionary> _dict; private readonly LinkedList _list; public LinkedHashSet(int initialCapacity) @@ -71,7 +71,7 @@ public void IntersectWith(IEnumerable? other) T[] ts = new T[Count]; CopyTo(ts, 0); - ISet set = other.ToHashSet(); + HashSet set = other.ToHashSet(); foreach (T t in this.ToArray()) { if (!set.Contains(t)) @@ -106,7 +106,7 @@ public bool IsProperSupersetOf(IEnumerable? other) { if (other is null) throw new ArgumentNullException(nameof(other)); - ISet set = other.ToHashSet(); + HashSet set = other.ToHashSet(); int otherCount = set.Count; if (Count > otherCount) { @@ -134,7 +134,7 @@ public bool IsSubsetOf(IEnumerable? other) { if (other is null) throw new ArgumentNullException(nameof(other)); - ISet set = other.ToHashSet(); + HashSet set = other.ToHashSet(); return this.All(t => set.Contains(t)); } @@ -167,7 +167,7 @@ public void SymmetricExceptWith(IEnumerable other) T[] ts = new T[Count]; CopyTo(ts, 0); - ISet set = other.ToHashSet(); + HashSet set = other.ToHashSet(); for (int index = 0; index < ts.Length; index++) { T t = ts[index]; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs index 89cfb7cafca..c9a90761834 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs @@ -320,13 +320,13 @@ public override void ReportBalanceChange(Address address, UInt256? before, UInt2 throw new InvalidOperationException($"{nameof(ParityLikeTxTracer)} did not expect state change report."); } - if (!_trace.StateChanges.ContainsKey(address)) + if (!_trace.StateChanges.TryGetValue(address, out ParityAccountStateChange? value)) { _trace.StateChanges[address] = new ParityAccountStateChange(); } else { - before = _trace.StateChanges[address].Balance?.Before ?? before; + before = value.Balance?.Before ?? before; } _trace.StateChanges[address].Balance = new ParityStateChange(before, after); @@ -339,13 +339,13 @@ public override void ReportCodeChange(Address address, byte[] before, byte[] aft throw new InvalidOperationException($"{nameof(ParityLikeTxTracer)} did not expect state change report."); } - if (!_trace.StateChanges.ContainsKey(address)) + if (!_trace.StateChanges.TryGetValue(address, out ParityAccountStateChange? value)) { _trace.StateChanges[address] = new ParityAccountStateChange(); } else { - before = _trace.StateChanges[address].Code?.Before ?? before; + before = value.Code?.Before ?? before; } _trace.StateChanges[address].Code = new ParityStateChange(before, after); @@ -353,13 +353,13 @@ public override void ReportCodeChange(Address address, byte[] before, byte[] aft public override void ReportNonceChange(Address address, UInt256? before, UInt256? after) { - if (!_trace.StateChanges!.ContainsKey(address)) + if (!_trace.StateChanges!.TryGetValue(address, out ParityAccountStateChange? value)) { _trace.StateChanges[address] = new ParityAccountStateChange(); } else { - before = _trace.StateChanges[address].Nonce?.Before ?? before; + before = value.Nonce?.Before ?? before; } _trace.StateChanges[address].Nonce = new ParityStateChange(before, after); @@ -367,17 +367,17 @@ public override void ReportNonceChange(Address address, UInt256? before, UInt256 public override void ReportStorageChange(in StorageCell storageCell, byte[] before, byte[] after) { - if (!_trace.StateChanges!.ContainsKey(storageCell.Address)) + if (!_trace.StateChanges!.TryGetValue(storageCell.Address, out ParityAccountStateChange? value)) { - _trace.StateChanges[storageCell.Address] = new ParityAccountStateChange(); + value = new ParityAccountStateChange(); + _trace.StateChanges[storageCell.Address] = value; } - Dictionary> storage = - _trace.StateChanges[storageCell.Address].Storage ?? (_trace.StateChanges[storageCell.Address].Storage = new Dictionary>()); + Dictionary> storage = value.Storage ?? (value.Storage = new Dictionary>()); - if (storage.TryGetValue(storageCell.Index, out ParityStateChange value)) + if (storage.TryGetValue(storageCell.Index, out ParityStateChange change)) { - before = value.Before ?? before; + before = change.Before ?? before; } storage[storageCell.Index] = new ParityStateChange(before, after); diff --git a/src/Nethermind/Nethermind.Network/P2P/Session.cs b/src/Nethermind/Nethermind.Network/P2P/Session.cs index 8b1bbda7e85..742976f4432 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Session.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Session.cs @@ -572,12 +572,13 @@ public void AddProtocolHandler(IProtocolHandler handler) private AdaptiveCodeResolver GetOrCreateResolver() { string key = string.Join(":", _protocols.Select(p => p.Key).OrderBy(x => x).ToArray()); - if (!_resolvers.ContainsKey(key)) + if (!_resolvers.TryGetValue(key, out AdaptiveCodeResolver? value)) { - _resolvers[key] = new AdaptiveCodeResolver(_protocols); + value = new AdaptiveCodeResolver(_protocols); + _resolvers[key] = value; } - return _resolvers[key]; + return value; } public override string ToString() diff --git a/src/Nethermind/Nethermind.Overseer.Test/Framework/TestBuilder.cs b/src/Nethermind/Nethermind.Overseer.Test/Framework/TestBuilder.cs index 4b1d09f411d..b8944ba3bfb 100644 --- a/src/Nethermind/Nethermind.Overseer.Test/Framework/TestBuilder.cs +++ b/src/Nethermind/Nethermind.Overseer.Test/Framework/TestBuilder.cs @@ -209,7 +209,7 @@ public TestBuilder StartNode(string name, string baseConfigFile, string key = nu private NethermindProcessWrapper GetOrCreateNode(string name, string baseConfigFile, string key) { - if (!Nodes.ContainsKey(name)) + if (!Nodes.TryGetValue(name, out NethermindProcessWrapper value)) { string bootnodes = string.Empty; foreach ((_, NethermindProcessWrapper process) in Nodes) @@ -227,11 +227,12 @@ private NethermindProcessWrapper GetOrCreateNode(string name, string baseConfigF int p2pPort = _startPort + _nodeCounter; int httpPort = _startHttpPort + _nodeCounter; TestContext.WriteLine($"Creating {name} at {p2pPort}, http://localhost:{httpPort}"); - Nodes[name] = _processBuilder.Create(name, _runnerDir, configPath, dbDir, httpPort, p2pPort, nodeKey, bootnodes); + value = _processBuilder.Create(name, _runnerDir, configPath, dbDir, httpPort, p2pPort, nodeKey, bootnodes); + Nodes[name] = value; _nodeCounter++; } - return Nodes[name]; + return value; } private string GetNodeKey(string key) diff --git a/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs b/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs index 267213abb09..f377336022f 100644 --- a/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs +++ b/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs @@ -70,7 +70,7 @@ protected override byte[] GetCurrentValue(in StorageCell storageCell) => /// public byte[] GetOriginal(in StorageCell storageCell) { - if (!_originalValues.ContainsKey(storageCell)) + if (!_originalValues.TryGetValue(storageCell, out var value)) { throw new InvalidOperationException("Get original should only be called after get within the same caching round"); } @@ -86,7 +86,7 @@ public byte[] GetOriginal(in StorageCell storageCell) } } - return _originalValues[storageCell]; + return value; } @@ -224,13 +224,13 @@ public void CommitTrees(long blockNumber) private StorageTree GetOrCreateStorage(Address address) { - if (!_storages.ContainsKey(address)) + if (!_storages.TryGetValue(address, out StorageTree? value)) { StorageTree storageTree = _storageTreeFactory.Create(address, _trieStore, _stateProvider.GetStorageRoot(address), StateRoot, _logManager); return _storages[address] = storageTree; } - return _storages[address]; + return value; } private byte[] LoadFromTree(in StorageCell storageCell) diff --git a/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs b/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs index d1e58694845..3592c5f6681 100644 --- a/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs +++ b/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs @@ -181,18 +181,19 @@ public void VisitBranch(TrieNode node, TrieVisitContext trieVisitContext) } else { - if (!_storageNodeInfos.ContainsKey(childHash)) + if (!_storageNodeInfos.TryGetValue(childHash, out StorageNodeInfo? value)) { - _storageNodeInfos[childHash] = new StorageNodeInfo(); + value = new StorageNodeInfo(); + _storageNodeInfos[childHash] = value; } if (!bumpedIndexes.Contains((byte)childIndex)) { bumpedIndexes.Add((byte)childIndex); - _storageNodeInfos[childHash].PathIndex = _pathTraversalIndex + 1; + value.PathIndex = _pathTraversalIndex + 1; } - _storageNodeInfos[childHash].StorageIndices.Add(storageIndex); + value.StorageIndices.Add(storageIndex); _nodeToVisitFilter.Add(childHash); } } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs index e8452578744..d4444db6aa8 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs @@ -25,7 +25,7 @@ namespace Nethermind.Synchronization.FastBlocks { public class HeadersSyncFeed : ActivatedSyncFeed { - private readonly IDictionary> _historicalOverrides = new Dictionary>() + private readonly Dictionary> _historicalOverrides = new Dictionary>() { // Kovan has some wrong difficulty in early blocks before using proper AuRa difficulty calculation // In order to support that we need to support another pivot diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs index 7fa40f87319..66950e82b67 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs @@ -973,12 +973,13 @@ private void AddDependency(Hash256 dependency, DependentItem dependentItem) { lock (_dependencies) { - if (!_dependencies.ContainsKey(dependency)) + if (!_dependencies.TryGetValue(dependency, out HashSet? value)) { - _dependencies[dependency] = new HashSet(DependentItemComparer.Instance); + value = new HashSet(DependentItemComparer.Instance); + _dependencies[dependency] = value; } - _dependencies[dependency].Add(dependentItem); + value.Add(dependentItem); } } diff --git a/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs b/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs index 6c6af5f1cf7..d332841cdc4 100644 --- a/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs +++ b/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs @@ -89,9 +89,9 @@ public bool LockAccount(Address address) public Signature Sign(Hash256 message, Address address, SecureString passphrase) { PrivateKey key; - if (_unlockedAccounts.ContainsKey(address)) + if (_unlockedAccounts.TryGetValue(address, out PrivateKey value)) { - key = _unlockedAccounts[address]; + key = value; } else { @@ -107,9 +107,9 @@ public Signature Sign(Hash256 message, Address address, SecureString passphrase) public Signature Sign(Hash256 message, Address address) { PrivateKey key; - if (_unlockedAccounts.ContainsKey(address)) + if (_unlockedAccounts.TryGetValue(address, out PrivateKey value)) { - key = _unlockedAccounts[address]; + key = value; } else { diff --git a/src/Nethermind/Nethermind.Wallet/DevWallet.cs b/src/Nethermind/Nethermind.Wallet/DevWallet.cs index 64e99519384..eef0c467c71 100644 --- a/src/Nethermind/Nethermind.Wallet/DevWallet.cs +++ b/src/Nethermind/Nethermind.Wallet/DevWallet.cs @@ -101,9 +101,9 @@ public bool LockAccount(Address address) } public Signature Sign(Hash256 message, Address address, SecureString passphrase) { - if (!_isUnlocked.ContainsKey(address)) throw new SecurityException("Account does not exist."); + if (!_isUnlocked.TryGetValue(address, out var value)) throw new SecurityException("Account does not exist."); - if (!_isUnlocked[address] && !CheckPassword(address, passphrase)) throw new SecurityException("Cannot sign without password or unlocked account."); + if (_isUnlocked[address] = !value && !CheckPassword(address, passphrase)) throw new SecurityException("Cannot sign without password or unlocked account."); return Sign(message, address); } From 8367e66b273a05d755da24e0463b089c9cae8e59 Mon Sep 17 00:00:00 2001 From: benaadams Date: Mon, 11 Dec 2023 16:29:41 +0000 Subject: [PATCH 2/6] fixes --- .../Nethermind.Consensus.Ethash/HintBasedCache.cs | 15 +++++++-------- .../Nethermind.Core/Collections/LinkedHashSet.cs | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs index b24aadeb45d..f9c117fcecf 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs @@ -79,12 +79,12 @@ public void Hint(Guid guid, long start, long end) if (alreadyCachedEpoch < startEpoch || alreadyCachedEpoch > endEpoch) { epochForGuid.Remove(alreadyCachedEpoch); - if (!_epochRefs.TryGetValue(alreadyCachedEpoch, out var value)) + if (!_epochRefs.TryGetValue(alreadyCachedEpoch, out var epochValue)) { throw new InvalidAsynchronousStateException("Epoch ref missing"); } - _epochRefs[alreadyCachedEpoch] = value - 1; + _epochRefs[alreadyCachedEpoch] = epochValue - 1; if (_epochRefs[alreadyCachedEpoch] == 0) { // _logger.Warn($"Removing data set for epoch {alreadyCachedEpoch}"); @@ -100,16 +100,15 @@ public void Hint(Guid guid, long start, long end) for (long i = startEpoch; i <= endEpoch; i++) { uint epoch = (uint)i; - if (!epochForGuid.Contains(epoch)) + if (epochForGuid.Add(epoch)) { - epochForGuid.Add(epoch); - if (!_epochRefs.TryGetValue(epoch, out var value)) + if (!_epochRefs.TryGetValue(epoch, out var epochValue)) { - value = 0; - _epochRefs[epoch] = value; + epochValue = 0; + _epochRefs[epoch] = epochValue; } - _epochRefs[epoch] = value + 1; + _epochRefs[epoch] = epochValue + 1; if (_epochRefs[epoch] == 1) { // _logger.Warn($"Building data set for epoch {epoch}"); diff --git a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs index 69d986c2913..698c46662fd 100644 --- a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs +++ b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs @@ -201,7 +201,7 @@ public void UnionWith(IEnumerable? other) public int Count => _dict.Count; - public bool IsReadOnly => _dict.IsReadOnly; + public bool IsReadOnly => false; void ICollection.Add(T item) { From 426b6666327abf1bcc798fb0f02bc67ec6d3a615 Mon Sep 17 00:00:00 2001 From: benaadams Date: Thu, 14 Dec 2023 11:42:18 +0000 Subject: [PATCH 3/6] Use CollectionsMarshal.GetValueRefOrAddDefault when appropriate --- .../Nethermind.Cli/Modules/CliModuleLoader.cs | 14 +++++----- src/Nethermind/Nethermind.Cli/NodeManager.cs | 5 ++-- .../SnapshotManager.cs | 5 ++-- .../HintBasedCache.cs | 5 ++-- .../Resettables/ResettableDictionary.cs | 6 +++++ .../Tracing/ParityStyle/ParityLikeTxTracer.cs | 27 ++++++++++--------- .../PersistentStorageProvider.cs | 7 ++--- .../Proofs/AccountProofCollector.cs | 6 ++--- .../FastSync/TreeSync.cs | 6 ++--- 9 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs b/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs index 695854077c0..84ef090fc70 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/CliModuleLoader.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Runtime.InteropServices; using System.Runtime.Loader; using Jint.Native; using Jint.Native.Object; @@ -92,17 +93,14 @@ private void LoadModule(CliModuleBase module) throw new InvalidDataException($"Method {methodInfo.Name} of {module.GetType().Name} should be decorated with one of {nameof(CliPropertyAttribute)} or {nameof(CliFunctionAttribute)}"); } - ObjectInstance instance; - if (!_objects.TryGetValue(objectName, out ObjectInstance? value)) + ref ObjectInstance? instance = ref CollectionsMarshal.GetValueRefOrAddDefault(_objects, objectName, out bool exists); + if (!exists) { instance = _engine.JintEngine.Object.Construct(Arguments.Empty); _engine.JintEngine.SetValue(objectName, instance); - value = instance; - _objects[objectName] = value; } - instance = value; - var @delegate = CreateDelegate(methodInfo, module); + Delegate @delegate = CreateDelegate(methodInfo, module); DelegateWrapper nativeDelegate = new DelegateWrapper(_engine.JintEngine, @delegate); if (itemName is not null) @@ -113,7 +111,7 @@ private void LoadModule(CliModuleBase module) _cliConsole.WriteLine($".{itemName}"); MethodsByModules[objectName].Add(itemName); - AddProperty(instance, itemName, nativeDelegate); + AddProperty(instance!, itemName, nativeDelegate); } else { @@ -121,7 +119,7 @@ private void LoadModule(CliModuleBase module) _cliConsole.WriteLine($".{itemName}({string.Join(", ", methodInfo.GetParameters().Select(p => p.Name))})"); MethodsByModules[objectName].Add(itemName + "("); - AddMethod(instance, itemName, nativeDelegate); + AddMethod(instance!, itemName, nativeDelegate); } } } diff --git a/src/Nethermind/Nethermind.Cli/NodeManager.cs b/src/Nethermind/Nethermind.Cli/NodeManager.cs index f6b90dbb4d3..c392a499e59 100644 --- a/src/Nethermind/Nethermind.Cli/NodeManager.cs +++ b/src/Nethermind/Nethermind.Cli/NodeManager.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Jint.Native; using Jint.Native.Json; @@ -44,10 +45,10 @@ public NodeManager(ICliEngine cliEngine, IJsonSerializer serializer, ICliConsole public void SwitchUri(Uri uri) { CurrentUri = uri.ToString(); - if (!_clients.TryGetValue(uri, out IJsonRpcClient? value)) + ref IJsonRpcClient? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_clients, uri, out bool exists); + if (!exists) { value = new BasicJsonRpcClient(uri, _serializer, _logManager); - _clients[uri] = value; } _currentClient = value; diff --git a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs index 85723f5e35b..2bf4541730e 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using Nethermind.Blockchain; using Nethermind.Core; @@ -353,10 +354,10 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch private bool Cast(Snapshot snapshot, Address address, bool authorize) { - if (!snapshot.Tally.TryGetValue(address, out Tally? value)) + ref Tally? value = ref CollectionsMarshal.GetValueRefOrAddDefault(snapshot.Tally, address, out bool exists); + if (!exists) { value = new Tally(authorize); - snapshot.Tally[address] = value; } // Ensure the vote is meaningful diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs index f9c117fcecf..4b0b1d3fa42 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Nethermind.Logging; @@ -55,10 +56,10 @@ public void Hint(Guid guid, long start, long end) throw new InvalidOperationException("Hint too wide"); } - if (!_epochsPerGuid.TryGetValue(guid, out HashSet? value)) + ref HashSet? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_epochsPerGuid, guid, out bool exists); + if (!exists) { value = new HashSet(); - _epochsPerGuid[guid] = value; } HashSet epochForGuid = value; diff --git a/src/Nethermind/Nethermind.Core/Resettables/ResettableDictionary.cs b/src/Nethermind/Nethermind.Core/Resettables/ResettableDictionary.cs index de3ad686817..7dd63feef16 100644 --- a/src/Nethermind/Nethermind.Core/Resettables/ResettableDictionary.cs +++ b/src/Nethermind/Nethermind.Core/Resettables/ResettableDictionary.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace Nethermind.Core.Resettables { @@ -96,6 +97,11 @@ public bool TryGetValue(TKey key, out TValue value) #pragma warning restore 8601 } + public ref TValue? GetValueRefOrAddDefault(TKey key, out bool exists) + { + return ref CollectionsMarshal.GetValueRefOrAddDefault(_wrapped, key, out exists); + } + public TValue this[TKey key] { get => _wrapped[key]; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs index c9a90761834..a7fbe99043f 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -320,16 +321,17 @@ public override void ReportBalanceChange(Address address, UInt256? before, UInt2 throw new InvalidOperationException($"{nameof(ParityLikeTxTracer)} did not expect state change report."); } - if (!_trace.StateChanges.TryGetValue(address, out ParityAccountStateChange? value)) + ref ParityAccountStateChange? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_trace.StateChanges, address, out bool exists); + if (!exists) { - _trace.StateChanges[address] = new ParityAccountStateChange(); + value = new ParityAccountStateChange(); } else { before = value.Balance?.Before ?? before; } - _trace.StateChanges[address].Balance = new ParityStateChange(before, after); + value.Balance = new ParityStateChange(before, after); } public override void ReportCodeChange(Address address, byte[] before, byte[] after) @@ -353,34 +355,35 @@ public override void ReportCodeChange(Address address, byte[] before, byte[] aft public override void ReportNonceChange(Address address, UInt256? before, UInt256? after) { - if (!_trace.StateChanges!.TryGetValue(address, out ParityAccountStateChange? value)) + ref ParityAccountStateChange? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_trace.StateChanges, address, out bool exists); + if (!exists) { - _trace.StateChanges[address] = new ParityAccountStateChange(); + value = new ParityAccountStateChange(); } else { before = value.Nonce?.Before ?? before; } - _trace.StateChanges[address].Nonce = new ParityStateChange(before, after); + value.Nonce = new ParityStateChange(before, after); } public override void ReportStorageChange(in StorageCell storageCell, byte[] before, byte[] after) { - if (!_trace.StateChanges!.TryGetValue(storageCell.Address, out ParityAccountStateChange? value)) + ref ParityAccountStateChange? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_trace.StateChanges, storageCell.Address, out bool exists); + if (!exists) { value = new ParityAccountStateChange(); - _trace.StateChanges[storageCell.Address] = value; } - Dictionary> storage = value.Storage ?? (value.Storage = new Dictionary>()); - - if (storage.TryGetValue(storageCell.Index, out ParityStateChange change)) + Dictionary> storage = value.Storage ??= []; + ref ParityStateChange? change = ref CollectionsMarshal.GetValueRefOrAddDefault(storage, storageCell.Index, out exists); + if (exists) { before = change.Before ?? before; } - storage[storageCell.Index] = new ParityStateChange(before, after); + change = new ParityStateChange(before, after); } public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) diff --git a/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs b/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs index f377336022f..723bdbf105f 100644 --- a/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs +++ b/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs @@ -224,10 +224,11 @@ public void CommitTrees(long blockNumber) private StorageTree GetOrCreateStorage(Address address) { - if (!_storages.TryGetValue(address, out StorageTree? value)) + ref StorageTree? value = ref _storages.GetValueRefOrAddDefault(address, out bool exists); + if (!exists) { - StorageTree storageTree = _storageTreeFactory.Create(address, _trieStore, _stateProvider.GetStorageRoot(address), StateRoot, _logManager); - return _storages[address] = storageTree; + value = _storageTreeFactory.Create(address, _trieStore, _stateProvider.GetStorageRoot(address), StateRoot, _logManager); + return value; } return value; diff --git a/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs b/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs index 3592c5f6681..8544b2629ac 100644 --- a/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs +++ b/src/Nethermind/Nethermind.State/Proofs/AccountProofCollector.cs @@ -4,8 +4,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using Nethermind.Core; -using Nethermind.Core.Buffers; using Nethermind.Core.Crypto; using Nethermind.Int256; using Nethermind.Serialization.Rlp; @@ -181,10 +181,10 @@ public void VisitBranch(TrieNode node, TrieVisitContext trieVisitContext) } else { - if (!_storageNodeInfos.TryGetValue(childHash, out StorageNodeInfo? value)) + ref StorageNodeInfo? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_storageNodeInfos, childHash, out bool exists); + if (!exists) { value = new StorageNodeInfo(); - _storageNodeInfos[childHash] = value; } if (!bumpedIndexes.Contains((byte)childIndex)) diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs index 66950e82b67..5a324211bda 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs @@ -6,11 +6,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Nethermind.Blockchain; using Nethermind.Core; -using Nethermind.Core.Buffers; using Nethermind.Core.Caching; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -973,10 +973,10 @@ private void AddDependency(Hash256 dependency, DependentItem dependentItem) { lock (_dependencies) { - if (!_dependencies.TryGetValue(dependency, out HashSet? value)) + ref HashSet? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_dependencies, dependency, out bool exists); + if (!exists) { value = new HashSet(DependentItemComparer.Instance); - _dependencies[dependency] = value; } value.Add(dependentItem); From 82ebd19a4275b69f1651dcc5347426fb40060f2b Mon Sep 17 00:00:00 2001 From: benaadams Date: Thu, 14 Dec 2023 11:47:22 +0000 Subject: [PATCH 4/6] Re add comment --- src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs index 2bf4541730e..04169f90e0f 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs @@ -362,6 +362,8 @@ private bool Cast(Snapshot snapshot, Address address, bool authorize) // Ensure the vote is meaningful if (!IsValidVote(snapshot, address, authorize)) return false; + + // Cast the vote into tally ref value.Votes++; return true; } From ffc5768b1cba7c4315491aaf6e6cf9f9aa7dbc4c Mon Sep 17 00:00:00 2001 From: benaadams Date: Thu, 14 Dec 2023 11:52:16 +0000 Subject: [PATCH 5/6] Missed one --- .../Tracing/ParityStyle/ParityLikeTxTracer.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs index a7fbe99043f..08fde62852a 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs @@ -341,16 +341,17 @@ public override void ReportCodeChange(Address address, byte[] before, byte[] aft throw new InvalidOperationException($"{nameof(ParityLikeTxTracer)} did not expect state change report."); } - if (!_trace.StateChanges.TryGetValue(address, out ParityAccountStateChange? value)) + ref ParityAccountStateChange? value = ref CollectionsMarshal.GetValueRefOrAddDefault(_trace.StateChanges, address, out bool exists); + if (!exists) { - _trace.StateChanges[address] = new ParityAccountStateChange(); + value = new ParityAccountStateChange(); } else { before = value.Code?.Before ?? before; } - _trace.StateChanges[address].Code = new ParityStateChange(before, after); + value.Code = new ParityStateChange(before, after); } public override void ReportNonceChange(Address address, UInt256? before, UInt256? after) From b37f701be99224528c12a49e2cb9dbfc92c03739 Mon Sep 17 00:00:00 2001 From: benaadams Date: Thu, 14 Dec 2023 12:04:53 +0000 Subject: [PATCH 6/6] Fix weird check --- src/Nethermind/Nethermind.Wallet/DevWallet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Wallet/DevWallet.cs b/src/Nethermind/Nethermind.Wallet/DevWallet.cs index eef0c467c71..7b3a1da6062 100644 --- a/src/Nethermind/Nethermind.Wallet/DevWallet.cs +++ b/src/Nethermind/Nethermind.Wallet/DevWallet.cs @@ -103,7 +103,7 @@ public Signature Sign(Hash256 message, Address address, SecureString passphrase) { if (!_isUnlocked.TryGetValue(address, out var value)) throw new SecurityException("Account does not exist."); - if (_isUnlocked[address] = !value && !CheckPassword(address, passphrase)) throw new SecurityException("Cannot sign without password or unlocked account."); + if (!value && !CheckPassword(address, passphrase)) throw new SecurityException("Cannot sign without password or unlocked account."); return Sign(message, address); }