Re-export curve25519_dalek::RistrettoPoint for dalek_ff_group::RistrettoPoint

Sacrifices a `Hash` implementation (inefficient and already shouldn't be used)
we appear to have only used in two files (which have been patched).
This commit is contained in:
Luke Parker
2025-09-05 17:31:09 -04:00
parent 2216ade8c4
commit ea275df26c
3 changed files with 18 additions and 31 deletions

View File

@@ -21,7 +21,7 @@ pub(crate) struct Blockchain<D: Db, T: TransactionTrait> {
block_number: u64, block_number: u64,
tip: [u8; 32], tip: [u8; 32],
participants: HashSet<<Ristretto as WrappedGroup>::G>, participants: HashSet<[u8; 32]>,
provided: ProvidedTransactions<D, T>, provided: ProvidedTransactions<D, T>,
mempool: Mempool<D, T>, mempool: Mempool<D, T>,
@@ -74,7 +74,10 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
let mut res = Self { let mut res = Self {
db: Some(db.clone()), db: Some(db.clone()),
genesis, genesis,
participants: participants.iter().copied().collect(), participants: participants
.iter()
.map(<<Ristretto as WrappedGroup>::G as GroupEncoding>::to_bytes)
.collect(),
block_number: 0, block_number: 0,
tip: genesis, tip: genesis,
@@ -173,7 +176,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
self.mempool.add::<N, _>( self.mempool.add::<N, _>(
|signer, order| { |signer, order| {
if self.participants.contains(&signer) { if self.participants.contains(&signer.to_bytes()) {
Some( Some(
db.get(Self::next_nonce_key(&self.genesis, &signer, &order)) db.get(Self::next_nonce_key(&self.genesis, &signer, &order))
.map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap())), .map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap())),
@@ -202,7 +205,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
if let Some(next_nonce) = self.mempool.next_nonce_in_mempool(signer, order.to_vec()) { if let Some(next_nonce) = self.mempool.next_nonce_in_mempool(signer, order.to_vec()) {
return Some(next_nonce); return Some(next_nonce);
} }
if self.participants.contains(signer) { if self.participants.contains(&signer.to_bytes()) {
Some( Some(
self self
.db .db
@@ -251,7 +254,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
self.tip, self.tip,
self.provided.transactions.clone(), self.provided.transactions.clone(),
&mut |signer, order| { &mut |signer, order| {
if self.participants.contains(signer) { if self.participants.contains(&signer.to_bytes()) {
let key = Self::next_nonce_key(&self.genesis, signer, order); let key = Self::next_nonce_key(&self.genesis, signer, order);
let next = txn let next = txn
.get(&key) .get(&key)

View File

@@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use dalek_ff_group::Ristretto; use dalek_ff_group::Ristretto;
use ciphersuite::*; use ciphersuite::{group::GroupEncoding, *};
use serai_db::{DbTxn, Db}; use serai_db::{DbTxn, Db};
@@ -21,9 +21,9 @@ pub(crate) struct Mempool<D: Db, T: TransactionTrait> {
db: D, db: D,
genesis: [u8; 32], genesis: [u8; 32],
last_nonce_in_mempool: HashMap<(<Ristretto as WrappedGroup>::G, Vec<u8>), u32>, last_nonce_in_mempool: HashMap<([u8; 32], Vec<u8>), u32>,
txs: HashMap<[u8; 32], Transaction<T>>, txs: HashMap<[u8; 32], Transaction<T>>,
txs_per_signer: HashMap<<Ristretto as WrappedGroup>::G, u32>, txs_per_signer: HashMap<[u8; 32], u32>,
} }
impl<D: Db, T: TransactionTrait> Mempool<D, T> { impl<D: Db, T: TransactionTrait> Mempool<D, T> {
@@ -82,6 +82,7 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
} }
Transaction::Application(tx) => match tx.kind() { Transaction::Application(tx) => match tx.kind() {
TransactionKind::Signed(order, Signed { signer, nonce, .. }) => { TransactionKind::Signed(order, Signed { signer, nonce, .. }) => {
let signer = signer.to_bytes();
let amount = *res.txs_per_signer.get(&signer).unwrap_or(&0) + 1; let amount = *res.txs_per_signer.get(&signer).unwrap_or(&0) + 1;
res.txs_per_signer.insert(signer, amount); res.txs_per_signer.insert(signer, amount);
@@ -140,6 +141,8 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
}; };
let mut next_nonce = blockchain_next_nonce; let mut next_nonce = blockchain_next_nonce;
let signer = signer.to_bytes();
if let Some(mempool_last_nonce) = if let Some(mempool_last_nonce) =
self.last_nonce_in_mempool.get(&(signer, order.clone())) self.last_nonce_in_mempool.get(&(signer, order.clone()))
{ {
@@ -182,7 +185,7 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
signer: &<Ristretto as WrappedGroup>::G, signer: &<Ristretto as WrappedGroup>::G,
order: Vec<u8>, order: Vec<u8>,
) -> Option<u32> { ) -> Option<u32> {
self.last_nonce_in_mempool.get(&(*signer, order)).copied().map(|nonce| nonce + 1) self.last_nonce_in_mempool.get(&(signer.to_bytes(), order)).copied().map(|nonce| nonce + 1)
} }
/// Get transactions to include in a block. /// Get transactions to include in a block.
@@ -243,6 +246,8 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
if let Some(tx) = self.txs.remove(tx) { if let Some(tx) = self.txs.remove(tx) {
if let TransactionKind::Signed(order, Signed { signer, nonce, .. }) = tx.kind() { if let TransactionKind::Signed(order, Signed { signer, nonce, .. }) = tx.kind() {
let signer = signer.to_bytes();
let amount = *self.txs_per_signer.get(&signer).unwrap() - 1; let amount = *self.txs_per_signer.get(&signer).unwrap() - 1;
self.txs_per_signer.insert(signer, amount); self.txs_per_signer.insert(signer, amount);

View File

@@ -8,7 +8,6 @@ use core::{
borrow::Borrow, borrow::Borrow,
ops::{Deref, Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign}, ops::{Deref, Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign},
iter::{Iterator, Sum}, iter::{Iterator, Sum},
hash::{Hash, Hasher},
}; };
use zeroize::Zeroize; use zeroize::Zeroize;
@@ -20,9 +19,8 @@ use subtle::{Choice, CtOption};
use curve25519_dalek::{ use curve25519_dalek::{
edwards::{EdwardsPoint as DEdwardsPoint, CompressedEdwardsY}, edwards::{EdwardsPoint as DEdwardsPoint, CompressedEdwardsY},
ristretto::{RistrettoPoint as DRistrettoPoint, CompressedRistretto},
}; };
pub use curve25519_dalek::Scalar; pub use curve25519_dalek::{Scalar, ristretto::RistrettoPoint};
use ::ciphersuite::group::{Group, GroupEncoding, prime::PrimeGroup}; use ::ciphersuite::group::{Group, GroupEncoding, prime::PrimeGroup};
@@ -259,17 +257,6 @@ macro_rules! dalek_group {
} }
impl PrimeGroup for $Point {} impl PrimeGroup for $Point {}
// Support being used as a key in a table
// While it is expensive as a key, due to the field operations required, there's frequently
// use cases for public key -> value lookups
#[allow(unknown_lints, renamed_and_removed_lints)]
#[allow(clippy::derived_hash_with_manual_eq, clippy::derive_hash_xor_eq)]
impl Hash for $Point {
fn hash<H: Hasher>(&self, state: &mut H) {
self.to_bytes().hash(state);
}
}
}; };
} }
@@ -281,14 +268,6 @@ dalek_group!(
CompressedEdwardsY, CompressedEdwardsY,
); );
dalek_group!(
RistrettoPoint,
DRistrettoPoint,
|_| true,
RistrettoBasepointTable,
CompressedRistretto,
);
#[test] #[test]
fn test_ed25519_group() { fn test_ed25519_group() {
ff_group_tests::group::test_prime_group_bits::<_, EdwardsPoint>(&mut rand_core::OsRng); ff_group_tests::group::test_prime_group_bits::<_, EdwardsPoint>(&mut rand_core::OsRng);