Skip to content

Commit 97091de

Browse files
committed
Move docstrings from implementation to interface
1 parent 9c937cb commit 97091de

File tree

19 files changed

+638
-625
lines changed

19 files changed

+638
-625
lines changed

eth/abc.py

Lines changed: 630 additions & 10 deletions
Large diffs are not rendered by default.

eth/chains/base.py

Lines changed: 1 addition & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ class BaseChain(Configurable, ChainAPI):
116116

117117
@classmethod
118118
def get_vm_class_for_block_number(cls, block_number: BlockNumber) -> Type[VirtualMachineAPI]:
119-
"""
120-
Returns the VM class for the given block number.
121-
"""
122119
if cls.vm_configuration is None:
123120
raise AttributeError("Chain classes must define the VMs in vm_configuration")
124121

@@ -142,13 +139,6 @@ def validate_chain(
142139
root: BlockHeaderAPI,
143140
descendants: Tuple[BlockHeaderAPI, ...],
144141
seal_check_random_sample_rate: int = 1) -> None:
145-
"""
146-
Validate that all of the descendents are valid, given that the root header is valid.
147-
148-
By default, check the seal validity (Proof-of-Work on Ethereum 1.x mainnet) of all headers.
149-
This can be expensive. Instead, check a random sample of seals using
150-
seal_check_random_sample_rate.
151-
"""
152142

