Monero: fix decoy selection algo and add test for latest spendable (#384)

* Monero: fix decoy selection algo and add test for latest spendable

- DSA only selected coinbase outputs and didn't match the wallet2
implementation
- Added test to make sure DSA will select a decoy output from the
most recent unlocked block
- Made usage of "height" in DSA consistent with other usage of
"height" in Monero code (height == num blocks in chain)
- Rely on monerod RPC response for output's unlocked status

* xmr runner tests mine until outputs are unlocked

* fingerprintable canoncial select decoys

* Separate fingerprintable canonical function

Makes it simpler for callers who are unconcered with consistent
canonical output selection across multiple clients to rely on
the simpler Decoy::select and not worry about fingerprintable
canonical

* fix merge conflicts

* Put back TODO for issue #104

* Fix incorrect check on distribution len

The RingCT distribution on mainnet doesn't start until well after
genesis, so the distribution length is expected to be < height.

To be clear, this was my mistake from this series of changes
to the DSA. I noticed this mistake because the DSA would error
when running on mainnet.
This commit is contained in:
Justin Berman
2024-02-19 18:34:10 -08:00
committed by GitHub
parent 4f1f7984a6
commit 92d8b91be9
10 changed files with 444 additions and 188 deletions

View File

@@ -338,7 +338,7 @@ impl Monero {
// All signers need to select the same decoys
// All signers use the same height and a seeded RNG to make sure they do so.
let decoys = Decoys::select(
let decoys = Decoys::fingerprintable_canonical_select(
&mut ChaCha20Rng::from_seed(transcript.rng_seed(b"decoys")),
&self.rpc,
protocol.ring_len(),
@@ -742,11 +742,11 @@ impl Network for Monero {
let protocol = self.rpc.get_protocol().await.unwrap();
let decoys = Decoys::select(
let decoys = Decoys::fingerprintable_canonical_select(
&mut OsRng,
&self.rpc,
protocol.ring_len(),
self.rpc.get_height().await.unwrap() - 1,
self.rpc.get_height().await.unwrap(),
&outputs,
)
.await