diff --git a/conftest.py b/conftest.py index b8f8939..4d558cd 100644 --- a/conftest.py +++ b/conftest.py @@ -1,12 +1,22 @@ import pytest +def get_open_port(): + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 0)) + s.listen(1) + port = s.getsockname()[1] + s.close() + return port + + @pytest.yield_fixture() def web3_tester(): from web3 import Web3 from web3.web3.rpcprovider import TestRPCProvider - provider = TestRPCProvider() + provider = TestRPCProvider(port=get_open_port()) _web3 = Web3(provider) diff --git a/requirements-dev.txt b/requirements-dev.txt index ed6dfb8..f5e1713 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ pytest>=2.8.2 pytest-pythonpath>=0.3 tox>=1.8.0 -eth-testrpc==0.2.0 +eth-testrpc==0.2.1 # Until pyethereum > 1.3.6 is released. https://github.com/ethereum/pyethereum/tarball/b06829e56e2a3de5276077a611ed8813b6cf5e74 diff --git a/tests/db-module/test_db_methods.py b/tests/db-module/test_db_methods.py new file mode 100644 index 0000000..9994bf2 --- /dev/null +++ b/tests/db-module/test_db_methods.py @@ -0,0 +1,21 @@ +import pytest + + +def test_putString(web3_tester): + with pytest.raises(DeprecationWarning): + web3_tester.db.putString('someDB', 'key', 'value') + + +def test_getString(web3_tester): + with pytest.raises(DeprecationWarning): + web3_tester.db.getString('someDB', 'key') + + +def test_putHex(web3_tester): + with pytest.raises(DeprecationWarning): + web3_tester.db.putHex('someDB', 'key', '0x12345') + + +def test_getHex(web3_tester): + with pytest.raises(DeprecationWarning): + web3_tester.db.getHex('someDB', 'key') diff --git a/tests/version/test_web3_version_props.py b/tests/version/test_web3_version_props.py index eba846d..ca54e41 100644 --- a/tests/version/test_web3_version_props.py +++ b/tests/version/test_web3_version_props.py @@ -8,3 +8,11 @@ def test_api_property(web3_tester): def test_node_property(web3_tester): assert web3_tester.version.node == testrpc.testrpc.web3_clientVersion() + + +def test_network_property(web3_tester): + assert web3_tester.version.network == testrpc.testrpc.net_version() + + +def test_ethereum_property(web3_tester): + assert web3_tester.version.ethereum == testrpc.testrpc.eth_protocolVersion() diff --git a/web3/main.py b/web3/main.py index 285d282..8f5ba9e 100644 --- a/web3/main.py +++ b/web3/main.py @@ -15,8 +15,8 @@ from web3.web3.rpcprovider import ( TestRPCProvider, is_testrpc_available, ) - from web3.web3.ipcprovider import IPCProvider + import web3.utils.encoding as encoding import web3.utils.currency as currency import web3.utils.address as address @@ -37,16 +37,16 @@ class Web3(object): def __init__(self, provider): self._requestManager = RequestManager(provider) self.currentProvider = provider - self.eth = Eth(self) - self.db = Db(self) - self.shh = Shh(self) - self.net = Net(self) - self.personal = Personal(self) + + self.eth = Eth(self._requestManager) + self.db = Db(self._requestManager) + self.shh = Shh(self._requestManager) + self.net = Net(self._requestManager) + self.personal = Personal(self._requestManager) + self.version = Version(self._requestManager) self.providers = copy.copy(DEFAULT_PROVIDERS) - self.version = Version(self._requestManager) - class Config: def __getattr__(self, key): @@ -63,13 +63,9 @@ class Web3(object): self.config = Config() - for prop in properties: - prop.attachToObject(self) - prop.setRequestManager(self._requestManager) - # Expose providers on the class - self.RPCProvider = RPCProvider - self.IPCProvider = IPCProvider + for class_name, klass in DEFAULT_PROVIDERS.items(): + setattr(self, class_name, klass) # Expose utility functions self.toHex = encoding.toHex @@ -93,35 +89,13 @@ class Web3(object): self._requestManager.reset(keepIsSyncing) def sha3(self, string, options): - return "0x" + sha3.sha3(string, options) + return b"0x" + sha3.sha3(string, options) def isConnected(self): return self.currentProvider and self.currentProvider.isConnected() - # def createBatch(self): - # return Batch(self) + def createBatch(self): + raise NotImplementedError("Not Implemented") def receive(self, requestid, timeout=0, keep=False): return self._requestManager.receive(requestid, timeout, keep) - -properties = [] -# Property({ -# "name": "version.node", -# "getter": "web3_clientVersion" -# }), -# Property({ -# "name": "version.network", -# "getter": "net_version", -# "inputFormatter": encoding.toDecimal -# }), -# Property({ -# "name": "version.ethereum", -# "getter": "eth_protocolVersion", -# "inputFormatter": encoding.toDecimal -# }), -# Property({ -# "name": "version.whisper", -# "getter": "shh_version", -# "inputFormatter": encoding.toDecimal -# }) -#] diff --git a/web3/version.py b/web3/version.py index 9cdd29f..1b62392 100644 --- a/web3/version.py +++ b/web3/version.py @@ -23,3 +23,17 @@ class Version(object): def getNetwork(self, *args, **kwargs): raise NotImplementedError("Async calling has not been implemented") + + @property + def ethereum(self): + return self.request_manager.request_blocking("eth_protocolVersion", []) + + def getEthereum(self, *args, **kwargs): + raise NotImplementedError("Async calling has not been implemented") + + @property + def whisper(self): + raise NotImplementedError("Async calling has not been implemented") + + def getWhisper(self, *args, **kwargs): + raise NotImplementedError("Async calling has not been implemented") diff --git a/web3/web3/methods/db.py b/web3/web3/methods/db.py index a7731af..c2e9286 100644 --- a/web3/web3/methods/db.py +++ b/web3/web3/methods/db.py @@ -1,35 +1,15 @@ -from web3.web3.method import Method - -methods = [ - { - "name": "putString", - "call": "db_putString", - "params": 3 - }, - { - "name": "getString", - "call": "db_getString", - "params": 2 - }, - { - "name": "putHex", - "call": "db_putHex", - "params": 3 - }, - { - "name": "getHex", - "call": "db_getHex", - "params": 2 - } -] - - class Db(object): + def __init__(self, request_manager): + self.request_manager = request_manager - def __init__(self, web3): - self._requestManager = web3._requestManager + def putString(self, *args, **kwargs): + raise DeprecationWarning("This function has been deprecated") - for method in methods: - method = Method(method) - method.attachToObject(self) - method.setRequestManager(web3._requestManager) + def getString(self, *args, **kwargs): + raise DeprecationWarning("This function has been deprecated") + + def putHex(self, *args, **kwargs): + raise DeprecationWarning("This function has been deprecated") + + def getHex(self, *args, **kwargs): + raise DeprecationWarning("This function has been deprecated") diff --git a/web3/web3/methods/shh.py b/web3/web3/methods/shh.py index 1d7a154..9c8c464 100644 --- a/web3/web3/methods/shh.py +++ b/web3/web3/methods/shh.py @@ -1,6 +1,7 @@ -from web3.web3.method import Method import web3.web3.formatters as formatters + +# TODO: remove this list methods = [ { "name": "post", @@ -32,11 +33,23 @@ methods = [ class Shh(object): + """ + TODO: flesh this out. + """ + def __init__(self, request_manager): + self.request_manager = request_manager - def __init__(self, web3): - self._requestManager = web3._requestManager + def post(self, *args, **kwargs): + raise NotImplementedError("Not Implemented") - for method in methods: - method = Method(method) - method.attachToObject(self) - method.setRequestManager(web3._requestManager) + def newIdentity(self, *args, **kwargs): + raise NotImplementedError("Not Implemented") + + def hasIdentity(self, *args, **kwargs): + raise NotImplementedError("Not Implemented") + + def newGroup(self, *args, **kwargs): + raise NotImplementedError("Not Implemented") + + def addToGroup(self, *args, **kwargs): + raise NotImplementedError("Not Implemented") diff --git a/web3/web3/requestmanager.py b/web3/web3/requestmanager.py index 5d2127b..c1b43e0 100644 --- a/web3/web3/requestmanager.py +++ b/web3/web3/requestmanager.py @@ -1,12 +1,8 @@ -import web3.web3.exceptions as exceptions -from web3.web3.jsonrpc import Jsonrpc - import uuid +import json import gevent - - class RequestManager(object): def __init__(self, provider): self.pending_requests = {} @@ -16,11 +12,22 @@ class RequestManager(object): """ Make a synchronous request using the provider """ - return self.provider.make_request(method, params) + response_raw = self.provider.make_request(method, params) + + response = json.loads(response_raw) + + if "error" in response: + raise ValueError(response["error"]) + + return response['result'] def request_async(self, method, params): request_id = uuid.uuid4() - self.pending_requests[request_id] = gevent.spawn(self.request_blocking, method, params) + self.pending_requests[request_id] = gevent.spawn( + self.request_blocking, + method, + params, + ) return request_id def receive_blocking(self, request_id, timeout=None): @@ -31,7 +38,14 @@ class RequestManager(object): else: if timeout is not None: timeout = gevent.Timeout(timeout).start() - return request.get(timeout=timeout) + response_raw = request.get(timeout=timeout) + + response = json.loads(response_raw) + + if "error" in response: + raise ValueError(response["error"]) + + return response['result'] def receive_async(self, request_id, *args, **kwargs): raise NotImplementedError("Callback pattern not implemented")