def test_has_protocol_qualifier(alice, my_logic): MyProtocol = ProtocolFactory() has_my_protocol = HasProtocol(MyProtocol) has_paragon = HasProtocol(ParagonProtocol) assert has_paragon(alice, my_logic) is True assert has_my_protocol(alice, my_logic) is False
class ETHAPI(Application): name = 'eth' qualifier = HasProtocol(ETHProtocol) head_info: HeadInfoTracker get_block_bodies: GetBlockBodiesExchange get_block_headers: GetBlockHeadersExchange get_node_data: GetNodeDataExchange get_receipts: GetReceiptsExchange def __init__(self) -> None: self.head_info = HeadInfoTracker() self.add_child_behavior(self.head_info.as_behavior()) # Request/Response API self.get_block_bodies = GetBlockBodiesExchange() self.get_block_headers = GetBlockHeadersExchange() self.get_node_data = GetNodeDataExchange() self.get_receipts = GetReceiptsExchange() self.add_child_behavior( ExchangeLogic(self.get_block_bodies).as_behavior()) self.add_child_behavior( ExchangeLogic(self.get_block_headers).as_behavior()) self.add_child_behavior( ExchangeLogic(self.get_node_data).as_behavior()) self.add_child_behavior(ExchangeLogic(self.get_receipts).as_behavior()) @cached_property def exchanges(self) -> Tuple[ExchangeAPI[Any, Any, Any], ...]: return ( self.get_block_bodies, self.get_block_headers, self.get_node_data, self.get_receipts, ) def get_extra_stats(self) -> Tuple[str, ...]: return tuple( f"{exchange.get_response_cmd_type()}: {exchange.tracker.get_stats()}" for exchange in self.exchanges) @cached_property def receipt(self) -> ETHHandshakeReceipt: return self.connection.get_receipt_by_type(ETHHandshakeReceipt) @cached_property def network_id(self) -> int: return self.receipt.network_id @cached_property def genesis_hash(self) -> Hash32: return self.receipt.genesis_hash
class ETHV64API(BaseETHAPI): qualifier = HasProtocol(ETHProtocolV64) head_info_tracker_cls = ETHHeadInfoTracker @cached_property def protocol(self) -> ProtocolAPI: return self.connection.get_protocol_by_type(ETHProtocolV64) @cached_property def receipt(self) -> ETHHandshakeReceipt: return self.connection.get_receipt_by_type(ETHHandshakeReceipt) def send_status(self, payload: StatusPayload) -> None: self.protocol.send(Status(payload))
class LESAPI(Application): name = 'les' qualifier = HasProtocol(LESProtocolV1) | HasProtocol(LESProtocolV2) head_info: HeadInfoTracker get_block_headers: GetBlockHeadersExchange def __init__(self) -> None: self.head_info = HeadInfoTracker() self.add_child_behavior(self.head_info.as_behavior()) self.get_block_headers = GetBlockHeadersExchange() self.add_child_behavior( ExchangeLogic(self.get_block_headers).as_behavior()) @cached_property def exchanges(self) -> Tuple[ExchangeAPI[Any, Any, Any], ...]: return (self.get_block_headers, ) def get_extra_stats(self) -> Tuple[str, ...]: return tuple( f"{exchange.get_response_cmd_type()}: {exchange.tracker.get_stats()}" for exchange in self.exchanges) @property def receipt(self) -> LESHandshakeReceipt: return self.connection.get_receipt_by_type(LESHandshakeReceipt) @cached_property def network_id(self) -> int: return self.receipt.network_id @cached_property def genesis_hash(self) -> Hash32: return self.receipt.genesis_hash
class ParagonAPI(Application): name = 'paragon' qualifier = HasProtocol(ParagonProtocol) @cached_property def protocol(self) -> ParagonProtocol: return self.connection.get_protocol_by_type(ParagonProtocol) def send_broadcast_data(self, data: bytes) -> None: self.protocol.send(BroadcastData(BroadcastDataPayload(data))) def send_get_sum(self, a: int, b: int) -> None: self.protocol.send(GetSum(GetSumPayload(a, b))) def send_sum(self, c: int) -> None: self.protocol.send(Sum(SumPayload(c)))
class ETHV65API(ETHV64API): qualifier = HasProtocol(ETHProtocolV65) @cached_property def protocol(self) -> ProtocolAPI: return self.connection.get_protocol_by_type(ETHProtocolV65) def __init__(self) -> None: super().__init__() # Request/Response API self.get_pooled_transactions = GetPooledTransactionsV65Exchange() self.add_child_behavior(ExchangeLogic(self.get_pooled_transactions).as_behavior()) def send_get_pooled_transactions(self, transaction_hashes: Sequence[Hash32]) -> None: self.protocol.send(GetPooledTransactionsV65(tuple(transaction_hashes)))
class WitnessAPI(Application): name = 'wit' qualifier = HasProtocol(WitnessProtocol) def __init__(self) -> None: self.logger = get_logger('trinity.protocol.wit.api.WitnessAPI') self.get_block_witness_hashes = BlockWitnessHashesExchange() self.add_child_behavior(ExchangeLogic(self.get_block_witness_hashes).as_behavior()) @cached_property def protocol(self) -> WitnessProtocol: return self.connection.get_protocol_by_type(WitnessProtocol) @cached_property def exchanges(self) -> Tuple[ExchangeAPI[Any, Any, Any], ...]: return (self.get_block_witness_hashes,) def get_extra_stats(self) -> Tuple[str, ...]: return tuple( f"{exchange.get_response_cmd_type()}: {exchange.tracker.get_stats()}" for exchange in self.exchanges )
from typing import Union from cached_property import cached_property from eth_typing import BlockNumber, Hash32 from p2p.logic import Application from p2p.qualifiers import HasProtocol from trinity.protocol.eth.api import ETHAPI from trinity.protocol.eth.proto import ETHProtocol from trinity.protocol.les.api import LESAPI from trinity.protocol.les.proto import LESProtocol, LESProtocolV2 from .abc import ChainInfoAPI, HeadInfoAPI AnyETHLES = HasProtocol(ETHProtocol) | HasProtocol(LESProtocolV2) | HasProtocol(LESProtocol) class ChainInfo(Application, ChainInfoAPI): name = 'eth1-chain-info' qualifier = AnyETHLES @cached_property def network_id(self) -> int: return self._get_logic().network_id @cached_property def genesis_hash(self) -> Hash32: return self._get_logic().genesis_hash
class LESV2API(BaseLESAPI[LESProtocolV2]): qualifier = HasProtocol(LESProtocolV2) @cached_property def protocol(self) -> LESProtocolV2: return self.connection.get_protocol_by_type(LESProtocolV2)
from cached_property import cached_property from eth_typing import BlockNumber, Hash32 from p2p.abc import ConnectionAPI from p2p.logic import Application from p2p.qualifiers import HasProtocol from trinity.protocol.eth.api import ETHV63API, ETHAPI from trinity.protocol.eth.proto import ETHProtocolV63, ETHProtocol from trinity.protocol.les.api import LESV1API, LESV2API from trinity.protocol.les.proto import LESProtocolV1, LESProtocolV2 from .abc import ChainInfoAPI, HeadInfoAPI AnyETHLES = HasProtocol(ETHProtocol) | HasProtocol( ETHProtocolV63) | HasProtocol(LESProtocolV2) | HasProtocol(LESProtocolV1) def choose_eth_or_les_api( connection: ConnectionAPI ) -> Union[ETHAPI, ETHV63API, LESV1API, LESV2API]: if connection.has_protocol(ETHProtocol): return connection.get_logic(ETHAPI.name, ETHAPI) elif connection.has_protocol(ETHProtocolV63): return connection.get_logic(ETHV63API.name, ETHV63API) elif connection.has_protocol(LESProtocolV2): return connection.get_logic(LESV2API.name, LESV2API) elif connection.has_protocol(LESProtocolV1): return connection.get_logic(LESV1API.name, LESV1API)
class ETHAPI(Application): name = 'eth' qualifier = HasProtocol(ETHProtocol) head_info: HeadInfoTracker get_block_bodies: GetBlockBodiesExchange get_block_headers: GetBlockHeadersExchange get_node_data: GetNodeDataExchange get_receipts: GetReceiptsExchange def __init__(self) -> None: self.head_info = HeadInfoTracker() self.add_child_behavior(self.head_info.as_behavior()) # Request/Response API self.get_block_bodies = GetBlockBodiesExchange() self.get_block_headers = GetBlockHeadersExchange() self.get_node_data = GetNodeDataExchange() self.get_receipts = GetReceiptsExchange() self.add_child_behavior( ExchangeLogic(self.get_block_bodies).as_behavior()) self.add_child_behavior( ExchangeLogic(self.get_block_headers).as_behavior()) self.add_child_behavior( ExchangeLogic(self.get_node_data).as_behavior()) self.add_child_behavior(ExchangeLogic(self.get_receipts).as_behavior()) @cached_property def exchanges(self) -> Tuple[ExchangeAPI[Any, Any, Any], ...]: return ( self.get_block_bodies, self.get_block_headers, self.get_node_data, self.get_receipts, ) def get_extra_stats(self) -> Tuple[str, ...]: return tuple( f"{exchange.get_response_cmd_type()}: {exchange.tracker.get_stats()}" for exchange in self.exchanges) @cached_property def protocol(self) -> ETHProtocol: return self.connection.get_protocol_by_type(ETHProtocol) @cached_property def receipt(self) -> ETHHandshakeReceipt: return self.connection.get_receipt_by_type(ETHHandshakeReceipt) @cached_property def network_id(self) -> int: return self.receipt.network_id @cached_property def genesis_hash(self) -> Hash32: return self.receipt.genesis_hash def send_status(self, payload: StatusPayload) -> None: self.protocol.send(Status(payload)) def send_get_node_data(self, node_hashes: Sequence[Hash32]) -> None: self.protocol.send(GetNodeData(tuple(node_hashes))) def send_node_data(self, nodes: Sequence[bytes]) -> None: self.protocol.send(NodeData(tuple(nodes))) def send_get_block_headers(self, block_number_or_hash: Union[BlockNumber, Hash32], max_headers: int, skip: int, reverse: bool) -> None: payload = BlockHeadersQuery(block_number_or_hash=block_number_or_hash, max_headers=max_headers, skip=skip, reverse=reverse) self.protocol.send(GetBlockHeaders(payload)) def send_block_headers(self, headers: Sequence[BlockHeaderAPI]) -> None: self.protocol.send(BlockHeaders(tuple(headers))) def send_get_block_bodies(self, block_hashes: Sequence[Hash32]) -> None: self.protocol.send(GetBlockBodies(tuple(block_hashes))) def send_block_bodies(self, blocks: Sequence[BlockAPI]) -> None: block_bodies = tuple( BlockBody(block.transactions, block.uncles) for block in blocks) self.protocol.send(BlockBodies(block_bodies)) def send_get_receipts(self, block_hashes: Sequence[Hash32]) -> None: self.protocol.send(GetReceipts(tuple(block_hashes))) def send_receipts(self, receipts: Sequence[Sequence[ReceiptAPI]]) -> None: self.protocol.send(Receipts(tuple(map(tuple, receipts)))) def send_transactions( self, transactions: Sequence[SignedTransactionAPI]) -> None: self.protocol.send(Transactions(tuple(transactions))) def send_new_block_hashes(self, *new_block_hashes: NewBlockHash) -> None: self.protocol.send(NewBlockHashes(new_block_hashes)) def send_new_block(self, block: BlockAPI, total_difficulty: int) -> None: block_fields = BlockFields(block.header, block.transactions, block.uncles) payload = NewBlockPayload(block_fields, total_difficulty) self.protocol.send(NewBlock(payload))
from cached_property import cached_property from eth_typing import BlockNumber, Hash32 from p2p.abc import ConnectionAPI from p2p.logic import Application from p2p.qualifiers import HasProtocol from trinity.protocol.eth.api import ETHV63API, ETHV65API, ETHV64API from trinity.protocol.eth.proto import ETHProtocolV63, ETHProtocolV64, ETHProtocolV65 from trinity.protocol.les.api import LESV1API, LESV2API from trinity.protocol.les.proto import LESProtocolV1, LESProtocolV2 from .abc import ChainInfoAPI, HeadInfoAPI AnyETHLES = HasProtocol(ETHProtocolV65) | HasProtocol( ETHProtocolV64) | HasProtocol(ETHProtocolV63) | HasProtocol( LESProtocolV2) | HasProtocol(LESProtocolV1) AnyETHLESAPI = Union[ETHV65API, ETHV64API, ETHV63API, LESV1API, LESV2API] def choose_eth_or_les_api(connection: ConnectionAPI) -> AnyETHLESAPI: if connection.has_protocol(ETHProtocolV65): return connection.get_logic(ETHV65API.name, ETHV65API) elif connection.has_protocol(ETHProtocolV64): return connection.get_logic(ETHV64API.name, ETHV64API) elif connection.has_protocol(ETHProtocolV63): return connection.get_logic(ETHV63API.name, ETHV63API) elif connection.has_protocol(LESProtocolV2):