Skip to content

Commit 21df7d9

Browse files
committed
added a check for POA extraData
fixed linting errors
1 parent f80b6db commit 21df7d9

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

@@ -48,6 +76,14 @@ def transaction_param_validator(web3):
4876
)
4977

5078

79+
BLOCK_VALIDATORS = {
80+
'extraData': check_extradata_length,
81+
}
82+
83+
84+
block_validator = apply_formatters_to_dict(BLOCK_VALIDATORS)
85+
86+
5187
@curry
5288
def chain_id_validator(web3):
5389
return compose(
@@ -56,13 +92,20 @@ def chain_id_validator(web3):
5692
)
5793

5894

95+
extra_data_validator = apply_formatter_if(is_not_null, block_validator)
96+
97+
5998
def build_validators_with_web3(w3):
6099
return dict(
61100
request_formatters={
62101
'eth_sendTransaction': chain_id_validator(w3),
63102
'eth_estimateGas': chain_id_validator(w3),
64103
'eth_call': chain_id_validator(w3),
65-
}
104+
},
105+
result_formatters={
106+
'eth_getBlockByHash': extra_data_validator,
107+
'eth_getBlockByNumber': extra_data_validator,
108+
},
66109
)
67110

68111

0 commit comments

Comments
 (0)