8000 Feat: Implement `Pod` trait on Uint types by 0xKitsune · Pull Request #292 · recmo/uint · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Feat: Implement Pod trait on Uint types #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 5, 2023
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `bytemuck` feature ([#292])

## [1.10.1] - 2023-07-30

### Fixed
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ rlp = { version = "0.5", optional = true, default-features = false }
serde = { version = "1", optional = true, default-features = false }
valuable = { version = "0.1", optional = true, default-features = false }
zeroize = { version = "1.6", optional = true, default-features = false }
bytemuck = { version = "1.13.1", optional = true, default-features = false }

# postgres
bytes = { version = "1.4", optional = true }
Expand Down Expand Up @@ -131,6 +132,7 @@ rlp = ["dep:rlp", "alloc"]
serde = ["dep:serde", "alloc"] # TODO: try to avoid alloc in serde impls
valuable = ["dep:valuable"]
zeroize = ["dep:zeroize"]
bytemuck = ["dep:bytemuck"]

postgres = ["dep:postgres-types", "dep:bytes", "std", "dep:thiserror"]
sqlx = ["dep:sqlx-core", "std", "dep:thiserror"]
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ named feature flag.
* [`pyo3`](https://docs.rs/pyo3): Implements the [`ToPyObject`](https://docs.rs/pyo3/latest/pyo3/conversion/trait.ToPyObject.html), [`IntoPy`](https://docs.rs/pyo3/latest/pyo3/conversion/trait.IntoPy.html) and [`FromPyObject`](https://docs.rs/pyo3/latest/pyo3/conversion/trait.FromPyObject.html) traits.
* [`parity-scale-codec`](https://docs.rs/parity-scale-codec): Implements the [`Encode`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.Encode.html), [`Decode`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.Decode.html), [`MaxEncodedLen`](https://github.com/paritytech/parity-scale-codec/blob/47d98a1c23dabc890fdb548d115a18070082c66e/src/max_encoded_len.rs) and [`HasCompact`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.HasCompact.html) traits.
* [`bn-rs`](https://docs.rs/bn-rs/latest/bn_rs/): Implements conversion to/from the [`BN`](https://docs.rs/bn-rs/latest/bn_rs/struct.BN.html) and [`BigNumber`](https://docs.rs/bn-rs/latest/bn_rs/struct.BigNumber.html).
* [`bytemuck`](https://docs.rs/bytemuck): Implements the [`Pod`](https://docs.rs/bytemuck/latest/bytemuck/trait.Pod.html) and [`Zeroable`](https://docs.rs/bytemuck/latest/bytemuck/trait.Zeroable.html) traits for [`Uint`] where the size is a multiple of 64, up to 1024. This allows `Uint` to be used where a `Pod` trait bound exists.


## Building and testing

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ pub mod nightly {
///
/// [std-overflow]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
#[repr(transparent)]
pub struct Uint<const BITS: usize, const LIMBS: usize> {
limbs: [u64; LIMBS],
}
Expand Down
82 changes: 82 additions & 0 deletions src/support/bytemuck.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! Support for the [`bytemuck`](https://crates.io/crates/bytemuck) crate.
#![cfg(feature = "bytemuck")]
#![cfg_attr(docsrs, doc(cfg(feature = "bytemuck")))]

use bytemuck::{Pod, Zeroable};
use ruint::Uint;

// Implement Zeroable for all `Uint` types.
unsafe impl<const BITS: usize, const LIMBS: usize> Zeroable for Uint<{ BITS }, { LIMBS }> {}

// Implement the `Pod` trait for `Uint` types with a size that is a multiple of
// 64, up to 1024. Note that implementors must have a size that is divisible by
// 64, and using `Uint` sizes not divisible by 64 would violate Pod's
// guarantees potentially leading to undefined behavior.
macro_rules! impl_pod {
($(($bits:expr, $limbs:expr)),+ $(,)?) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: these are really literal, as non-literal expr are invalid in this context. no change needed

$(
unsafe impl Pod for Uint<{$bits}, $limbs> {}
)+
};
}

impl_pod! {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to replace this with a generic_const_expr usage when cfg(feature = "nightly") ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide more insight on what this might look like? I can take a look into updating the implementation to use generic_const_expr when nightly is enabled.

Would you want this updated before merging the current changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just following up on this, let me know what you think. I'm happy to take a look into it if this would be blocking to get the PR merged.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't consider this a blocker

(64, 1),
(128, 2),
(192, 3),
(256, 4),
(320, 5),
(384, 6),
(448, 7),
(512, 8),
(576, 9),
(640, 10),
(704, 11),
(768, 12),
(832, 13),
(896, 14),
(960, 15),
(1024, 16),
}

#[cfg(test)]
mod tests {
use bytemuck::{Pod, Zeroable};
use ruint::Uint;

#[test]
fn test_uint_pod() {
test_pod::<64, 1>();
test_pod::<128, 2>();
test_pod::<192, 3>();
test_pod::<256, 4>();
test_pod::<320, 5>();
test_pod::<384, 6>();
test_pod::<448, 7>();
test_pod::<512, 8>();
test_pod::<576, 9>();
test_pod::<640, 10>();
test_pod::<704, 11>();
test_pod::<768, 12>();
test_pod::<832, 13>();
test_pod::<896, 14>();
test_pod::<960, 15>();
test_pod::<1024, 16>();
}

fn test_pod<const BITS: usize, const LIMBS: usize>()
where
Uint<{ BITS }, { LIMBS }>: Zeroable + Pod + Eq + Default,
{
let val = Uint::<{ BITS }, { LIMBS }>::default();
let bytes = bytemuck::bytes_of(&val);

assert_eq!(
bytes.len(),
std::mem::size_of::<Uint<{ BITS }, { LIMBS }>>()
);

let zeroed_val: Uint<{ BITS }, { LIMBS }> = Zeroable::zeroed();
assert_eq!(zeroed_val, Uint::<{ BITS }, { LIMBS }>::default());
}
}
1 change: 1 addition & 0 deletions src/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod arbitrary;
mod ark_ff;
mod ark_ff_04;
mod bn_rs;
mod bytemuck;
mod fastrlp;
mod num_bigint;
pub mod postgres;
Expand Down
0