Skip to content
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 by Bors] - Use a fixed state hasher in bevy_reflect for deterministic Reflect::reflect_hash() across processes #7583

Closed
wants to merge 6 commits into from

Conversation

johanhelsing
Copy link
Contributor

@johanhelsing johanhelsing commented Feb 9, 2023

Objective

  • bevy_ggrs uses reflect_hash in order to produce checksums for its world snapshots. These checksums are sent between clients in order to detect desyncronization.
  • However, since we currently use async::AHasher with the std feature, this means that hashes will always be different for different peers, even if the state is identical.
  • This means bevy_ggrs needs a way to get a deterministic (fixed) hash.

Solution

  • Add a feature to use bevy_utils::FixedState for the hasher used by bevy_reflect.
  • Always use bevy_utils::FixedState for initializing the bevy_reflect hasher.

Changelog

  • bevy_reflect now uses a fixed state for its hasher, which means the output of Reflect::reflect_hash is now deterministic across processes.

@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Reflection Runtime information about types labels Feb 9, 2023
@alice-i-cecile
Copy link
Member

It's hard to imagine a case where we wouldn't want this. Why should this be a feature, rather than always enabled?

@johanhelsing
Copy link
Contributor Author

It's hard to imagine a case where we wouldn't want this. Why should this be a feature, rather than always enabled?

Yeah, I guess the possibility of DOS attacks through bevy_reflect are pretty far fetched. I guess if anything it should probably an opt-in feature to make it runtime-seeded.

Hard-coding to always use fixed state

@johanhelsing johanhelsing changed the title Add bevy_reflect/fixed_hash feature for deterministic Reflect::reflect_hash() Use a fixed state hasher in bevy_reflect for deterministic Reflect::reflect_hash() across processes Feb 10, 2023
crates/bevy_reflect/src/reflect.rs Outdated Show resolved Hide resolved
use bevy_utils::FixedState;

#[inline]
pub fn reflect_hasher() -> bevy_utils::AHasher {
Copy link
Member

@MrGVSV MrGVSV Feb 13, 2023

Choose a reason for hiding this comment

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

Nit: This should probably have a doc stating what it does, how/where it's used, and when/why to use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also done :)

@johanhelsing johanhelsing requested review from alice-i-cecile and MrGVSV and removed request for alice-i-cecile and MrGVSV February 17, 2023 07:38
@johanhelsing
Copy link
Contributor Author

Sorry for the noise, still figuring out how the "reviewers" system on github works

@james7132 james7132 added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Feb 17, 2023
@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Feb 17, 2023
…eflect_hash() across processes (#7583)

# Objective

- bevy_ggrs uses `reflect_hash` in order to produce checksums for its world snapshots. These checksums are sent between clients in order to detect desyncronization.
- However, since we currently use `async::AHasher` with the `std` feature, this means that hashes will always be different for different peers, even if the state is identical.
- This means bevy_ggrs needs a way to get a deterministic (fixed) hash.

## Solution

- ~~Add a feature to use `bevy_utils::FixedState` for the hasher used by bevy_reflect.~~
- Always use `bevy_utils::FixedState` for initializing the bevy_reflect hasher. 

---

## Changelog

- bevy_reflect now uses a fixed state for its hasher, which means the output of `Reflect::reflect_hash` is now deterministic across processes.
@bors
Copy link
Contributor

bors bot commented Feb 17, 2023

Build failed (retrying...):

bors bot pushed a commit that referenced this pull request Feb 17, 2023
…eflect_hash() across processes (#7583)

# Objective

- bevy_ggrs uses `reflect_hash` in order to produce checksums for its world snapshots. These checksums are sent between clients in order to detect desyncronization.
- However, since we currently use `async::AHasher` with the `std` feature, this means that hashes will always be different for different peers, even if the state is identical.
- This means bevy_ggrs needs a way to get a deterministic (fixed) hash.

## Solution

- ~~Add a feature to use `bevy_utils::FixedState` for the hasher used by bevy_reflect.~~
- Always use `bevy_utils::FixedState` for initializing the bevy_reflect hasher. 

---

## Changelog

- bevy_reflect now uses a fixed state for its hasher, which means the output of `Reflect::reflect_hash` is now deterministic across processes.
@bors bors bot changed the title Use a fixed state hasher in bevy_reflect for deterministic Reflect::reflect_hash() across processes [Merged by Bors] - Use a fixed state hasher in bevy_reflect for deterministic Reflect::reflect_hash() across processes Feb 17, 2023
@bors bors bot closed this Feb 17, 2023
myreprise1 pushed a commit to myreprise1/bevy that referenced this pull request Feb 18, 2023
…eflect_hash() across processes (bevyengine#7583)

- bevy_ggrs uses `reflect_hash` in order to produce checksums for its world snapshots. These checksums are sent between clients in order to detect desyncronization.
- However, since we currently use `async::AHasher` with the `std` feature, this means that hashes will always be different for different peers, even if the state is identical.
- This means bevy_ggrs needs a way to get a deterministic (fixed) hash.

- ~~Add a feature to use `bevy_utils::FixedState` for the hasher used by bevy_reflect.~~
- Always use `bevy_utils::FixedState` for initializing the bevy_reflect hasher.

---

- bevy_reflect now uses a fixed state for its hasher, which means the output of `Reflect::reflect_hash` is now deterministic across processes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Reflection Runtime information about types C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants