示例#1
0
def test_farm_two_blocks():
    """
    In this test, we farm two blocks: one empty block,
    then one block which spends the coinbase transaction from the empty block.
    """
    REWARD = 10000
    unspent_db = RAM_DB()
    chain_view = ChainView.for_genesis_hash(GENESIS_BLOCK, unspent_db)

    assert chain_view.genesis_hash == GENESIS_BLOCK
    assert chain_view.tip_hash == HeaderHash(GENESIS_BLOCK)
    assert chain_view.tip_index == 0
    assert chain_view.unspent_db == unspent_db

    pos_1 = ProofOfSpace(get_pool_public_key(), get_plot_public_key())

    puzzle_hash = puzzle_hash_for_index(1)

    empty_spend_bundle = SpendBundle.aggregate([])
    header, header_signature, body = farm_block(GENESIS_BLOCK,
                                                Signature.zero(), 1, pos_1,
                                                empty_spend_bundle,
                                                puzzle_hash, REWARD)

    run = asyncio.get_event_loop().run_until_complete
    additions, removals = run(
        chain_view.accept_new_block(header, unspent_db, REWARD, 0))
    assert len(additions) == 2
    assert len(removals) == 0
    # TODO: check additions
    assert additions[1].puzzle_hash == body.fees_coin.puzzle_hash
    assert additions[1].amount == 0

    chain_view = run(
        chain_view.augment_chain_view(header, header_signature, unspent_db,
                                      unspent_db, REWARD, 0))

    assert chain_view.genesis_hash == GENESIS_BLOCK
    assert chain_view.tip_hash == HeaderHash(header)
    assert chain_view.tip_index == 1
    assert chain_view.unspent_db == unspent_db

    conditions = standard_conditions()
    spend_bundle_2 = spend_coin(coin=additions[0],
                                conditions=conditions,
                                index=1)

    assert validate_spend_bundle_signature(spend_bundle_2)

    pos_2 = ProofOfSpace(get_pool_public_key(1), get_plot_public_key())

    header_2, header_signature_2, body_2 = farm_block(header, header_signature,
                                                      2, pos_2, spend_bundle_2,
                                                      puzzle_hash, REWARD)
    print(header_2)
    print(header_signature_2)

    removals = removals_for_body(body_2)
    assert len(removals) == 1
    assert removals[0] == list(spend_bundle_2.coin_solutions)[0].coin.name()
async def farm_block(wallet, ledger_api, last_known_header):
    coinbase_puzzle_hash = wallet.get_new_puzzlehash()
    fees_puzzle_hash = wallet.get_new_puzzlehash()
    r = await ledger_api.next_block(coinbase_puzzle_hash=coinbase_puzzle_hash,
                                    fees_puzzle_hash=fees_puzzle_hash)
    header = r['header']
    header_hash = HeaderHash(header)
    tip = await ledger_api.get_tip()
    await process_blocks(
        wallet, ledger_api, tip['genesis_hash']
        if last_known_header is None else last_known_header, header_hash)
    return header_hash
示例#3
0
 async def augment_chain_view(self, header, header_signature, storage,
                              new_unspent_db, reward,
                              timestamp) -> "ChainView":
     tip_index = self.tip_index + 1
     additions, removals = await self.accept_new_block(
         header, storage, reward, timestamp)
     await apply_deltas(tip_index, additions, removals, storage,
                        new_unspent_db)
     chain_view = self.__class__(self.genesis_hash, HeaderHash(header),
                                 header_signature, tip_index,
                                 new_unspent_db)
     await chain_view.check_tip_signature(storage)
     return chain_view
