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

[compiler-v2] Lambda lifting + first steps towards a pipeline for ast trafo #12318

Merged
merged 4 commits into from
Mar 7, 2024

Conversation

wrwg
Copy link
Contributor

@wrwg wrwg commented Mar 1, 2024

This implements lambda lifting as rewrite on GlobalEnv. Lambda lifting appeared necessary for prover connection, because this is how the v1 integration works. It's not that clear any longer whether lambda lifting is really needed, but now the work is done, and we should preserve it for future general support of HOFs.

As this is now the 5th or so so transformation on the environment before the bytecode pipeline starts. to support this adequate in the test suite, there is also a first step towards an EnvProcessorPipeline, and a new submodule env-pipeline which should eventually contain those processors. For now it is just lambda lifting.

Copy link

trunk-io bot commented Mar 1, 2024

⏱️ 28h 19m total CI duration on this PR
Job Cumulative Duration Recent Runs
rust-unit-coverage 4h 37m 🟩
windows-build 4h 28m 🟩🟩🟩🟩🟩 (+9 more)
rust-unit-tests 3h 49m 🟩🟩🟩 (+8 more)
rust-move-tests 3h 40m 🟩🟩🟩 (+7 more)
rust-smoke-coverage 3h 38m 🟩
rust-move-unit-coverage 2h 31m 🟩🟩🟩 (+7 more)
rust-lints 1h 5m 🟩🟩🟩 (+8 more)
run-tests-main-branch 56m 🟩🟩🟩🟩 (+9 more)
check 48m 🟥🟩🟩 (+9 more)
rust-smoke-tests 31m 🟩
check-dynamic-deps 28m 🟩🟩🟩🟩🟩 (+9 more)
general-lints 24m 🟩🟩🟩🟩 (+8 more)
execution-performance / single-node-performance 21m 🟩
forge-compat-test / forge 15m 🟩
forge-e2e-test / forge 14m 🟩
rust-images / rust-all 13m 🟩
semgrep/ci 6m 🟩🟩🟩🟩🟩 (+9 more)
cli-e2e-tests / run-cli-tests 6m 🟩
file_change_determinator 3m 🟩🟩🟩🟩🟩 (+9 more)
file_change_determinator 2m 🟩🟩🟩🟩🟩 (+9 more)
node-api-compatibility-tests / node-api-compatibility-tests 51s 🟩
permission-check 47s 🟩🟩🟩🟩🟩 (+9 more)
permission-check 46s 🟩🟩🟩🟩🟩 (+9 more)
permission-check 42s 🟩🟩🟩🟩🟩 (+9 more)
permission-check 35s 🟩🟩🟩🟩🟩 (+9 more)
upload-to-codecov 12s 🟩
file_change_determinator 9s 🟩
execution-performance / file_change_determinator 8s 🟩
permission-check 4s 🟩
determine-docker-build-metadata 1s 🟩

settingsfeedbackdocs ⋅ learn more about trunk.io

Copy link

codecov bot commented Mar 1, 2024

Codecov Report

Attention: Patch coverage is 94.15205% with 20 lines in your changes are missing coverage. Please review.

Project coverage is 63.9%. Comparing base (ad04f0f) to head (16d1e10).
Report is 1 commits behind head on main.

Files Patch % Lines
...move-compiler-v2/src/env_pipeline/lambda_lifter.rs 94.1% 14 Missing ⚠️
third_party/move/move-model/src/model.rs 93.4% 3 Missing ⚠️
...ty/move/move-compiler-v2/src/bytecode_generator.rs 0.0% 1 Missing ⚠️
third_party/move/move-model/src/exp_rewriter.rs 85.7% 1 Missing ⚠️
.../move-prover/boogie-backend/src/spec_translator.rs 0.0% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main   #12318    +/-   ##
========================================
  Coverage    63.9%    63.9%            
========================================
  Files         801      803     +2     
  Lines      177744   178075   +331     
========================================
+ Hits       113629   113945   +316     
- Misses      64115    64130    +15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@brmataptos brmataptos left a comment

