-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterfaces.py
More file actions
146 lines (107 loc) · 4.73 KB
/
Copy pathinterfaces.py
File metadata and controls
146 lines (107 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""The abstractions the server depends on: the shared data shapes and the collaborator protocols.
:class:`~komet_node.server.StellarRpcServer` is written against these, not against the
concrete `NodeInterpreter` / `TransactionEncoder` / `ChainStore`, so the concretes can be
injected (and substituted in tests) — the dependency-inversion boundary. The concrete classes
declare that they implement the protocols, and a composition root wires them together (see
``build_server`` in ``__main__.py``).
Two kinds of thing live here so both the protocols and the concretes can share them without
either importing the other:
- the request/response and disk data shapes (``TypedDict``);
- the ``Interpreter`` / ``Encoder`` / ``Store`` protocols.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Protocol, TypedDict
if TYPE_CHECKING:
from collections.abc import Callable, Mapping
from pathlib import Path
from pyk.kast.inner import KInner
# ----------------------------------------------------------------------
# Data shapes (functional TypedDict form: the keys are JSON wire / disk
# names, some camelCase, so they cannot be class attributes).
# ----------------------------------------------------------------------
# The request envelopes consumed by node.md. `steps` is the JSON-encoded operation list; for a
# wasm upload it is empty and the steps ride in the <program> cell instead. Key *order* also
# matters to K's JSON matcher — which a TypedDict cannot express, only the fields and types.
TxRequest = TypedDict(
'TxRequest',
{'method': str, 'id': Any, 'now': str, 'txHash': str, 'envelopeXdr': str, 'steps': list},
)
SimulateRequest = TypedDict(
'SimulateRequest',
{'method': str, 'id': Any, 'now': str, 'steps': list},
)
# The internal simulateTransaction result K emits: always ``latestLedger``, then either
# ``error`` (a failed simulation) or ``returnValue`` (a JSON SCVal). total=False — mutually
# exclusive outcomes.
SimulateResult = TypedDict(
'SimulateResult',
{'latestLedger': int, 'error': str, 'returnValue': Any},
total=False,
)
# The ``ledgers/ledger_<seq>.json`` record for one closed ledger; carries the header XDR
# artifacts (hash/headerXdr/metadataXdr) that only Python can build.
LedgerRecord = TypedDict(
'LedgerRecord',
{
'sequence': int,
'txHash': str,
'closedAt': int,
'hash': str,
'headerXdr': str,
'metadataXdr': str,
},
)
# One entry of an ``events/events_<ledger>.json`` array, in the getEvents Event shape.
EventRecord = TypedDict(
'EventRecord',
{
'type': str,
'ledger': int,
'ledgerClosedAt': str,
'contractId': str,
'id': str,
'inSuccessfulContractCall': bool,
'txHash': str,
'topic': list[str],
'value': str,
},
)
# ----------------------------------------------------------------------
# Collaborator protocols
# ----------------------------------------------------------------------
class Interpreter(Protocol):
"""Runs RPC request envelopes through the K node semantics (see ``NodeInterpreter``)."""
def empty_config(self) -> str: ...
def run(
self,
state_file: Path,
io_dir: Path,
request: Mapping[str, Any],
program_steps: list[KInner] | None = ...,
*,
commit: bool = ...,
) -> str | None: ...
class Encoder(Protocol):
"""Decodes Stellar XDR transactions into node request envelopes (see ``TransactionEncoder``)."""
network_passphrase: str
def build_tx_request(
self, method: str, rpc_id: Any, transaction_xdr: str, now: str
) -> tuple[TxRequest, list[KInner] | None, dict[str, bytes]]: ...
def build_simulate_request(self, rpc_id: Any, transaction_xdr: str, now: str) -> SimulateRequest: ...
class Store(Protocol):
"""Reads and writes the files of a komet-node io-dir (see ``ChainStore``)."""
root: Path
state_file: Path
wasms_dir: Path
def initialize(self, empty_config: Callable[[], str]) -> bool: ...
def latest_ledger(self) -> int: ...
def has_receipt(self, tx_hash: str) -> bool: ...
def read_receipt(self, tx_hash: str) -> dict[str, Any]: ...
def write_receipt(self, tx_hash: str, receipt: dict[str, Any]) -> None: ...
def read_ledger(self, sequence: int) -> LedgerRecord | None: ...
def write_ledger(self, record: LedgerRecord) -> None: ...
def write_wasm(self, wasm_hash: str, wasm: bytes) -> None: ...
def read_staged_event_lines(self) -> list[str]: ...
def clear_staged_events(self) -> None: ...
def write_events(self, ledger: int, events: list[EventRecord]) -> None: ...
def archive_request(self, method: str | None, params: dict[str, Any], request_id: Any) -> None: ...