示例#4
0
def farm_block(previous_header, previous_signature, block_number,
               proof_of_space, spend_bundle, coinbase_puzzle_hash, reward):

    fees_puzzle_hash = puzzle_hash_for_index(3)

    coinbase_coin, coinbase_signature = create_coinbase_coin_and_signature(
        block_number, coinbase_puzzle_hash, reward,
        proof_of_space.pool_public_key)

    timestamp = int(1e10) + 300 * block_number
    header, body = farm_new_block(previous_header, previous_signature,
                                  block_number, proof_of_space, spend_bundle,
                                  coinbase_coin, coinbase_signature,
                                  fees_puzzle_hash, timestamp)

    header_signature = sign_header(header, proof_of_space.plot_public_key)

    bad_bls_public_key = BLSPublicKey.from_bytes(public_key_bytes_for_index(9))

    bad_eor_public_key = EORPrivateKey(std_hash(bytes([5]))).public_key()

    hkp = header_signature.aggsig_pair(proof_of_space.plot_public_key,
                                       HeaderHash(header))
    _ = header_signature.validate([hkp])
    assert _

    hkp = header_signature.aggsig_pair(bad_eor_public_key, HeaderHash(header))
    assert not header_signature.validate([hkp])

    hkp = body.coinbase_signature.aggsig_pair(proof_of_space.pool_public_key,
                                              body.coinbase_coin.name())
    assert body.coinbase_signature.validate([hkp])

    hkp = body.coinbase_signature.aggsig_pair(bad_bls_public_key,
                                              body.coinbase_coin.name())
    assert not body.coinbase_signature.validate([hkp])
    return header, header_signature, body
示例#5
0
 async def sync(self):
     """
     Get blocks from ledger sim and make a note of new and spent coins
     that are "interesting".
     """
     headers = []
     tip_dict = await self._ledger_sim.get_tip()
     genesis_hash = tip_dict["genesis_hash"]
     header_hash = tip_dict["tip_hash"]
     header_index = tip_dict["tip_index"]
     while True:
         if header_hash == genesis_hash:
             break
         if len(self._header_list
                ) >= header_index and header_hash == HeaderHash(
                    self._header_list[header_index - 1]):
             break
         preimage = await self._ledger_sim.hash_preimage(hash=header_hash)
         header = Header.from_bytes(preimage)
         headers.append(header)
         header_hash = header.previous_hash
         header_index -= 1
     await self.rollback_to_block(header_index)
     new_block_count = len(headers)
     while headers:
         header = headers.pop()
         preimage = await self._ledger_sim.hash_preimage(
             hash=header.body_hash)
         body = Body.from_bytes(preimage)
         additions = [
             _ for _ in additions_for_body(body)
             if _.puzzle_hash in self._interested_puzzled_hashes
         ]
         removals = [
             _ for _ in removals_for_body(body)
             if _ in self._interested_puzzled_hashes
         ]
         await apply_deltas(header_index, additions, removals, self, self)
         self._header_list.append(header)
         header_index += 1
     return new_block_count
示例#6
0
async def check_header_signature(header_hash: HeaderHash,
                                 header_signature: Signature,
                                 storage: Storage):

    # fetch header for header_hash

    header = await header_hash.obj(storage)
    if header is None:
        raise ConsensusError(Err.MISSING_FROM_STORAGE, header_hash)

    # get proof of space

    pos = await header.proof_of_space_hash.obj(storage)
    if pos is None:
        raise ConsensusError(Err.MISSING_FROM_STORAGE,
                             header.proof_of_space_hash)

    # verify header signature

    hkp = header_signature.aggsig_pair(pos.plot_public_key, HeaderHash(header))
    if not header_signature.validate([hkp]):
        raise ConsensusError(Err.BAD_HEADER_SIGNATURE, header_signature)
示例#7
0
import datetime
import logging

from chiasim.atoms import uint64
from chiasim.farming import farm_new_block, get_plot_public_key, sign_header
from chiasim.hashable import (HeaderHash, ProgramHash, ProofOfSpace,
                              SpendBundle, Header)
from chiasim.pool import (create_coinbase_coin_and_signature,
                          get_pool_public_key)
from chiasim.remote.api_decorators import api_request
from chiasim.validation import ChainView, validate_spend_bundle_signature
from chiasim.hashable.Body import BodyList

log = logging.getLogger(__name__)

GENESIS_HASH = HeaderHash([0] * 32)


class LedgerAPI:
    def __init__(self, block_tip: HeaderHash, storage):
        self._chain_view = ChainView.for_genesis_hash(GENESIS_HASH, storage)
        self._storage = storage
        self._unspent_db = storage  # TODO: fixme, HACK
        self._spend_bundles = []
        self._next_block_lock = asyncio.Lock()
        self._now = 0

    async def do_ping(self, m=None):
        log.info("ping")
        return dict(response="got ping message %r at time %s" %
                    (m, datetime.datetime.utcnow()))