153143
all_indices = range(len(descendants))
154144
if seal_check_random_sample_rate == 1:
@@ -178,12 +168,6 @@ def validate_chain(
178168

179169

180170
class Chain(BaseChain):
181-
"""
182-
A Chain is a combination of one or more VM classes. Each VM is associated
183-
with a range of blocks. The Chain class acts as a wrapper around these other
184-
VM classes, delegating operations to the appropriate VM depending on the
185-
current block number.
186-
"""
187171
logger = logging.getLogger("eth.chain.chain.Chain")
188172
gas_estimator: StaticMethod[Callable[[StateAPI, SignedTransactionAPI], int]] = None
189173

@@ -219,9 +203,6 @@ def from_genesis(cls,
219203
base_db: AtomicDatabaseAPI,
220204
genesis_params: Dict[str, HeaderParams],
221205
genesis_state: AccountState=None) -> 'BaseChain':
222-
"""
223-
Initializes the Chain from a genesis state.
224-
"""
225206
genesis_vm_class = cls.get_vm_class_for_block_number(BlockNumber(0))
226207

227208
pre_genesis_header = BlockHeader(difficulty=0, block_number=-1, gas_limit=0)
@@ -255,9 +236,6 @@ def from_genesis(cls,
255236
def from_genesis_header(cls,
256237
base_db: AtomicDatabaseAPI,
257238
genesis_header: BlockHeaderAPI) -> 'BaseChain':
258-
"""
259-
Initializes the chain from the genesis header.
260-
"""
261239
chaindb = cls.get_chaindb_class()(base_db)
262240
chaindb.persist_header(genesis_header)
263241
return cls(base_db)
@@ -266,9 +244,6 @@ def from_genesis_header(cls,
266244
# VM API
267245
#
268246
def get_vm(self, at_header: BlockHeaderAPI = None) -> VirtualMachineAPI:
269-
"""
270-
Returns the VM instance for the given block number.
271-
"""
272247
header = self.ensure_header(at_header)
273248
vm_class = self.get_vm_class_for_block_number(header.block_number)
274249
chain_context = ChainContext(self.chain_id)
@@ -280,37 +255,18 @@ def get_vm(self, at_header: BlockHeaderAPI = None) -> VirtualMachineAPI:
280255
def create_header_from_parent(self,
281256
parent_header: BlockHeaderAPI,
282257
**header_params: HeaderParams) -> BlockHeaderAPI:
283-
"""
284-
Passthrough helper to the VM class of the block descending from the
285-
given header.
286-
"""
287258
return self.get_vm_class_for_block_number(
288259
block_number=BlockNumber(parent_header.block_number + 1),
289260
).create_header_from_parent(parent_header, **header_params)
290261

291262
def get_block_header_by_hash(self, block_hash: Hash32) -> BlockHeaderAPI:
292-
"""
293-
Returns the requested block header as specified by block hash.
294-
295-
Raises BlockNotFound if there's no block header with the given hash in the db.
296-
"""
297263
validate_word(block_hash, title="Block Hash")
298264
return self.chaindb.get_block_header_by_hash(block_hash)
299265

300266
def get_canonical_head(self) -> BlockHeaderAPI:
301-
"""
302-
Returns the block header at the canonical chain head.
303-
304-
Raises CanonicalHeadNotFound if there's no head defined for the canonical chain.
305-
"""
306267
return self.chaindb.get_canonical_head()
307268

308269
def get_score(self, block_hash: Hash32) -> int:
309-
"""
310-
Returns the difficulty score of the block with the given hash.
311-
312-
Raises HeaderNotFound if there is no matching black hash.
313-
"""
314270
return self.headerdb.get_score(block_hash)
315271

316272
def ensure_header(self, header: BlockHeaderAPI = None) -> BlockHeaderAPI:
@@ -328,9 +284,6 @@ def ensure_header(self, header: BlockHeaderAPI = None) -> BlockHeaderAPI:
328284
# Block API
329285
#
330286
def get_ancestors(self, limit: int, header: BlockHeaderAPI) -> Tuple[BlockAPI, ...]:
331-
"""
332-
Return `limit` number of ancestor blocks from the current canonical head.
333-
"""
334287
ancestor_count = min(header.block_number, limit)
335288

336289
# We construct a temporary block object
@@ -350,59 +303,29 @@ def get_ancestors(self, limit: int, header: BlockHeaderAPI) -> Tuple[BlockAPI, .
350303
return tuple(take(ancestor_count, ancestor_generator))
351304

352305
def get_block(self) -> BlockAPI:
353-
"""
354-
Returns the current TIP block.
355-
"""
356306
return self.get_vm().get_block()
357307

358308
def get_block_by_hash(self, block_hash: Hash32) -> BlockAPI:
359-
"""
360-
Returns the requested block as specified by block hash.
361-
"""
362309
validate_word(block_hash, title="Block Hash")
363310
block_header = self.get_block_header_by_hash(block_hash)
364311
return self.get_block_by_header(block_header)
365312

366313
def get_block_by_header(self, block_header: BlockHeaderAPI) -> BlockAPI:
367-
"""
368-
Returns the requested block as specified by the block header.
369-
"""
370314
vm = self.get_vm(block_header)
371315
return vm.get_block()
372316

373317
def get_canonical_block_by_number(self, block_number: BlockNumber) -> BlockAPI:
374-
"""
375-
Returns the block with the given number in the canonical chain.
376-
377-
Raises BlockNotFound if there's no block with the given number in the
378-
canonical chain.
379-
"""
380318
validate_uint256(block_number, title="Block Number")
381319
return self.get_block_by_hash(self.chaindb.get_canonical_block_hash(block_number))
382320

383321
def get_canonical_block_hash(self, block_number: BlockNumber) -> Hash32:
384-
"""
385-
Returns the block hash with the given number in the canonical chain.
386-
387-
Raises BlockNotFound if there's no block with the given number in the
388-
canonical chain.
389-
"""
390322
return self.chaindb.get_canonical_block_hash(block_number)
391323

392324
def build_block_with_transactions(
393325
self,
394326
transactions: Sequence[SignedTransactionAPI],
395327
parent_header: BlockHeaderAPI = None
396328
) -> Tuple[BlockAPI, Tuple[ReceiptAPI, ...], Tuple[ComputationAPI, ...]]:
397-
"""
398-
Generate a block with the provided transactions. This does *not* import
399-
that block into your chain. If you want this new block in your chain,
400-
run :meth:`~import_block` with the result block from this method.
401-
402-
:param transactions: an iterable of transactions to insert to the block
403-
:param parent_header: parent of the new block -- or canonical head if ``None``
404-
:return: (new block, receipts, computations)
405-
"""
406329
base_header = self.ensure_header(parent_header)
407330
vm = self.get_vm(base_header)
408331

@@ -415,13 +338,6 @@ def build_block_with_transactions(
415338
# Transaction API
416339
#
417340
def get_canonical_transaction(self, transaction_hash: Hash32) -> SignedTransactionAPI:
418-
"""
419-
Returns the requested transaction as specified by the transaction hash
420-
from the canonical chain.
421-
422-
Raises TransactionNotFound if no transaction with the specified hash is
423-
found in the main chain.
424-
"""
425341
(block_num, index) = self.chaindb.get_transaction_index(transaction_hash)
426342
VM_class = self.get_vm_class_for_block_number(block_num)
427343

@@ -440,9 +356,6 @@ def get_canonical_transaction(self, transaction_hash: Hash32) -> SignedTransacti
440356
)
441357

442358
def create_transaction(self, *args: Any, **kwargs: Any) -> SignedTransactionAPI:
443-
"""
444-
Passthrough helper to the current VM class.
445-
"""
446359
return self.get_vm().create_transaction(*args, **kwargs)
447360

448361
def create_unsigned_transaction(self,
@@ -453,9 +366,6 @@ def create_unsigned_transaction(self,
453366
to: Address,
454367
value: int,
455368
data: bytes) -> UnsignedTransactionAPI:
456-
"""
457-
Passthrough helper to the current VM class.
458-
"""
459369
return self.get_vm().create_unsigned_transaction(
460370
nonce=nonce,
461371
gas_price=gas_price,
@@ -483,10 +393,7 @@ def get_transaction_result(
483393
self,
484394
transaction: SignedTransactionAPI,
485395
at_header: BlockHeaderAPI) -> bytes:
486-
"""
487-
Return the result of running the given transaction.
488-
This is referred to as a `call()` in web3.
489-
"""
396+
490397
with self.get_vm(at_header).state_in_temp_block() as state:
491398
computation = state.costless_execute_transaction(transaction)
492399

@@ -497,10 +404,6 @@ def estimate_gas(
497404
self,
498405
transaction: SignedTransactionAPI,
499406
at_header: BlockHeaderAPI = None) -> int:
500-
"""
501-
Returns an estimation of the amount of gas the given transaction will
502-
use if executed on top of the block specified by the given header.
503-
"""
504407
if at_header is None:
505408
at_header = self.get_canonical_head()
506409
with self.get_vm(at_header).state_in_temp_block() as state:
@@ -510,13 +413,6 @@ def import_block(self,
510413
block: BlockAPI,
511414
perform_validation: bool=True
512415
) -> Tuple[BlockAPI, Tuple[BlockAPI, ...], Tuple[BlockAPI, ...]]:
513-
"""
514-
Imports a complete block and returns a 3-tuple
515-
516-
- the imported block
517-
- a tuple of blocks which are now part of the canonical chain.
518-
- a tuple of blocks which were canonical and now are no longer canonical.
519-
"""
520416

521417
try:
522418
parent_header = self.get_block_header_by_hash(block.header.parent_hash)
@@ -567,15 +463,6 @@ def validate_receipt(self, receipt: ReceiptAPI, at_header: BlockHeaderAPI) -> No
567463
VM_class.validate_receipt(receipt)
568464

569465
def validate_block(self, block: BlockAPI) -> None:
570-
"""
571-
Performs validation on a block that is either being mined or imported.
572-
573-
Since block validation (specifically the uncle validation) must have
574-
access to the ancestor blocks, this validation must occur at the Chain
575-
level.
576-
577-
Cannot be used to validate genesis block.
578-
"""
579466
if block.is_genesis:
580467
raise ValidationError("Cannot validate genesis block this way")
581468
VM_class = self.get_vm_class_for_block_number(BlockNumber(block.number))
@@ -585,16 +472,10 @@ def validate_block(self, block: BlockAPI) -> None:
585472
self.validate_gaslimit(block.header)
586473

587474
def validate_seal(self, header: BlockHeaderAPI) -> None:
588-
"""
589-
Validate the seal on the given header.
590-
"""
591475
VM_class = self.get_vm_class_for_block_number(BlockNumber(header.block_number))
592476
VM_class.validate_seal(header)
593477

594478
def validate_gaslimit(self, header: BlockHeaderAPI) -> None:
595-
"""
596-
Validate the gas limit on the given header.
597-
"""
598479
parent_header = self.get_block_header_by_hash(header.parent_hash)
599480
low_bound, high_bound = compute_gas_limit_bounds(parent_header)
600481
if header.gas_limit < low_bound:
@@ -611,9 +492,6 @@ def validate_gaslimit(self, header: BlockHeaderAPI) -> None:
611492
)
612493

613494
def validate_uncles(self, block: BlockAPI) -> None:
614-
"""
615-
Validate the uncles for the given block.
616-
"""
617495
has_uncles = len(block.uncles) > 0
618496
should_have_uncles = block.header.uncles_hash != EMPTY_UNCLE_HASH
619497

@@ -701,12 +579,6 @@ def __init__(self, base_db: AtomicDatabaseAPI, header: BlockHeaderAPI = None) ->
701579
def apply_transaction(self,
702580
transaction: SignedTransactionAPI
703581
) -> Tuple[BlockAPI, ReceiptAPI, ComputationAPI]:
704-
"""
705-
Applies the transaction to the current tip block.
706-
707-
WARNING: ReceiptAPI and Transaction trie generation is computationally
708-
heavy and incurs significant performance overhead.
709-
"""
710582
vm = self.get_vm(self.header)
711583
base_block = vm.get_block()
712584

@@ -737,10 +609,6 @@ def import_block(self,
737609
return imported_block, new_canonical_blocks, old_canonical_blocks
738610

739611
def mine_block(self, *args: Any, **kwargs: Any) -> BlockAPI:
740-
"""
741-
Mines the current block. Proxies to the current Virtual Machine.
742-
See VM. :meth:`~eth.vm.base.VM.mine_block`
743-
"""
744612
mined_block = self.get_vm(self.header).mine_block(*args, **kwargs)
745613

746614
self.validate_block(mined_block)

eth/chains/header.py

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ def __init__(self, base_db: AtomicDatabaseAPI, header: BlockHeaderAPI = None) ->
4848
def from_genesis_header(cls,
4949
base_db: AtomicDatabaseAPI,
5050
genesis_header: BlockHeaderAPI) -> HeaderChainAPI:
51-
"""
52-
Initializes the chain from the genesis header.
53-
"""
5451
headerdb = cls.get_headerdb_class()(cast(BaseAtomicDB, base_db))
5552
headerdb.persist_header(genesis_header)
5653
return cls(base_db, genesis_header)
@@ -60,9 +57,6 @@ def from_genesis_header(cls,
6057
#
6158
@classmethod
6259
def get_headerdb_class(cls) -> Type[HeaderDatabaseAPI]:
63-
"""
64-
Returns the class which should be used for the `headerdb`
65-
"""
6660
if cls._headerdb_class is None:
6761
raise AttributeError("HeaderChain classes must set a `headerdb_class`")
6862
return cls._headerdb_class
@@ -71,57 +65,26 @@ def get_headerdb_class(cls) -> Type[HeaderDatabaseAPI]:
7165
# Canonical Chain API
7266
#
7367
def get_canonical_block_hash(self, block_number: BlockNumber) -> Hash32:
74-
"""
75-
Direct passthrough to `headerdb`
76-
"""
7768
return self.headerdb.get_canonical_block_hash(block_number)
7869

7970
def get_canonical_block_header_by_number(self, block_number: BlockNumber) -> BlockHeaderAPI:
80-
"""
81-
Direct passthrough to `headerdb`
82-
"""
8371
return self.headerdb.get_canonical_block_header_by_number(block_number)
8472

8573
def get_canonical_head(self) -> BlockHeaderAPI:
86-
"""
87-
Direct passthrough to `headerdb`
88-
"""
8974
return self.headerdb.get_canonical_head()
9075

9176
#
9277
# Header API
9378
#
9479
def get_block_header_by_hash(self, block_hash: Hash32) -> BlockHeaderAPI:
95-
"""
96-
Direct passthrough to `headerdb`
97-
"""
9880
return self.headerdb.get_block_header_by_hash(block_hash)
9981

10082
def header_exists(self, block_hash: Hash32) -> bool:
101-
"""
102-
Direct passthrough to `headerdb`
103-
"""
10483
return self.headerdb.header_exists(block_hash)
10584

10685
def import_header(self,
10786
header: BlockHeaderAPI
10887
) -> Tuple[Tuple[BlockHeaderAPI, ...], Tuple[BlockHeaderAPI, ...]]:
109-
"""
110-
Direct passthrough to `headerdb`
111-
112-
Also updates the local `header` property to be the latest canonical head.
113-
114-
Returns an iterable of headers representing the headers that are newly
115-
part of the canonical chain.
116-
117-
- If the imported header is not part of the canonical chain then an
118-
empty tuple will be returned.
119-
- If the imported header simply extends the canonical chain then a
120-
length-1 tuple with the imported header will be returned.
121-
- If the header is part of a non-canonical chain which overtakes the
122-
current canonical chain then the returned tuple will contain the
123-
headers which are newly part of the canonical chain.
124-
"""
12588
new_canonical_headers = self.headerdb.persist_header(header)
12689
self.header = self.get_canonical_head()
12790
return new_canonical_headers

0 commit comments

Comments
 (0)