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

Injectable primitives #1470

Merged
merged 7 commits into from
Oct 31, 2023
Merged

Injectable primitives #1470

merged 7 commits into from
Oct 31, 2023

Conversation

alexytsu
Copy link
Contributor

@alexytsu alexytsu commented Oct 30, 2023

#1371

The design here is to:

- Define all injectable behaviour as a method of the Primitives trait
- FakePrimitives stores optional override behaviour for each method
- Expose the ability to inject this behaviour on the vm_api::VM trait
- Where the behaviour overlaps with "runtime" behaviour such as with the Verifier trait, the implementer of Verifier should delegate to the VM's primitives.

For example, here verify_replica_update is added to Primitives and implemented in FakePrimitives. The VM api allows test authors to override this behaviour. InvocationCtx, delegates to the VM instance so as to select the (potentially) overriden behavior.

All Verifier functionality has been moved to Primitives. Primitives is Faked by FakedPrimitives in the TestVM which provides default behaviour or can be overridden via the trait methods of VM

@alexytsu alexytsu force-pushed the alexytsu/1348-injectable-primitives branch from 445ca30 to bb9ab41 Compare October 30, 2023 07:35
@alexytsu alexytsu changed the base branch from master to alexytsu/1348-testable-values October 30, 2023 07:35
@alexytsu
Copy link
Contributor Author

@anorth Can you please let me know if this would have solved your testing needs in #1370 (comment)?

If so, I can apply this more widely to other behaviours of the TestVM (the rest of the methods in Verifier and Primitives to start with)

@alexytsu alexytsu requested a review from anorth October 30, 2023 07:44
@alexytsu alexytsu force-pushed the alexytsu/1348-testable-values branch from 5aee49e to 649515a Compare October 30, 2023 22:52
test_vm/src/fakes.rs Outdated Show resolved Hide resolved
test_vm/src/fakes.rs Outdated Show resolved Hide resolved
@@ -51,7 +51,7 @@ pub use messaging::*;

/// An in-memory rust-execution VM for testing builtin-actors that yields sensible stack traces and debug info
pub struct TestVM {
pub primitives: FakePrimitives,
pub primitives: RefCell<FakePrimitives>,
Copy link
Member

Choose a reason for hiding this comment

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

If this is going to be boxed, can we use RefCell<dyn Primitives> instead? It would be much nicer to be able to set_primitives(...) rather than expose a method for each one individually.

Copy link
Contributor Author

@alexytsu alexytsu Oct 31, 2023

Choose a reason for hiding this comment

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

Currently relying on FakePrimitives being Cloneable to pass out a Primitives instance.

dyn Primitives wouldn't be cloneable.

A workaround might be to add an explicit "clone" method on the primitives trait that returns a Box

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another option is for Primitives to break the interior-mutability pattern and require a mutable instance to set_primitives. This avoids having the RefCell allowing us to revert to returning a &Primitives (which means we don't have to clone)

test_vm/src/fakes.rs Outdated Show resolved Hide resolved
runtime/src/runtime/fvm.rs Outdated Show resolved Hide resolved
@@ -1054,7 +1054,7 @@ impl Actor {
let quant = state.quant_spec_for_deadline(rt.policy(), dl_idx);

for update in &decls_by_deadline[&dl_idx] {
rt.verify_replica_update(&update.proof_inputs).with_context_code(
Verifier::verify_replica_update(rt, &update.proof_inputs).with_context_code(
Copy link
Member

Choose a reason for hiding this comment

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

I don't think requiring this calling convention will be reasonable given the method is available directly on rt. I also can't tell why the change is needed though. If there is a real thing happening here, I think it's too subtle for future developers to follow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since runtime implements both Primitives and Verifier which both now have verify_replica_update with the same signature, we need to specify which method to dispatch to.

The Primitives could have differently named functions - perhaps prefixed?

Copy link
Member

Choose a reason for hiding this comment

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

Since runtime implements both Primitives and Verifier which both now have verify_replica_update with the same signature

Ok I think the design problem originates here. Primitives and Verifier are IMO just a boring and unnecessary separation of the methods required by a complete Runtime impl. It shouldn't drive any other code structure. We could in principle just inline them all into Runtime, and perhaps should in practise if the separation cause problems. We'd still then need a trait for external behaviour to inject into a VM, and forwarding methods. But the Primitives trait is doing two jobs here, and perhaps should do just one.

  • One solution might be to keep the separation and have Primitives and Verifier separately injectable into the VM. I.e. not "Define all injectable behaviour as a method of the Primitives trait".
  • Another is to delete the Verifier trait and merge its methods into Primitives. The distinction is pretty arbitrary anyway. There might be some friction around the fake-proofs build config though.

Base automatically changed from alexytsu/1348-testable-values to master October 30, 2023 23:12
@alexytsu alexytsu force-pushed the alexytsu/1348-injectable-primitives branch from 9dfaecc to 52ff5c1 Compare October 31, 2023 02:43
@alexytsu alexytsu marked this pull request as ready for review October 31, 2023 02:59
@alexytsu alexytsu requested a review from anorth October 31, 2023 02:59
@alexytsu alexytsu mentioned this pull request Oct 31, 2023
Copy link
Member

@anorth anorth left a comment

Choose a reason for hiding this comment

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

LGTM, but #1473 looks even better. Consider squashing those together there before merge.

* export FakePrimitives from fakes

* export FakePrimitives
@alexytsu alexytsu enabled auto-merge October 31, 2023 22:12
@alexytsu alexytsu added this pull request to the merge queue Oct 31, 2023
Merged via the queue into master with commit 73376df Oct 31, 2023
12 checks passed
@alexytsu alexytsu deleted the alexytsu/1348-injectable-primitives branch October 31, 2023 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants