Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit fcb9d92

Browse files
committed
Return witness metadata: node hashes, addresses, slots, bytecode
- only log trie node hashes present in DB - import_block includes MetaWitness by default, mining requires calling mine_block_extended(), to make for easier API changes - tiny typo fix in release note: 1st and last 2 bytes, instead of 1st 3 - prefer frozenset when order doesn't matter - Add new release notes for this feature
1 parent f89fa61 commit fcb9d92

File tree

18 files changed

+363
-47
lines changed

18 files changed

+363
-47
lines changed

docs/guides/understanding_the_mining_process.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ Now that we have the building blocks available, let's put it all together and mi
186186

187187
# We have to finalize the block first in order to be able read the
188188
# attributes that are important for the PoW algorithm
189-
block = chain.get_vm().finalize_block(chain.get_block())
189+
block_result = chain.get_vm().finalize_block(chain.get_block())
190+
block = block_result.block
190191

191192
# based on mining_hash, block number and difficulty we can perform
192193
# the actual Proof of Work (PoW) mechanism to mine the correct
@@ -373,7 +374,8 @@ zero value transfer transaction.
373374
(<ByzantiumBlock(#Block #1...)
374375
>>> # We have to finalize the block first in order to be able read the
375376
>>> # attributes that are important for the PoW algorithm
376-
>>> block = chain.get_vm().finalize_block(chain.get_block())
377+
>>> block_result = chain.get_vm().finalize_block(chain.get_block())
378+
>>> block = block_result.block
377379

378380
>>> # based on mining_hash, block number and difficulty we can perform
379381
>>> # the actual Proof of Work (PoW) mechanism to mine the correct

eth/abc.py

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
ClassVar,
99
ContextManager,
1010
Dict,
11+
FrozenSet,
1112
Iterable,
1213
Iterator,
1314
MutableMapping,
@@ -334,10 +335,53 @@ def is_genesis(self) -> bool:
334335
...
335336

336337

338+
class MetaWitnessAPI(ABC):
339+
@property
340+
@abstractmethod
341+
def hashes(self) -> FrozenSet[Hash32]:
342+
...
343+
344+
@property
345+
@abstractmethod
346+
def accounts_queried(self) -> FrozenSet[Address]:
347+
...
348+
349+
@property
350+
@abstractmethod
351+
def account_bytecodes_queried(self) -> FrozenSet[Address]:
352+
...
353+
354+
@abstractmethod
355+
def get_slots_queried(self, address: Address) -> FrozenSet[int]:
356+
...
357+
358+
@property
359+
@abstractmethod
360+
def total_slots_queried(self) -> int:
361+
"""
362+
Summed across all accounts, how many storage slots were queried?
363+
"""
364+
...
365+
366+
367+
class BlockAndMetaWitness(NamedTuple):
368+
"""
369+
After evaluating a block using the VirtualMachine, this information
370+
becomes available.
371+
"""
372+
block: BlockAPI
373+
meta_witness: MetaWitnessAPI
374+
375+
337376
class BlockImportResult(NamedTuple):
377+
"""
378+
After importing and persisting a block into the active chain, this information
379+
becomes available.
380+
"""
338381
imported_block: BlockAPI
339382
new_canonical_blocks: Tuple[BlockAPI, ...]
340383
old_canonical_blocks: Tuple[BlockAPI, ...]
384+
meta_witness: MetaWitnessAPI
341385

342386

343387
class SchemaAPI(ABC):
@@ -1631,6 +1675,13 @@ def persist(self, db: DatabaseAPI) -> None:
16311675
"""
16321676
...
16331677

1678+
@abstractmethod
1679+
def get_accessed_slots(self) -> FrozenSet[int]:
1680+
"""
1681+
List all the slots that had been accessed since object creation.
1682+
"""
1683+
...
1684+
16341685

16351686
class AccountDatabaseAPI(ABC):
16361687
"""
@@ -1835,7 +1886,7 @@ def make_state_root(self) -> Hash32:
18351886
...
18361887

18371888
@abstractmethod
1838-
def persist(self) -> None:
1889+
def persist(self) -> MetaWitnessAPI:
18391890
"""
18401891
Send changes to underlying database, including the trie state
18411892
so that it will forever be possible to read the trie from this checkpoint.
@@ -2192,7 +2243,7 @@ def lock_changes(self) -> None:
21922243
...
21932244

21942245
@abstractmethod
2195-
def persist(self) -> None:
2246+
def persist(self) -> MetaWitnessAPI:
21962247
"""
21972248
Persist the current state to the database.
21982249
"""
@@ -2490,14 +2541,14 @@ def make_receipt(self,
24902541
# Mining
24912542
#
24922543
@abstractmethod
2493-
def import_block(self, block: BlockAPI) -> BlockAPI:
2544+
def import_block(self, block: BlockAPI) -> BlockAndMetaWitness:
24942545
"""
24952546
Import the given block to the chain.
24962547
"""
24972548
...
24982549

24992550
@abstractmethod
2500-
def mine_block(self, *args: Any, **kwargs: Any) -> BlockAPI:
2551+
def mine_block(self, *args: Any, **kwargs: Any) -> BlockAndMetaWitness:
25012552
"""
25022553
Mine the current block. Proxies to self.pack_block method.
25032554
"""
@@ -2518,7 +2569,7 @@ def set_block_transactions(self,
25182569
# Finalization
25192570
#
25202571
@abstractmethod
2521-
def finalize_block(self, block: BlockAPI) -> BlockAPI:
2572+
def finalize_block(self, block: BlockAPI) -> BlockAndMetaWitness:
25222573
"""
25232574
Perform any finalization steps like awarding the block mining reward,
25242575
and persisting the final state root.
@@ -3312,3 +3363,11 @@ def mine_block(self, *args: Any, **kwargs: Any) -> BlockAPI:
33123363
See VM. :meth:`~eth.vm.base.VM.mine_block`
33133364
"""
33143365
...
3366+
3367+
@abstractmethod
3368+
def mine_block_extended(self, *args: Any, **kwargs: Any) -> BlockAndMetaWitness:
3369+
"""
3370+
Just like :meth:`~mine_block`, but includes extra returned info. Currently,
3371+
the only extra info returned is the :class:`MetaWitness`.
3372+
"""
3373+
...

eth/chains/base.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@
3939
)
4040
from eth.abc import (
4141
BlockAPI,
42+
BlockAndMetaWitness,
4243
MiningChainAPI,
4344
AtomicDatabaseAPI,
4445
BlockHeaderAPI,
46+
BlockImportResult,
4547
ChainAPI,
4648
ChainDatabaseAPI,
4749
ConsensusContextAPI,
@@ -51,7 +53,6 @@
5153
StateAPI,
5254
SignedTransactionAPI,
5355
UnsignedTransactionAPI,
54-
BlockImportResult
5556
)
5657
from eth.consensus import (
5758
ConsensusContext,
@@ -467,7 +468,8 @@ def import_block(self,
467468
)
468469

469470
base_header_for_import = self.create_header_from_parent(parent_header)
470-
imported_block = self.get_vm(base_header_for_import).import_block(block)
471+
block_result = self.get_vm(base_header_for_import).import_block(block)
472+
imported_block = block_result.block
471473

472474
# Validate the imported block.
473475
if perform_validation:
@@ -503,7 +505,8 @@ def import_block(self,
503505
return BlockImportResult(
504506
imported_block=imported_block,
505507
new_canonical_blocks=new_canonical_blocks,
506-
old_canonical_blocks=old_canonical_blocks
508+
old_canonical_blocks=old_canonical_blocks,
509+
meta_witness=block_result.meta_witness,
507510
)
508511

509512
#
@@ -662,13 +665,17 @@ def import_block(self,
662665
return result
663666

664667
def mine_block(self, *args: Any, **kwargs: Any) -> BlockAPI:
665-
mined_block = self.get_vm(self.header).mine_block(*args, **kwargs)
668+
return self.mine_block_extended(*args, **kwargs).block
669+
670+
def mine_block_extended(self, *args: Any, **kwargs: Any) -> BlockAndMetaWitness:
671+
mine_result = self.get_vm(self.header).mine_block(*args, **kwargs)
672+
mined_block = mine_result.block
666673

667674
self.validate_block(mined_block)
668675

669676
self.chaindb.persist_block(mined_block)
670677
self.header = self.create_header_from_parent(mined_block.header)
671-
return mined_block
678+
return mine_result
672679

673680
def get_vm(self, at_header: BlockHeaderAPI = None) -> VirtualMachineAPI:
674681
if at_header is None:

0 commit comments

Comments
 (0)