Merge branch 'next' into next-polkadot-sdk

This commit is contained in:
Luke Parker
2025-09-06 04:26:10 -04:00
7 changed files with 26 additions and 36 deletions

View File

@@ -5,7 +5,7 @@ inputs:
version: version:
description: "Version to download and run" description: "Version to download and run"
required: false required: false
default: "27.0" default: "29.1"
runs: runs:
using: "composite" using: "composite"

View File

@@ -10,7 +10,7 @@ inputs:
bitcoin-version: bitcoin-version:
description: "Bitcoin version to download and run as a regtest node" description: "Bitcoin version to download and run as a regtest node"
required: false required: false
default: "27.1" default: "29.1"
runs: runs:
using: "composite" using: "composite"

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);

View File

@@ -419,7 +419,7 @@ macro_rules! odd_prime_field_with_specific_repr {
const ONE_MOD_EIGHT: bool = (MODULUS.as_words()[0] % 8) == 1; const ONE_MOD_EIGHT: bool = (MODULUS.as_words()[0] % 8) == 1;
const FIVE_MOD_EIGHT: bool = (MODULUS.as_words()[0] % 8) == 5; const FIVE_MOD_EIGHT: bool = (MODULUS.as_words()[0] % 8) == 5;
let sqrt = if THREE_MOD_FOUR { let mut sqrt = if THREE_MOD_FOUR {
const SQRT_EXP: UnderlyingUint = const SQRT_EXP: UnderlyingUint =
MODULUS.shr_vartime(2).wrapping_add(&UnderlyingUint::ONE); MODULUS.shr_vartime(2).wrapping_add(&UnderlyingUint::ONE);
Self(self.0.pow(&SQRT_EXP)) Self(self.0.pow(&SQRT_EXP))
@@ -449,7 +449,10 @@ macro_rules! odd_prime_field_with_specific_repr {
Self(upsilon * self.0 * (i - Self::ONE.0)) Self(upsilon * self.0 * (i - Self::ONE.0))
}; };
let sqrt = <_>::conditional_select(&sqrt, &-sqrt, sqrt.0.retrieve().is_odd()); // Normalize to the even choice of square root
// `let ()` is used to assert how `conditional_negate` operates in-place
let () = sqrt.conditional_negate(sqrt.is_odd());
CtOption::new(sqrt, sqrt.square().ct_eq(self)) CtOption::new(sqrt, sqrt.square().ct_eq(self))
} }
fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) { fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {

View File

@@ -7,7 +7,7 @@ pub fn bitcoin(orchestration_path: &Path, network: Network) {
const DOWNLOAD_BITCOIN: &str = r#" const DOWNLOAD_BITCOIN: &str = r#"
FROM alpine:latest AS bitcoin FROM alpine:latest AS bitcoin
ENV BITCOIN_VERSION=27.1 ENV BITCOIN_VERSION=29.1
RUN apk --no-cache add wget git gnupg RUN apk --no-cache add wget git gnupg