Skip to content

Commit 41b47b2

Browse files
committed
light: NoEligiblePeers if bytecode is unavailable
1 parent bba202e commit 41b47b2

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

p2p/lightchain.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
from p2p.exceptions import (
3737
BadLESResponse,
38+
NoEligiblePeers,
3839
)
3940
from p2p.cancel_token import CancelToken
4041
from p2p import protocol
@@ -160,6 +161,15 @@ async def get_contract_code(self, block_hash: Hash32, address: Address) -> bytes
160161
:return: bytecode of the contract, ``b''`` if no code is set
161162
"""
162163
peer = cast(LESPeer, self.peer_pool.highest_td_peer)
164+
165+
# get account for later verification, and
166+
# to confirm that our highest total difficulty peer has the info
167+
try:
168+
account = await self.get_account(block_hash, address)
169+
except HeaderNotFound as exc:
170+
raise NoEligiblePeers("Our best peer does not have header %s" % block_hash) from exc
171+
172+
# request contract code
163173
request_id = gen_request_id()
164174
peer.sub_proto.send_get_contract_code(block_hash, keccak(address), request_id)
165175
reply = await self._wait_for_reply(request_id)
@@ -170,12 +180,15 @@ async def get_contract_code(self, block_hash: Hash32, address: Address) -> bytes
170180
bytecode = reply['codes'][0]
171181

172182
# validate bytecode against a proven account
173-
account = await self.get_account(block_hash, address)
174-
175183
if account.code_hash == keccak(bytecode):
176184
return bytecode
185+
elif bytecode == b'':
186+
# TODO disambiguate failure types here, and raise the appropriate exception
187+
# An (incorrectly) empty bytecode might indicate a bad-acting peer, or it might not
188+
raise NoEligiblePeers("Our best peer incorrectly responded with an empty code value")
177189
else:
178-
# disconnect from this bad peer
190+
# a bad-acting peer sent an invalid non-empty bytecode
191+
# disconnect from the peer
179192
await self.disconnect_peer(peer, DisconnectReason.subprotocol_error)
180193
# try again with another peer
181194
return await self.get_contract_code(block_hash, address)

0 commit comments

Comments
 (0)