Choose a reason for hiding this comment

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

Any chance we can split the AST pipeline from the lambda lifting?

AST pipeline looks reasonable. Lambda lifting will take more time to review.

third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
@brmataptos brmataptos self-requested a review March 1, 2024 21:26
@@ -11,3 +11,122 @@ error: Break outside of a loop not supported in function-typed arguments (lambda
40 │ brk2(| | break);
│ ^^^^^

// -- Model dump before bytecode pipeline
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this being dumped after an error? Doing so is dangerous, as model may be not consistent.

} else {
self.env_pipeline.run(&mut env);
ok = Self::check_diags(&mut test_output.borrow_mut(), &env);
if self.dump_ast == AstDumpLevel::EndStage {
Copy link
Contributor

Choose a reason for hiding this comment

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

Only dump if ok.

third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
@brmataptos brmataptos self-requested a review March 1, 2024 22:06
Copy link
Contributor

@brmataptos brmataptos left a comment

Choose a reason for hiding this comment

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

You forgot about Assign statements. See comments below for recognizing free modified variables. Rewriting the lambda body to turn modified variables into &mut ref parameters may be tricky (but perhaps also kind of fun). I note that an Assign may set multiple variables, some of them also appearing in the RHS of the Assign. It's probably wisest to treat free_modified_vars the same as free_vars in the body of the closure and copy them in and out from &mut params at start and end of the function. (Good thing we don't currently allow return in lambdas.)

I really, really suggest splitting the AST pipeline from the Lambda lifting.

let mut curr_free_params = mem::take(&mut self.free_params);
let mut curr_free_locals = mem::take(&mut self.free_locals);
let result = self.rewrite_exp_descent(exp);
self.free_params.append(&mut curr_free_params);
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably better to keep the earlier use, since that way any error about the free var will reference the first use in the code. Easiest just to swap before the append:

mem::swap(&mut self.free_params, &mut curr_free_params);
mem::swap(&mut self.free_locals, &mut curr_free_locals);

though we could use a new var and mem::replace instead, I think this code is small enough to not allow confusion.

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'm not getting your swap comment. Those vars need to be cleared before descent, then when we return joined back into the result. Its written in the comment above. The swap wont do this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, yeah. I forgot that BTreeMap::append overwrites the original.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack

self.free_locals.retain(|name, _| !exiting.contains(name));
}

fn rewrite_local_var(&mut self, id: NodeId, sym: Symbol) -> Option<Exp> {
Copy link
Contributor

Choose a reason for hiding this comment

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

You also need to implement rewrite_pattern and catch the case matches!(pat, Pattern::Var(id, sym)) and entering_scope=false and record it in self.free_modified_syms. You will have to subtract exiting syms from it in rewrite_exit_scope above, and then do a second rewrite pass to turn all free modified syms into &mut params and modify all uses to read/write through the references. Note that both Temporary and Parameter can show up as a Pattern::Var, but that's a tiny part of the problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, but I'm not going for this complexity, at least for now. When a variable is assigned to our mutably borrowed, I produce now an error.

This is similar as in Java and C# lambdas, and I think C++ has this too. We may go back and make this more powerful, but lets start simple here. Indeed, for inlined lambdas this restriction doesn't exist, but they also have other stuff which can be done which can't be in a regular lambda.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, then you need an error in this case. Ok, see it.

@brmataptos
Copy link
Contributor

I forgot to note that occurrences of free vars (of both types: Index and Symbol) in a mutable Borrow should generate a mutable free var which also needs to be handled somehow. Again, copy-in-and-out seems easiest in general, though if there is no other use of the free var in the lambda then perhaps a &mut param could be passed in.

But this is sounding even harder to implement, even if we could have refs in tuples and could represent a pointer to a fun.

Copy link
Contributor Author

@wrwg wrwg left a comment

Choose a reason for hiding this comment

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

Thank you, PTAL

let mut curr_free_params = mem::take(&mut self.free_params);
let mut curr_free_locals = mem::take(&mut self.free_locals);
let result = self.rewrite_exp_descent(exp);
self.free_params.append(&mut curr_free_params);
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'm not getting your swap comment. Those vars need to be cleared before descent, then when we return joined back into the result. Its written in the comment above. The swap wont do this.

self.free_locals.retain(|name, _| !exiting.contains(name));
}

