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

Feature/schema comparisons #1836

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
Open

Feature/schema comparisons #1836

wants to merge 13 commits into from

Conversation

dhedey
Copy link
Contributor

@dhedey dhedey commented Jun 25, 2024

Summary

Part 1 of implementing schema comparisons REP (the underlying tooling). Part 2 with the macros and implementing on various types will follow in another PR (EDIT: #1848 )

PR splits into two parts:

  • Various SBOR improvements:
    • To improve code quality / correctness / error messages in the traverser
    • To add scrypto_decode_with_nice_error and manifest_decode_with_nice_error
  • Adding of the schema_comparison tooling
  • Various type-hell neatenings
    • Swaps CustomSchema::CustomTypeKind<L> for explicit CustomSchema::CustomLocalTypeKind and CustomSchema::AggregatorLocalTypeKind which simplifies a lot
    • Introduces some aliases to make using these types much less boilerplatey
    • Adds a CustomSchema::DefaultCustomExtension which we can use for encoding/decoding the schemas, which allows us to remove lots of really ugly/confusing bounds around the specific extension which we use for schema comparison, allowing us to just talk in terms of CustomSchema - because the schemas now know how to encode/decode themselves against the default extension. The default extension for ScryptoCustomSchema is now ScryptoExtension (chosen over ManifestExtension for sanity).

I'd recommend review commit-by-commit.

Details

Like the REP, the Schema comparison tooling operates over:

  • A named, ordered lists of a SingleTypeSchema or a NamedTypesSchema (for a composite schema) - representing supported versions of the type.
  • A "current" SingleTypeSchema or NamedTypesSchema.
  • Some comparison setting which compares schema N to schema N + 1

The backwards compatibility tooling ensures that the current schema is equal to the latest named version ; and ensures sequential labelled versions are backwards compatible. Any failure outputs nice errors when it detects incompatibilities.

In separate news, the new recommended aliases are:

pub type LocalTypeKind<S> = TypeKind<<S as CustomSchema>::CustomLocalTypeKind, LocalTypeId>;
pub type AggregatorTypeKind<S> =
    TypeKind<<S as CustomSchema>::CustomAggregatorTypeKind, RustTypeId>;

pub type LocalTypeData<S> = TypeData<<S as CustomSchema>::CustomLocalTypeKind, LocalTypeId>;
pub type AggregatorTypeData<S> =
    TypeData<<S as CustomSchema>::CustomAggregatorTypeKind, RustTypeId>;

Testing

The traversal changes are tested in payload_validator.rs and the schema comparison changes are tested in schema_comparison.rs in sbor-tests.

Update Recommendations

Where slowness on errors and larger compile size are okay, you can change from scrypto_decode to scrypto_decode_with_nice_error which gives much clearer errors if there is a failure. This would be useful in e.g. the node.

If you get a compile error, change:

  • CustomSchema::CustomTypeKind<LocalTypeId> to CustomSchema::CustomLocalTypeKind
  • CustomSchema::CustomTypeKind<RustTypeId> to CustomSchema::AggregatorLocalTypeKind

For Internal Integrators

Hold off integrating the schema traversal changes until there are macros in place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically generic versions of the BasicX, ScryptoX and ManifestX traits which are needed to simplify generic bounds (e.g. in schema_comparison) - where I basically need to require that a Schema is encodable/decodable in a given extension.

For example, that a ScryptoSchema = Schema<ScryptoCustomSchema> can be encoded with ValueKind<ScryptoCustomValueKind> (-- or indeed ValueKind<ManifestCustomValueKind> - because the scrypto schema is shared by both the ScryptoExtension and ManifestExtension).

Copy link

github-actions bot commented Jun 25, 2024

Docker tags
docker.io/radixdlt/private-scrypto-builder:b1b3f4c2d3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have quite a lot of changes in this file.

Mainly motivated by improving the invariants we can rely on in the code, and in particular, in the container_stack which has now officially become the ancestor_path which allows us to enforce that the current_child_index always exists.

But effectively the code now captures more clearly the fact it's a state machine, and the correctness is more obvious.

In particular, error cases are handled much better - and the state of the ancestor_path is now "correct" when outputting an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also taken a look at the benchmarks:

The new benchmark for schema::validate_payload is:

schema::validate_payload
                        time:   [392.59 µs 392.83 µs 393.17 µs]

Versus another PR:

schema::validate_payload
                        time:   [381.06 µs 381.17 µs 381.29 µs]

So I think that’s acceptable. I imagine it’s either within fluctuation or due to my no longer caching the container width.

I can add back the container width cache on the ancestor item if we want - interested to hear thoughts form reviewers.

Copy link

github-actions bot commented Jun 25, 2024

Benchmark for b1b3f4c

Click to view benchmark
Test Base PR %
costing::bench_prepare_wasm 64.9±0.16ms 66.0±0.15ms +1.69%
costing::decode_sbor 10.9±0.03µs 11.2±0.03µs +2.75%
costing::decode_sbor_bytes 29.4±0.05µs 29.2±0.09µs -0.68%
costing::deserialize_wasm 1289.7±7.22µs 1301.5±9.53µs +0.91%
costing::instantiate_flash_loan 3.6±0.07ms 3.8±0.52ms +5.56%
costing::instantiate_radiswap 5.8±0.07ms 5.6±0.05ms -3.45%
costing::spin_loop 21.5±0.05ms 21.4±0.03ms -0.47%
costing::validate_sbor_payload 27.9±0.07µs 26.4±0.06µs -5.38%
costing::validate_sbor_payload_bytes 248.1±0.67ns 203.6±0.54ns -17.94%
costing::validate_secp256k1 76.2±0.12µs 76.2±0.10µs 0.00%
costing::validate_wasm 36.3±0.06ms 37.0±0.07ms +1.93%
decimal::add/0 8.4±0.00ns 8.4±0.00ns 0.00%
decimal::add/rust-native 9.8±0.00ns 9.8±0.00ns 0.00%
decimal::add/wasmer 114.2±0.10ns 116.3±0.22ns +1.84%
decimal::add/wasmer-call-native 449.3±3.47ns 446.0±0.45ns -0.73%
decimal::add/wasmi 615.9±9.24ns 631.8±3.58ns +2.58%
decimal::add/wasmi-call-native 5.2±0.01µs 4.9±0.01µs -5.77%
decimal::div/0 191.2±0.27ns 191.7±0.14ns +0.26%
decimal::from_string/0 154.2±0.23ns 161.9±0.34ns +4.99%
decimal::mul/0 141.6±0.29ns 143.3±0.04ns +1.20%
decimal::mul/rust-native 138.3±0.17ns 138.9±0.07ns +0.43%
decimal::mul/wasmer 1506.9±0.72ns 1529.9±1.41ns +1.53%
decimal::mul/wasmer-call-native 575.4±0.57ns 578.2±0.81ns +0.49%
decimal::mul/wasmi 41.3±0.08µs 40.2±0.07µs -2.66%
decimal::mul/wasmi-call-native 5.3±0.01µs 5.1±0.01µs -3.77%
decimal::pow/0 651.9±0.61ns 650.7±1.49ns -0.18%
decimal::pow/rust-native 629.9±1.72ns 635.0±2.05ns +0.81%
decimal::pow/wasmer 6.6±0.00µs 6.6±0.01µs 0.00%
decimal::pow/wasmer-call-native 1016.5±0.71ns 1020.7±0.61ns +0.41%
decimal::pow/wasmi 197.0±0.25µs 190.8±0.53µs -3.15%
decimal::pow/wasmi-call-native 5.2±0.01µs 5.1±0.01µs -1.92%
decimal::root/0 8.0±0.01µs 8.2±0.01µs +2.50%
decimal::sub/0 8.5±0.01ns 8.5±0.01ns 0.00%
decimal::to_string/0 476.8±1.87ns 465.7±0.52ns -2.33%
precise_decimal::add/0 9.5±0.00ns 9.3±0.01ns -2.11%
precise_decimal::add/rust-native 11.4±0.00ns 11.4±0.00ns 0.00%
precise_decimal::add/wasmer 127.2±0.05ns 128.2±0.91ns +0.79%
precise_decimal::add/wasmer-call-native 507.3±0.77ns 513.9±2.25ns +1.30%
precise_decimal::add/wasmi 769.7±2.84ns 773.7±7.66ns +0.52%
precise_decimal::add/wasmi-call-native 6.5±0.01µs 6.4±0.03µs -1.54%
precise_decimal::div/0 314.6±3.94ns 300.7±0.48ns -4.42%
precise_decimal::from_string/0 199.8±0.22ns 199.2±0.43ns -0.30%
precise_decimal::mul/0 368.7±1.82ns 345.7±0.34ns -6.24%
precise_decimal::mul/rust-native 304.7±0.43ns 302.4±0.20ns -0.75%
precise_decimal::mul/wasmer 3.5±0.01µs 3.5±0.00µs 0.00%
precise_decimal::mul/wasmer-call-native 859.9±3.89ns 828.6±1.69ns -3.64%
precise_decimal::mul/wasmi 108.4±1.19µs 104.8±0.26µs -3.32%
precise_decimal::mul/wasmi-call-native 7.0±0.04µs 6.8±0.01µs -2.86%
precise_decimal::pow/0 1873.2±10.98ns 1847.4±2.76ns -1.38%
precise_decimal::pow/rust-native 1448.8±4.81ns 1450.5±3.31ns +0.12%
precise_decimal::pow/wasmer 16.3±0.00µs 16.6±0.01µs +1.84%
precise_decimal::pow/wasmer-call-native 2.1±0.00µs 2.1±0.00µs 0.00%
precise_decimal::pow/wasmi 512.0±0.65µs 508.0±1.04µs -0.78%
precise_decimal::pow/wasmi-call-native 13.1±0.05µs 12.7±0.03µs -3.05%
precise_decimal::root/0 57.4±0.08µs 58.2±0.02µs +1.39%
precise_decimal::sub/0 9.5±0.01ns 9.5±0.01ns 0.00%
precise_decimal::to_string/0 739.5±1.32ns 722.4±0.67ns -2.31%
schema::validate_payload 344.0±0.37µs 354.5±0.32µs +3.05%
transaction::radiswap 5.4±0.02ms 5.5±0.03ms +1.85%
transaction::transfer 1751.2±4.07µs 1800.1±3.89µs +2.79%
transaction_processing::prepare 2.2±0.00ms 2.5±0.00ms +13.64%
transaction_processing::prepare_and_decompile 6.1±0.03ms 6.7±0.05ms +9.84%
transaction_processing::prepare_and_decompile_and_recompile 25.1±1.73ms 25.1±0.86ms 0.00%
transaction_validation::validate_manifest 42.2±0.04µs 42.3±0.10µs +0.24%
transaction_validation::verify_bls_2KB 971.2±14.84µs 997.9±37.46µs +2.75%
transaction_validation::verify_bls_32B 1009.5±46.60µs 976.2±23.38µs -3.30%
transaction_validation::verify_ecdsa 74.3±0.06µs 74.2±0.08µs -0.13%
transaction_validation::verify_ed25519 54.9±0.22µs 54.6±0.09µs -0.55%

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of this type hell with the CustomExtensions is fixed in #1837

I'm interested if people feel I should split this file out into separate sub-files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants