Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEMP ON HOLD] refactor: Use SBOR raw value across engine for better worst case performance #1860

Draft
wants to merge 11 commits into
base: develop
Choose a base branch
from
  •  
  •  
  •  
25 changes: 14 additions & 11 deletions radix-clis/src/resim/cmd_publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,24 @@ impl Publish {
let original_code = PackageCodeOriginalCode { code };
let instrumented_code = PackageCodeInstrumentedCode { instrumented_code };
{
let key =
SpreadPrefixKeyMapper::map_to_db_sort_key(&scrypto_encode(&code_hash).unwrap());
let key = SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode_to_payload(&code_hash).unwrap(),
);
let update =
DatabaseUpdate::Set(scrypto_encode(&vm_type.into_locked_substate()).unwrap());
vm_type_updates.insert(key, update);

let key =
SpreadPrefixKeyMapper::map_to_db_sort_key(&scrypto_encode(&code_hash).unwrap());
let key = SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode_to_payload(&code_hash).unwrap(),
);
let update = DatabaseUpdate::Set(
scrypto_encode(&original_code.into_locked_substate()).unwrap(),
);
original_code_updates.insert(key, update);

let key =
SpreadPrefixKeyMapper::map_to_db_sort_key(&scrypto_encode(&code_hash).unwrap());
let key = SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode_to_payload(&code_hash).unwrap(),
);
let update = DatabaseUpdate::Set(
scrypto_encode(&instrumented_code.into_locked_substate()).unwrap(),
);
Expand All @@ -190,7 +193,7 @@ impl Publish {
let schema_hash = blueprint_schema.schema.generate_schema_hash();
schema_updates.insert(
SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode(&schema_hash).unwrap(),
&scrypto_encode_to_payload(&schema_hash).unwrap(),
),
DatabaseUpdate::Set(
scrypto_encode(&blueprint_schema.schema.into_locked_substate()).unwrap(),
Expand Down Expand Up @@ -264,13 +267,13 @@ impl Publish {
};
blueprint_updates.insert(
SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode(&blueprint_version_key.clone()).unwrap(),
&scrypto_encode_to_payload(&blueprint_version_key.clone()).unwrap(),
),
DatabaseUpdate::Set(scrypto_encode(&def.into_locked_substate()).unwrap()),
);
dependency_updates.insert(
SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode(&blueprint_version_key.clone()).unwrap(),
&scrypto_encode_to_payload(&blueprint_version_key.clone()).unwrap(),
),
DatabaseUpdate::Set(
scrypto_encode(
Expand All @@ -284,7 +287,7 @@ impl Publish {
);
auth_config_updates.insert(
SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode(&blueprint_version_key.clone()).unwrap(),
&scrypto_encode_to_payload(&blueprint_version_key.clone()).unwrap(),
),
DatabaseUpdate::Set(
scrypto_encode(&blueprint_definition.auth_config.into_locked_substate())
Expand All @@ -293,7 +296,7 @@ impl Publish {
);
royalty_config_updates.insert(
SpreadPrefixKeyMapper::map_to_db_sort_key(
&scrypto_encode(&blueprint_version_key.clone()).unwrap(),
&scrypto_encode_to_payload(&blueprint_version_key.clone()).unwrap(),
),
DatabaseUpdate::Set(
scrypto_encode(&blueprint_definition.royalty_config.into_locked_substate())
Expand Down
5 changes: 2 additions & 3 deletions radix-clis/src/resim/dumper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,8 @@ fn get_entity_metadata<T: SubstateDatabase>(
)
.unwrap()
.map(|(key, value)| {
let map_key = key.into_map();
let key = scrypto_decode::<String>(&map_key).unwrap();
let value = scrypto_decode::<MetadataEntryEntryPayload>(&value).unwrap();
let key: String = key.into_map().decode_as().unwrap();
let value: MetadataEntryEntryPayload = value.decode_as().unwrap();
(key, value.fully_update_and_into_latest_version())
})
.collect()
Expand Down
14 changes: 4 additions & 10 deletions radix-common/benches/schema.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use criterion::{criterion_group, criterion_main, Criterion};
use radix_common::data::scrypto::{scrypto_encode, ScryptoCustomExtension, ScryptoCustomSchema};
use radix_common::prelude::SCRYPTO_SBOR_V1_MAX_DEPTH;
use radix_common::data::scrypto::*;
use radix_common::*;
use sbor::rust::prelude::*;
use sbor::*;
Expand Down Expand Up @@ -49,18 +48,13 @@ pub fn get_simple_dataset(repeat: usize) -> SimpleStruct {
const REPEAT: usize = 1000;

fn bench_schema_new(b: &mut Criterion) {
let bytes = scrypto_encode(&get_simple_dataset(REPEAT)).unwrap();
let payload = scrypto_encode_to_payload(&get_simple_dataset(REPEAT)).unwrap();
let validation_context = ();
let (type_id, schema) =
generate_full_schema_from_single_type::<SimpleStruct, ScryptoCustomSchema>();
b.bench_function("schema::validate_payload", |b| {
b.iter(|| {
let result = validate_payload_against_schema::<ScryptoCustomExtension, _>(
&bytes,
schema.v1(),
type_id,
&(),
SCRYPTO_SBOR_V1_MAX_DEPTH,
);
let result = payload.validate_against_type(schema.v1(), type_id, &validation_context);
assert!(result.is_ok())
})
});
Expand Down
1 change: 1 addition & 0 deletions radix-common/src/data/manifest/custom_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub enum ManifestCustomExtension {}

impl CustomExtension for ManifestCustomExtension {
const PAYLOAD_PREFIX: u8 = MANIFEST_SBOR_V1_PAYLOAD_PREFIX;
const DEFAULT_DEPTH_LIMIT: usize = MANIFEST_SBOR_V1_MAX_DEPTH;

type CustomValueKind = ManifestCustomValueKind;
type CustomTraversal = ManifestCustomTraversal;
Expand Down
2 changes: 1 addition & 1 deletion radix-common/src/data/manifest/custom_formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ mod tests {

let context = ManifestValueDisplayContext::with_optional_bech32(Some(&encoder));

let payload = ManifestRawPayload::new_from_valid_owned(payload);
let payload = ManifestRawPayload::from_valid_payload(payload);

let actual_rustlike = payload.to_string(ValueDisplayParameters::Schemaless {
display_mode: DisplayMode::RustLike,
Expand Down
4 changes: 2 additions & 2 deletions radix-common/src/data/manifest/custom_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ mod tests {
let payload = manifest_encode(&value).unwrap();

assert_json_eq(
ManifestRawPayload::new_from_valid_slice(&payload).serializable(
ManifestRawPayload::from_valid_payload_slice(&payload).serializable(
SerializationParameters::Schemaless {
mode: SerializationMode::Natural,
custom_context: context.into(),
Expand All @@ -320,7 +320,7 @@ mod tests {
let payload = manifest_encode(&value).unwrap();

assert_json_eq(
ManifestRawPayload::new_from_valid_slice(&payload).serializable(
ManifestRawPayload::from_valid_payload_slice(&payload).serializable(
SerializationParameters::Schemaless {
mode: SerializationMode::Programmatic,
custom_context: context.into(),
Expand Down
38 changes: 10 additions & 28 deletions radix-common/src/data/manifest/custom_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ mod tests {

#[test]
fn valid_manifest_composite_value_passes_validation_against_radix_blueprint_schema_init() {
let payload = manifest_encode(&(
let payload = manifest_encode_to_payload(&(
ManifestValue::Custom {
value: ManifestCustomValue::Address(ManifestAddress::Static(
XRD.as_node_id().clone(),
Expand Down Expand Up @@ -312,20 +312,14 @@ mod tests {
let (type_id, schema) =
generate_full_schema_from_single_type::<MyScryptoTuple, ScryptoCustomSchema>();

let result = validate_payload_against_schema::<ManifestCustomExtension, _>(
&payload,
schema.v1(),
type_id,
&(),
MANIFEST_SBOR_V1_MAX_DEPTH,
);
let result = payload.validate_against_type(schema.v1(), type_id, &());

result.expect("Validation check failed");
}

#[test]
fn manifest_address_fails_validation_against_mismatching_radix_blueprint_schema_init() {
let payload = manifest_encode(&ManifestValue::Custom {
let payload = manifest_encode_to_payload(&ManifestValue::Custom {
value: ManifestCustomValue::Address(ManifestAddress::Static(XRD.as_node_id().clone())),
})
.unwrap();
Expand All @@ -339,7 +333,7 @@ mod tests {

#[test]
fn manifest_blob_fails_validation_against_mismatching_radix_blueprint_schema_init() {
let payload = manifest_encode(&ManifestValue::Custom {
let payload = manifest_encode_to_payload(&ManifestValue::Custom {
value: ManifestCustomValue::Blob(ManifestBlobRef([0; 32])),
})
.unwrap();
Expand All @@ -355,7 +349,7 @@ mod tests {
#[test]
fn manifest_entire_worktop_expression_fails_validation_against_mismatching_radix_blueprint_schema_init(
) {
let payload = manifest_encode(&ManifestValue::Custom {
let payload = manifest_encode_to_payload(&ManifestValue::Custom {
value: ManifestCustomValue::Expression(ManifestExpression::EntireWorktop),
})
.unwrap();
Expand All @@ -371,7 +365,7 @@ mod tests {
#[test]
fn manifest_entire_auth_zone_expression_fails_validation_against_mismatching_radix_blueprint_schema_init(
) {
let payload = manifest_encode(&ManifestValue::Custom {
let payload = manifest_encode_to_payload(&ManifestValue::Custom {
value: ManifestCustomValue::Expression(ManifestExpression::EntireAuthZone),
})
.unwrap();
Expand All @@ -384,30 +378,18 @@ mod tests {
expect_does_not_match::<u8>(&payload);
}

fn expect_matches<T: ScryptoDescribe>(payload: &[u8]) {
fn expect_matches<T: ScryptoDescribe>(payload: &ManifestOwnedRawPayload) {
let (type_id, schema) = generate_full_schema_from_single_type::<T, ScryptoCustomSchema>();

let result = validate_payload_against_schema::<ManifestCustomExtension, _>(
&payload,
schema.v1(),
type_id,
&(),
MANIFEST_SBOR_V1_MAX_DEPTH,
);
let result = payload.validate_against_type(schema.v1(), type_id, &());

result.expect("Expected validation to succeed");
}

fn expect_does_not_match<T: ScryptoDescribe>(payload: &[u8]) {
fn expect_does_not_match<T: ScryptoDescribe>(payload: &ManifestOwnedRawPayload) {
let (type_id, schema) = generate_full_schema_from_single_type::<T, ScryptoCustomSchema>();

let result = validate_payload_against_schema::<ManifestCustomExtension, _>(
&payload,
schema.v1(),
type_id,
&(),
MANIFEST_SBOR_V1_MAX_DEPTH,
);
let result = payload.validate_against_type(schema.v1(), type_id, &());

matches!(
result,
Expand Down
16 changes: 16 additions & 0 deletions radix-common/src/data/manifest/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,22 @@ pub fn manifest_encode<T: ManifestEncode + ?Sized>(value: &T) -> Result<Vec<u8>,
manifest_encode_with_depth_limit(value, MANIFEST_SBOR_V1_MAX_DEPTH)
}

pub fn manifest_encode_to_payload<T: ManifestEncode + ?Sized>(
value: &T,
) -> Result<ManifestOwnedRawPayload, EncodeError> {
Ok(ManifestOwnedRawPayload::from_valid_payload(
manifest_encode(value)?,
))
}

pub fn manifest_encode_to_value<T: ManifestEncode + ?Sized>(
value: &T,
) -> Result<ManifestOwnedRawValue, EncodeError> {
Ok(ManifestOwnedRawValue::from_valid_payload(manifest_encode(
value,
)?))
}

pub fn manifest_encode_with_depth_limit<T: ManifestEncode + ?Sized>(
value: &T,
depth_limit: usize,
Expand Down
1 change: 1 addition & 0 deletions radix-common/src/data/scrypto/custom_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub struct ScryptoCustomExtension {}

impl CustomExtension for ScryptoCustomExtension {
const PAYLOAD_PREFIX: u8 = SCRYPTO_SBOR_V1_PAYLOAD_PREFIX;
const DEFAULT_DEPTH_LIMIT: usize = SCRYPTO_SBOR_V1_MAX_DEPTH;

type CustomValueKind = ScryptoCustomValueKind;
type CustomTraversal = ScryptoCustomTraversal;
Expand Down
2 changes: 1 addition & 1 deletion radix-common/src/data/scrypto/custom_formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ mod tests {

let context = ScryptoValueDisplayContext::with_optional_bech32(Some(&encoder));

let payload = ScryptoRawPayload::new_from_valid_owned(scrypto_encode(&value).unwrap());
let payload = ScryptoRawPayload::from_valid_payload(scrypto_encode(&value).unwrap());

let actual_rustlike = payload.to_string(ValueDisplayParameters::Schemaless {
display_mode: DisplayMode::RustLike,
Expand Down
4 changes: 4 additions & 0 deletions radix-common/src/data/scrypto/custom_payload_wrappers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::internal_prelude::*;

pub type ScryptoRawPayload<'a> = RawPayload<'a, ScryptoCustomExtension>;
pub type ScryptoUnvalidatedRawPayload<'a> = UnvalidatedRawPayload<'a, ScryptoCustomExtension>;
pub type ScryptoOwnedRawPayload = RawPayload<'static, ScryptoCustomExtension>;
pub type ScryptoUnvalidatedOwnedRawPayload = UnvalidatedRawPayload<'static, ScryptoCustomExtension>;
pub type ScryptoRawValue<'a> = RawValue<'a, ScryptoCustomExtension>;
pub type ScryptoUnvalidatedRawValue<'a> = UnvalidatedRawValue<'a, ScryptoCustomExtension>;
pub type ScryptoOwnedRawValue = RawValue<'static, ScryptoCustomExtension>;
pub type ScryptoUnvalidatedOwnedRawValue = UnvalidatedRawValue<'static, ScryptoCustomExtension>;
4 changes: 2 additions & 2 deletions radix-common/src/data/scrypto/custom_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ mod tests {
let payload = scrypto_encode(&value).unwrap();

assert_json_eq(
ScryptoRawPayload::new_from_valid_slice(&payload).serializable(
ScryptoRawPayload::from_valid_payload_slice(&payload).serializable(
SerializationParameters::Schemaless {
mode: SerializationMode::Natural,
custom_context: context.into(),
Expand All @@ -271,7 +271,7 @@ mod tests {
let payload = scrypto_encode(&value).unwrap();

assert_json_eq(
ScryptoRawPayload::new_from_valid_slice(&payload).serializable(
ScryptoRawPayload::from_valid_payload_slice(&payload).serializable(
SerializationParameters::Schemaless {
mode: SerializationMode::Programmatic,
custom_context: context.into(),
Expand Down
18 changes: 8 additions & 10 deletions radix-common/src/data/scrypto/custom_well_known_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,16 +648,14 @@ mod tests {
fn test_statically_valid<T: ScryptoEncode>(id: WellKnownTypeId, value: T) {
let type_name = core::any::type_name::<T>();

validate_payload_against_schema::<ScryptoCustomExtension, _>(
&scrypto_encode(&value).unwrap(),
&ScryptoCustomSchema::empty_schema(),
id.into(),
&(),
10,
)
.unwrap_or_else(|err| {
panic!("Expected value for {type_name} to match well known type but got: {err:?}")
});
let schema = ScryptoCustomSchema::empty_schema();
let context = ();
scrypto_encode_to_payload(&value)
.unwrap()
.validate_against_type(&schema, id.into(), &context)
.unwrap_or_else(|err| {
panic!("Expected value for {type_name} to match well known type but got: {err:?}")
});
}

fn test_type_data_equivalent<T: ScryptoDescribe>(id: WellKnownTypeId) {
Expand Down
20 changes: 18 additions & 2 deletions radix-common/src/data/scrypto/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ pub type ScryptoDecoder<'a> = VecDecoder<'a, ScryptoCustomValueKind>;
pub type ScryptoTraverser<'a> = VecTraverser<'a, ScryptoCustomTraversal>;
pub type ScryptoValueKind = ValueKind<ScryptoCustomValueKind>;
pub type ScryptoValue = Value<ScryptoCustomValueKind, ScryptoCustomValue>;
pub type RawScryptoValue<'a> = RawValue<'a, ScryptoCustomExtension>;
pub type RawScryptoPayload<'a> = RawPayload<'a, ScryptoCustomExtension>;
// NOTE: ScryptoRawValue, ScryptoOwnedRawValue, ScryptoRawPayload, ScryptoOwnedRawPayload
// are defined in another file

// The following trait "aliases" are to be used in parameters.
//
Expand Down Expand Up @@ -50,6 +50,22 @@ pub fn scrypto_encode<T: ScryptoEncode + ?Sized>(value: &T) -> Result<Vec<u8>, E
scrypto_encode_with_depth_limit(value, SCRYPTO_SBOR_V1_MAX_DEPTH)
}

pub fn scrypto_encode_to_payload<T: ScryptoEncode + ?Sized>(
value: &T,
) -> Result<ScryptoOwnedRawPayload, EncodeError> {
Ok(ScryptoOwnedRawPayload::from_valid_payload(scrypto_encode(
value,
)?))
}

pub fn scrypto_encode_to_value<T: ScryptoEncode + ?Sized>(
value: &T,
) -> Result<ScryptoOwnedRawValue, EncodeError> {
Ok(ScryptoOwnedRawValue::from_valid_payload(scrypto_encode(
value,
)?))
}

pub fn scrypto_encode_with_depth_limit<T: ScryptoEncode + ?Sized>(
value: &T,
depth_limit: usize,
Expand Down
4 changes: 0 additions & 4 deletions radix-common/src/data/scrypto/model/non_fungible_local_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,6 @@ impl NonFungibleLocalId {
pub const fn ruid(value: [u8; 32]) -> Self {
Self::RUID(RUIDNonFungibleLocalId(value))
}

pub fn to_key(&self) -> Vec<u8> {
scrypto_encode(self).expect("Failed to encode non-fungible local id")
}
}

/// The implementation of const constructors for the non-fungible local id.
Expand Down
4 changes: 2 additions & 2 deletions radix-common/src/math/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use super::CheckedTruncate;
/// The finite set of values are of the form `m / 10^18`, where `m` is
/// an integer such that `-2^(192 - 1) <= m < 2^(192 - 1)`.
///
/// Fractional part: ~60 bits/18 digits
/// Integer part : 132 bits /40 digits
/// Fractional part: ~60 bits / 18 digits
/// Integer part : ~132 bits / ~40 digits
/// Max : 3138550867693340381917894711603833208051.177722232017256447
/// Min : -3138550867693340381917894711603833208051.177722232017256448
///
Expand Down
Loading
Loading