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/nullification costing #1949

Merged
merged 7 commits into from
Oct 8, 2024
Merged

Conversation

iamyulong
Copy link
Member

Summary

Add deferred costing for nullifications.

Copy link

github-actions bot commented Oct 7, 2024

Phylum Report Link

Copy link

github-actions bot commented Oct 7, 2024

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

Copy link

github-actions bot commented Oct 7, 2024

Benchmark for 32ffece

Click to view benchmark
Test Base PR %
costing::bench_prepare_wasm 46.3±0.10ms 45.6±0.10ms -1.51%
costing::decode_encoded_i8_array_to_manifest_raw_value 19.1±0.05ms 19.0±0.05ms -0.52%
costing::decode_encoded_i8_array_to_manifest_value 42.3±0.03ms 42.5±0.07ms +0.47%
costing::decode_encoded_tuple_array_to_manifest_raw_value 69.6±0.10ms 71.1±0.21ms +2.16%
costing::decode_encoded_tuple_array_to_manifest_value 98.9±0.16ms 98.3±0.18ms -0.61%
costing::decode_encoded_u8_array_to_manifest_raw_value 32.1±0.09µs 32.5±0.07µs +1.25%
costing::decode_encoded_u8_array_to_manifest_value 42.3±0.05ms 42.5±0.04ms +0.47%
costing::decode_rpd_to_manifest_raw_value 14.6±0.03µs 14.2±0.06µs -2.74%
costing::decode_rpd_to_manifest_value 11.0±0.04µs 10.7±0.02µs -2.73%
costing::deserialize_wasm 1287.6±4.66µs 1261.6±5.80µs -2.02%
costing::execute_transaction_creating_big_vec_substates 691.9±6.26ms 709.0±9.09ms +2.47%
costing::execute_transaction_reading_big_vec_substates 573.1±0.40ms 586.1±1.63ms +2.27%
costing::instantiate_flash_loan 1003.0±1374.15µs 963.9±904.58µs -3.90%
costing::instantiate_radiswap 1098.2±1505.59µs 992.3±1261.35µs -9.64%
costing::spin_loop 21.9±0.04ms 23.3±0.20ms +6.39%
costing::validate_sbor_payload 32.2±0.08µs 27.7±0.04µs -13.98%
costing::validate_sbor_payload_bytes 256.1±0.69ns 205.7±1.21ns -19.68%
costing::validate_secp256k1 76.7±0.05µs 77.0±0.19µs +0.39%
costing::validate_wasm 34.0±0.05ms 33.9±0.05ms -0.29%
decimal::add/0 8.4±0.00ns 8.4±0.00ns 0.00%
decimal::add/rust-native 9.9±0.01ns 9.9±0.01ns 0.00%
decimal::add/wasmi 218.7±0.56ns 223.8±0.33ns +2.33%
decimal::add/wasmi-call-native 2.0±0.00µs 2.2±0.00µs +10.00%
decimal::div/0 188.0±0.31ns 186.6±0.10ns -0.74%
decimal::from_string/0 153.4±0.09ns 152.9±0.09ns -0.33%
decimal::mul/0 154.2±0.07ns 149.0±0.13ns -3.37%
decimal::mul/rust-native 148.6±0.17ns 147.5±0.10ns -0.74%
decimal::mul/wasmi 11.7±0.03µs 11.8±0.02µs +0.85%
decimal::mul/wasmi-call-native 2.3±0.01µs 2.3±0.01µs 0.00%
decimal::pow/0 690.4±0.42ns 691.3±1.16ns +0.13%
decimal::pow/rust-native 677.9±0.34ns 679.1±0.77ns +0.18%
decimal::pow/wasmi 58.6±0.41µs 57.5±0.30µs -1.88%
decimal::pow/wasmi-call-native 3.4±0.00µs 3.4±0.00µs 0.00%
decimal::root/0 8.1±0.01µs 8.2±0.01µs +1.23%
decimal::sub/0 9.1±0.00ns 9.0±0.28ns -1.10%
decimal::to_string/0 456.9±2.26ns 449.9±1.61ns -1.53%
large_transaction_processing::prepare 2.6±0.00ms 2.6±0.00ms 0.00%
large_transaction_processing::prepare_and_decompile 7.0±0.06ms 7.0±0.04ms 0.00%
large_transaction_processing::prepare_and_decompile_and_recompile 32.5±0.07ms 31.7±1.51ms -2.46%
precise_decimal::add/0 8.8±0.03ns 9.1±0.01ns +3.41%
precise_decimal::add/rust-native 10.8±0.04ns 10.7±0.04ns -0.93%
precise_decimal::add/wasmi 268.3±1.06ns 270.6±0.91ns +0.86%
precise_decimal::add/wasmi-call-native 2.7±0.01µs 2.9±0.04µs +7.41%
precise_decimal::div/0 316.0±0.20ns 319.2±1.35ns +1.01%
precise_decimal::from_string/0 203.8±0.79ns 203.0±0.52ns -0.39%
precise_decimal::mul/0 362.5±0.21ns 364.6±0.60ns +0.58%
precise_decimal::mul/rust-native 329.6±1.93ns 337.8±2.32ns +2.49%
precise_decimal::mul/wasmi 34.8±0.40µs 34.4±0.15µs -1.15%
precise_decimal::mul/wasmi-call-native 3.1±0.00µs 3.2±0.00µs +3.23%
precise_decimal::pow/0 1960.8±7.98ns 1965.0±3.85ns +0.21%
precise_decimal::pow/rust-native 1535.5±1.74ns 1534.7±1.54ns -0.05%
precise_decimal::pow/wasmi 164.9±0.44µs 168.6±0.62µs +2.24%
precise_decimal::pow/wasmi-call-native 5.7±0.02µs 5.8±0.00µs +1.75%
precise_decimal::root/0 58.0±0.04µs 58.4±0.01µs +0.69%
precise_decimal::sub/0 8.9±0.08ns 9.2±0.02ns +3.37%
precise_decimal::to_string/0 704.1±1.24ns 698.6±0.80ns -0.78%
schema::validate_payload 365.8±1.22µs 366.6±1.54µs +0.22%
transaction::radiswap 5.2±0.03ms 5.2±0.02ms 0.00%
transaction::transfer 1870.1±2.55µs 1868.6±3.28µs -0.08%
transaction_validation::validate_manifest 43.1±0.06µs 43.0±0.03µs -0.23%
transaction_validation::verify_bls_2KB 1031.0±30.37µs 1006.3±14.75µs -2.40%
transaction_validation::verify_bls_32B 1036.4±35.80µs 1003.9±10.98µs -3.14%
transaction_validation::verify_ecdsa 74.6±0.10µs 74.6±0.07µs 0.00%
transaction_validation::verify_ed25519 42.0±0.11µs 42.2±0.19µs +0.48%

