-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
[sui-execution] Verifier trait creates and accepts Meter #16941
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Ignored Deployments
|
sui-execution/src/verifier.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file contains the main change -- everything else flows from this.
56a57d7
to
e4ed633
Compare
Some(self.max_back_edges_per_function() as usize), | ||
Some(self.max_back_edges_per_module() as usize), | ||
) | ||
} else { | ||
(None, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this sort of split? I thought we used the DummyMeter outside of signing (in which case these would be ignored?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that these configs are not part of metering, they are part of the verifier itself. I do think it's a bit incongruous that we change these verifier configs to be more restrictive during signing, but I didn't want to remove them.
Previously we were using the same Meter
whether it was signing or not, and had to pass it different parameters. This PR changes that requirement, so it highlights this incongruity a bit more. I think it's something we can definitely revisit -- it would clean things up even more.
@@ -70,7 +70,7 @@ pub(crate) fn verify<'a>( | |||
resolver: &'a BinaryIndexedView<'a>, | |||
function_view: &FunctionView, | |||
name_def_map: &'a HashMap<IdentifierIndex, FunctionDefinitionIndex>, | |||
meter: &mut impl Meter, | |||
meter: &mut (impl Meter + ?Sized), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to change the declaration of Meter
to something like trait Meter: ?Sized
to reduce the number of changes here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly not -- I tried that, but it is not allowed: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b43a8efd102d9c894f66a9293040d04f
@@ -71,7 +71,7 @@ fn test_max_number_of_bytecode() { | |||
let module = dummy_procedure_module(nops); | |||
|
|||
let result = | |||
CodeUnitVerifier::verify_module(&VerifierConfig::unbounded(), &module, &mut DummyMeter); | |||
CodeUnitVerifier::verify_module(&VerifierConfig::default(), &module, &mut DummyMeter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did a lot of these change from unbounded to default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously the config for the meter and for the verifier were coupled, and the only difference between VerifierConfig::unbounded
and VerifierConfig::default
were parameters that actually belong to the meter. By creating a separate MeterConfig
, I got rid of the distinction (the parameters were unused anyway because here we're passing in a DummyMeter
).
Supersede `Verifier::meter_compiled_modules_with_overrides` by: - Allowing `meter_compiled_modules` and `meter_compiled_bytes` to accept a custom meter. - Extracting the generation of `VerifierConfig` out to the `sui-protocol-config` crate. - Splitting up `VerifierConfig` into itself and `MeterConfig`. - Adding a `Verifier::meter` function for creating the meter that is used during signing. - Removed the meter as a field of each `Verifier`. This means that we can now pass a different meter type when we don't want to enforce metering, and no longer need to modify the config in-place to achieve the same result. To make this work, I needed to enable the use of a `&mut dyn Meter` trait object to instantiate what was previously a `&mut impl Meter` parameter everywhere. To do this, I created a forwarding trait implementation of `Meter` for `&mut dyn Meter` and added an extra relaxation of `+ ?Sized` to all the `&mut impl Meter` parameters to allow the trait object to instantiate them. This is in preparation for passing a custom meter into this new parameter when instantiated by the CLI to capture all information about scopes during metering. Today we don't do that which means: - We only report back information about the last module and function we verified. - We can incorrectly report that everything is fine, (package would pass verification) even if there was some previous module or function that exceeded the stated limits. Test Plan: ``` sui$ cargo build --bin sui sui$ cargo simtest sui$ env SUI_SKIP_SIMTESTS=1 cargo nextest run external-crates$ ./tests.sh deepbook$ cargo run --bin sui -p sui -- client verify-bytecode-meter ```
e4ed633
to
90628d9
Compare
## Description The motivation for this change is to properly track the modules being visited in the `Meter`, so that in our command line tool, we can provide an output that correctly tracks how many meter ticks were used to verify each function and module. Prior to this change, the metered verifier pretended like there was only "one module" that all the functions being verified were in. This change introduces the level of packages that ticks from modules are transferred to. We also add an explicit protocol config parameter to set a max tick limit per package (whose value is the same as the function and module level limits currently). This was not strictly necessary but was done to avoid confusion (caused by treating the module level limit as the package level limit). This should be a behaviour preserving change, but in some cases we may do more work verifying transactions because of how the ticks for each module are now gathered in isolation before being transferred to the package scope. In any case, a behaviour change would be okay, because metering (and related errors) is only used during signing, and not execution. ## Test Plan ``` sui$ cargo simtest deepbook$ cargo run --bin sui -p sui -- client verify-bytecode-meter ``` ## Stack - #16903 - #16941
…6963) ## Description Use a custom meter to track every function and module that is verified, and display all of them. ## Test Plan ``` deepbook$ cargo run --bin sui -p sui \ -- client verify-bytecode-meter \ --module build/DeepBook/bytecode_modules/math.mv ╭──────────────────────────────────────╮ │ Package will pass metering check! │ ├──────────────────────────────────────┤ │ Limits │ ├─────────────────────────┬────────────┤ │ packages │ 16,000,000 │ │ modules │ 16,000,000 │ │ functions │ 16,000,000 │ ├─────────────────────────┴────────────┤ │ Ticks Used │ ├─────────────────────────┬────────────┤ │ <unknown> │ 41,915 │ │ math │ 41,915 │ │ unsafe_mul │ 1,225 │ │ unsafe_mul_round │ 5,675 │ │ mul │ 2,410 │ │ mul_round │ 2,905 │ │ unsafe_div │ 1,225 │ │ unsafe_div_round │ 6,085 │ │ div_round │ 2,905 │ │ count_leading_zeros │ 19,485 │ ├─────────────────────────┴────────────┤ │ Package will pass metering check! │ ╰──────────────────────────────────────╯ ``` ## Stack - #16903 - #16941 - #16945 --- If your changes are not user-facing and do not break anything, you can skip the following section. Otherwise, please briefly describe what has changed under the Release Notes section. ### Type of Change (Check all that apply) - [ ] protocol change - [x] user-visible impact - [ ] breaking change for a client SDKs - [ ] breaking change for FNs (FN binary must upgrade) - [ ] breaking change for validators or node operators (must upgrade binaries) - [ ] breaking change for on-chain data layout - [ ] necessitate either a data wipe or data migration ### Release notes `sui client verify-bytecode-meter` prints a breakdown of verifier cost by module and function in a package.
When passing modules to `sui client verify-bytecode-meter`, support passing multiple `--modules` to be treated as a single package. ## Test Plan ``` deepbook$ cargo run --bin sui -p sui \ -- client verify-bytecode-meter \ --module build/DeepBook/bytecode_modules/math.mv \ --module build/DeepBook/bytecode_modules/clob.mv Running bytecode verifier for 2 modules ╭──────────────────────────────────────────────────╮ │ Package will pass metering check! │ ├──────────────────────────────────────────────────┤ │ Limits │ ├─────────────────────────────────────┬────────────┤ │ packages │ 16,000,000 │ │ modules │ 16,000,000 │ │ functions │ 16,000,000 │ ├─────────────────────────────────────┴────────────┤ │ Ticks Used │ ├─────────────────────────────────────┬────────────┤ │ <unknown> │ 1,859,140 │ │ math │ 41,915 │ │ unsafe_mul │ 1,225 │ │ unsafe_mul_round │ 5,675 │ │ mul │ 2,410 │ │ mul_round │ 2,905 │ │ unsafe_div │ 1,225 │ │ unsafe_div_round │ 6,085 │ │ div_round │ 2,905 │ │ count_leading_zeros │ 19,485 │ │ clob │ 1,817,225 │ │ destroy_empty_level │ 1,205 │ │ create_account │ 360 │ │ create_pool │ 480 │ │ deposit_base │ 5,490 │ │ deposit_quote │ 5,490 │ │ withdraw_base │ 6,500 │ │ withdraw_quote │ 6,500 │ │ swap_exact_base_for_quote │ 20,805 │ │ swap_exact_quote_for_base │ 18,590 │ │ match_bid_with_quote_quantity │ 383,275 │ │ match_bid │ 310,200 │ │ match_ask │ 316,500 │ │ place_market_order │ 37,615 │ │ inject_limit_order │ 70,195 │ │ place_limit_order │ 184,740 │ │ order_is_bid │ 540 │ │ emit_order_canceled │ 4,905 │ │ emit_order_filled │ 8,335 │ │ cancel_order │ 57,890 │ │ remove_order │ 20,095 │ │ cancel_all_orders │ 64,425 │ │ batch_cancel_order │ 102,405 │ │ list_open_orders │ 57,300 │ │ account_balance │ 6,620 │ │ get_market_price │ 3,265 │ │ get_level2_book_status_bid_side │ 39,785 │ │ get_level2_book_status_ask_side │ 39,785 │ │ get_level2_book_status │ 23,545 │ │ get_order_status │ 20,385 │ ├─────────────────────────────────────┴────────────┤ │ Package will pass metering check! │ ╰──────────────────────────────────────────────────╯ ``` ## Stack - #16903 - #16941 - #16945 - #16963 --- If your changes are not user-facing and do not break anything, you can skip the following section. Otherwise, please briefly describe what has changed under the Release Notes section. ### Type of Change (Check all that apply) - [ ] protocol change - [x] user-visible impact - [ ] breaking change for a client SDKs - [ ] breaking change for FNs (FN binary must upgrade) - [ ] breaking change for validators or node operators (must upgrade binaries) - [ ] breaking change for on-chain data layout - [ ] necessitate either a data wipe or data migration ### Release notes `sui client verify-bytecode-meter` supports passing multiple `--module` flags to verify multiple compiled modules together as if they were one package.
Description
Supersede
Verifier::meter_compiled_modules_with_overrides
by:meter_compiled_modules
andmeter_compiled_bytes
to accept a custom meter.VerifierConfig
out to thesui-protocol-config
crate.VerifierConfig
into itself andMeterConfig
.Verifier::meter
function for creating the meter that is used during signing.Verifier
.This means that we can now pass a different meter type when we don't want to enforce metering, and no longer need to modify the config in-place to achieve the same result.
To make this work, I needed to enable the use of a
&mut dyn Meter
trait object to instantiate what was previously a&mut impl Meter
parameter everywhere. To do this, I created a forwarding trait implementation ofMeter
for&mut dyn Meter
and added an extra relaxation of+ ?Sized
to all the&mut impl Meter
parameters to allow the trait object to instantiate them.This is in preparation for passing a custom meter into this new parameter when instantiated by the CLI to capture all information about scopes during metering.
Today we don't do that which means:
Test Plan
Stack