@@ -35,39 +35,66 @@ def __len__(self):
35
35
return self .peer_count
36
36
37
37
38
- @pytest .fixture
39
- def p2p_server (monkeypatch , p2p_server , mock_peer_pool ):
40
- monkeypatch .setattr (p2p_server , 'peer_pool' , mock_peer_pool )
41
- return p2p_server
38
+ def id_from_rpc_request (param ):
39
+ if isinstance (param , bytes ):
40
+ request = json .loads (param .decode ())
41
+ if 'method' in request and 'params' in request :
42
+ rpc_params = (repr (p ) for p in request ['params' ])
43
+ return '%s(%s)' % (request ['method' ], ', ' .join (rpc_params ))
44
+ else :
45
+ return repr (param )
46
+ else :
47
+ return repr (param )
48
+
49
+
50
+ def can_decode_json (potential ):
51
+ try :
52
+ json .loads (potential .decode ())
53
+ return True
54
+ except json .decoder .JSONDecodeError :
55
+ return False
56
+
57
+
58
+ async def get_ipc_response (
59
+ jsonrpc_ipc_pipe_path ,
60
+ request_msg ,
61
+ event_loop ):
62
+ assert wait_for (jsonrpc_ipc_pipe_path ), "IPC server did not successfully start with IPC file"
63
+
64
+ reader , writer = await asyncio .open_unix_connection (str (jsonrpc_ipc_pipe_path ), loop = event_loop )
65
+
66
+ writer .write (request_msg )
67
+ await writer .drain ()
68
+ result_bytes = b''
69
+ while not can_decode_json (result_bytes ):
70
+ result_bytes += await asyncio .tasks .wait_for (reader .readuntil (b'}' ), 0.25 , loop = event_loop )
71
+
72
+ writer .close ()
73
+ return json .loads (result_bytes .decode ())
42
74
43
75
44
76
@pytest .mark .asyncio
45
77
@pytest .mark .parametrize (
46
- 'request_msg, mock_peer_pool, expected' ,
78
+ 'request_msg, expected' ,
47
79
(
48
80
(
49
81
b'{}' ,
50
- MockPeerPool (),
51
82
{'error' : "Invalid Request: empty" },
52
83
),
53
84
(
54
85
build_request ('notamethod' ),
55
- MockPeerPool (),
56
86
{'error' : "Invalid RPC method: 'notamethod'" , 'id' : 3 , 'jsonrpc' : '2.0' },
57
87
),
58
88
(
59
89
build_request ('eth_mining' ),
60
- MockPeerPool (),
61
90
{'result' : False , 'id' : 3 , 'jsonrpc' : '2.0' },
62
91
),
63
92
(
64
93
build_request ('web3_clientVersion' ),
65
- MockPeerPool (),
66
94
{'result' : construct_trinity_client_identifier (), 'id' : 3 , 'jsonrpc' : '2.0' },
67
95
),
68
96
(
69
97
build_request ('web3_sha3' , ['0x89987239849872' ]),
70
- MockPeerPool (),
71
98
{
72
99
'result' : '0xb3406131994d9c859de3c4400e12f630638e1e992c6453358c16d0e6ce2b1a70' ,
73
100
'id' : 3 ,
@@ -76,7 +103,6 @@ def p2p_server(monkeypatch, p2p_server, mock_peer_pool):
76
103
),
77
104
(
78
105
build_request ('web3_sha3' , ['0x' ]),
79
- MockPeerPool (),
80
106
{
81
107
'result' : '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' ,
82
108
'id' : 3 ,
@@ -85,9 +111,119 @@ def p2p_server(monkeypatch, p2p_server, mock_peer_pool):
85
111
),
86
112
(
87
113
build_request ('net_version' ),
88
- MockPeerPool (),
89
114
{'result' : '1337' , 'id' : 3 , 'jsonrpc' : '2.0' },
90
115
),
116
+ (
117
+ build_request ('net_listening' ),
118
+ {'result' : True , 'id' : 3 , 'jsonrpc' : '2.0' },
119
+ ),
120
+ ),
121
+ )
122
+ async def test_ipc_requests (
123
+ jsonrpc_ipc_pipe_path ,
124
+ request_msg ,
125
+ expected ,
126
+ event_loop ,
127
+ ipc_server ):
128
+ result = await get_ipc_response (jsonrpc_ipc_pipe_path , request_msg , event_loop )
129
+ assert result == expected
130
+
131
+
132
+ @pytest .mark .asyncio
133
+ @pytest .mark .parametrize (
134
+ 'request_msg, expected' ,
135
+ (
136
+ (
137
+ # simple transaction, with all fields inferred
138
+ # (except 'to', which must be provided when not creating a contract)
139
+ build_request ('eth_estimateGas' , params = [{'to' : '0x' + '00' * 20 }, 'latest' ]),
140
+ # simple transactions are correctly identified as 21000 gas during estimation
141
+ {'result' : hex (21000 ), 'id' : 3 , 'jsonrpc' : '2.0' },
142
+ ),
143
+ (
144
+ # test block number
145
+ build_request ('eth_estimateGas' , params = [{'to' : '0x' + '00' * 20 }, '0x0' ]),
146
+ {'result' : hex (21000 ), 'id' : 3 , 'jsonrpc' : '2.0' },
147
+ ),
148
+ (
149
+ # another simple transaction, with all fields provided
150
+ build_request ('eth_estimateGas' , params = [{
151
+ 'to' : '0x' + '00' * 20 ,
152
+ 'from' : '0x' + '11' * 20 ,
153
+ 'gasPrice' : '0x2' ,
154
+ 'gas' : '0x3' ,
155
+ 'value' : '0x0' ,
156
+ 'data' : '0x' ,
157
+ }, 'latest' ]),
158
+ {'result' : hex (21000 ), 'id' : 3 , 'jsonrpc' : '2.0' },
159
+ ),
160
+ (
161
+ # try adding garbage data to increase estimate
162
+ build_request ('eth_estimateGas' , params = [{
163
+ 'to' : '0x' + '00' * 20 ,
164
+ 'data' : '0x01' ,
165
+ }, 'latest' ]),
166
+ {'result' : hex (21068 ), 'id' : 3 , 'jsonrpc' : '2.0' },
167
+ ),
168
+ (
169
+ # deploy a tiny contract
170
+ build_request ('eth_estimateGas' , params = [{
171
+ 'data' : '0x3838533838f3' ,
172
+ }, 'latest' ]),
173
+ {'result' : hex (65483 ), 'id' : 3 , 'jsonrpc' : '2.0' },
174
+ ),
175
+ (
176
+ # specifying v,r,s is invalid
177
+ build_request ('eth_estimateGas' , params = [{
178
+ 'v' : '0x' + '00' * 20 ,
179
+ 'r' : '0x' + '00' * 20 ,
180
+ 's' : '0x' + '00' * 20 ,
181
+ }, 'latest' ]),
182
+ {
183
+ 'error' : "The following invalid fields were given in a transaction: ['r', 's', 'v']. Only ['data', 'from', 'gas', 'gasPrice', 'to', 'value'] are allowed" , # noqa: E501
184
+ 'id' : 3 ,
185
+ 'jsonrpc' : '2.0' ,
186
+ }
187
+ ),
188
+ (
189
+ # specifying gas_price is invalid
190
+ build_request ('eth_estimateGas' , params = [{
191
+ 'gas_price' : '0x0' ,
192
+ }, 'latest' ]),
193
+ {
194
+ 'error' : "The following invalid fields were given in a transaction: ['gas_price']. Only ['data', 'from', 'gas', 'gasPrice', 'to', 'value'] are allowed" , # noqa: E501
195
+ 'id' : 3 ,
196
+ 'jsonrpc' : '2.0' ,
197
+ }
198
+ ),
199
+ (
200
+ # specifying nonce is invalid
201
+ build_request ('eth_estimateGas' , params = [{
202
+ 'nonce' : '0x01' ,
203
+ }, 'latest' ]),
204
+ {
205
+ 'error' : "The following invalid fields were given in a transaction: ['nonce']. Only ['data', 'from', 'gas', 'gasPrice', 'to', 'value'] are allowed" , # noqa: E501
206
+ 'id' : 3 ,
207
+ 'jsonrpc' : '2.0' ,
208
+ }
209
+ ),
210
+ ),
211
+ ids = id_from_rpc_request ,
212
+ )
213
+ async def test_estimate_gas_on_ipc (
214
+ jsonrpc_ipc_pipe_path ,
215
+ request_msg ,
216
+ expected ,
217
+ event_loop ,
218
+ ipc_server ):
219
+ result = await get_ipc_response (jsonrpc_ipc_pipe_path , request_msg , event_loop )
220
+ assert result == expected
221
+
222
+
223
+ @pytest .mark .asyncio
224
+ @pytest .mark .parametrize (
225
+ 'request_msg, mock_peer_pool, expected' ,
226
+ (
91
227
(
92
228
build_request ('net_peerCount' ),
93
229
MockPeerPool (peer_count = 1 ),
@@ -98,31 +234,19 @@ def p2p_server(monkeypatch, p2p_server, mock_peer_pool):
98
234
MockPeerPool (peer_count = 0 ),
99
235
{'result' : '0x0' , 'id' : 3 , 'jsonrpc' : '2.0' },
100
236
),
101
- (
102
- build_request ('net_listening' ),
103
- MockPeerPool (),
104
- {'result' : True , 'id' : 3 , 'jsonrpc' : '2.0' },
105
- ),
106
237
),
107
238
ids = [
108
- 'empty' , 'notamethod' , 'eth_mining' , 'web3_clientVersion' ,
109
- 'web3_sha3_1' , 'web3_sha3_2' , 'net_version' , 'net_peerCount_1' ,
110
- 'net_peerCount_0' , 'net_listening_true' ,
239
+ 'net_peerCount_1' , 'net_peerCount_0' ,
111
240
],
112
241
)
113
- async def test_ipc_requests (jsonrpc_ipc_pipe_path ,
114
- request_msg ,
115
- expected ,
116
- event_loop ,
117
- ipc_server ):
118
- assert wait_for (jsonrpc_ipc_pipe_path ), "IPC server did not successfully start with IPC file"
119
-
120
- reader , writer = await asyncio .open_unix_connection (str (jsonrpc_ipc_pipe_path ), loop = event_loop )
121
-
122
- writer .write (request_msg )
123
- await writer .drain ()
124
- result_bytes = await asyncio .tasks .wait_for (reader .readuntil (b'}' ), 0.25 , loop = event_loop )
125
-
126
- result = json .loads (result_bytes .decode ())
242
+ async def test_peer_pool_over_ipc (
243
+ monkeypatch ,
244
+ jsonrpc_ipc_pipe_path ,
245
+ request_msg ,
246
+ mock_peer_pool ,
247
+ expected ,
248
+ event_loop ,
249
+ ipc_server ):
250
+ monkeypatch .setattr (ipc_server .rpc .modules ['net' ], '_peer_pool' , mock_peer_pool )
251
+ result = await get_ipc_response (jsonrpc_ipc_pipe_path , request_msg , event_loop )
127
252
assert result == expected
128
- writer .close ()
0 commit comments