Skip to content

Commit 02a82f2

Browse files
committed
added a check for POA extraData
fixed linting errors
1 parent c8320cc commit 02a82f2

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

tests/core/eth-module/test_poa.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import pytest
22

3+
from web3.exceptions import (
4+
ValidationError,
5+
)
36
from web3.middleware import (
47
construct_fixture_middleware,
58
geth_poa_middleware,
@@ -12,7 +15,7 @@ def test_long_extra_data(web3):
1215
'eth_getBlockByNumber': {'extraData': '0x' + 'ff' * 33},
1316
})
1417
web3.middleware_stack.inject(return_block_with_long_extra_data, layer=0)
15-
with pytest.raises(ValueError):
18+
with pytest.raises(ValidationError):
1619
web3.eth.getBlock('latest')
1720

1821

web3/middleware/validation.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
from cytoolz import (
2+
complement,
23
compose,
34
curry,
45
dissoc,
56
)
67
from eth_utils.curried import (
78
apply_formatter_at_index,
9+
apply_formatter_if,
810
apply_formatters_to_dict,
11+
is_null,
12+
)
13+
from hexbytes import (
14+
HexBytes,
915
)
1016

1117
from web3.exceptions import (
@@ -15,6 +21,11 @@
1521
construct_web3_formatting_middleware,
1622
)
1723

24+
MAX_EXTRADATA_LENGTH = 32
25+
26+
27+
is_not_null = complement(is_null)
28+
1829

1930
@curry
2031
def validate_chain_id(web3, chain_id):
@@ -30,6 +41,23 @@ def validate_chain_id(web3, chain_id):
3041
)
3142

3243

44+
def check_extradata_length(val):
45+
if not isinstance(val, (str, int, bytes)):
46+
return val
47+
result = HexBytes(val)
48+
if len(result) > MAX_EXTRADATA_LENGTH:
49+
raise ValidationError(
50+
"The field extraData is %d bytes, but should be %d. "
51+
"It is quite likely that you are connected to a POA chain. "
52+
"Refer "
53+
"http://web3py.readthedocs.io/en/latest/middleware.html#geth-style-proof-of-authority "
54+
"for more details. The full extraData is: %r" % (
55+
len(result), MAX_EXTRADATA_LENGTH, result
56+
)
57+
)
58+
return val
59+
60+
3361
def transaction_normalizer(transaction):
3462
return dissoc(transaction, 'chainId')
3563

@@ -44,6 +72,14 @@ def transaction_param_validator(web3):
4472
)
4573

4674

75+
BLOCK_VALIDATORS = {
76+
'extraData': check_extradata_length,
77+
}
78+
79+
80+
block_validator = apply_formatters_to_dict(BLOCK_VALIDATORS)
81+
82+
4783
@curry
4884
def chain_id_validator(web3):
4985
return compose(
@@ -52,13 +88,20 @@ def chain_id_validator(web3):
5288
)
5389

5490

91+
extra_data_validator = apply_formatter_if(is_not_null, block_validator)
92+
93+
5594
def build_validators_with_web3(w3):
5695
return dict(
5796
request_formatters={
5897
'eth_sendTransaction': chain_id_validator(w3),
5998
'eth_estimateGas': chain_id_validator(w3),
6099
'eth_call': chain_id_validator(w3),
61-
}
100+
},
101+
result_formatters={
102+
'eth_getBlockByHash': extra_data_validator,
103+
'eth_getBlockByNumber': extra_data_validator,
104+
},
62105
)
63106

64107

0 commit comments

Comments
 (0)