streamingfast / substreams-rs

7 stars 3 forks source link

Implement arithmetic support for `substreams-rs` scalar `BigInt` and `BigDecimal` #12

Closed maoueh closed 3 months ago

maoueh commented 1 year ago

Today, all arithmetic done on BigInt or BigDecimal in from substreams-rs needs to happen between their native type (BigInt and BigInt or BigInt and BigDecimal).

We should implement more of the native arithmetic so that the most standard operations (add, sub, mul, div) can be done against primitive types as well as between BigDecimal/BigInt where it make sense.

For example:

let value = BigDecimal::from(BigInt::from_unsigned_bytes_be(&value.bytes))
let divider = BigDecimal::from(1e18 as i64)

let result = value / divider;

Could easily have been written as:

let value = BigInt::from_unsigned_bytes_be(&value.bytes) / 1e18 as f64

Where value would be a BigDecimal because divided by a f64. This is not an exhaustive list, but here some I would like to see added:

To support all <signed/unsigned integer>, it will probably make sense to use a Rust macro so we don't repeat everything.

Also, some consideration for signed/unsigned conversion will probably be needed, for example an unsigned BigInt minus an integer will become a BigInt signed.

We might need also to check about underflow/overflow but shouldn't be too important for our use case because BigInt/BigDecimal deals with arbitrary precisions.