@@ -79,11 +79,33 @@ impl Codec {
7979 fn decode ( d : PlutusData ) -> CoreResult < DataJson > {
8080 Ok ( match d {
8181 PlutusData :: BigInt ( BigInt :: Int ( int) ) => DataJson :: Int { int : int. into ( ) } ,
82- PlutusData :: BigInt ( pallas_primitives:: BigInt :: BigUInt ( _) )
83- | PlutusData :: BigInt ( pallas_primitives:: BigInt :: BigNInt ( _) ) => {
84- return Err ( CoreError :: msg (
85- "Infinitely large numbers are not supported! Max is Rust i128." ,
86- ) )
82+ PlutusData :: BigInt ( BigInt :: BigUInt ( uint) ) => {
83+ let int: i128 = num_bigint:: BigUint :: from_bytes_be ( & uint)
84+ . try_into ( )
85+ . map_err ( |_| {
86+ CoreError :: msg (
87+ "Infinitely large numbers are not supported! Max is Rust i128" ,
88+ )
89+ } ) ?;
90+ DataJson :: Int { int }
91+ }
92+ PlutusData :: BigInt ( BigInt :: BigNInt ( nint) ) => {
93+ let int: u128 = num_bigint:: BigUint :: from_bytes_be ( & nint)
94+ . try_into ( )
95+ . map_err ( |_| {
96+ CoreError :: msg (
97+ "Infinitely large numbers are not supported! Max is Rust i128" ,
98+ )
99+ } ) ?;
100+ if int <= i128:: MAX as u128 + 1 {
101+ DataJson :: Int {
102+ int : -( int as i128 ) ,
103+ }
104+ } else {
105+ return Err ( CoreError :: msg (
106+ "Infinitely large numbers are not supported! Max is Rust i128" ,
107+ ) ) ;
108+ }
87109 }
88110 PlutusData :: BoundedBytes ( bytes) => DataJson :: Bytes {
89111 bytes : bytes. to_string ( ) ,
@@ -1166,6 +1188,7 @@ mod tests {
11661188 use std:: cmp:: Ordering ;
11671189
11681190 use crate :: codec:: ConstrConversion ;
1191+ use fraction:: FromPrimitive ;
11691192 use pallas_primitives:: { Constr , PlutusData } ;
11701193
11711194 use super :: Assets ;
@@ -1236,4 +1259,30 @@ mod tests {
12361259 assert_eq ! ( assets1. partial_cmp( & assets4) , None ) ;
12371260 assert_eq ! ( assets4. partial_cmp( & assets1) , None ) ;
12381261 }
1262+
1263+ #[ test]
1264+ fn test_big_num ( ) {
1265+ let original_num = 1234567890 ;
1266+ let bytes = num_bigint:: BigInt :: from_i128 ( original_num)
1267+ . unwrap ( )
1268+ . to_bytes_be ( )
1269+ . 1 ;
1270+ let num: i128 = num_bigint:: BigUint :: from_bytes_be ( & bytes)
1271+ . try_into ( )
1272+ . unwrap ( ) ;
1273+ assert_eq ! ( original_num, num) ;
1274+ }
1275+
1276+ #[ test]
1277+ fn test_big_num_negative ( ) {
1278+ let original_num = -1234567890 ;
1279+ let bytes = num_bigint:: BigInt :: from_i128 ( original_num)
1280+ . unwrap ( )
1281+ . to_bytes_be ( )
1282+ . 1 ;
1283+ let num: u128 = num_bigint:: BigUint :: from_bytes_be ( & bytes)
1284+ . try_into ( )
1285+ . unwrap ( ) ;
1286+ assert_eq ! ( original_num, -( num as i128 ) ) ;
1287+ }
12391288}
0 commit comments