fn rewrite_local_var(&mut self, id: NodeId, sym: Symbol) -> Option<Exp> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, but I'm not going for this complexity, at least for now. When a variable is assigned to our mutably borrowed, I produce now an error.

This is similar as in Java and C# lambdas, and I think C++ has this too. We may go back and make this more powerful, but lets start simple here. Indeed, for inlined lambdas this restriction doesn't exist, but they also have other stuff which can be done which can't be in a regular lambda.

third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
third_party/move/move-compiler-v2/src/env_pipeline/mod.rs Outdated Show resolved Hide resolved
@wrwg wrwg requested a review from brmataptos March 2, 2024 01:17
let mut curr_free_params = mem::take(&mut self.free_params);
let mut curr_free_locals = mem::take(&mut self.free_locals);
let result = self.rewrite_exp_descent(exp);
self.free_params.append(&mut curr_free_params);
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, yeah. I forgot that BTreeMap::append overwrites the original.

self.free_locals.retain(|name, _| !exiting.contains(name));
}

fn rewrite_local_var(&mut self, id: NodeId, sym: Symbol) -> Option<Exp> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, then you need an error in this case. Ok, see it.

env.error(
&loc,
&format!(
"captured parameter `{}` cannot be modified inside of a lambda",
Copy link
Contributor

Choose a reason for hiding this comment

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

You should probably also call this a "captured variable" here, since parameters can appear in an Assign expression as a symbol and will be treated as a local. Determining whether the Assign symbol is a parameter or not requires tracking var scoping outside of the lambda, so probably isn't worth it. Easier to just change the error message to be consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@wrwg wrwg force-pushed the wrwg/lambda branch 3 times, most recently from c0cd2dc to 472a1e1 Compare March 3, 2024 06:37
@wrwg
Copy link
Contributor Author

wrwg commented Mar 4, 2024

I forgot to note that occurrences of free vars (of both types: Index and Symbol) in a mutable Borrow should generate a mutable free var which also needs to be handled somehow. Again, copy-in-and-out seems easiest in general, though if there is no other use of the free var in the lambda then perhaps a &mut param could be passed in.

But this is sounding even harder to implement, even if we could have refs in tuples and could represent a pointer to a fun.

Addressed for now by error message. PTAL

@wrwg wrwg force-pushed the wrwg/lambda branch 4 times, most recently from 7815551 to d9847a1 Compare March 4, 2024 18:50
Copy link
Contributor

@vineethk vineethk left a comment

Choose a reason for hiding this comment

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

Mostly minor comments.

/// Represents a pipeline of processors working on the global environment.
#[derive(Default)]
pub struct EnvProcessorPipeline<'a> {
/// A sequence of transformations to run on the model.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// A sequence of transformations to run on the model.
/// A sequence of transformations to run on the model.
/// For each processor, we store its name and the transformation function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


impl<'a> EnvProcessorPipeline<'a> {
/// Adds a processor to the pipeline.
pub fn add<P>(&mut self, name: &str, processor: P)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice, I think we can do this style of generics for stackless bytecode add_processor as well, and reduce quite a bunch of code!

Not an action item for this PR, I can do it as a follow up refactoring once this lands.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The stackless processors are significantly more expressive via their trait, I was just to lazy to introduce a trait here.

But we can build an adapter for a processor which wraps a function and makes it easier to create.

}

/// Runs the pipeline. Running will be ended if any of the steps produces an error.
/// The function returns true of all steps succeeded without errors.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// The function returns true of all steps succeeded without errors.
/// The function returns true if all steps succeeded without errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -1314,6 +1314,7 @@ impl<'a> ExpRewriterFunctions for ExpRewriter<'a> {
pub enum Operation {
MoveFunction(ModuleId, FunId),
SpecFunction(ModuleId, SpecFunId, Option<Vec<MemoryLabel>>),
Copy link
Contributor

Choose a reason for hiding this comment

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

move SpecFunction to below the comment // Specification specific (while not related to the change in the PR, it is an easy fix, hence suggested).

Copy link
Contributor

Choose a reason for hiding this comment

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

Closure should also be in the "Spec only" section.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

enum AstDumpLevel {
#[default]
None,
EndStage,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
EndStage,
EndStage, // only dump model AST after running all stages of env processor pipeline.

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 the AST operation which does not have this section, its also not that easy because there is 75% overlap.

function_checker::check_access_and_use(&mut env, false);
ok = Self::check_diags(&mut test_output.borrow_mut(), &env);
// Run env processor pipeline.
if self.dump_ast == AstDumpLevel::AllStages {
Copy link
Contributor

Choose a reason for hiding this comment

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

We may eventually want to selectively dump stages, but I am ok implementing that when we have a concrete usecase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SG

result_type: Type,
def: Exp,
) {
let called_funs = def.called_funs();
Copy link
Contributor

Choose a reason for hiding this comment

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

Would we want to extend called_funs() to include closures that can be called as well (it is currently limited to move functions called)? Or maybe we expect this to be implemented when full support for lambda is added?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually a good catch, I added this now to called_funs() so it is not forgotten.

}
}
// Now that we have processed all functions and released
// al references to the env, mutate it.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// al references to the env, mutate it.
// all references to the env, mutate it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

/// Any unbound locals used so far.
free_locals: BTreeMap<Symbol, VarInfo>,
/// NodeId's of lambdas which are parameters to inline functions
/// if those should be exempted. Pushed down during descend.
Copy link
Contributor

Choose a reason for hiding this comment

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

exempted from what? (document)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

exempted from lambda lifting. Clarified.

@wrwg wrwg requested a review from brmataptos March 5, 2024 07:06
Copy link
Contributor

@brmataptos brmataptos left a comment

Choose a reason for hiding this comment

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

It would be good if we could have single-purpose PRs.

The lambda change still needs more scrutiny and tests (e.g., nested lambdas, proper errors with mutation constructs), but as it's disabled by default it's probably ok to commit as is.

//!
//! - Inside of specification expressions;
//! - For a lambda argument of a regular (not inline) function
//!
Copy link
Contributor

Choose a reason for hiding this comment

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

//! - For a lambda without side-effects to free variables

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -1314,6 +1314,7 @@ impl<'a> ExpRewriterFunctions for ExpRewriter<'a> {
pub enum Operation {
MoveFunction(ModuleId, FunId),
SpecFunction(ModuleId, SpecFunId, Option<Vec<MemoryLabel>>),
Copy link
Contributor

Choose a reason for hiding this comment

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

Closure should also be in the "Spec only" section.

@@ -1,4 +1,4 @@
// ---- Model Dump
// -- Model dump before bytecode pipeline
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure it was useful to change this message, as it's clearly the final Model.

wrwg added 3 commits March 6, 2024 22:52
… trafo

This implements lambda lifting as rewrite on `GlobalEnv`. Lambda lifting appeared necessary for prover connection, because this is how the v1 integration works. Its not that clear any longer whether lambda lifting is really needed, but now the work is done, and we shoukd preseve it for future general support of HOFs.

As this is now the 5th or so so transformation on the environment before the bytecode pipeline starts. to support this adequate in the test suite, there is also a first step towards an `EnvProcessorPipeline`, and a new submodule `env-pipeline` which should contain those processors. For now it is just lambda lifting.
Copy link
Contributor Author

@wrwg wrwg left a comment

Choose a reason for hiding this comment

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

Thanks for the reviews.

It would be good if we could have single-purpose PRs.

Actually I think we are more productive if we refactor this code on the fly while we develop new features. But it also depends on the particular use case. Here the new pipeline is a triviality compared to the rest of the PR, larger refactorings would be a different story.

The lambda change still needs more scrutiny and tests (e.g., nested lambdas, proper errors with mutation constructs), but as it's disabled by default it's probably ok to commit as is.

Added a test for nesting.

//!
//! - Inside of specification expressions;
//! - For a lambda argument of a regular (not inline) function
//!
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

let mut curr_free_params = mem::take(&mut self.free_params);
let mut curr_free_locals = mem::take(&mut self.free_locals);
let result = self.rewrite_exp_descent(exp);
self.free_params.append(&mut curr_free_params);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack

@@ -1314,6 +1314,7 @@ impl<'a> ExpRewriterFunctions for ExpRewriter<'a> {
pub enum Operation {
MoveFunction(ModuleId, FunId),
SpecFunction(ModuleId, SpecFunId, Option<Vec<MemoryLabel>>),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@wrwg wrwg enabled auto-merge (squash) March 7, 2024 06:53

This comment has been minimized.

This comment has been minimized.

Copy link
Contributor

github-actions bot commented Mar 7, 2024

✅ Forge suite realistic_env_max_load success on 16d1e10415a3735845a83f4fde2e40f1e90b84eb

two traffics test: inner traffic : committed: 7640 txn/s, latency: 5135 ms, (p50: 5100 ms, p90: 6000 ms, p99: 10200 ms), latency samples: 3300780
two traffics test : committed: 100 txn/s, latency: 1863 ms, (p50: 1800 ms, p90: 2100 ms, p99: 4700 ms), latency samples: 1800
Latency breakdown for phase 0: ["QsBatchToPos: max: 0.231, avg: 0.203", "QsPosToProposal: max: 0.310, avg: 0.278", "ConsensusProposalToOrdered: max: 0.486, avg: 0.440", "ConsensusOrderedToCommit: max: 0.334, avg: 0.311", "ConsensusProposalToCommit: max: 0.777, avg: 0.752"]
Max round gap was 1 [limit 4] at version 1392059. Max no progress secs was 4.032167 [limit 15] at version 1392059.
Test Ok

Copy link
Contributor

github-actions bot commented Mar 7, 2024

✅ Forge suite compat success on aptos-node-v1.9.5 ==> 16d1e10415a3735845a83f4fde2e40f1e90b84eb

Compatibility test results for aptos-node-v1.9.5 ==> 16d1e10415a3735845a83f4fde2e40f1e90b84eb (PR)
1. Check liveness of validators at old version: aptos-node-v1.9.5
compatibility::simple-validator-upgrade::liveness-check : committed: 5631 txn/s, latency: 5578 ms, (p50: 4800 ms, p90: 9300 ms, p99: 12700 ms), latency samples: 214000
2. Upgrading first Validator to new version: 16d1e10415a3735845a83f4fde2e40f1e90b84eb
compatibility::simple-validator-upgrade::single-validator-upgrade : committed: 684 txn/s, latency: 35167 ms, (p50: 36400 ms, p90: 54900 ms, p99: 56900 ms), latency samples: 56100
3. Upgrading rest of first batch to new version: 16d1e10415a3735845a83f4fde2e40f1e90b84eb
compatibility::simple-validator-upgrade::half-validator-upgrade : committed: 396 txn/s, submitted: 657 txn/s, expired: 261 txn/s, latency: 25762 ms, (p50: 24700 ms, p90: 54800 ms, p99: 58800 ms), latency samples: 36087
4. upgrading second batch to new version: 16d1e10415a3735845a83f4fde2e40f1e90b84eb
compatibility::simple-validator-upgrade::rest-validator-upgrade : committed: 1684 txn/s, latency: 17691 ms, (p50: 18600 ms, p90: 24000 ms, p99: 24600 ms), latency samples: 75800
5. check swarm health
Compatibility test for aptos-node-v1.9.5 ==> 16d1e10415a3735845a83f4fde2e40f1e90b84eb passed
Test Ok

@wrwg wrwg merged commit e3cdf20 into main Mar 7, 2024
80 of 83 checks passed
@wrwg wrwg deleted the wrwg/lambda branch March 7, 2024 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants