[release-v2.1] main: Use backported mixing updates.#3659
Merged
davecgh merged 20 commits intodecred:release-v2.1from Apr 6, 2026
Merged
[release-v2.1] main: Use backported mixing updates.#3659davecgh merged 20 commits intodecred:release-v2.1from
davecgh merged 20 commits intodecred:release-v2.1from
Conversation
x25519 was the ECDH used in the older client-server mixing implementation, but this was replaced with secp256k1 ECDH in the peer-to-peer implementation. Remove a lingering reference to x25519 that didn't get updated.
This adds benchmarks for signing and validating utxo proofs.
Sum(nil) creates an unnecessary heap allocation appending the digest to the nil slice. Replace these calls with direct calls to the (*blake256.Hasher256).Sum256 method to avoid unnecessary allocations and copies. While here, use the hasher's specialized Write* methods in the utxoproof package to improve readability.
Creating the hash to verify the schnorr signature can be done without causing any allocations. This has also been moved out into a new schnorrHash helper function to reuse across both signing and verification.
This modifies the debug log for evicted mempool orphans to explicitly call out that it is referring to mempool orphans to avoid any potential confusion between orphans of other types that exist (for example mixpool orphans).
This renames the internal rpcserver SubmitMixMessage interface method to AcceptMixMessage to more accurately reflect what it actually does and updates the comments accordingly. The comments also previously incorrectly claimed that the method submits the message to the network after it processes it, but that is handled by RelayMixMessages instead.
This makes use of the slices.Contains method to determine when a key exchange orphan references a pair request that has been added during orphan reconsideration.
This renames the type used for orphan messages to orphanMsg to avoid shadowing the name with variables. The name "orphan" is better for variables.
The current behavior when adding orphans is slightly different for KEs and other types of mixing messages. Specifically, orphan KEs overwrite any existing entries while other types do not. The preferred behavior is to keep existing orphans so that the timestamps reflect the time they were first added, and, in the future, any other data associated with the orphan also reflects when it was first seen. Instead of just adding an additional check for KEs to remedy the aforementioned, this consolidates the logic for adding mixpool orphans by introducing a new function named addOrphan and updates the places that add orphans to use it. The new function will only add orphans when they are not already in the pool. This approach simplifies future modifications to the logic related to adding orphans, ensures the same logic is consistently applied regardless of the path leading up to the addition of an orphan, and is more consistent with the how the long standing and battle tested existing code in the mempool handles adding orphans.
This consolidates the logic for removing mixpool orphans by introducing a new function named removeOrphan and updates the places that remove orphans to use it. This approach simplifies future modifications to the logic related to removing orphans, ensures the same logic is consistently applied regardless of the path leading up to the removal of an orphan, and is more consistent with the how the long standing and battle tested existing code in the mempool handles removing orphans. It is perhaps worth noting that there is a very slight tradeoff in terms of a few extra map length checks and removals that the existing code was able to avoid in some circumstances due to having specialized knowledge, but the difference is entirely negligible and does not warrant the downsides to splitting the removal logic all over the code.
This modifies the map that tracks orphans by their associated identity to point to the entire orphan struct instead of only the mixing message associated with it. This will allow any additional data associated with the orphan message to be immediately available without needing another orphans map lookup.
This allows a caller-provided source to be associated with mix messages. This is useful for things such as keeping track of which peers messages were first seen from and grouping messages on per-peer source. This currently only keeps track of the source with orphans to pave the way for some upcoming changes related to orphans. It might also be useful in the future to store it with messages in the main pool too, but that is not done for now since there are no immediate plans to make use of it.
In addition to the existing logic which evicts orphans once an epoch has expired and when the peer that sent the orphans disconnects, this implements proactive eviction of mixing message orphans once the orphan pool grows to a maximum limit. The eviction algorithm works as follows: - Determine the source peer that sent the most remaining active orphans - Remove as many orphans sent by that peer as possible until the orphan pool size reaches 75% of the maximum allowed amount - Repeat the previous two steps as many times as necessary to reach the target pruned orphan pool size In short, it prioritizes removing the orphans sent by the peer that sent the most. This approach was chosen because it is fairly efficient and, in practice, orphan messages are quite rare after initial startup when ongoing mixing sessions are discovered, so any peer sending a lot of orphans is likely experiencing severe connectivity issues or otherwise misbehaving. It also has the added benefit of handling a variety of orphan flooding misbehavior well. A comprehensive set of tests is included to ensure the behavior works as expected.
This avoids reusing the same initial seed for multiple tests when testing with -count greater than 1. The -seed flag now requires providing the initial nonce in the string, so that the failing test can be reproduced with -count=1. If a test fails, the flag to reproduce is logged at the end of the output.
The cleanup function returned by useTestLogger must disable writes to the backend to prevent client goroutines still running after the test finishes from writing to the old *testing.T logger and panicking.
Tests run on an increased schedule by artifically ticking the epoch. This would occasionally result in a disruption tests hanging due to the two clients involved being ticked at roughly the same time but continuing with a different Unix epoch. There was a roughly 50% chance that when this happened, the test would hang, depending on which of the two clients contained the misbehaving peer. Test reliability has been improved by passing same time.Time value with the intended epoch to the testTickC channel by the test function. Client code also signals to the tests when it is waiting for a test epoch, allowing the test to wait for all clients before proceeding with the current time as the epoch.
This commit places stricter limits on message sizes without changes to wire protocol. These reduced limits help avoid memory exhaustion when mixing messages must be saved to the orphan pool.
PRs which duplicated inputs would allow for low cost entry to the mixpool and could be used to consume excessive memory resources.
This updates the 2.1 release branch to use the latest version of the mixing module which includes various optimizations, orphan source tracking, proactive orphan eviction, tighter standardness limits on mixing message sizes, and stricter rejection of malformed mixing pair requests. In particular, the following updated module version is used: - github.com/decred/dcrd/mixing@v0.7.0
jrick
approved these changes
Apr 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This updates the 2.1 release branch to use the latest version of the
mixingmodule which includes various optimizations, orphan source tracking, proactive orphan eviction, tighter standardness limits on mixing message sizes, and stricter rejection of malformed mixing pair requests.In particular, the following updated module version is used:
Note that it also cherry picks all of the commits included in updates to the
mixingmodule to ensure they are also included in the release branch even though it is not strictly necessary sincego.modhas been updated to require the new release and thus will pull in the new code. However, from past experience, not having code backported to modules available in the release branch too leads to headaches for devs building from source in their local workspace with overrides such as those ingo.work.The following PRs are included: