Merge pull request #10281 from f321x/dont_connect_to_other_networks
interface: check genesis hash on connection
This commit is contained in:
@@ -328,6 +328,9 @@ class PaddedRSTransport(RSTransport):
|
|||||||
|
|
||||||
MIN_PACKET_SIZE = 1024
|
MIN_PACKET_SIZE = 1024
|
||||||
WAIT_FOR_BUFFER_GROWTH_SECONDS = 1.0
|
WAIT_FOR_BUFFER_GROWTH_SECONDS = 1.0
|
||||||
|
# (unpadded) amount of bytes sent instantly before beginning with polling.
|
||||||
|
# This makes the initial handshake where a few small messages are exchanged faster.
|
||||||
|
WARMUP_BUDGET_SIZE = 1024
|
||||||
|
|
||||||
session: Optional['RPCSession']
|
session: Optional['RPCSession']
|
||||||
|
|
||||||
@@ -361,6 +364,7 @@ class PaddedRSTransport(RSTransport):
|
|||||||
self._force_send
|
self._force_send
|
||||||
or len(buf) >= self.MIN_PACKET_SIZE
|
or len(buf) >= self.MIN_PACKET_SIZE
|
||||||
or self._last_send + self.WAIT_FOR_BUFFER_GROWTH_SECONDS < time.monotonic()
|
or self._last_send + self.WAIT_FOR_BUFFER_GROWTH_SECONDS < time.monotonic()
|
||||||
|
or self.session.send_size < self.WARMUP_BUDGET_SIZE
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
assert buf[-2:] in (b"}\n", b"]\n"), f"unexpected json-rpc terminator: {buf[-2:]=!r}"
|
assert buf[-2:] in (b"}\n", b"]\n"), f"unexpected json-rpc terminator: {buf[-2:]=!r}"
|
||||||
@@ -950,6 +954,7 @@ class Interface(Logger):
|
|||||||
proxy=self.proxy,
|
proxy=self.proxy,
|
||||||
transport=PaddedRSTransport,
|
transport=PaddedRSTransport,
|
||||||
) as session:
|
) as session:
|
||||||
|
start = time.perf_counter()
|
||||||
self.session = session # type: NotificationSession
|
self.session = session # type: NotificationSession
|
||||||
self.session.set_default_timeout(self.network.get_network_timeout_seconds(NetworkTimeout.Generic))
|
self.session.set_default_timeout(self.network.get_network_timeout_seconds(NetworkTimeout.Generic))
|
||||||
try:
|
try:
|
||||||
@@ -964,7 +969,15 @@ class Interface(Logger):
|
|||||||
if not self.network.check_interface_against_healthy_spread_of_connected_servers(self):
|
if not self.network.check_interface_against_healthy_spread_of_connected_servers(self):
|
||||||
raise GracefulDisconnect(f'too many connected servers already '
|
raise GracefulDisconnect(f'too many connected servers already '
|
||||||
f'in bucket {self.bucket_based_on_ipaddress()}')
|
f'in bucket {self.bucket_based_on_ipaddress()}')
|
||||||
self.logger.info(f"connection established. version: {ver}")
|
|
||||||
|
try:
|
||||||
|
features = await session.send_request('server.features')
|
||||||
|
server_genesis_hash = assert_dict_contains_field(features, field_name='genesis_hash')
|
||||||
|
except (aiorpcx.jsonrpc.RPCError, RequestCorrupted) as e:
|
||||||
|
raise GracefulDisconnect(e)
|
||||||
|
if server_genesis_hash != constants.net.GENESIS:
|
||||||
|
raise GracefulDisconnect(f'server on different chain: {server_genesis_hash=}. ours: {constants.net.GENESIS}')
|
||||||
|
self.logger.info(f"connection established. version: {ver}, handshake duration: {(time.perf_counter() - start) * 1000:.2f} ms")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with self.taskgroup as group:
|
async with self.taskgroup as group:
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from electrum.util import OldTaskGroup, bfh
|
|||||||
from electrum.logging import Logger
|
from electrum.logging import Logger
|
||||||
from electrum.simple_config import SimpleConfig
|
from electrum.simple_config import SimpleConfig
|
||||||
from electrum.transaction import Transaction
|
from electrum.transaction import Transaction
|
||||||
|
from electrum import constants
|
||||||
|
|
||||||
from . import ElectrumTestCase
|
from . import ElectrumTestCase
|
||||||
|
|
||||||
@@ -130,6 +131,7 @@ class ServerSession(aiorpcx.RPCSession, Logger):
|
|||||||
async def handle_request(self, request):
|
async def handle_request(self, request):
|
||||||
handlers = {
|
handlers = {
|
||||||
'server.version': self._handle_server_version,
|
'server.version': self._handle_server_version,
|
||||||
|
'server.features': self._handle_server_features,
|
||||||
'blockchain.estimatefee': self._handle_estimatefee,
|
'blockchain.estimatefee': self._handle_estimatefee,
|
||||||
'blockchain.headers.subscribe': self._handle_headers_subscribe,
|
'blockchain.headers.subscribe': self._handle_headers_subscribe,
|
||||||
'blockchain.block.header': self._handle_block_header,
|
'blockchain.block.header': self._handle_block_header,
|
||||||
@@ -146,6 +148,17 @@ class ServerSession(aiorpcx.RPCSession, Logger):
|
|||||||
async def _handle_server_version(self, client_name='', protocol_version=None):
|
async def _handle_server_version(self, client_name='', protocol_version=None):
|
||||||
return ['best_server_impl/0.1', '1.4']
|
return ['best_server_impl/0.1', '1.4']
|
||||||
|
|
||||||
|
async def _handle_server_features(self) -> dict:
|
||||||
|
return {
|
||||||
|
'genesis_hash': constants.net.GENESIS,
|
||||||
|
'hosts': {"14.3.140.101": {"tcp_port": 51001, "ssl_port": 51002}},
|
||||||
|
'protocol_max': '1.7.0',
|
||||||
|
'protocol_min': '1.4.3',
|
||||||
|
'pruning': None,
|
||||||
|
'server_version': 'ElectrumX 1.19.0',
|
||||||
|
'hash_function': 'sha256',
|
||||||
|
}
|
||||||
|
|
||||||
async def _handle_estimatefee(self, number, mode=None):
|
async def _handle_estimatefee(self, number, mode=None):
|
||||||
return 1000
|
return 1000
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user