Copy link
Contributor

@dhedey dhedey left a comment

Choose a reason for hiding this comment

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

Nice! A few thoughts/suggestions

.and_then(|_| {
match hash_nullification {
IntentHashNullification::TransactionIntent { .. } => {
// Transaction intent nullification is historically not costed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we clarify that it's nominally included in the base fee?

Copy link
Member Author

Choose a reason for hiding this comment

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

There is no base fee, but tx_payload_cost fee which is proportional to payload size.

// The size of a typical transfer transaction is 400 bytes, and the cost will be 400 * 40 = 16,000 cost units
// The max size of a transaction is 1 MiB, and the cost will be 1,048,576 * 40 = 41,943,040 cost units
// This is roughly 1/24 of storing data in substate store per current setup.
mul(cast(size), 40)

Copy link
Contributor

@dhedey dhedey Oct 7, 2024

Choose a reason for hiding this comment

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

Oh! I thought there was a base fee. Interesting. Perhaps we should add one at Cuttlefish to account for the ident? Or just bill for TransactionIntent nullification from Cuttlefish? (switching on the system logic version)

Copy link
Member Author

@iamyulong iamyulong Oct 7, 2024

Choose a reason for hiding this comment

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

We have various uncosted substate reads (such as systemboot, vmboot, kernelboot).

Per the comment above, the minimum transaction cost units is about 16,000, which is just enough to cover one ReadFromDBNotFound (which is much more expensive than ReadFromDB).

I think we can live with this for now, OR introduce a larger base.

Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about the system logic tweak to also bill for transaction intent reads? Would be quite straightforward I imagine?

Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps we should add one at Cuttlefish to account for the ident

At execution time, we can't tell if it's v1 or v2.

If we start charging for transaction intent from cuttlefish, fees for all transaction will be increased, which has a user impact. Not too sure about if it's worth to do it now.

Copy link
Contributor

@dhedey dhedey Oct 8, 2024

Choose a reason for hiding this comment

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

We're in system here, right?

We have access to the version number either from version state (current) or from a generic (if we merge #1919 ).

If we start charging for transaction intent from cuttlefish, fees for all transaction will be increased, which has a user impact. Not too sure about if it's worth to do it now.

It will, but not by much I imagine?

Copy link
Member Author

Choose a reason for hiding this comment

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

We can expose such information to the system.

It's more about "if it's good to have a discrepancy between v1 and v2".

Copy link
Member Author

Choose a reason for hiding this comment

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

It will, but not by much I imagine?

It's about 16,000.

radix-engine/src/system/system_callback.rs Outdated Show resolved Hide resolved
radix-engine/src/system/system_callback.rs Outdated Show resolved Hide resolved
radix-engine/src/system/system_callback.rs Show resolved Hide resolved
@@ -290,6 +295,9 @@ pub mod owned {
RefCheck {
event: RefCheckEventOwned,
},
Nullification {
io_access: Vec<IOAccess>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Naively, I'd have expected this to be split between execution cost for the read, and finalization cost for the write?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also I wonder if we should use more intuitive names here, for the purpose of the receipt? (because "Nullification" is not really a common name in crypto/literature, even if we're using it internally)

  • ExecutionCostingEntry::CheckIntentValidity
  • FinalizationCostingEntry::RecordIntentCommits

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds reasonable to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

FinalizationCostingEntry::RecordIntentCommits is actually covered by FinalizationCostingEntry::CommitStateUpdates

Copy link
Contributor

@dhedey dhedey Oct 7, 2024

Choose a reason for hiding this comment

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

Are you sure? When I looked at the code, I thought I saw that finalisation of the state updates (i.e. CommitStateUpdates) was calculated from the state changes before the intent state changes were added (which happens at receipt creation time after finalization, because it needs to be after the result is decided), so I don’t believe the cost of the state updates was captured. This is why I suggested separating them explicitly

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right! I don't know what I was thinking. Let me add it explicitly.

And looks like we don't need to defer this cost, but apply at finalization time. If it fails, there is no commit anyway. Even fairer to users.

Copy link
Contributor

@dhedey dhedey Oct 8, 2024

Choose a reason for hiding this comment

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

Sounds good.

And if we (ever) add billing for non-contingent intents (currently just transaction intents), these should possibly be billed up front/deferred.

@iamyulong iamyulong force-pushed the feature/nullification-costing branch from bc95310 to 31bd7d9 Compare October 7, 2024 20:00
@iamyulong iamyulong force-pushed the feature/nullification-costing branch from 42ddd8b to ef4aa5e Compare October 8, 2024 08:16
@iamyulong
Copy link
Member Author

Merging this PR.

The only pending question is "if we want to apply costing for the transaction intent hash status, and whether it's for v2 only OR v1 + v2", which can be addressed separately.

@iamyulong iamyulong merged commit 065e7a9 into develop Oct 8, 2024
31 checks passed
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.

2 participants