diff --git a/pyethapp/jsonrpc.py b/pyethapp/jsonrpc.py index ca311ecb..70bb9c89 100644 --- a/pyethapp/jsonrpc.py +++ b/pyethapp/jsonrpc.py @@ -540,7 +540,12 @@ def filter_decoder(filter_dict, chain): if 'topics' in filter_dict: topics = [] for topic in filter_dict['topics']: - if topic is not None: + if type(topic) == list: + or_topics = [] + for or_topic in topic: + or_topics.append(big_endian_to_int(data_decoder(or_topic))) + topics.append(or_topics) + elif topic is not None: log.debug('with topic', topic=topic) log.debug('decoded', topic=data_decoder(topic)) log.debug('int', topic=big_endian_to_int(data_decoder(topic))) @@ -1295,7 +1300,11 @@ def __init__(self, chain, first_block, last_block, addresses=None, topics=None): self.topics = topics if self.topics: for topic in self.topics: - assert topic is None or is_numeric(topic) + assert topic is None or is_numeric(topic) \ + or type(topic) == list + if type(topic) == list: + for or_topic in topic: + assert or_topic is None or is_numeric(or_topic) self.last_head = self.chain.head self.last_block_checked = None @@ -1352,6 +1361,7 @@ def check(self): # go through all receipts of all blocks # logger.debug('blocks to check', blocks=blocks_to_check) new_logs = {} + for i, block in enumerate(blocks_to_check): if not isinstance(block, (ethereum.blocks.Block, ethereum.blocks.CachedBlock)): _bloom = self.chain.get_bloom(block) @@ -1365,9 +1375,30 @@ def check(self): if not pass_address_check: continue # Check that the bloom for this block contains all of the desired topics - _topic_bloom = bloom.bloom_from_list(map(int32.serialize, self.topics or [])) - if bloom.bloom_combine(_bloom, _topic_bloom) != _bloom: - continue + or_topics = list() + and_topics = list() + for topic in self.topics or []: + if type(topic) == list: + or_topics += topic + else: + and_topics.append(topic) + if or_topics: + # In case of the frequent usage of multiple 'or' statements in the filter + # the following logic should be optimized so that the fewer amount of blocks gets checked. + # It is currently optimal for filters with a single 'or' statement. + _topic_and_bloom = bloom.bloom_from_list(map(int32.serialize, and_topics or [])) + bloom_passed = False + for or_t in or_topics: + or_bl = bloom.bloom_from_list(map(int32.serialize, [or_t])) + if bloom.bloom_combine(_bloom, _topic_and_bloom, or_bl) == _bloom: + bloom_passed = True + break + if not bloom_passed: + continue + else: + _topic_bloom = bloom.bloom_from_list(map(int32.serialize, self.topics or [])) + if bloom.bloom_combine(_bloom, _topic_bloom) != _bloom: + continue block = self.chain.get(block) print 'bloom filter passed' logger.debug('-') @@ -1384,8 +1415,13 @@ def check(self): topic_match = False for filter_topic, log_topic in zip(self.topics, log.topics): if filter_topic is not None and filter_topic != log_topic: - logger.debug('topic mismatch', want=filter_topic, have=log_topic) - topic_match = False + if type(filter_topic) == list: + if log_topic not in filter_topic: + logger.debug('topic mismatch', want=filter_topic, have=log_topic) + topic_match = False + else: + logger.debug('topic mismatch', want=filter_topic, have=log_topic) + topic_match = False if not topic_match: continue # check for address diff --git a/pyethapp/rpc_client.py b/pyethapp/rpc_client.py index dba809f8..65e89126 100644 --- a/pyethapp/rpc_client.py +++ b/pyethapp/rpc_client.py @@ -117,10 +117,13 @@ class JSONRPCClient(object): protocol = JSONRPCProtocol() def __init__(self, host='127.0.0.1', port=4000, print_communication=True, - privkey=None, sender=None, use_ssl=False): + privkey=None, sender=None, use_ssl=False, transport=None): "specify privkey for local signing" - self.transport = HttpPostClientTransport('{}://{}:{}'.format( - 'https' if use_ssl else 'http', host, port)) + if transport is None: + self.transport = HttpPostClientTransport('{}://{}:{}'.format( + 'https' if use_ssl else 'http', host, port)) + else: + self.transport = transport self.print_communication = print_communication self.privkey = privkey self._sender = sender diff --git a/pyethapp/tests/test_jsonrpc.py b/pyethapp/tests/test_jsonrpc.py index 87f307e5..6b980055 100644 --- a/pyethapp/tests/test_jsonrpc.py +++ b/pyethapp/tests/test_jsonrpc.py @@ -4,6 +4,7 @@ from itertools import count import gevent import gc +import json import pytest import rlp @@ -24,14 +25,18 @@ from pyethapp.eth_service import ChainService from pyethapp.jsonrpc import Compilers, JSONRPCServer, quantity_encoder, address_encoder, data_decoder, \ data_encoder, default_gasprice, default_startgas +from pyethapp.rpc_client import JSONRPCClient +from tinyrpc.protocols.jsonrpc import JSONRPCProtocol from pyethapp.profiles import PROFILES from pyethapp.pow_service import PoWService +from ethereum import _solidity +from ethereum.abi import event_id, normalize_name +from pyethapp.rpc_client import ContractProxy ethereum.keys.PBKDF2_CONSTANTS['c'] = 100 # faster key derivation log = get_logger('test.jsonrpc') # pylint: disable=invalid-name SOLIDITY_AVAILABLE = 'solidity' in Compilers().compilers - # EVM code corresponding to the following solidity code: # # contract LogTest { @@ -123,6 +128,19 @@ def test_compile_solidity(): PROFILES['testnet']['eth']['block']['ACCOUNT_INITIAL_NONCE']]) def test_app(request, tmpdir): + class TestTransport(object): + def __init__(self, call_func): + self.call_func = call_func + + def send_message(self, request): + request = json.loads(request) + method = request.get('method') + args = request.get('params') + if not args: + return self.call_func(method) + else: + return self.call_func(method, *args) + class TestApp(EthApp): def start(self): @@ -136,7 +154,10 @@ def start(self): locked_account = Account.new('', tester.keys[2]) locked_account.lock() self.services.accounts.add_account(locked_account, store=False) + self.privkey = None assert set(acct.address for acct in self.services.accounts) == set(tester.accounts[:3]) + test_transport = TestTransport(call_func=self.rpc_request) + self.client = JSONRPCClient(transport=test_transport) def mine_next_block(self): """Mine until a valid nonce is found. @@ -156,7 +177,7 @@ def mine_next_block(self): assert self.services.chain.chain.head.difficulty == 1 return self.services.chain.chain.head - def rpc_request(self, method, *args): + def rpc_request(self, method, *args, **kwargs): """Simulate an incoming JSON RPC request and return the result. Example:: @@ -164,11 +185,11 @@ def rpc_request(self, method, *args): >>> assert test_app.rpc_request('eth_getBalance', '0x' + 'ff' * 20) == '0x0' """ - log.debug('simulating rpc request', method=method) + log.debug('simulating rpc request', method=method, call_args=args, call_kwargs=kwargs) method = self.services.jsonrpc.dispatcher.get_method(method) - res = method(*args) + res = method(*args, **kwargs) log.debug('got response', response=res) - return res + return json.dumps(dict(result=res, jsonrpc=JSONRPCProtocol.JSON_RPC_VERSION, id=42)) config = { 'data_dir': str(tmpdir), @@ -225,6 +246,285 @@ def fin(): return app +def get_event(full_abi, event_name): + for description in full_abi: + name = description.get('name') + + # skip constructors + if name is None: + continue + + normalized_name = normalize_name(name) + + if normalized_name == event_name: + return description + + +def get_eventname_types(event_description): + if 'name' not in event_description: + raise ValueError('Not an event description, missing the name.') + + name = normalize_name(event_description['name']) + encode_types = [ + element['type'] + for element in event_description['inputs'] + ] + return name, encode_types + + +sample_sol_code = """ + +contract SampleContract { + uint256 balance1 = 0; + uint256 balance2 = 0; + uint256 balance3 = 0; + event Event1(address bidder, uint256 indexed amount); + event Event2(address bidder, uint256 indexed amount1, uint256 indexed amount2); + event Event3(address bidder, uint256 indexed amount1, uint256 indexed amount2, uint256 indexed amount3); + + function trigger1(uint256 amount) + { + balance1 += amount; + Event1(msg.sender, balance1); + } + function trigger2(uint256 amount) { + balance2 += amount; + Event2(msg.sender, balance1, balance2); + } + function trigger3(uint256 amount) { + balance3 += amount; + Event3(msg.sender, balance1, balance2, balance3); + } + function getbalance1() + constant + returns (uint256) + { + return balance1; + } + function getbalance2() + constant + returns (uint256) + { + return balance2; + } + function getbalance3() + constant + returns (uint256) + { + return balance3; + } +} + +""" + + +def test_logfilters_topics(test_app): + # slogging.configure(':trace') + sample_compiled = _solidity.compile_code( + sample_sol_code, + combined='bin,abi', + ) + + theabi = sample_compiled['SampleContract']['abi'] + theevm = sample_compiled['SampleContract']['bin_hex'] + + sender_address = test_app.services.accounts.unlocked_accounts[0].address + sender = address_encoder(sender_address) + + event1 = get_event(theabi, 'Event1') + event2 = get_event(theabi, 'Event2') + event3 = get_event(theabi, 'Event3') + event1_id = event_id(*get_eventname_types(event1)) + event2_id = event_id(*get_eventname_types(event2)) + event3_id = event_id(*get_eventname_types(event3)) + + test_app.mine_next_block() # start with a fresh block + + n0 = test_app.services.chain.chain.head.number + assert n0 == 1 + + contract_creation = { + 'from': sender, + 'data': '0x' + theevm, + 'gas': quantity_encoder(1000000) + } + + tx_hash = test_app.client.call('eth_sendTransaction', contract_creation) + test_app.mine_next_block() + receipt = test_app.client.call('eth_getTransactionReceipt', tx_hash) + contract_address = receipt['contractAddress'] + + sample_contract = ContractProxy(sender_address, theabi, contract_address, + test_app.client.call, test_app.client.send_transaction) + + topic1 = hex(event1_id).rstrip("L") + topic2 = hex(event2_id).rstrip("L") + topic3 = hex(event3_id).rstrip("L") + topica, topicb, topicc = \ + '0x0000000000000000000000000000000000000000000000000000000000000001',\ + '0x0000000000000000000000000000000000000000000000000000000000000064',\ + '0x00000000000000000000000000000000000000000000000000000000000003e8' + topic_filter_1 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic1] + }) + topic_filter_2 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic2] + }) + topic_filter_3 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic3] + }) + topic_filter_4 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic1, topica] + }) + + topic_filter_5 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic2, topica, topicb] + }) + topic_filter_6 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic3, topica, topicb, topicc] + }) + topic_filter_7 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topica, topicb, topicc] + }) + topic_filter_8 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic3, topica, topicb] + }) + topic_filter_9 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topicc, topicb, topica, topic3] + }) + topic_filter_10 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topicb, topicc, topica, topic3] + }) + topic_filter_11 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic2, topica] + }) + topic_filter_12 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic3, topica] + }) + topic_filter_13 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topica, topicb] + }) + topic_filter_14 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic2, [topica, topicb]] + }) + topic_filter_15 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [[topic1, topic2], topica] + }) + topic_filter_16 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [[topic1, topic2, topic3]] + }) + topic_filter_17 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [[topic1, topic2, topic3, topica, topicb, topicc]] + }) + topic_filter_18 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic2, topica, topicb, [topic2, topica, topicb]] + }) + topic_filter_19 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [topic1, topica, topicb] + }) + topic_filter_20 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [[topic1, topic2], [topica, topicb], [topica, topicb]] + }) + topic_filter_21 = test_app.client.call('eth_newFilter', { + 'fromBlock': 0, + 'toBlock': 'pending', + 'topics': [[topic2, topic3], [topica, topicb], [topica, topicb]] + }) + + thecode = test_app.client.call('eth_getCode', address_encoder(sample_contract.address)) + assert len(thecode) > 2 + + sample_contract.trigger1(1) + test_app.mine_next_block() + sample_contract.trigger2(100) + test_app.mine_next_block() + sample_contract.trigger3(1000) + test_app.mine_next_block() + + tl1 = test_app.client.call('eth_getFilterChanges', topic_filter_1) + assert len(tl1) == 1 + tl2 = test_app.client.call('eth_getFilterChanges', topic_filter_2) + assert len(tl2) == 1 + tl3 = test_app.client.call('eth_getFilterChanges', topic_filter_3) + assert len(tl3) == 1 + tl4 = test_app.client.call('eth_getFilterChanges', topic_filter_4) + assert len(tl4) == 1 + tl5 = test_app.client.call('eth_getFilterChanges', topic_filter_5) + assert len(tl5) == 1 + tl6 = test_app.client.call('eth_getFilterChanges', topic_filter_6) + assert len(tl6) == 1 + tl7 = test_app.client.call('eth_getFilterChanges', topic_filter_7) + assert len(tl7) == 0 + tl8 = test_app.client.call('eth_getFilterChanges', topic_filter_8) + assert len(tl8) == 1 + tl9 = test_app.client.call('eth_getFilterChanges', topic_filter_9) + assert len(tl9) == 0 + tl10 = test_app.client.call('eth_getFilterChanges', topic_filter_10) + assert len(tl10) == 0 + tl11 = test_app.client.call('eth_getFilterChanges', topic_filter_11) + assert len(tl11) == 1 + tl12 = test_app.client.call('eth_getFilterChanges', topic_filter_12) + assert len(tl12) == 1 + tl13 = test_app.client.call('eth_getFilterChanges', topic_filter_13) + assert len(tl13) == 0 + tl14 = test_app.client.call('eth_getFilterChanges', topic_filter_14) + assert len(tl14) == 1 + tl15 = test_app.client.call('eth_getFilterChanges', topic_filter_15) + assert len(tl15) == 2 + tl16 = test_app.client.call('eth_getFilterChanges', topic_filter_16) + assert len(tl16) == 3 + tl17 = test_app.client.call('eth_getFilterChanges', topic_filter_17) + assert len(tl17) == 3 + tl18 = test_app.client.call('eth_getFilterChanges', topic_filter_18) + assert len(tl18) == 0 + tl19 = test_app.client.call('eth_getFilterChanges', topic_filter_19) + assert len(tl19) == 0 + tl20 = test_app.client.call('eth_getFilterChanges', topic_filter_20) + assert len(tl20) == 1 + tl21 = test_app.client.call('eth_getFilterChanges', topic_filter_21) + assert len(tl21) == 2 + + def test_send_transaction(test_app): chain = test_app.services.chain.chain assert chain.head_candidate.get_balance('\xff' * 20) == 0 @@ -235,7 +535,7 @@ def test_send_transaction(test_app): 'to': address_encoder('\xff' * 20), 'value': quantity_encoder(1) } - tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx)) + tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx)) assert tx_hash == chain.head_candidate.get_transaction(0).hash assert chain.head_candidate.get_balance('\xff' * 20) == 1 test_app.mine_next_block() @@ -244,7 +544,7 @@ def test_send_transaction(test_app): # send transactions from account which can't pay gas tx['from'] = address_encoder(test_app.services.accounts.unlocked_accounts[1].address) - tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx)) + tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx)) assert chain.head_candidate.get_transactions() == [] @@ -264,7 +564,7 @@ def main(a,b): 'to': address_encoder(tx_to), 'data': evm_code.encode('hex') } - data_decoder(test_app.rpc_request('eth_sendTransaction', tx)) + data_decoder(test_app.client.call('eth_sendTransaction', tx)) creates = chain.head_candidate.get_transaction(0).creates code = chain.head_candidate.account_to_dict(creates)['code'] @@ -294,7 +594,7 @@ def main(a,b): tx = ethereum.transactions.Transaction(nonce, default_gasprice, default_startgas, tx_to, 0, evm_code, 0, 0, 0) test_app.services.accounts.sign_tx(sender, tx) raw_transaction = data_encoder(rlp.codec.encode(tx, ethereum.transactions.Transaction)) - data_decoder(test_app.rpc_request('eth_sendRawTransaction', raw_transaction)) + data_decoder(test_app.client.call('eth_sendRawTransaction', raw_transaction)) creates = chain.head_candidate.get_transaction(0).creates code = chain.head_candidate.account_to_dict(creates)['code'] @@ -310,8 +610,8 @@ def main(a,b): def test_pending_transaction_filter(test_app): - filter_id = test_app.rpc_request('eth_newPendingTransactionFilter') - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == [] + filter_id = test_app.client.call('eth_newPendingTransactionFilter') + assert test_app.client.call('eth_getFilterChanges', filter_id) == [] tx = { 'from': address_encoder(test_app.services.accounts.unlocked_accounts[0].address), 'to': address_encoder('\xff' * 20) @@ -321,13 +621,13 @@ def test_sequence(s): tx_hashes = [] for c in s: if c == 't': - tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx)) + tx_hashes.append(test_app.client.call('eth_sendTransaction', tx)) elif c == 'b': test_app.mine_next_block() else: assert False - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == tx_hashes - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == [] + assert test_app.client.call('eth_getFilterChanges', filter_id) == tx_hashes + assert test_app.client.call('eth_getFilterChanges', filter_id) == [] sequences = [ 't', @@ -342,15 +642,15 @@ def test_sequence(s): def test_new_block_filter(test_app): - filter_id = test_app.rpc_request('eth_newBlockFilter') - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == [] + filter_id = test_app.client.call('eth_newBlockFilter') + assert test_app.client.call('eth_getFilterChanges', filter_id) == [] h = test_app.mine_next_block().hash - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == [data_encoder(h)] - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == [] + assert test_app.client.call('eth_getFilterChanges', filter_id) == [data_encoder(h)] + assert test_app.client.call('eth_getFilterChanges', filter_id) == [] hashes = [data_encoder(test_app.mine_next_block().hash) for i in range(3)] - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == hashes - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == [] - assert test_app.rpc_request('eth_getFilterChanges', filter_id) == [] + assert test_app.client.call('eth_getFilterChanges', filter_id) == hashes + assert test_app.client.call('eth_getFilterChanges', filter_id) == [] + assert test_app.client.call('eth_getFilterChanges', filter_id) == [] def test_get_logs(test_app): @@ -361,9 +661,9 @@ def test_get_logs(test_app): 'from': sender, 'data': data_encoder(LOG_EVM) } - tx_hash = test_app.rpc_request('eth_sendTransaction', contract_creation) + tx_hash = test_app.client.call('eth_sendTransaction', contract_creation) test_app.mine_next_block() - receipt = test_app.rpc_request('eth_getTransactionReceipt', tx_hash) + receipt = test_app.client.call('eth_getTransactionReceipt', tx_hash) contract_address = receipt['contractAddress'] tx = { 'from': sender, @@ -371,8 +671,8 @@ def test_get_logs(test_app): } # single log in pending block - test_app.rpc_request('eth_sendTransaction', tx) - logs1 = test_app.rpc_request('eth_getLogs', { + test_app.client.call('eth_sendTransaction', tx) + logs1 = test_app.client.call('eth_getLogs', { 'fromBlock': 'pending', 'toBlock': 'pending' }) @@ -385,7 +685,7 @@ def test_get_logs(test_app): assert logs1[0]['blockNumber'] is None assert logs1[0]['address'] == contract_address - logs2 = test_app.rpc_request('eth_getLogs', { + logs2 = test_app.client.call('eth_getLogs', { 'fromBlock': 'pending', 'toBlock': 'pending' }) @@ -393,7 +693,7 @@ def test_get_logs(test_app): # same log, but now mined in head test_app.mine_next_block() - logs3 = test_app.rpc_request('eth_getLogs', { + logs3 = test_app.client.call('eth_getLogs', { 'fromBlock': 'latest', 'toBlock': 'latest' }) @@ -406,16 +706,16 @@ def test_get_logs(test_app): assert logs3[0]['address'] == contract_address # another log in pending block - test_app.rpc_request('eth_sendTransaction', tx) - logs4 = test_app.rpc_request('eth_getLogs', { + test_app.client.call('eth_sendTransaction', tx) + logs4 = test_app.client.call('eth_getLogs', { 'fromBlock': 'latest', 'toBlock': 'pending' }) assert logs4 == [logs1[0], logs3[0]] or logs4 == [logs3[0], logs1[0]] # two logs in pending block - test_app.rpc_request('eth_sendTransaction', tx) - logs5 = test_app.rpc_request('eth_getLogs', { + test_app.client.call('eth_sendTransaction', tx) + logs5 = test_app.client.call('eth_getLogs', { 'fromBlock': 'pending', 'toBlock': 'pending' }) @@ -424,7 +724,7 @@ def test_get_logs(test_app): # two logs in head test_app.mine_next_block() - logs6 = test_app.rpc_request('eth_getLogs', { + logs6 = test_app.client.call('eth_getLogs', { 'fromBlock': 'latest', 'toBlock': 'pending' }) @@ -437,8 +737,8 @@ def test_get_logs(test_app): assert sorted([log['transactionIndex'] for log in logs6]) == ['0x0', '0x1'] # everything together with another log in pending block - test_app.rpc_request('eth_sendTransaction', tx) - logs7 = test_app.rpc_request('eth_getLogs', { + test_app.client.call('eth_sendTransaction', tx) + logs7 = test_app.client.call('eth_getLogs', { 'fromBlock': quantity_encoder(n0), 'toBlock': 'pending' }) @@ -454,29 +754,30 @@ def test_get_filter_changes(test_app): 'from': sender, 'data': data_encoder(LOG_EVM) } - tx_hash = test_app.rpc_request('eth_sendTransaction', contract_creation) + tx_hash = test_app.client.call('eth_sendTransaction', contract_creation) test_app.mine_next_block() - receipt = test_app.rpc_request('eth_getTransactionReceipt', tx_hash) + receipt = test_app.client.call('eth_getTransactionReceipt', tx_hash) contract_address = receipt['contractAddress'] tx = { 'from': sender, 'to': contract_address } - pending_filter_id = test_app.rpc_request('eth_newFilter', { + pending_filter_id = test_app.client.call('eth_newFilter', { 'fromBlock': 'pending', 'toBlock': 'pending' }) - latest_filter_id = test_app.rpc_request('eth_newFilter', { + latest_filter_id = test_app.client.call('eth_newFilter', { 'fromBlock': 'latest', 'toBlock': 'latest' }) + tx_hashes = [] logs = [] # tx in pending block - tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx)) - logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id)) + tx_hashes.append(test_app.client.call('eth_sendTransaction', tx)) + logs.append(test_app.client.call('eth_getFilterChanges', pending_filter_id)) assert len(logs[-1]) == 1 assert logs[-1][0]['type'] == 'pending' assert logs[-1][0]['logIndex'] is None @@ -487,14 +788,14 @@ def test_get_filter_changes(test_app): assert logs[-1][0]['address'] == contract_address pending_log = logs[-1][0] - logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id)) + logs.append(test_app.client.call('eth_getFilterChanges', pending_filter_id)) assert logs[-1] == [] - logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id)) + logs.append(test_app.client.call('eth_getFilterChanges', latest_filter_id)) assert logs[-1] == [] test_app.mine_next_block() - logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id)) + logs.append(test_app.client.call('eth_getFilterChanges', latest_filter_id)) assert len(logs[-1]) == 1 # log from before, but now mined assert logs[-1][0]['type'] == 'mined' assert logs[-1][0]['logIndex'] == '0x0' @@ -506,9 +807,9 @@ def test_get_filter_changes(test_app): logs_in_range = [logs[-1][0]] # send tx and mine block - tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx)) + tx_hashes.append(test_app.client.call('eth_sendTransaction', tx)) test_app.mine_next_block() - logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id)) + logs.append(test_app.client.call('eth_getFilterChanges', pending_filter_id)) assert len(logs[-1]) == 1 assert logs[-1][0]['type'] == 'mined' assert logs[-1][0]['logIndex'] == '0x0' @@ -519,22 +820,22 @@ def test_get_filter_changes(test_app): assert logs[-1][0]['address'] == contract_address logs_in_range.append(logs[-1][0]) - logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id)) + logs.append(test_app.client.call('eth_getFilterChanges', latest_filter_id)) assert logs[-1] == logs[-2] # latest and pending filter see same (mined) log - logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id)) + logs.append(test_app.client.call('eth_getFilterChanges', latest_filter_id)) assert logs[-1] == [] test_app.mine_next_block() - logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id)) + logs.append(test_app.client.call('eth_getFilterChanges', pending_filter_id)) assert logs[-1] == [] - range_filter_id = test_app.rpc_request('eth_newFilter', { + range_filter_id = test_app.client.call('eth_newFilter', { 'fromBlock': quantity_encoder(test_app.services.chain.chain.head.number - 3), 'toBlock': 'pending' }) - tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx)) - logs.append(test_app.rpc_request('eth_getFilterChanges', range_filter_id)) + tx_hashes.append(test_app.client.call('eth_sendTransaction', tx)) + logs.append(test_app.client.call('eth_getFilterChanges', range_filter_id)) assert sorted(logs[-1]) == sorted(logs_in_range + [pending_log]) @@ -545,20 +846,20 @@ def test_eth_nonce(test_app): :param test_app: :return: """ - assert test_app.rpc_request('eth_getTransactionCount', address_encoder(tester.accounts[0])) == '0x0' + assert test_app.client.call('eth_getTransactionCount', address_encoder(tester.accounts[0])) == '0x0' assert ( - int(test_app.rpc_request('eth_nonce', address_encoder(tester.accounts[0])), 16) == + int(test_app.client.call('eth_nonce', address_encoder(tester.accounts[0])), 16) == test_app.config['eth']['block']['ACCOUNT_INITIAL_NONCE']) - assert test_app.rpc_request('eth_sendTransaction', dict(sender=address_encoder(tester.accounts[0]), to='')) - assert test_app.rpc_request('eth_getTransactionCount', address_encoder(tester.accounts[0])) == '0x1' + assert test_app.client.call('eth_sendTransaction', dict(sender=address_encoder(tester.accounts[0]), to='')) + assert test_app.client.call('eth_getTransactionCount', address_encoder(tester.accounts[0])) == '0x1' assert ( - int(test_app.rpc_request('eth_nonce', address_encoder(tester.accounts[0])), 16) == + int(test_app.client.call('eth_nonce', address_encoder(tester.accounts[0])), 16) == test_app.config['eth']['block']['ACCOUNT_INITIAL_NONCE'] + 1) - assert test_app.rpc_request('eth_sendTransaction', dict(sender=address_encoder(tester.accounts[0]), to='')) - assert test_app.rpc_request('eth_getTransactionCount', address_encoder(tester.accounts[0])) == '0x2' + assert test_app.client.call('eth_sendTransaction', dict(sender=address_encoder(tester.accounts[0]), to='')) + assert test_app.client.call('eth_getTransactionCount', address_encoder(tester.accounts[0])) == '0x2' test_app.mine_next_block() assert test_app.services.chain.chain.head.number == 1 assert ( - int(test_app.rpc_request('eth_nonce', address_encoder(tester.accounts[0])), 16) == + int(test_app.client.call('eth_nonce', address_encoder(tester.accounts[0])), 16) == test_app.config['eth']['block']['ACCOUNT_INITIAL_NONCE'] + 2)