@@ -35,39 +35,70 @@ 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
),
88
+ (
89
+ build_request ('eth_accounts' ),
90
+ {'result' : [], 'id' : 3 , 'jsonrpc' : '2.0' },
91
+ ),
58
92
(
59
93
build_request ('eth_mining' ),
60
- MockPeerPool (),
61
94
{'result' : False , 'id' : 3 , 'jsonrpc' : '2.0' },
62
95
),
63
96
(
64
97
build_request ('web3_clientVersion' ),
65
- MockPeerPool (),
66
98
{'result' : construct_trinity_client_identifier (), 'id' : 3 , 'jsonrpc' : '2.0' },
67
99
),
68
100
(
69
101
build_request ('web3_sha3' , ['0x89987239849872' ]),
70
- MockPeerPool (),
71
102
{
72
103
'result' : '0xb3406131994d9c859de3c4400e12f630638e1e992c6453358c16d0e6ce2b1a70' ,
73
104
'id' : 3 ,
@@ -76,7 +107,6 @@ def p2p_server(monkeypatch, p2p_server, mock_peer_pool):
76
107
),
77
108
(
78
109
build_request ('web3_sha3' , ['0x' ]),
79
- MockPeerPool (),
80
110
{
81
111
'result' : '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' ,
82
112
'id' : 3 ,
@@ -85,9 +115,119 @@ def p2p_server(monkeypatch, p2p_server, mock_peer_pool):
85
115
),
86
116
(
87
117
build_request ('net_version' ),
88
- MockPeerPool (),
89
118
{'result' : '1337' , 'id' : 3 , 'jsonrpc' : '2.0' },
90
119
),
120
+ (
121
+ build_request ('net_listening' ),
122
+ {'result' : True , 'id' : 3 , 'jsonrpc' : '2.0' },
123
+ ),
124
+ ),
125
+ )
126
+ async def test_ipc_requests (
127
+ jsonrpc_ipc_pipe_path ,
128
+ request_msg ,
129
+ expected ,
130
+ event_loop ,
131
+ ipc_server ):
132
+ result = await get_ipc_response (jsonrpc_ipc_pipe_path , request_msg , event_loop )
133
+ assert result == expected
134
+
135
+
136
+ @pytest .mark .asyncio
137
+ @pytest .mark .parametrize (
138
+ 'request_msg, expected' ,
139
+ (
140
+ (
141
+ # simple transaction, with all fields inferred
142
+ # (except 'to', which must be provided when not creating a contract)
143
+ build_request ('eth_estimateGas' , params = [{'to' : '0x' + '00' * 20 }, 'latest' ]),
144
+ # simple transactions are correctly identified as 21000 gas during estimation
145
+ {'result' : hex (21000 ), 'id' : 3 , 'jsonrpc' : '2.0' },
146
+ ),
147
+ (
148
+ # test block number
149
+ build_request ('eth_estimateGas' , params = [{'to' : '0x' + '00' * 20 }, '0x0' ]),
150
+ {'result' : hex (21000 ), 'id' : 3 , 'jsonrpc' : '2.0' },
151
+ ),
152
+ (
153
+ # another simple transaction, with all fields provided
154
+ build_request ('eth_estimateGas' , params = [{
155
+ 'to' : '0x' + '00' * 20 ,
156
+ 'from' : '0x' + '11' * 20 ,
157
+ 'gasPrice' : '0x2' ,
158
+ 'gas' : '0x3' ,
159
+ 'value' : '0x0' ,
160
+ 'data' : '0x' ,
161
+ }, 'latest' ]),
162
+ {'result' : hex (21000 ), 'id' : 3 , 'jsonrpc' : '2.0' },
163
+ ),
164
+ (
165
+ # try adding garbage data to increase estimate
166
+ build_request ('eth_estimateGas' , params = [{
167
+ 'to' : '0x' + '00' * 20 ,
168
+ 'data' : '0x01' ,
169
+ }, 'latest' ]),
170
+ {'result' : hex (21068 ), 'id' : 3 , 'jsonrpc' : '2.0' },
171
+ ),
172
+ (
173
+ # deploy a tiny contract
174
+ build_request ('eth_estimateGas' , params = [{
175
+ 'data' : '0x3838533838f3' ,
176
+ }, 'latest' ]),
177
+ {'result' : hex (65483 ), 'id' : 3 , 'jsonrpc' : '2.0' },
178
+ ),
179
+ (
180
+ # specifying v,r,s is invalid
181
+ build_request ('eth_estimateGas' , params = [{
182
+ 'v' : '0x' + '00' * 20 ,
183
+ 'r' : '0x' + '00' * 20 ,
184
+ 's' : '0x' + '00' * 20 ,
185
+ }, 'latest' ]),
186
+ {
187
+ 'error' : "The following invalid fields were given in a transaction: ['r', 's', 'v']. Only ['data', 'from', 'gas', 'gasPrice', 'to', 'value'] are allowed" , # noqa: E501
188
+ 'id' : 3 ,
189
+ 'jsonrpc' : '2.0' ,
190
+ }
191
+ ),
192
+ (
193
+ # specifying gas_price is invalid
194
+ build_request ('eth_estimateGas' , params = [{
195
+ 'gas_price' : '0x0' ,
196
+ }, 'latest' ]),
197
+ {
198
+ 'error' : "The following invalid fields were given in a transaction: ['gas_price']. Only ['data', 'from', 'gas', 'gasPrice', 'to', 'value'] are allowed" , # noqa: E501
199
+ 'id' : 3 ,
200
+ 'jsonrpc' : '2.0' ,
201
+ }
202
+ ),
203
+ (
204
+ # specifying nonce is invalid
205
+ build_request ('eth_estimateGas' , params = [{
206
+ 'nonce' : '0x01' ,
207
+ }, 'latest' ]),
208
+ {
209
+ 'error' : "The following invalid fields were given in a transaction: ['nonce']. Only ['data', 'from', 'gas', 'gasPrice', 'to', 'value'] are allowed" , # noqa: E501
210
+ 'id' : 3 ,
211
+ 'jsonrpc' : '2.0' ,
212
+ }
213
+ ),
214
+ ),
215
+ ids = id_from_rpc_request ,
216
+ )
217
+ async def test_estimate_gas_on_ipc (
218
+ jsonrpc_ipc_pipe_path ,
219
+ request_msg ,
220
+ expected ,
221
+ event_loop ,
222
+ ipc_server ):
223
+ result = await get_ipc_response (jsonrpc_ipc_pipe_path , request_msg , event_loop )
224
+ assert result == expected
225
+
226
+
227
+ @pytest .mark .asyncio
228
+ @pytest .mark .parametrize (
229
+ 'request_msg, mock_peer_pool, expected' ,
230
+ (
91
231
(
92
232
build_request ('net_peerCount' ),
93
233
MockPeerPool (peer_count = 1 ),
@@ -98,31 +238,19 @@ def p2p_server(monkeypatch, p2p_server, mock_peer_pool):
98
238
MockPeerPool (peer_count = 0 ),
99
239
{'result' : '0x0' , 'id' : 3 , 'jsonrpc' : '2.0' },
100
240
),
101
- (
102
- build_request ('net_listening' ),
103
- MockPeerPool (),
104
- {'result' : True , 'id' : 3 , 'jsonrpc' : '2.0' },
105
- ),
106
241
),
107
242
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' ,
243
+ 'net_peerCount_1' , 'net_peerCount_0' ,
111
244
],
112
245
)
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 ())
246
+ async def test_peer_pool_over_ipc (
247
+ monkeypatch ,
248
+ jsonrpc_ipc_pipe_path ,
249
+ request_msg ,
250
+ mock_peer_pool ,
251
+ expected ,
252
+ event_loop ,
253
+ ipc_server ):
254
+ monkeypatch .setattr (ipc_server .rpc .modules ['net' ], '_peer_pool' , mock_peer_pool )
255
+ result = await get_ipc_response (jsonrpc_ipc_pipe_path , request_msg , event_loop )
127
256
assert result == expected
128
- writer .close ()
0 commit comments