Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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))
Exemple #4
0
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
Exemple #5
0
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)))
Exemple #6
0
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)))
Exemple #7
0
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
        )
Exemple #8
0
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
Exemple #9
0
class LESV2API(BaseLESAPI[LESProtocolV2]):
    qualifier = HasProtocol(LESProtocolV2)

    @cached_property
    def protocol(self) -> LESProtocolV2:
        return self.connection.get_protocol_by_type(LESProtocolV2)
Exemple #10
0
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)
Exemple #11
0
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))
Exemple #12
0
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):