AleoNet / snarkVM

A Virtual Machine for Zero-Knowledge Executions
https://snarkvm.org
Apache License 2.0
1.08k stars 1.5k forks source link

[Bug] Serde deserialization of u128 numbers in block data defaults to float instead of u128 #2560

Open iamalwaysuncomfortable opened 1 month ago

iamalwaysuncomfortable commented 1 month ago

🐛 Bug Report

Structs with u128 members related to the puzzle are starting to get into sizes that can only be represented in u128 numbers (i.e. the cumulative_weight member of the Header object). As a side effect, Serde based deserializers are starting to have the behavior of interpreting these numbers as floats during deserialization causing Serde deserialization of objects like Block to fail when deserializing from JSON.

For context as to why this happens, the Number enum in serde-json without the arbitraryprecision flag can hold a u64, i64, or f64. Thus without the arbitraryprecision flag, Number isn't capable of holding a u128 directly as an integer type and defaults to storing it as an f64. SnarkVM doesn't handle this explicitly causing deserialization to fail.

This will affect Rust code deserializing Blocks from JSON.

Steps to Reproduce

  1. Use GET request using the reqwest library to download block 1243302
  2. Attempt to deserialize the json object into a Block
  3. A deserialization failure occurs

A workaround for now for libraries deserializing Blocks with using Serde in Rust is to use the arbitrary_precision feature. A longer term fix would be to examine visitor patterns that work over u128 numbers and ensure the logic explicitly deserializes them into u128.

vicsn commented 1 month ago

Potentially related: https://github.com/AleoNet/snarkVM/pull/2559