From 1458649714e03be3a5b2c093f5f5ad1d665b5132 Mon Sep 17 00:00:00 2001 From: Niraj Kamdar Date: Mon, 24 Oct 2022 19:38:39 +0530 Subject: [PATCH 1/2] feat: add support for interface --- .../polywrap-client/polywrap_client/client.py | 19 ++- .../simple-interface/implementation/wrap.info | Bin 0 -> 1975 bytes .../simple-interface/implementation/wrap.wasm | Bin 0 -> 43278 bytes .../simple-interface/interface/wrap.info | Bin 0 -> 635 bytes .../cases/simple-interface/wrapper/wrap.info | Bin 0 -> 1779 bytes .../cases/simple-interface/wrapper/wrap.wasm | Bin 0 -> 47187 bytes packages/polywrap-client/tests/test_client.py | 42 ++++- .../polywrap_core/types/client.py | 6 + .../types/interface_implementation.py | 9 ++ .../polywrap_core/types/invoke.py | 8 +- .../polywrap-wasm/polywrap_wasm/imports.py | 152 ++++++++++++++++++ .../polywrap_wasm/types/state.py | 1 + 12 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 packages/polywrap-client/tests/cases/simple-interface/implementation/wrap.info create mode 100755 packages/polywrap-client/tests/cases/simple-interface/implementation/wrap.wasm create mode 100644 packages/polywrap-client/tests/cases/simple-interface/interface/wrap.info create mode 100644 packages/polywrap-client/tests/cases/simple-interface/wrapper/wrap.info create mode 100755 packages/polywrap-client/tests/cases/simple-interface/wrapper/wrap.wasm create mode 100644 packages/polywrap-core/polywrap_core/types/interface_implementation.py diff --git a/packages/polywrap-client/polywrap_client/client.py b/packages/polywrap-client/polywrap_client/client.py index ddbdbe32..b34cdaa7 100644 --- a/packages/polywrap-client/polywrap_client/client.py +++ b/packages/polywrap-client/polywrap_client/client.py @@ -20,6 +20,7 @@ UriPackage, UriPackageOrWrapper, UriResolutionContext, + InterfaceImplementations, Wrapper, ) from polywrap_msgpack import msgpack_decode, msgpack_encode @@ -53,6 +54,17 @@ def get_uri_resolver( def get_envs(self, options: Optional[GetEnvsOptions] = None) -> List[Env]: return self._config.envs + def get_interfaces(self) -> List[InterfaceImplementations]: + return self._config.interfaces + + def get_implementations(self, uri: Uri) -> Result[List[Uri], Exception]: + if interface_implementations := next( + filter(lambda x: x.interface == uri, self._config.interfaces), None + ): + return Ok(interface_implementations.implementations) + else: + return Err(ValueError(f"Unable to find implementations for uri: {uri}")) + def get_env_by_uri( self, uri: Uri, options: Optional[GetEnvsOptions] = None ) -> Union[Env, None]: @@ -62,7 +74,9 @@ async def get_file(self, uri: Uri, options: GetFileOptions) -> Union[bytes, str] loaded_wrapper = (await self.load_wrapper(uri)).unwrap() return await loaded_wrapper.get_file(options) - async def get_manifest(self, uri: Uri, options: Optional[GetManifestOptions] = None) -> AnyWrapManifest: + async def get_manifest( + self, uri: Uri, options: Optional[GetManifestOptions] = None + ) -> AnyWrapManifest: loaded_wrapper = (await self.load_wrapper(uri)).unwrap() return loaded_wrapper.get_manifest() @@ -124,4 +138,5 @@ async def invoke(self, options: InvokerOptions) -> InvokeResult: return result except Exception as e: - return InvokeResult(result=None, error=e) + raise e + # return InvokeResult(result=None, error=e) diff --git a/packages/polywrap-client/tests/cases/simple-interface/implementation/wrap.info b/packages/polywrap-client/tests/cases/simple-interface/implementation/wrap.info new file mode 100644 index 0000000000000000000000000000000000000000..afe55c112cf144ee065e1431dcb953371e7641f5 GIT binary patch literal 1975 zcmeHI!A{#i5DiieduaO8k`Ae_-A9>UUiZFbinZcruk9Qp|k4lz`!QY3nA zuk@d~o^jTW?X-e$>?zUid$Tid-i-U>bC8OABHUQt90}&av;|7ZZ<)v zrkOxm73;>4lVl?)-z<)a9grF0H0cg+J=wxXZd`UNX$r8e6~!~Y|eeasdN3mIdr_6Lo~ BWi9{! literal 0 HcmV?d00001 diff --git a/packages/polywrap-client/tests/cases/simple-interface/implementation/wrap.wasm b/packages/polywrap-client/tests/cases/simple-interface/implementation/wrap.wasm new file mode 100755 index 0000000000000000000000000000000000000000..e8772878ceb4720ef332678dfc6735d2f0a21e68 GIT binary patch literal 43278 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 literal 0 HcmV?d00001 diff --git a/packages/polywrap-client/tests/test_client.py b/packages/polywrap-client/tests/test_client.py index c2a9799c..a8157aa8 100644 --- a/packages/polywrap-client/tests/test_client.py +++ b/packages/polywrap-client/tests/test_client.py @@ -1,7 +1,7 @@ from pathlib import Path from polywrap_client import PolywrapClient -from polywrap_core import Uri, InvokerOptions +from polywrap_core import Uri, InvokerOptions, InterfaceImplementations from polywrap_uri_resolvers import BaseUriResolver, SimpleFileReader from polywrap_client.client import PolywrapClientConfig @@ -31,17 +31,43 @@ async def test_subinvoke(): }, ) - client = PolywrapClient(config=PolywrapClientConfig( - envs=[], resolver=uri_resolver - )) + client = PolywrapClient(config=PolywrapClientConfig(envs=[], resolver=uri_resolver)) uri = Uri( f'fs/{Path(__file__).parent.joinpath("cases", "simple-subinvoke", "invoke").absolute()}' ) - args = b'\x82\xa1a\x01\xa1b\x02' - options = InvokerOptions( - uri=uri, method="add", args=args, encode_result=False - ) + args = {"a": 1, "b": 2} + options = InvokerOptions(uri=uri, method="add", args=args, encode_result=False) result = await client.invoke(options) assert result.result == "1 + 2 = 3" + +async def test_interface_implementation(): + uri_resolver = BaseUriResolver( + file_reader=SimpleFileReader(), + redirects={}, + ) + + impl_uri = Uri( + f'fs/{Path(__file__).parent.joinpath("cases", "simple-interface", "implementation").absolute()}' + ) + + client = PolywrapClient( + config=PolywrapClientConfig( + envs=[], + resolver=uri_resolver, + interfaces=[ + InterfaceImplementations( + interface=Uri("ens/interface.eth"), implementations=[impl_uri] + ) + ], + ) + ) + uri = Uri( + f'fs/{Path(__file__).parent.joinpath("cases", "simple-interface", "wrapper").absolute()}' + ) + args = {"arg": {"str": "hello", "uint8": 2}} + options = InvokerOptions(uri=uri, method="moduleMethod", args=args, encode_result=False) + result = await client.invoke(options) + + assert result.result == {"str": "hello", "uint8": 2} diff --git a/packages/polywrap-core/polywrap_core/types/client.py b/packages/polywrap-core/polywrap_core/types/client.py index 754409b2..c84ad645 100644 --- a/packages/polywrap-core/polywrap_core/types/client.py +++ b/packages/polywrap-core/polywrap_core/types/client.py @@ -6,6 +6,7 @@ from polywrap_manifest import DeserializeManifestOptions, AnyWrapManifest +from .interface_implementation import InterfaceImplementations from .env import Env from .invoke import Invoker from .uri import Uri @@ -16,6 +17,7 @@ @dataclass(slots=True, kw_only=True) class ClientConfig: envs: List[Env] = field(default_factory=list) + interfaces: List[InterfaceImplementations] = field(default_factory=list) resolver: IUriResolver @@ -41,6 +43,10 @@ class GetManifestOptions(DeserializeManifestOptions): class Client(Invoker, UriResolverHandler): + @abstractmethod + def get_interfaces(self) -> List[InterfaceImplementations]: + pass + @abstractmethod def get_envs(self, options: Optional[GetEnvsOptions] = None) -> List[Env]: pass diff --git a/packages/polywrap-core/polywrap_core/types/interface_implementation.py b/packages/polywrap-core/polywrap_core/types/interface_implementation.py new file mode 100644 index 00000000..dbaf4a21 --- /dev/null +++ b/packages/polywrap-core/polywrap_core/types/interface_implementation.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass +from typing import List + +from .uri import Uri + +@dataclass(slots=True, kw_only=True) +class InterfaceImplementations: + interface: Uri + implementations: List[Uri] diff --git a/packages/polywrap-core/polywrap_core/types/invoke.py b/packages/polywrap-core/polywrap_core/types/invoke.py index b46d2cf6..3fde9a02 100644 --- a/packages/polywrap-core/polywrap_core/types/invoke.py +++ b/packages/polywrap-core/polywrap_core/types/invoke.py @@ -2,7 +2,9 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, List, Optional, Union + +from result import Result from .uri import Uri from .uri_resolution_context import IUriResolutionContext @@ -57,6 +59,10 @@ class Invoker(ABC): async def invoke(self, options: InvokerOptions) -> InvokeResult: pass + @abstractmethod + def get_implementations(self, uri: Uri) -> Result[List[Uri], Exception]: + pass + class Invocable(ABC): @abstractmethod diff --git a/packages/polywrap-wasm/polywrap_wasm/imports.py b/packages/polywrap-wasm/polywrap_wasm/imports.py index 9434f74c..b45dcc58 100644 --- a/packages/polywrap-wasm/polywrap_wasm/imports.py +++ b/packages/polywrap-wasm/polywrap_wasm/imports.py @@ -1,4 +1,6 @@ +from typing import List from polywrap_core import Invoker, InvokeResult, InvokerOptions, Uri +from polywrap_msgpack import msgpack_encode from unsync import Unfuture, unsync from wasmtime import ( FuncType, @@ -11,6 +13,7 @@ Store, ValType, ) +from result import Err from .buffer import read_bytes, read_string, write_bytes, write_string from .errors import WasmAbortError @@ -36,6 +39,18 @@ def create_instance( """ mem = Memory(store, MemoryType(Limits(1, None))) + wrap_debug_log_type = FuncType( + [ + ValType.i32(), + ValType.i32() + ], + [], + ) + + def wrap_debug_log(ptr: int, len: int) -> None: + msg = read_string(mem.data_ptr(store), mem.data_len(store), ptr, len) + print(msg) + wrap_abort_type = FuncType( [ ValType.i32(), @@ -116,6 +131,9 @@ def wrap_subinvoke( args_ptr: int, args_len: int, ) -> bool: + state.subinvoke["result"] = None + state.subinvoke["error"] = None + uri = read_string(mem.data_ptr(store), mem.data_len(store), uri_ptr, uri_len) method = read_string( mem.data_ptr(store), mem.data_len(store), method_ptr, method_len @@ -173,15 +191,149 @@ def wrap_subinvoke_error(ptr: int) -> None: mem.data_ptr(store), mem.data_len(store), state.subinvoke["error"], ptr ) + wrap_subinvoke_implementation_type = FuncType( + [ + ValType.i32(), + ValType.i32(), + ValType.i32(), + ValType.i32(), + ValType.i32(), + ValType.i32(), + ValType.i32(), + ValType.i32(), + ], + [ValType.i32()], + ) + + def wrap_subinvoke_implementation( + interface_uri_ptr: int, + interface_uri_len: int, + impl_uri_ptr: int, + impl_uri_len: int, + method_ptr: int, + method_len: int, + args_ptr: int, + args_len: int + ) -> bool: + state.subinvoke_implementation["result"] = None + state.subinvoke_implementation["error"] = None + + interface_uri = read_string(mem.data_ptr(store), mem.data_len(store), interface_uri_ptr, interface_uri_len) + impl_uri = read_string(mem.data_ptr(store), mem.data_len(store), impl_uri_ptr, impl_uri_len) + method = read_string( + mem.data_ptr(store), mem.data_len(store), method_ptr, method_len + ) + args = read_bytes(mem.data_ptr(store), mem.data_len(store), args_ptr, args_len) + + unfuture_result: Unfuture[InvokeResult] = unsync_invoke( + invoker, + InvokerOptions(uri=Uri(impl_uri), method=method, args=args, encode_result=True), + ) + result = unfuture_result.result() + + if result.result: + state.subinvoke_implementation["result"] = result.result + return True + elif result.error: + state.subinvoke_implementation["error"] = "".join(str(x) for x in result.error.args) + return False + else: + raise ValueError(f"interface implementation subinvoke failed for uri: {interface_uri}!") + + wrap_subinvoke_implementation_result_len_type = FuncType([], [ValType.i32()]) + + def wrap_subinvoke_implementation_result_len() -> int: + if not state.subinvoke_implementation["result"]: + raise WasmAbortError( + "__wrap_subinvoke_implementation_result_len: subinvoke_implementation.result is not set" + ) + return len(state.subinvoke_implementation["result"]) + + wrap_subinvoke_implementation_result_type = FuncType([ValType.i32()], []) + + def wrap_subinvoke_implementation_result(ptr: int) -> None: + if not state.subinvoke_implementation["result"]: + raise WasmAbortError("__wrap_subinvoke_implementation_result: subinvoke_implementation.result is not set") + write_bytes( + mem.data_ptr(store), mem.data_len(store), state.subinvoke_implementation["result"], ptr + ) + + wrap_subinvoke_implementation_error_len_type = FuncType([], [ValType.i32()]) + + def wrap_subinvoke_implementation_error_len() -> int: + if not state.subinvoke_implementation["error"]: + raise WasmAbortError( + "__wrap_subinvoke_implementation_error_len: subinvoke_implementation.error is not set" + ) + return len(state.subinvoke_implementation["error"]) + + wrap_subinvoke_implementation_error_type = FuncType([ValType.i32()], []) + + def wrap_subinvoke_implementation_error(ptr: int) -> None: + if not state.subinvoke_implementation["error"]: + raise WasmAbortError("__wrap_subinvoke_implementation_error: subinvoke_implementation.error is not set") + write_string( + mem.data_ptr(store), mem.data_len(store), state.subinvoke_implementation["error"], ptr + ) + + wrap_get_implementations_type = FuncType([ValType.i32(), ValType.i32()], [ValType.i32()]) + + def wrap_get_implementations(uri_ptr: int, uri_len: int) -> bool: + uri = read_string(mem.data_ptr(store), mem.data_len(store), uri_ptr, uri_len) + result = invoker.get_implementations(uri=Uri(uri)) + if isinstance(result, Err): + raise WasmAbortError(" ".join(result.unwrap_err().args)) + implementations: List[str] = [uri.uri for uri in result.unwrap()] + state.get_implementations_result = msgpack_encode(implementations) + return len(implementations) > 0 + + wrap_get_implementations_result_len_type = FuncType([], [ValType.i32()]) + + def wrap_get_implementations_result_len() -> int: + if not state.get_implementations_result: + raise WasmAbortError( + "__wrap_get_implementations_result_len: get_implementations_result is not set" + ) + return len(state.get_implementations_result) + + wrap_get_implementations_result_type = FuncType([ValType.i32()], []) + + def wrap_get_implementations_result(ptr: int) -> None: + if not state.get_implementations_result: + raise WasmAbortError("__wrap_get_implementations_result: get_implementations_result is not set") + write_bytes( + mem.data_ptr(store), mem.data_len(store), state.get_implementations_result, ptr + ) + + # TODO: use generics or any on wasmtime codebase to fix typings + linker.define_func("wrap", "__wrap_debug_log", wrap_debug_log_type, wrap_debug_log) # type: ignore partially unknown linker.define_func("wrap", "__wrap_abort", wrap_abort_type, wrap_abort) # type: ignore partially unknown + + # invoke linker.define_func("wrap", "__wrap_invoke_args", wrap_invoke_args_type, wrap_invoke_args) # type: ignore partially unknown linker.define_func("wrap", "__wrap_invoke_result", wrap_invoke_result_type, wrap_invoke_result) # type: ignore partially unknown linker.define_func("wrap", "__wrap_invoke_error", wrap_invoke_error_type, wrap_invoke_error) # type: ignore partially unknown + + # subinvoke linker.define_func("wrap", "__wrap_subinvoke", wrap_subinvoke_type, wrap_subinvoke) # type: ignore partially unknown linker.define_func("wrap", "__wrap_subinvoke_result_len", wrap_subinvoke_result_len_type, wrap_subinvoke_result_len) # type: ignore partially unknown linker.define_func("wrap", "__wrap_subinvoke_result", wrap_subinvoke_result_type, wrap_subinvoke_result) # type: ignore partially unknown linker.define_func("wrap", "__wrap_subinvoke_error_len", wrap_subinvoke_error_len_type, wrap_subinvoke_error_len) # type: ignore partially unknown linker.define_func("wrap", "__wrap_subinvoke_error", wrap_subinvoke_error_type, wrap_subinvoke_error) # type: ignore partially unknown + + # subinvoke implementation + linker.define_func("wrap", "__wrap_subinvokeImplementation", wrap_subinvoke_implementation_type, wrap_subinvoke_implementation) # type: ignore partially unknown + linker.define_func("wrap", "__wrap_subinvokeImplementation_result_len", wrap_subinvoke_implementation_result_len_type, wrap_subinvoke_implementation_result_len) # type: ignore partially unknown + linker.define_func("wrap", "__wrap_subinvokeImplementation_result", wrap_subinvoke_implementation_result_type, wrap_subinvoke_implementation_result) # type: ignore partially unknown + linker.define_func("wrap", "__wrap_subinvokeImplementation_error_len", wrap_subinvoke_implementation_error_len_type, wrap_subinvoke_implementation_error_len) # type: ignore partially unknown + linker.define_func("wrap", "__wrap_subinvokeImplementation_error", wrap_subinvoke_implementation_error_type, wrap_subinvoke_implementation_error) # type: ignore partially unknown + + # getImplementations + linker.define_func("wrap", "__wrap_getImplementations", wrap_get_implementations_type, wrap_get_implementations) # type: ignore partially unknown + linker.define_func("wrap", "__wrap_getImplementations_result_len", wrap_get_implementations_result_len_type, wrap_get_implementations_result_len) # type: ignore partially unknown + linker.define_func("wrap", "__wrap_getImplementations_result", wrap_get_implementations_result_type, wrap_get_implementations_result) # type: ignore partially unknown + + # memory linker.define("env", "memory", mem) return linker.instantiate(store, module) diff --git a/packages/polywrap-wasm/polywrap_wasm/types/state.py b/packages/polywrap-wasm/polywrap_wasm/types/state.py index 8d7c0afe..8892569c 100644 --- a/packages/polywrap-wasm/polywrap_wasm/types/state.py +++ b/packages/polywrap-wasm/polywrap_wasm/types/state.py @@ -30,6 +30,7 @@ class State: subinvoke_implementation: RawSubinvokeImplementationResult = field( default_factory=lambda: {"result": None, "error": None, "args": []} ) + get_implementations_result: Optional[bytes] = None method: Optional[str] = None args: Optional[bytes] = None env: Optional[bytes] = None From 5e660b61eedebe8e3b559afc2be37399d159c3b2 Mon Sep 17 00:00:00 2001 From: Niraj Kamdar Date: Mon, 24 Oct 2022 19:47:22 +0530 Subject: [PATCH 2/2] fix(polywrap-wasm): tests --- packages/polywrap-wasm/tests/test_wasm_wrapper.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/polywrap-wasm/tests/test_wasm_wrapper.py b/packages/polywrap-wasm/tests/test_wasm_wrapper.py index 81fad29c..ce0d6d3e 100644 --- a/packages/polywrap-wasm/tests/test_wasm_wrapper.py +++ b/packages/polywrap-wasm/tests/test_wasm_wrapper.py @@ -1,3 +1,4 @@ +from typing import List import pytest from pathlib import Path @@ -9,11 +10,17 @@ from polywrap_wasm.constants import WRAP_MANIFEST_PATH +from result import Result, Err + @pytest.fixture def mock_invoker(): class MockInvoker(Invoker): async def invoke(self, options: InvokerOptions) -> InvokeResult: return InvokeResult() + + def get_implementations(self, uri: Uri) -> Result[List[Uri], Exception]: + return Err(NotImplementedError()) + return MockInvoker()