Search Unity

(Case 1325367) There is already a BlobAsset with the hash: *** in the Store or Computed List

Discussion in 'Physics for ECS' started by Zec_, Mar 25, 2021.

  1. Zec_

    Zec_

    Joined:
    Feb 9, 2017
    Posts:
    148
    Have encountered a case where the physics authoring of colliders ended up with two diverging BlobAsset-hashes, where both of the hashes resulted in the identical hash for the in the BlobAssetStore, breaking conversion. I dug in the packages and logged some:

    This is the full callstack:
    Code (CSharp):
    1. ArgumentException: There is already a BlobAsset with the hash: c47f879e57e102f4292a13899e2d602f in the Store or the Computed list. You should add a newly computed BlobAsset only once.
    2.   at Unity.Entities.BlobAssetComputationContext`2[TS,TB].AddComputedBlobAsset (Unity.Entities.Hash128 hash, Unity.Entities.BlobAssetReference`1[T] blob) [0x00050] in C:\SLS\ProjectM_2\Game\Packages\com.unity.entities@0.17.0-preview.41\Unity.Entities.Hybrid\GameObjectConversion\BlobAssetComputationContext.cs:116
    3.   at Unity.Physics.Authoring.BaseShapeConversionSystem`1[T].OnUpdate () [0x002af] in C:\SLS\ProjectM_2\Game\Packages\com.unity.physics@0.5.1-preview.2\Unity.Physics.Hybrid\Conversion\BaseShapeConversionSystem.cs:253
    4.   at Unity.Entities.ComponentSystem.Update () [0x0005f] in C:\SLS\ProjectM_2\Game\Packages\com.unity.entities@0.17.0-preview.41\Unity.Entities\ComponentSystem.cs:114
    5.   at Unity.Entities.ComponentSystemGroup.UpdateAllSystems () [0x000c7] in C:\SLS\ProjectM_2\Game\Packages\com.unity.entities@0.17.0-preview.41\Unity.Entities\ComponentSystemGroup.cs:472
    The log is however misleading, as I eventually found out that it's actually two different physics hashes that gets combined with a type, and then becomes the same hash which caused a collision in the BlobAssetStore. I added these logs where the issue occurs:
    upload_2021-3-25_17-25-6.png

    In the screenshot above, BlobAssetStore.TryAdd is called. The next screenshot is from the BlobAssetStore.TryAdd method, where I add a second log that catches the failure.
    upload_2021-3-25_17-24-28.png

    The result showed that two different physics hashes ended up becoming the same BlobAssetStore hash, resulting in a hash-collision. See the logs below:
    Code (CSharp):
    1. // d9a37f4c0c94eeb5fcef25ac00bdb738 is a hash generated in the physics conversion. In TryAdd it's combined with the generic collider type and becomes d62e0153d62e0153d62e0153d62e0153
    2. BaseShapeConversionSystem Hash: d9a37f4c0c94eeb5fcef25ac00bdb738
    3.  
    4. BlobAssetStore.TryAdd<Unity.Physics.Collider>
    5. Hash: d9a37f4c0c94eeb5fcef25ac00bdb738, TypedHash: d62e0153d62e0153d62e0153d62e0153
    6.  
    7. // c47f879e57e102f4292a13899e2d602f is a hash generated in the physics conversion. In TryAdd it's combined with the generic collider type and also becomes d62e0153d62e0153d62e0153d62e0153, and therefore collides with the different hash above!
    8. BaseShapeConversionSystem Hash: c47f879e57e102f4292a13899e2d602f
    9.  
    10. BlobAssetStore.TryAdd<Unity.Physics.Collider>
    11. Hash: c47f879e57e102f4292a13899e2d602f, TypedHash: d62e0153d62e0153d62e0153d62e0153
    Both of these hash registrations originate from BaseShapeConversionSystem.cs:253. Note that the physics hashes are the same, but the TypedHash that is registered in the BlobAssetStore becomes the same hash after the ComputeKeyAndTypeHash function.

    I can unfortunately not share the massive project, and can't reproduce it in a smaller scene. I can remove the issue by modifying one of the prefabs a little, which results in a different hash.

    One can quite likely reproduce this by just taking the hashes from the logs and running them through the BlobAssetStore.TryAdd, which will result in the collision.
     
    Last edited: Mar 25, 2021
    Phalanxen likes this.
  2. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    Hi @Zec_ , thank you for bringing this up! This is definitely a bug, either in BlobAssetStore.ComputeKeyAndTypeHash or in Unity.Mathematics.math.hash(uint4x2 v) that it calls internally.
    It'd be great if you could report it for Entities package (so you can track it), but please let me know if that's not an option and I'll handle it.
     
  3. Zec_

    Zec_

    Joined:
    Feb 9, 2017
    Posts:
    148
    Thanks for the response. I wasn't able to create a small reproduceable project with my actual assets, so I took some time to set up a small test case that just registers the two colliding hashes in a BlobAssetStore as if they were colliders, which proves the collision.
    upload_2021-3-29_19-48-15.png

    Reported as Case 1325367 with a small sample project that contains the simple MonoBehaviour in the screenshot. Updated the title of this thread as well to reflect the case number.
     
    milos85miki likes this.
  4. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    Thanks for the awesome repro, the fix for this will be included in a future entities release. Due to some unfortunate implicit conversion the hash was truncated to 32 bits before use, resulting in statistically higher-than-expected frequency of collisions.

    There's a trivial patch possible by patching some entities code (it's a very small one-liner), but it does require maintaining a local copy of the relevant package so if it's possible I advise waiting.
     
  5. Zec_

    Zec_

    Joined:
    Feb 9, 2017
    Posts:
    148
    I'm not really in that big need of the fix as we modified one of the colliders that it occurred on slightly to generate a different PhysicsCollider hash. My project does however manage local copies for many packages with minor adjustments and bugfixes, so if you don't mind sharing that line of code and the approximate location for it, I would gladly take it to be able to avoid future instances of the issue until the next package version gets released.
     
  6. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    Sure thing! Pared down from a unified diff so your best best may be applying it by hand (the important bit is the use of math.hashwide instead of math.hash in ComputeKeyAndTypeHash.

    a/com.unity.entities/Unity.Entities.Hybrid/GameObjectConversion/BlobAssetStore.cs
    +++ b/com.unity.entities/Unity.Entities.Hybrid/GameObjectConversion/BlobAssetStore.cs
    @@ -178,7 +178,7 @@ static uint ComputeTypeHash(Type type)

    static Hash128 ComputeKeyAndTypeHash(Hash128 key, Type type)
    {
    - return new Hash128(math.hash(new uint4x2 { c0 = key.Value, c1 = new uint4(ComputeTypeHash(type))}));
    + return new Hash128(math.hashwide(new uint4x2 { c0 = key.Value, c1 = new uint4(ComputeTypeHash(type))}));
    }

    /// <summary>
     
    Haneferd and Zec_ like this.