diff --git a/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs index f69fd037235..0a92614363a 100644 --- a/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs @@ -685,8 +685,8 @@ fn insert_values_nested( let is_required = known_required.contains(&property_key); let field_type = match type_value { - "integer" => DocumentPropertyType::Integer, - "number" => DocumentPropertyType::Number, + "integer" => DocumentPropertyType::I64, + "number" => DocumentPropertyType::F64, "string" => DocumentPropertyType::String(StringPropertySizes { min_length: inner_properties.get_optional_integer(property_names::MIN_LENGTH)?, max_length: inner_properties.get_optional_integer(property_names::MAX_LENGTH)?, diff --git a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs index b8f106c6bec..63a3f390d8d 100644 --- a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs @@ -43,9 +43,17 @@ pub struct ByteArrayPropertySizes { // @append_only #[derive(Debug, PartialEq, Clone, Serialize)] pub enum DocumentPropertyType { - ///Todo decompose integer - Integer, - Number, + U128, + I128, + U64, + I64, + U32, + I32, + U16, + I16, + U8, + I8, + F64, String(StringPropertySizes), ByteArray(ByteArrayPropertySizes), Identifier, @@ -59,21 +67,53 @@ pub enum DocumentPropertyType { impl DocumentPropertyType { pub fn try_from_name(name: &str) -> Result { match name { - "integer" => Ok(DocumentPropertyType::Integer), - "number" => Ok(DocumentPropertyType::Number), + "u128" => Ok(DocumentPropertyType::U128), + "i128" => Ok(DocumentPropertyType::I128), + "u64" => Ok(DocumentPropertyType::U64), + "i64" | "integer" => Ok(DocumentPropertyType::I64), + "u32" => Ok(DocumentPropertyType::U32), + "i32" => Ok(DocumentPropertyType::I32), + "u16" => Ok(DocumentPropertyType::U16), + "i16" => Ok(DocumentPropertyType::I16), + "u8" => Ok(DocumentPropertyType::U8), + "i8" => Ok(DocumentPropertyType::I8), + "f64" | "number" => Ok(DocumentPropertyType::F64), "boolean" => Ok(DocumentPropertyType::Boolean), "date" => Ok(DocumentPropertyType::Date), "identifier" => Ok(DocumentPropertyType::Identifier), - _ => Err(DataContractError::ValueWrongType( - "invalid type".to_string(), + "string" => Ok(DocumentPropertyType::String(StringPropertySizes { + min_length: None, + max_length: None, + })), + "byteArray" => Ok(DocumentPropertyType::ByteArray(ByteArrayPropertySizes { + min_size: None, + max_size: None, + })), + "object" => Ok(DocumentPropertyType::Object(IndexMap::new())), + "array" => Err(DataContractError::ValueWrongType( + "array type needs to specify the inner type".to_string(), )), + "variableTypeArray" => Ok(DocumentPropertyType::VariableTypeArray(Vec::new())), + name => Err(DataContractError::ValueWrongType(format!( + "invalid type {}", + name + ))), } } pub fn name(&self) -> String { match self { - DocumentPropertyType::Integer => "integer".to_string(), - DocumentPropertyType::Number => "number".to_string(), + DocumentPropertyType::U128 => "u128".to_string(), + DocumentPropertyType::I128 => "i128".to_string(), + DocumentPropertyType::U64 => "u64".to_string(), + DocumentPropertyType::I64 => "i64".to_string(), + DocumentPropertyType::U32 => "u32".to_string(), + DocumentPropertyType::I32 => "i32".to_string(), + DocumentPropertyType::U16 => "u16".to_string(), + DocumentPropertyType::I16 => "i16".to_string(), + DocumentPropertyType::U8 => "u8".to_string(), + DocumentPropertyType::I8 => "i8".to_string(), + DocumentPropertyType::F64 => "f64".to_string(), DocumentPropertyType::String(_) => "string".to_string(), DocumentPropertyType::ByteArray(_) => "byteArray".to_string(), DocumentPropertyType::Identifier => "identifier".to_string(), @@ -87,8 +127,17 @@ impl DocumentPropertyType { pub fn min_size(&self) -> Option { match self { - DocumentPropertyType::Integer => Some(8), - DocumentPropertyType::Number => Some(8), + DocumentPropertyType::U128 => Some(16), + DocumentPropertyType::I128 => Some(16), + DocumentPropertyType::U64 => Some(8), + DocumentPropertyType::I64 => Some(8), + DocumentPropertyType::U32 => Some(4), + DocumentPropertyType::I32 => Some(4), + DocumentPropertyType::U16 => Some(2), + DocumentPropertyType::I16 => Some(2), + DocumentPropertyType::U8 => Some(1), + DocumentPropertyType::I8 => Some(1), + DocumentPropertyType::F64 => Some(8), DocumentPropertyType::String(sizes) => match sizes.min_length { None => Some(0), Some(size) => Some(size), @@ -111,8 +160,17 @@ impl DocumentPropertyType { pub fn min_byte_size(&self) -> Option { match self { - DocumentPropertyType::Integer => Some(8), - DocumentPropertyType::Number => Some(8), + DocumentPropertyType::U128 => Some(16), + DocumentPropertyType::I128 => Some(16), + DocumentPropertyType::U64 => Some(8), + DocumentPropertyType::I64 => Some(8), + DocumentPropertyType::U32 => Some(4), + DocumentPropertyType::I32 => Some(4), + DocumentPropertyType::U16 => Some(2), + DocumentPropertyType::I16 => Some(2), + DocumentPropertyType::U8 => Some(1), + DocumentPropertyType::I8 => Some(1), + DocumentPropertyType::F64 => Some(8), DocumentPropertyType::String(sizes) => match sizes.min_length { None => Some(0), Some(size) => Some(size * 4), @@ -135,8 +193,17 @@ impl DocumentPropertyType { pub fn max_byte_size(&self) -> Option { match self { - DocumentPropertyType::Integer => Some(8), - DocumentPropertyType::Number => Some(8), + DocumentPropertyType::U128 => Some(16), + DocumentPropertyType::I128 => Some(16), + DocumentPropertyType::U64 => Some(8), + DocumentPropertyType::I64 => Some(8), + DocumentPropertyType::U32 => Some(4), + DocumentPropertyType::I32 => Some(4), + DocumentPropertyType::U16 => Some(2), + DocumentPropertyType::I16 => Some(2), + DocumentPropertyType::U8 => Some(1), + DocumentPropertyType::I8 => Some(1), + DocumentPropertyType::F64 => Some(8), DocumentPropertyType::String(sizes) => match sizes.max_length { None => Some(u16::MAX), Some(size) => Some(size * 4), @@ -159,8 +226,17 @@ impl DocumentPropertyType { pub fn max_size(&self) -> Option { match self { - DocumentPropertyType::Integer => Some(8), - DocumentPropertyType::Number => Some(8), + DocumentPropertyType::U128 => Some(16), + DocumentPropertyType::I128 => Some(16), + DocumentPropertyType::U64 => Some(8), + DocumentPropertyType::I64 => Some(8), + DocumentPropertyType::U32 => Some(4), + DocumentPropertyType::I32 => Some(4), + DocumentPropertyType::U16 => Some(2), + DocumentPropertyType::I16 => Some(2), + DocumentPropertyType::U8 => Some(1), + DocumentPropertyType::I8 => Some(1), + DocumentPropertyType::F64 => Some(8), DocumentPropertyType::String(sizes) => match sizes.max_length { None => Some(16383), Some(size) => Some(size), @@ -241,8 +317,17 @@ impl DocumentPropertyType { pub fn random_value(&self, rng: &mut StdRng) -> Value { match self { - DocumentPropertyType::Integer => Value::I64(rng.gen::()), - DocumentPropertyType::Number => Value::Float(rng.gen::()), + DocumentPropertyType::U128 => Value::U128(rng.gen::()), + DocumentPropertyType::I128 => Value::I128(rng.gen::()), + DocumentPropertyType::U64 => Value::U64(rng.gen::()), + DocumentPropertyType::I64 => Value::I64(rng.gen::()), + DocumentPropertyType::U32 => Value::U32(rng.gen::()), + DocumentPropertyType::I32 => Value::I32(rng.gen::()), + DocumentPropertyType::U16 => Value::U16(rng.gen::()), + DocumentPropertyType::I16 => Value::I16(rng.gen::()), + DocumentPropertyType::U8 => Value::U8(rng.gen::()), + DocumentPropertyType::I8 => Value::I8(rng.gen::()), + DocumentPropertyType::F64 => Value::Float(rng.gen::()), DocumentPropertyType::String(_) => { let size = self.random_size(rng); Value::Text( @@ -300,8 +385,17 @@ impl DocumentPropertyType { pub fn random_sub_filled_value(&self, rng: &mut StdRng) -> Value { match self { - DocumentPropertyType::Integer => Value::I64(rng.gen::()), - DocumentPropertyType::Number => Value::Float(rng.gen::()), + DocumentPropertyType::U128 => Value::U128(rng.gen::()), + DocumentPropertyType::I128 => Value::I128(rng.gen::()), + DocumentPropertyType::U64 => Value::U64(rng.gen::()), + DocumentPropertyType::I64 => Value::I64(rng.gen::()), + DocumentPropertyType::U32 => Value::U32(rng.gen::()), + DocumentPropertyType::I32 => Value::I32(rng.gen::()), + DocumentPropertyType::U16 => Value::U16(rng.gen::()), + DocumentPropertyType::I16 => Value::I16(rng.gen::()), + DocumentPropertyType::U8 => Value::U8(rng.gen::()), + DocumentPropertyType::I8 => Value::I8(rng.gen::()), + DocumentPropertyType::F64 => Value::Float(rng.gen::()), DocumentPropertyType::String(_) => { let size = self.min_size().unwrap(); Value::Text( @@ -340,8 +434,17 @@ impl DocumentPropertyType { pub fn random_filled_value(&self, rng: &mut StdRng) -> Value { match self { - DocumentPropertyType::Integer => Value::I64(rng.gen::()), - DocumentPropertyType::Number => Value::Float(rng.gen::()), + DocumentPropertyType::U128 => Value::U128(rng.gen::()), + DocumentPropertyType::I128 => Value::I128(rng.gen::()), + DocumentPropertyType::U64 => Value::U64(rng.gen::()), + DocumentPropertyType::I64 => Value::I64(rng.gen::()), + DocumentPropertyType::U32 => Value::U32(rng.gen::()), + DocumentPropertyType::I32 => Value::I32(rng.gen::()), + DocumentPropertyType::U16 => Value::U16(rng.gen::()), + DocumentPropertyType::I16 => Value::I16(rng.gen::()), + DocumentPropertyType::U8 => Value::U8(rng.gen::()), + DocumentPropertyType::I8 => Value::I8(rng.gen::()), + DocumentPropertyType::F64 => Value::Float(rng.gen::()), DocumentPropertyType::String(_) => { let size = self.max_size().unwrap(); Value::Text( @@ -413,6 +516,86 @@ impl DocumentPropertyType { } } match self { + DocumentPropertyType::U128 => { + let value = buf.read_u128::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading u128 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::U128(value)), false)) + } + DocumentPropertyType::I128 => { + let value = buf.read_i128::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading i128 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::I128(value)), false)) + } + DocumentPropertyType::U64 => { + let value = buf.read_u64::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading u64 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::U64(value)), false)) + } + DocumentPropertyType::I64 => { + let value = buf.read_i64::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading i64 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::I64(value)), false)) + } + DocumentPropertyType::U32 => { + let value = buf.read_u32::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading u32 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::U32(value)), false)) + } + DocumentPropertyType::I32 => { + let value = buf.read_i32::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading i32 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::I32(value)), false)) + } + DocumentPropertyType::U16 => { + let value = buf.read_u16::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading u16 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::U16(value)), false)) + } + DocumentPropertyType::I16 => { + let value = buf.read_i16::().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading i16 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::I16(value)), false)) + } + DocumentPropertyType::U8 => { + let value = buf.read_u8().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading u8 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::U8(value)), false)) + } + DocumentPropertyType::I8 => { + let value = buf.read_i8().map_err(|_| { + DataContractError::CorruptedSerialization( + "error reading i8 from serialized document".to_string(), + ) + })?; + Ok((Some(Value::I8(value)), false)) + } DocumentPropertyType::String(_) => { let bytes = Self::read_varint_value(buf)?; let string = String::from_utf8(bytes).map_err(|_| { @@ -422,7 +605,7 @@ impl DocumentPropertyType { })?; Ok((Some(Value::Text(string)), false)) } - DocumentPropertyType::Date | DocumentPropertyType::Number => { + DocumentPropertyType::Date | DocumentPropertyType::F64 => { let date = buf.read_f64::().map_err(|_| { DataContractError::CorruptedSerialization( "error reading date/number from serialized document".to_string(), @@ -430,14 +613,6 @@ impl DocumentPropertyType { })?; Ok((Some(Value::Float(date)), false)) } - DocumentPropertyType::Integer => { - let integer = buf.read_i64::().map_err(|_| { - DataContractError::CorruptedSerialization( - "error reading integer from serialized document".to_string(), - ) - })?; - Ok((Some(Value::I64(integer)), false)) - } DocumentPropertyType::Boolean => { let value = buf.read_u8().map_err(|_| { DataContractError::CorruptedSerialization( @@ -565,7 +740,7 @@ impl DocumentPropertyType { Err(get_field_type_matching_error(&value).into()) } } - DocumentPropertyType::Date => { + DocumentPropertyType::Date | DocumentPropertyType::F64 => { let value_as_f64 = value.into_float().map_err(ProtocolError::ValueError)?; let mut value_bytes = value_as_f64.to_be_bytes().to_vec(); if required { @@ -577,25 +752,113 @@ impl DocumentPropertyType { Ok(r_vec) } } - DocumentPropertyType::Integer => { + DocumentPropertyType::U128 => { + let value_as_u128: u128 = + value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_u128.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::I128 => { + let value_as_i128: i128 = + value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_i128.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::U64 => { + let value_as_u64: u64 = value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_u64.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::I64 => { let value_as_i64: i64 = value.into_integer().map_err(ProtocolError::ValueError)?; let mut value_bytes = value_as_i64.to_be_bytes().to_vec(); if required { Ok(value_bytes) } else { - // if the value wasn't required we need to add a byte to prove it existed let mut r_vec = vec![255u8]; r_vec.append(&mut value_bytes); Ok(r_vec) } } - DocumentPropertyType::Number => { - let value_as_f64 = value.into_float().map_err(ProtocolError::ValueError)?; - let mut value_bytes = value_as_f64.to_be_bytes().to_vec(); + DocumentPropertyType::U32 => { + let value_as_u32: u32 = value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_u32.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::I32 => { + let value_as_i32: i32 = value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_i32.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::U16 => { + let value_as_u16: u16 = value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_u16.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::I16 => { + let value_as_i16: i16 = value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_i16.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::U8 => { + let value_as_u8: u8 = value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_u8.to_be_bytes().to_vec(); + if required { + Ok(value_bytes) + } else { + let mut r_vec = vec![255u8]; + r_vec.append(&mut value_bytes); + Ok(r_vec) + } + } + DocumentPropertyType::I8 => { + let value_as_i8: i8 = value.into_integer().map_err(ProtocolError::ValueError)?; + let mut value_bytes = value_as_i8.to_be_bytes().to_vec(); if required { Ok(value_bytes) } else { - // if the value wasn't required we need to add a byte to prove it existed let mut r_vec = vec![255u8]; r_vec.append(&mut value_bytes); Ok(r_vec) @@ -712,11 +975,47 @@ impl DocumentPropertyType { Ok(r_vec) } } - DocumentPropertyType::Integer => { + DocumentPropertyType::U128 => { + let value_as_u128: u128 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_u128.to_be_bytes().to_vec()) + } + DocumentPropertyType::I128 => { + let value_as_i128: i128 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_i128.to_be_bytes().to_vec()) + } + DocumentPropertyType::U64 => { + let value_as_u64: u64 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_u64.to_be_bytes().to_vec()) + } + DocumentPropertyType::I64 => { let value_as_i64: i64 = value.to_integer().map_err(ProtocolError::ValueError)?; Ok(value_as_i64.to_be_bytes().to_vec()) } - DocumentPropertyType::Number => { + DocumentPropertyType::U32 => { + let value_as_u32: u32 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_u32.to_be_bytes().to_vec()) + } + DocumentPropertyType::I32 => { + let value_as_i32: i32 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_i32.to_be_bytes().to_vec()) + } + DocumentPropertyType::U16 => { + let value_as_u16: u16 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_u16.to_be_bytes().to_vec()) + } + DocumentPropertyType::I16 => { + let value_as_i16: i16 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_i16.to_be_bytes().to_vec()) + } + DocumentPropertyType::U8 => { + let value_as_u8: u8 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_u8.to_be_bytes().to_vec()) + } + DocumentPropertyType::I8 => { + let value_as_i8: i8 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(value_as_i8.to_be_bytes().to_vec()) + } + DocumentPropertyType::F64 => { let value_as_f64 = value.to_float().map_err(ProtocolError::ValueError)?; Ok(value_as_f64.to_be_bytes().to_vec()) } @@ -819,12 +1118,47 @@ impl DocumentPropertyType { DocumentPropertyType::Date => Ok(DocumentPropertyType::encode_date_timestamp( value.to_integer().map_err(ProtocolError::ValueError)?, )), - DocumentPropertyType::Integer => { + DocumentPropertyType::U128 => { + let value_as_u128 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_u128(value_as_u128)) + } + DocumentPropertyType::I128 => { + let value_as_i128 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_i128(value_as_i128)) + } + DocumentPropertyType::U64 => { + let value_as_u64 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_u64(value_as_u64)) + } + DocumentPropertyType::I64 => { let value_as_i64 = value.to_integer().map_err(ProtocolError::ValueError)?; - Ok(DocumentPropertyType::encode_i64(value_as_i64)) } - DocumentPropertyType::Number => Ok(Self::encode_float( + DocumentPropertyType::U32 => { + let value_as_u32 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_u32(value_as_u32)) + } + DocumentPropertyType::I32 => { + let value_as_i32 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_i32(value_as_i32)) + } + DocumentPropertyType::U16 => { + let value_as_u16 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_u16(value_as_u16)) + } + DocumentPropertyType::I16 => { + let value_as_i16 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_i16(value_as_i16)) + } + DocumentPropertyType::U8 => { + let value_as_u8 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_u8(value_as_u8)) + } + DocumentPropertyType::I8 => { + let value_as_i8 = value.to_integer().map_err(ProtocolError::ValueError)?; + Ok(DocumentPropertyType::encode_i8(value_as_i8)) + } + DocumentPropertyType::F64 => Ok(Self::encode_float( value.to_float().map_err(ProtocolError::ValueError)?, )), DocumentPropertyType::ByteArray(_) => { @@ -884,13 +1218,67 @@ impl DocumentPropertyType { )?; Ok(Value::U64(timestamp)) } - DocumentPropertyType::Integer => { + DocumentPropertyType::U128 => { + let integer = DocumentPropertyType::decode_u128(value).ok_or( + ProtocolError::DecodingError("could not decode u128".to_string()), + )?; + Ok(Value::U128(integer)) + } + DocumentPropertyType::I128 => { + let integer = DocumentPropertyType::decode_i128(value).ok_or( + ProtocolError::DecodingError("could not decode i128".to_string()), + )?; + Ok(Value::I128(integer)) + } + DocumentPropertyType::U64 => { + let integer = DocumentPropertyType::decode_u64(value).ok_or( + ProtocolError::DecodingError("could not decode u64".to_string()), + )?; + Ok(Value::U64(integer)) + } + DocumentPropertyType::I64 => { let integer = DocumentPropertyType::decode_i64(value).ok_or( - ProtocolError::DecodingError("could not decode integer".to_string()), + ProtocolError::DecodingError("could not decode i64".to_string()), )?; Ok(Value::I64(integer)) } - DocumentPropertyType::Number => { + DocumentPropertyType::U32 => { + let integer = DocumentPropertyType::decode_u32(value).ok_or( + ProtocolError::DecodingError("could not decode u32".to_string()), + )?; + Ok(Value::U32(integer)) + } + DocumentPropertyType::I32 => { + let integer = DocumentPropertyType::decode_i32(value).ok_or( + ProtocolError::DecodingError("could not decode i32".to_string()), + )?; + Ok(Value::I32(integer)) + } + DocumentPropertyType::U16 => { + let integer = DocumentPropertyType::decode_u16(value).ok_or( + ProtocolError::DecodingError("could not decode u16".to_string()), + )?; + Ok(Value::U16(integer)) + } + DocumentPropertyType::I16 => { + let integer = DocumentPropertyType::decode_i16(value).ok_or( + ProtocolError::DecodingError("could not decode i16".to_string()), + )?; + Ok(Value::I16(integer)) + } + DocumentPropertyType::U8 => { + let integer = DocumentPropertyType::decode_u8(value).ok_or( + ProtocolError::DecodingError("could not decode u8".to_string()), + )?; + Ok(Value::U8(integer)) + } + DocumentPropertyType::I8 => { + let integer = DocumentPropertyType::decode_i8(value).ok_or( + ProtocolError::DecodingError("could not decode i8".to_string()), + )?; + Ok(Value::I8(integer)) + } + DocumentPropertyType::F64 => { let float = DocumentPropertyType::decode_float(value).ok_or( ProtocolError::DecodingError("could not decode float".to_string()), )?; @@ -947,10 +1335,57 @@ impl DocumentPropertyType { } Ok(Value::Text(str.to_string())) } - DocumentPropertyType::Integer => str.parse::().map(Value::I128).map_err(|_| { - DataContractError::ValueWrongType("value is not an integer from string".to_string()) + DocumentPropertyType::U128 => str.parse::().map(Value::U128).map_err(|_| { + DataContractError::ValueWrongType( + "value is not a u128 integer from string".to_string(), + ) + }), + DocumentPropertyType::I128 => str.parse::().map(Value::I128).map_err(|_| { + DataContractError::ValueWrongType( + "value is not an i128 integer from string".to_string(), + ) + }), + DocumentPropertyType::U64 => str.parse::().map(Value::U64).map_err(|_| { + DataContractError::ValueWrongType( + "value is not a u64 integer from string".to_string(), + ) + }), + DocumentPropertyType::I64 => str.parse::().map(Value::I64).map_err(|_| { + DataContractError::ValueWrongType( + "value is not an i64 integer from string".to_string(), + ) + }), + DocumentPropertyType::U32 => str.parse::().map(Value::U32).map_err(|_| { + DataContractError::ValueWrongType( + "value is not a u32 integer from string".to_string(), + ) + }), + DocumentPropertyType::I32 => str.parse::().map(Value::I32).map_err(|_| { + DataContractError::ValueWrongType( + "value is not an i32 integer from string".to_string(), + ) + }), + DocumentPropertyType::U16 => str.parse::().map(Value::U16).map_err(|_| { + DataContractError::ValueWrongType( + "value is not a u16 integer from string".to_string(), + ) }), - DocumentPropertyType::Number | DocumentPropertyType::Date => { + DocumentPropertyType::I16 => str.parse::().map(Value::I16).map_err(|_| { + DataContractError::ValueWrongType( + "value is not an i16 integer from string".to_string(), + ) + }), + DocumentPropertyType::U8 => str.parse::().map(Value::U8).map_err(|_| { + DataContractError::ValueWrongType( + "value is not a u8 integer from string".to_string(), + ) + }), + DocumentPropertyType::I8 => str.parse::().map(Value::I8).map_err(|_| { + DataContractError::ValueWrongType( + "value is not an i8 integer from string".to_string(), + ) + }), + DocumentPropertyType::F64 | DocumentPropertyType::Date => { str.parse::().map(Value::Float).map_err(|_| { DataContractError::ValueWrongType( "value is not a float from string".to_string(), @@ -1014,6 +1449,99 @@ impl DocumentPropertyType { Self::decode_u64(val) } + pub fn encode_u128(val: u128) -> Vec { + // Positive integers are represented in binary with the signed bit set to 0 + // Negative integers are represented in 2's complement form + + // Encode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut wtr = vec![]; + wtr.write_u128::(val).unwrap(); + + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + wtr[0] ^= 0b1000_0000; + + wtr + } + + /// Decodes an unsigned integer on 128 bits. + pub fn decode_u128(val: &[u8]) -> Option { + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + let mut val = val.to_vec(); + val[0] ^= 0b1000_0000; + + // Decode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut rdr = val.as_slice(); + rdr.read_u128::().ok() + } + + pub fn encode_i128(val: i128) -> Vec { + // Positive integers are represented in binary with the signed bit set to 0 + // Negative integers are represented in 2's complement form + + // Encode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut wtr = vec![]; + wtr.write_i128::(val).unwrap(); + + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + wtr[0] ^= 0b1000_0000; + + wtr + } + + pub fn decode_i128(val: &[u8]) -> Option { + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + let mut val = val.to_vec(); + val[0] ^= 0b1000_0000; + + // Decode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut rdr = val.as_slice(); + rdr.read_i128::().ok() + } + pub fn encode_u64(val: u64) -> Vec { // Positive integers are represented in binary with the signed bit set to 0 // Negative integers are represented in 2's complement form @@ -1061,6 +1589,52 @@ impl DocumentPropertyType { rdr.read_u64::().ok() } + pub fn encode_i64(val: i64) -> Vec { + // Positive integers are represented in binary with the signed bit set to 0 + // Negative integers are represented in 2's complement form + + // Encode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut wtr = vec![]; + wtr.write_i64::(val).unwrap(); + + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + wtr[0] ^= 0b1000_0000; + + wtr + } + + pub fn decode_i64(val: &[u8]) -> Option { + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + let mut val = val.to_vec(); + val[0] ^= 0b1000_0000; + + // Decode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut rdr = val.as_slice(); + rdr.read_i64::().ok() + } + pub fn encode_u32(val: u32) -> Vec { // Positive integers are represented in binary with the signed bit set to 0 // Negative integers are represented in 2's complement form @@ -1108,7 +1682,7 @@ impl DocumentPropertyType { rdr.read_u32::().ok() } - pub fn encode_i64(val: i64) -> Vec { + pub fn encode_i32(val: i32) -> Vec { // Positive integers are represented in binary with the signed bit set to 0 // Negative integers are represented in 2's complement form @@ -1118,7 +1692,7 @@ impl DocumentPropertyType { // and a bigger negative number would be greater than a smaller one // maintains sort order for each domain let mut wtr = vec![]; - wtr.write_i64::(val).unwrap(); + wtr.write_i32::(val).unwrap(); // Flip the sign bit // to deal with interaction between the domains @@ -1133,7 +1707,7 @@ impl DocumentPropertyType { wtr } - pub fn decode_i64(val: &[u8]) -> Option { + pub fn decode_i32(val: &[u8]) -> Option { // Flip the sign bit // to deal with interaction between the domains // 2's complement values have the sign bit set to 1 @@ -1151,7 +1725,193 @@ impl DocumentPropertyType { // and a bigger negative number would be greater than a smaller one // maintains sort order for each domain let mut rdr = val.as_slice(); - rdr.read_i64::().ok() + rdr.read_i32::().ok() + } + + pub fn encode_u16(val: u16) -> Vec { + // Positive integers are represented in binary with the signed bit set to 0 + // Negative integers are represented in 2's complement form + + // Encode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut wtr = vec![]; + wtr.write_u16::(val).unwrap(); + + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + wtr[0] ^= 0b1000_0000; + + wtr + } + + /// Decodes an unsigned integer on 32 bits. + pub fn decode_u16(val: &[u8]) -> Option { + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + let mut val = val.to_vec(); + val[0] ^= 0b1000_0000; + + // Decode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut rdr = val.as_slice(); + rdr.read_u16::().ok() + } + + pub fn encode_i16(val: i16) -> Vec { + // Positive integers are represented in binary with the signed bit set to 0 + // Negative integers are represented in 2's complement form + + // Encode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut wtr = vec![]; + wtr.write_i16::(val).unwrap(); + + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + wtr[0] ^= 0b1000_0000; + + wtr + } + + pub fn decode_i16(val: &[u8]) -> Option { + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + let mut val = val.to_vec(); + val[0] ^= 0b1000_0000; + + // Decode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut rdr = val.as_slice(); + rdr.read_i16::().ok() + } + + pub fn encode_u8(val: u8) -> Vec { + // Positive integers are represented in binary with the signed bit set to 0 + // Negative integers are represented in 2's complement form + + // Encode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut wtr = vec![]; + wtr.write_u8(val).unwrap(); + + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + wtr[0] ^= 0b1000_0000; + + wtr + } + + /// Decodes an unsigned integer on 8 bits. + pub fn decode_u8(val: &[u8]) -> Option { + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + let mut val = val.to_vec(); + val[0] ^= 0b1000_0000; + + // Decode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut rdr = val.as_slice(); + rdr.read_u8().ok() + } + + pub fn encode_i8(val: i8) -> Vec { + // Positive integers are represented in binary with the signed bit set to 0 + // Negative integers are represented in 2's complement form + + // Encode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut wtr = vec![]; + wtr.write_i8(val).unwrap(); + + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + wtr[0] ^= 0b1000_0000; + + wtr + } + + pub fn decode_i8(val: &[u8]) -> Option { + // Flip the sign bit + // to deal with interaction between the domains + // 2's complement values have the sign bit set to 1 + // this makes them greater than the positive domain in terms of sort order + // to fix this, we just flip the sign bit + // so positive integers have the high bit and negative integers have the low bit + // the relative order of elements in each domain is still maintained, as the + // change was uniform across all elements + let mut val = val.to_vec(); + val[0] ^= 0b1000_0000; + + // Decode the integer in big endian form + // This ensures that most significant bits are compared first + // a bigger positive number would be greater than a smaller one + // and a bigger negative number would be greater than a smaller one + // maintains sort order for each domain + let mut rdr = val.as_slice(); + rdr.read_i8().ok() } pub fn encode_float(val: f64) -> Vec { diff --git a/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs b/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs index 6681c47c28a..78d9c08f2e9 100644 --- a/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs @@ -158,13 +158,13 @@ impl DocumentTypeV0 { max_length, }) } else if random_weight < field_weights.string_weight + field_weights.integer_weight { - DocumentPropertyType::Integer + DocumentPropertyType::I64 } else if random_weight < field_weights.string_weight + field_weights.integer_weight + field_weights.float_weight { - DocumentPropertyType::Number + DocumentPropertyType::F64 } else if random_weight < field_weights.string_weight + field_weights.integer_weight @@ -280,7 +280,8 @@ impl DocumentTypeV0 { } serde_json::Value::Object(schema) }, - DocumentPropertyType::Integer => { + DocumentPropertyType::U128 | DocumentPropertyType::U64 | DocumentPropertyType::U32 | DocumentPropertyType::U16 | DocumentPropertyType::U8 | + DocumentPropertyType::I128 | DocumentPropertyType::I64 | DocumentPropertyType::I32 | DocumentPropertyType::I16 | DocumentPropertyType::I8 => { let mut schema = serde_json::Map::new(); schema.insert("type".to_string(), serde_json::Value::String("integer".to_owned())); // Add min and max if specified in parameters @@ -290,7 +291,7 @@ impl DocumentTypeV0 { schema.insert("maximum".to_string(), serde_json::Value::Number(serde_json::Number::from(integer_max))); serde_json::Value::Object(schema) }, - DocumentPropertyType::Number => { + DocumentPropertyType::F64 => { let mut schema = serde_json::Map::new(); schema.insert("type".to_string(), serde_json::Value::String("number".to_owned())); // Add min and max if specified in parameters @@ -481,13 +482,13 @@ impl DocumentTypeV0 { max_length, }) } else if random_weight < field_weights.string_weight + field_weights.integer_weight { - DocumentPropertyType::Integer + DocumentPropertyType::I64 } else if random_weight < field_weights.string_weight + field_weights.integer_weight + field_weights.float_weight { - DocumentPropertyType::Number + DocumentPropertyType::F64 } else if random_weight < field_weights.string_weight + field_weights.integer_weight diff --git a/packages/rs-drive/src/query/conditions.rs b/packages/rs-drive/src/query/conditions.rs index e360475f247..24b5600f9f5 100644 --- a/packages/rs-drive/src/query/conditions.rs +++ b/packages/rs-drive/src/query/conditions.rs @@ -1077,7 +1077,7 @@ impl<'a> WhereClause { let property_type = match field_name.as_str() { "$id" | "$ownerId" => Cow::Owned(DocumentPropertyType::Identifier), "$createdAt" | "$updatedAt" => Cow::Owned(DocumentPropertyType::Date), - "$revision" => Cow::Owned(DocumentPropertyType::Integer), + "$revision" => Cow::Owned(DocumentPropertyType::U64), property_name => { let Some(property) = document_type.properties().get(property_name) else { return Err(Error::Query(QuerySyntaxError::InvalidInClause( @@ -1212,7 +1212,7 @@ impl<'a> WhereClause { let property_type = match field_name.as_str() { "$id" | "$ownerId" => Cow::Owned(DocumentPropertyType::Identifier), "$createdAt" | "$updatedAt" => Cow::Owned(DocumentPropertyType::Date), - "$revision" => Cow::Owned(DocumentPropertyType::Integer), + "$revision" => Cow::Owned(DocumentPropertyType::U64), property_name => { let Some(property) = document_type.properties().get(property_name) else {