Skip to content

Instantly share code, notes, and snippets.

@gsalgado
Created November 7, 2020 18:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gsalgado/569d168f2032c3d8c767fd37f511d412 to your computer and use it in GitHub Desktop.
Save gsalgado/569d168f2032c3d8c767fd37f511d412 to your computer and use it in GitHub Desktop.
# ===== Mining clique blocks on trinity ==============
# - Need a genesis block with a known signer
# encoded_pk = '0x9abedf188f6e81a2473c4385fdd3610695eb9c33a0d135cbcb19d9ad8e303e56'
# pk = PrivateKey(decode_hex(encoded_pk))
# extra_data = encode_hex(
# VANITY_LENGTH * b'0' + pk.public_key.to_canonical_address() + SIGNATURE_LENGTH * b'0')
# # Use the above value in the extraData of a custom genesis.json config
# # Run trinity with '--genesis <custom-genesis.json> --nodekey <encoded_pk>'
# =============== Create a transaction ==========================
from eth_keys import keys
from eth_utils import decode_hex
from eth_typing import Address
from p2p.tools.factories import PublicKeyFactory
from eth.consensus.clique.constants import (NONCE_DROP, VANITY_LENGTH, SIGNATURE_LENGTH)
from eth.consensus.clique._utils import (get_block_signer, sign_block_header)
BLOCK_SIGNER = trinity_config.nodekey
extra_data_len = VANITY_LENGTH + SIGNATURE_LENGTH
header = mining_chain.header.copy(extra_data=extra_data_len * b'0')
signed_header = sign_block_header(header, BLOCK_SIGNER)
mining_chain.header = signed_header
# This should be one of the funded accounts in our genesis.
SENDER_PRIVATE_KEY = keys.PrivateKey(b'\x00' * 31 + b'\x01')
SENDER = Address(SENDER_PRIVATE_KEY.public_key.to_canonical_address())
# RECIPIENT = Address(PublicKeyFactory().to_canonical_address())
RECIPIENT = Address(b'\x01' * 20)
tx = mining_chain.get_vm().create_unsigned_transaction(
nonce=mining_chain.get_vm().state.get_nonce(SENDER),
gas_price=10,
gas=1000000,
to=RECIPIENT,
value=101,
data=b'abc',
)
signed_tx = tx.as_signed_transaction(SENDER_PRIVATE_KEY)
_, _, computation = mining_chain.apply_transaction(signed_tx)
computation.raise_if_error()
# ======================= Mine new block ======================
difficulty = 2
header = mining_chain.header.copy(
extra_data=extra_data_len * b'0', difficulty=difficulty, nonce=NONCE_DROP)
signed_header = sign_block_header(header, BLOCK_SIGNER)
# Because of https://github.com/ethereum/py-evm/issues/1962 we need to import the block in a
# separate chain so that we can get its witness
mined_block, meta_witness = mining_chain.mine_block_extended(
extra_data=signed_header.extra_data, difficulty=difficulty, nonce=NONCE_DROP)
import_result = mining_chain2.import_block(mined_block)
assert len(import_result.meta_witness.hashes) > 0
# ===================== Store witness hashes in our DB ==================
from trinity.protocol.wit.db import AsyncWitnessDB
wit_db = AsyncWitnessDB(db)
wit_db.persist_witness_hashes(mined_block.hash, tuple(import_result.meta_witness.hashes))
# ======================= Announce new block ======================
from lahja import AsyncioEndpoint, ConnectionConfig
from trinity.sync.common.events import NewBlockMined
from trinity.components.builtin.new_block.component import NewBlockComponent
endpoint = AsyncioEndpoint('console')
await endpoint._start()
newblock_conn = ConnectionConfig.from_name(NewBlockComponent.get_endpoint_name(), trinity_config.ipc_dir)
await endpoint.connect_to_endpoints(newblock_conn)
await endpoint.wait_until_any_endpoint_subscribed_to(NewBlockMined)
await endpoint.broadcast(NewBlockMined(mined_block, mining_chain.get_score(mined_block.hash)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment