You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds a foreign_calls::layer::Layer construct which is used to compose ForeignCallExecutor instances. DefaultForeignCallExecutor, DebugForeignCallExecutor and TestForeignCallExecutor are reimplemented with this layering.
The DefaultForeignCallExecutor allows us to inject a base layer, which the TestForeignCallExecutor uses to change the behaviour when nothing handles the call; this way we can reuse the default composition without having to repeat the logic in the test, similar to how the DefaultDebugForeignCallExecutor did it earlier.
Follow up for this would be:
Make the mock layer in the DefaultForeignCallExecutor optional, so that during normal execution no contract can install a mock and then handle foreign calls that should hit URLs. A DisabledMockForeignCallExecutor has been added in this PR, but it's unused. (I'm not sure this is a legit concern, but I didn't see any reason it wouldn't work).
Make run_test accept a generic function to create a ForeignCallExecutor on top of the Unhandled base handler, instead of explicitly creating a DefaultForeignCallExecutor, so that we don't depend on RPCForeignCallExecutor in the tests, and then we can compile them to Wasm. feat!: nargo::ops::test::run_test generic in ForeignCallExecutor #6858
Additional Context
It's a breaking change because it changes the return type of DefaultForeignCallHandler::new, although the way it's called is the same for now.
Documentation*
Check one:
No documentation needed.
Documentation included in this PR.
[For Experimental Features] Documentation to be submitted in a separate PR.
PR Checklist*
I have tested the changes locally.
I have formatted the changes with Prettier and/or cargo fmt on default settings.
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
If I'm understanding things correctly, DefaultForeignCallExecutor used to have three internal executors and it would try them one after the other. Now in this PR they are layered on top of each other, so the effect is the same... except that we end up without duplicated code.
That's right, the DefaultForeignCallExecutor knew exactly which requests should go where, and then the handlers it dispatched to also inspected the call to decide whether they should be the ones handling it. Sometimes the DefaultForeignCallExecutor looked for this NoHandler error as a legitimate signal to carry on to the next handler. Namely the MockForeignCallExecutor may or may not be able to handle arbitrary calls, depending on the calls history came before.
Then the DefaultForeignCallExecutor returned an empty result. To inject further logic before this happens, the TestForeignCallExecutor had to repeat the whole setup, which now it doesn't have to any more, although it could have been achieved in different ways I suppose.
With layering there is a chance to combine layers differently, and also to remove duplication by passing around builder functions. There is more reliance on the NoHandlers error mechanism, at the cost of cloning more strings, but I think we could even remove the wrapped String as the content might never be accessed.
In the next extension we could add something like layers::Either that could be for example either the MockExecutor or the DisabledMockExecutor, or add a flag to the MockExecutor would be fine as well.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Problem*
Followup for #6849
Summary*
Adds a
foreign_calls::layer::Layerconstruct which is used to composeForeignCallExecutorinstances.DefaultForeignCallExecutor,DebugForeignCallExecutorandTestForeignCallExecutorare reimplemented with this layering.The
DefaultForeignCallExecutorallows us to inject a base layer, which theTestForeignCallExecutoruses to change the behaviour when nothing handles the call; this way we can reuse the default composition without having to repeat the logic in the test, similar to how theDefaultDebugForeignCallExecutordid it earlier.Follow up for this would be:
DefaultForeignCallExecutoroptional, so that during normal execution no contract can install a mock and then handle foreign calls that should hit URLs. ADisabledMockForeignCallExecutorhas been added in this PR, but it's unused. (I'm not sure this is a legit concern, but I didn't see any reason it wouldn't work).run_testaccept a generic function to create aForeignCallExecutoron top of theUnhandledbase handler, instead of explicitly creating aDefaultForeignCallExecutor, so that we don't depend onRPCForeignCallExecutorin the tests, and then we can compile them to Wasm. feat!:nargo::ops::test::run_testgeneric inForeignCallExecutor#6858Additional Context
It's a breaking change because it changes the return type of
DefaultForeignCallHandler::new, although the way it's called is the same for now.Documentation*
Check one:
PR Checklist*
cargo fmton default settings.