예제 #1
0
async def setup_full_system(consensus_constants: ConsensusConstants,
                            b_tools=None,
                            b_tools_1=None,
                            connect_to_daemon=False):
    if b_tools is None:
        b_tools = BlockTools(constants=test_constants)
    if b_tools_1 is None:
        b_tools_1 = BlockTools(constants=test_constants)
    node_iters = [
        setup_introducer(21233),
        setup_harvester(21234, 21235, consensus_constants, b_tools),
        setup_farmer(21235, consensus_constants, b_tools, uint16(21237)),
        setup_vdf_clients(8000),
        setup_timelord(21236, 21237, False, consensus_constants, b_tools),
        setup_full_node(consensus_constants, "blockchain_test.db", 21237,
                        b_tools, 21233, False, 10, True, connect_to_daemon),
        setup_full_node(consensus_constants, "blockchain_test_2.db", 21238,
                        b_tools_1, 21233, False, 10, True, connect_to_daemon),
        setup_vdf_client(7999),
        setup_timelord(21239, 21238, True, consensus_constants, b_tools_1),
    ]

    introducer, introducer_server = await node_iters[0].__anext__()
    harvester, harvester_server = await node_iters[1].__anext__()
    farmer, farmer_server = await node_iters[2].__anext__()

    async def num_connections():
        count = len(harvester.server.all_connections.items())
        return count

    await time_out_assert_custom_interval(10, 3, num_connections, 1)

    vdf_clients = await node_iters[3].__anext__()
    timelord, timelord_server = await node_iters[4].__anext__()
    node_api_1 = await node_iters[5].__anext__()
    node_api_2 = await node_iters[6].__anext__()
    vdf_sanitizer = await node_iters[7].__anext__()
    sanitizer, sanitizer_server = await node_iters[8].__anext__()

    yield (
        node_api_1,
        node_api_2,
        harvester,
        farmer,
        introducer,
        timelord,
        vdf_clients,
        vdf_sanitizer,
        sanitizer,
        node_api_1.full_node.server,
    )

    await _teardown_nodes(node_iters)
예제 #2
0
async def setup_simulators_and_wallets(
    simulator_count: int,
    wallet_count: int,
    dic: Dict,
    starting_height=None,
    key_seed=None,
    starting_port=50000,
):
    simulators: List[FullNodeAPI] = []
    wallets = []
    node_iters = []

    consensus_constants = constants_for_dic(dic)
    for index in range(0, simulator_count):
        port = starting_port + index
        db_name = f"blockchain_test_{port}.db"
        bt_tools = BlockTools(consensus_constants,
                              const_dict=dic)  # block tools modifies constants
        sim = setup_full_node(
            bt_tools.constants,
            db_name,
            port,
            bt_tools,
            simulator=True,
        )
        simulators.append(await sim.__anext__())
        node_iters.append(sim)

    for index in range(0, wallet_count):
        if key_seed is None:
            seed = std_hash(uint32(index))
        else:
            seed = key_seed
        port = starting_port + 5000 + index
        bt_tools = BlockTools(consensus_constants,
                              const_dict=dic)  # block tools modifies constants
        wlt = setup_wallet_node(
            port,
            bt_tools.constants,
            bt_tools,
            None,
            key_seed=seed,
            starting_height=starting_height,
        )
        wallets.append(await wlt.__anext__())
        node_iters.append(wlt)

    yield simulators, wallets

    await _teardown_nodes(node_iters)
예제 #3
0
    def test_json(self):
        bt = BlockTools()

        test_constants: Dict[str, Any] = {
            "DIFFICULTY_STARTING": 5,
            "DISCRIMINANT_SIZE_BITS": 16,
            "BLOCK_TIME_TARGET": 10,
            "MIN_BLOCK_TIME": 2,
            "DIFFICULTY_EPOCH": 12,  # The number of blocks per epoch
            "DIFFICULTY_DELAY": 3,  # EPOCH / WARP_FACTOR
        }
        block = bt.create_genesis_block(test_constants, bytes([0] * 32), b"0")

        dict_block = block.to_json_dict()
        assert FullBlock.from_json_dict(dict_block) == block
    async def test_generator_hash(self, initial_blockchain):
        blocks, b = initial_blockchain
        new_header_data = HeaderData(
            blocks[9].header.data.height,
            blocks[9].header.data.prev_header_hash,
            blocks[9].header.data.timestamp,
            blocks[9].header.data.filter_hash,
            blocks[9].header.data.proof_of_space_hash,
            blocks[9].header.data.weight,
            blocks[9].header.data.total_iters,
            blocks[9].header.data.additions_root,
            blocks[9].header.data.removals_root,
            blocks[9].header.data.coinbase,
            blocks[9].header.data.coinbase_signature,
            blocks[9].header.data.fees_coin,
            blocks[9].header.data.aggregated_signature,
            blocks[9].header.data.cost,
            blocks[9].header.data.extension_data,
            bytes([1] * 32),
        )

        block_bad = FullBlock(
            blocks[9].proof_of_space,
            blocks[9].proof_of_time,
            Header(
                new_header_data,
                BlockTools.get_harvester_signature(
                    new_header_data, blocks[9].proof_of_space.plot_pubkey),
            ),
            blocks[9].transactions_generator,
            blocks[9].transactions_filter,
        )
        result, removed, error_code = await b.receive_block(block_bad)
        assert result == ReceiveBlockResult.INVALID_BLOCK
        assert error_code == Err.INVALID_TRANSACTIONS_GENERATOR_HASH
예제 #5
0
async def setup_two_nodes(consensus_constants: ConsensusConstants):
    """
    Setup and teardown of two full nodes, with blockchains and separate DBs.
    """
    node_iters = [
        setup_full_node(consensus_constants,
                        "blockchain_test.db",
                        21234,
                        BlockTools(constants=test_constants),
                        simulator=False),
        setup_full_node(consensus_constants,
                        "blockchain_test_2.db",
                        21235,
                        BlockTools(constants=test_constants),
                        simulator=False),
    ]

    fn1 = await node_iters[0].__anext__()
    fn2 = await node_iters[1].__anext__()

    yield fn1, fn2, fn1.full_node.server, fn2.full_node.server

    await _teardown_nodes(node_iters)
예제 #6
0
def main() -> None:
    config = load_config_cli(DEFAULT_ROOT_PATH, "config.yaml", SERVICE_NAME)
    config["database_path"] = config["simulator_database_path"]
    config["peer_db_path"] = config["simulator_peer_db_path"]
    config["introducer_peer"]["host"] = "127.0.0.1"
    config["introducer_peer"]["port"] = 58555
    config["selected_network"] = "testnet0"
    config["simulation"] = True
    kwargs = service_kwargs_for_full_node_simulator(
        DEFAULT_ROOT_PATH,
        config,
        BlockTools(test_constants),
    )
    return run_service(**kwargs)
    async def test_invalid_pos_hash(self, initial_blockchain):
        blocks, b = initial_blockchain

        bad_pos_proof = bytearray([i for i in blocks[9].proof_of_space.proof])
        bad_pos_proof[0] = uint8((bad_pos_proof[0] + 1) % 256)
        bad_pos = ProofOfSpace(
            blocks[9].proof_of_space.challenge_hash,
            blocks[9].proof_of_space.pool_pubkey,
            blocks[9].proof_of_space.plot_pubkey,
            blocks[9].proof_of_space.size,
            bytes(bad_pos_proof),
        )
        new_header_data = HeaderData(
            blocks[9].header.data.height,
            blocks[9].header.data.prev_header_hash,
            blocks[9].header.data.timestamp,
            blocks[9].header.data.filter_hash,
            bad_pos.get_hash(),
            blocks[9].header.data.weight,
            blocks[9].header.data.total_iters,
            blocks[9].header.data.additions_root,
            blocks[9].header.data.removals_root,
            blocks[9].header.data.coinbase,
            blocks[9].header.data.coinbase_signature,
            blocks[9].header.data.fees_coin,
            blocks[9].header.data.aggregated_signature,
            blocks[9].header.data.cost,
            blocks[9].header.data.extension_data,
            blocks[9].header.data.generator_hash,
        )

        # Proof of space has invalid
        block_bad = FullBlock(
            blocks[9].proof_of_space,
            blocks[9].proof_of_time,
            Header(
                new_header_data,
                BlockTools.get_harvester_signature(
                    new_header_data, blocks[9].proof_of_space.plot_pubkey),
            ),
            blocks[9].transactions_generator,
            blocks[9].transactions_filter,
        )
        result, removed, error_code = await b.receive_block(block_bad)
        assert result == ReceiveBlockResult.INVALID_BLOCK
        assert error_code == Err.INVALID_POSPACE_HASH
    async def test_invalid_coinbase_signature(self, initial_blockchain):
        blocks, b = initial_blockchain

        coinbase_coin, coinbase_signature = create_coinbase_coin_and_signature(
            blocks[9].header.data.height,
            blocks[9].header.data.coinbase.puzzle_hash,
            uint64(9991),
            bt.pool_sk,
        )
        new_header_data = HeaderData(
            blocks[9].header.data.height,
            blocks[9].header.data.prev_header_hash,
            blocks[9].header.data.timestamp,
            blocks[9].header.data.filter_hash,
            blocks[9].header.data.proof_of_space_hash,
            blocks[9].header.data.weight,
            blocks[9].header.data.total_iters,
            blocks[9].header.data.additions_root,
            blocks[9].header.data.removals_root,
            blocks[9].header.data.coinbase,
            coinbase_signature,
            blocks[9].header.data.fees_coin,
            blocks[9].header.data.aggregated_signature,
            blocks[9].header.data.cost,
            blocks[9].header.data.extension_data,
            blocks[9].header.data.generator_hash,
        )

        # Coinbase amount invalid
        block_bad = FullBlock(
            blocks[9].proof_of_space,
            blocks[9].proof_of_time,
            Header(
                new_header_data,
                BlockTools.get_harvester_signature(
                    new_header_data, blocks[9].proof_of_space.plot_pubkey),
            ),
            blocks[9].transactions_generator,
            blocks[9].transactions_filter,
        )
        result, removed, error_code = await b.receive_block(block_bad)
        assert result == ReceiveBlockResult.INVALID_BLOCK
        assert error_code == Err.INVALID_COINBASE_SIGNATURE
예제 #9
0
async def setup_n_nodes(consensus_constants: ConsensusConstants, n: int):
    """
    Setup and teardown of two full nodes, with blockchains and separate DBs.
    """
    port_start = 21244
    node_iters = []
    for i in range(n):
        node_iters.append(
            setup_full_node(
                consensus_constants,
                f"blockchain_test_{i}.db",
                port_start + i,
                BlockTools(constants=test_constants),
                simulator=False,
            ))
    nodes = []
    for ni in node_iters:
        nodes.append(await ni.__anext__())

    yield nodes

    await _teardown_nodes(node_iters)
예제 #10
0
async def setup_node_and_wallet(consensus_constants: ConsensusConstants,
                                starting_height=None,
                                key_seed=None):
    btools = BlockTools(constants=test_constants)
    node_iters = [
        setup_full_node(consensus_constants,
                        "blockchain_test.db",
                        21234,
                        btools,
                        simulator=False),
        setup_wallet_node(21235,
                          consensus_constants,
                          btools,
                          None,
                          starting_height=starting_height,
                          key_seed=key_seed),
    ]

    full_node_api = await node_iters[0].__anext__()
    wallet, s2 = await node_iters[1].__anext__()

    yield full_node_api, wallet, full_node_api.full_node.server, s2

    await _teardown_nodes(node_iters)
예제 #11
0
from chia.server.start_harvester import service_kwargs_for_harvester
from chia.server.start_introducer import service_kwargs_for_introducer
from chia.server.start_service import Service
from chia.server.start_timelord import service_kwargs_for_timelord
from chia.server.start_wallet import service_kwargs_for_wallet
from chia.simulator.start_simulator import service_kwargs_for_full_node_simulator
from chia.timelord.timelord_launcher import kill_processes, spawn_process
from chia.types.peer_info import PeerInfo
from chia.util.bech32m import encode_puzzle_hash
from tests.block_tools import BlockTools, test_constants
from chia.util.hash import std_hash
from chia.util.ints import uint16, uint32
from chia.util.keychain import Keychain, bytes_to_mnemonic
from tests.time_out_assert import time_out_assert_custom_interval

bt = BlockTools(constants=test_constants)

self_hostname = bt.config["self_hostname"]


def constants_for_dic(dic):
    return test_constants.replace(**dic)


async def _teardown_nodes(node_aiters: List) -> None:
    awaitables = [node_iter.__anext__() for node_iter in node_aiters]
    for sublist_awaitable in asyncio.as_completed(awaitables):
        try:
            await sublist_awaitable
        except StopAsyncIteration:
            pass
예제 #12
0
    wallet_protocol,
)
from src.simulator.simulator_protocol import FarmNewBlockProtocol, ReorgProtocol
from src.util.bundle_tools import best_solution_program
from src.server.outbound_message import OutboundMessage
from src.server.server import ChiaServer
from src.types.full_block import FullBlock
from src.types.spend_bundle import SpendBundle
from src.types.header import Header
from src.util.api_decorators import api_request
from src.util.ints import uint64
from tests.block_tools import BlockTools

OutboundMessageGenerator = AsyncGenerator[OutboundMessage, None]

bt = BlockTools()


class FullNodeSimulator(FullNode):
    def _set_server(self, server: ChiaServer):
        super()._set_server(server)

    async def _on_connect(self) -> OutboundMessageGenerator:
        """
        Whenever we connect to another node / wallet, send them our current heads. Also send heads to farmers
        and challenges to timelords.
        """
        async for msg in super()._on_connect():
            yield msg

    @api_request
예제 #13
0
if __name__ == "__main__":
    from tests.block_tools import BlockTools, test_constants
    from chia.util.default_root import DEFAULT_ROOT_PATH

    # TODO: mariano: fix this with new consensus
    bt = BlockTools(root_path=DEFAULT_ROOT_PATH)
    new_genesis_block = bt.create_genesis_block(test_constants, b"0")

    print(bytes(new_genesis_block))
예제 #14
0
 async def extra_node(self):
     b_tools = BlockTools(constants=test_constants_modified)
     async for _ in setup_full_node(test_constants_modified,
                                    "blockchain_test_3.db", 21240, b_tools):
         yield _
예제 #15
0
from chia.protocols.timelord_protocol import NewInfusionPointVDF
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.unfinished_block import UnfinishedBlock
from chia.util.block_cache import BlockCache
from tests.block_tools import get_signage_point, BlockTools
from chia.util.hash import std_hash
from chia.util.ints import uint8, uint32, uint64, uint128
from tests.core.fixtures import default_1000_blocks, create_blockchain  # noqa: F401
from tests.setup_nodes import test_constants as test_constants_original

test_constants = test_constants_original.replace(
    **{
        "DISCRIMINANT_SIZE_BITS": 32,
        "SUB_SLOT_ITERS_STARTING": 2**12
    })
bt = BlockTools(test_constants)


@pytest.fixture(scope="session")
def event_loop():
    loop = asyncio.get_event_loop()
    yield loop


log = logging.getLogger(__name__)


@pytest.fixture(scope="function")
async def empty_blockchain():
    bc1, connection, db_path = await create_blockchain(test_constants)
    yield bc1
예제 #16
0
import json

import aiohttp
import pytest
from chia.server.outbound_message import NodeType
from chia.server.server import ssl_context_for_server
from chia.types.peer_info import PeerInfo
from tests.block_tools import BlockTools
from chia.util.ints import uint16
from chia.util.ws_message import create_payload
from tests.core.node_height import node_height_at_least
from tests.setup_nodes import setup_daemon, self_hostname, setup_full_system
from tests.simulation.test_simulation import test_constants_modified
from tests.time_out_assert import time_out_assert, time_out_assert_custom_interval

b_tools = BlockTools(constants=test_constants_modified)
b_tools_1 = BlockTools(constants=test_constants_modified)
new_config = b_tools._config
new_config["daemon_port"] = 55401
b_tools.change_config(new_config)


class TestDaemon:
    @pytest.fixture(scope="function")
    async def get_daemon(self):
        async for _ in setup_daemon(btools=b_tools):
            yield _

    @pytest.fixture(scope="function")
    async def simulation(self):
        async for _ in setup_full_system(b_tools_1.constants,
    async def test_invalid_filter(self, two_nodes):
        num_blocks = 10
        wallet_a = WalletTool()
        coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
        wallet_receiver = WalletTool()
        receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()

        blocks = bt.get_consecutive_blocks(
            test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash
        )
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        for block in blocks:
            async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(block)
            ):
                pass

        spent_block = blocks[1]

        spend_bundle = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spent_block.header.data.coinbase
        )

        assert spend_bundle is not None
        tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle
        )
        async for _ in full_node_1.respond_transaction(tx):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
        assert sb is spend_bundle

        last_block = blocks[10]
        next_spendbundle = await full_node_1.mempool_manager.create_bundle_for_tip(
            last_block.header
        )
        assert next_spendbundle is not None

        program = best_solution_program(next_spendbundle)
        aggsig = next_spendbundle.aggregated_signature

        dic_h = {11: (program, aggsig)}
        new_blocks = bt.get_consecutive_blocks(
            test_constants, 1, blocks, 10, b"", coinbase_puzzlehash, dic_h
        )

        next_block = new_blocks[11]

        bad_header = HeaderData(
            next_block.header.data.height,
            next_block.header.data.prev_header_hash,
            next_block.header.data.timestamp,
            bytes32(bytes([3] * 32)),
            next_block.header.data.proof_of_space_hash,
            next_block.header.data.weight,
            next_block.header.data.total_iters,
            next_block.header.data.additions_root,
            next_block.header.data.removals_root,
            next_block.header.data.coinbase,
            next_block.header.data.coinbase_signature,
            next_block.header.data.fees_coin,
            next_block.header.data.aggregated_signature,
            next_block.header.data.cost,
            next_block.header.data.extension_data,
            next_block.header.data.generator_hash,
        )
        bad_block = FullBlock(
            next_block.proof_of_space,
            next_block.proof_of_time,
            Header(
                bad_header,
                BlockTools.get_harvester_signature(
                    bad_header, next_block.proof_of_space.plot_pubkey
                ),
            ),
            next_block.transactions_generator,
            next_block.transactions_filter,
        )
        result, removed, error_code = await full_node_1.blockchain.receive_block(
            bad_block
        )
        assert result == ReceiveBlockResult.INVALID_BLOCK
        assert error_code == Err.INVALID_TRANSACTIONS_FILTER_HASH

        result, removed, error_code = await full_node_1.blockchain.receive_block(
            next_block
        )
        assert result == ReceiveBlockResult.ADDED_TO_HEAD
예제 #18
0
import asyncio
from secrets import token_bytes
from typing import Any, Dict
import os
import sqlite3
import random

import pytest
from src.consensus.constants import constants
from src.store import FullNodeStore
from src.types.full_block import FullBlock
from src.types.sized_bytes import bytes32
from src.util.ints import uint32, uint64
from tests.block_tools import BlockTools

bt = BlockTools()

test_constants: Dict[str, Any] = {
    "DIFFICULTY_STARTING": 5,
    "DISCRIMINANT_SIZE_BITS": 16,
    "BLOCK_TIME_TARGET": 10,
    "MIN_BLOCK_TIME": 2,
    "DIFFICULTY_FACTOR": 3,
    "DIFFICULTY_EPOCH": 12,  # The number of blocks per epoch
    "DIFFICULTY_WARP_FACTOR":
    4,  # DELAY divides EPOCH in order to warp efficiently.
    "DIFFICULTY_DELAY": 3,  # EPOCH / WARP_FACTOR
}
test_constants["GENESIS_BLOCK"] = bytes(
    bt.create_genesis_block(test_constants, bytes([0] * 32), b"0"))
    async def test_timestamp(self, initial_blockchain):
        blocks, b = initial_blockchain
        # Time too far in the past
        new_header_data = HeaderData(
            blocks[9].header.data.height,
            blocks[9].header.data.prev_header_hash,
            blocks[9].header.data.timestamp - 1000,
            blocks[9].header.data.filter_hash,
            blocks[9].header.data.proof_of_space_hash,
            blocks[9].header.data.weight,
            blocks[9].header.data.total_iters,
            blocks[9].header.data.additions_root,
            blocks[9].header.data.removals_root,
            blocks[9].header.data.coinbase,
            blocks[9].header.data.coinbase_signature,
            blocks[9].header.data.fees_coin,
            blocks[9].header.data.aggregated_signature,
            blocks[9].header.data.cost,
            blocks[9].header.data.extension_data,
            blocks[9].header.data.generator_hash,
        )

        block_bad = FullBlock(
            blocks[9].proof_of_space,
            blocks[9].proof_of_time,
            Header(
                new_header_data,
                BlockTools.get_harvester_signature(
                    new_header_data, blocks[9].proof_of_space.plot_pubkey),
            ),
            blocks[9].transactions_generator,
            blocks[9].transactions_filter,
        )
        result, removed, error_code = await b.receive_block(block_bad)
        assert (result) == ReceiveBlockResult.INVALID_BLOCK
        assert error_code == Err.TIMESTAMP_TOO_FAR_IN_PAST

        # Time too far in the future
        new_header_data = HeaderData(
            blocks[9].header.data.height,
            blocks[9].header.data.prev_header_hash,
            uint64(int(time.time() + 3600 * 3)),
            blocks[9].header.data.filter_hash,
            blocks[9].header.data.proof_of_space_hash,
            blocks[9].header.data.weight,
            blocks[9].header.data.total_iters,
            blocks[9].header.data.additions_root,
            blocks[9].header.data.removals_root,
            blocks[9].header.data.coinbase,
            blocks[9].header.data.coinbase_signature,
            blocks[9].header.data.fees_coin,
            blocks[9].header.data.aggregated_signature,
            blocks[9].header.data.cost,
            blocks[9].header.data.extension_data,
            blocks[9].header.data.generator_hash,
        )
        block_bad = FullBlock(
            blocks[9].proof_of_space,
            blocks[9].proof_of_time,
            Header(
                new_header_data,
                BlockTools.get_harvester_signature(
                    new_header_data, blocks[9].proof_of_space.plot_pubkey),
            ),
            blocks[9].transactions_generator,
            blocks[9].transactions_filter,
        )
        result, removed, error_code = await b.receive_block(block_bad)
        assert (result) == ReceiveBlockResult.INVALID_BLOCK
        assert error_code == Err.TIMESTAMP_TOO_FAR_IN_FUTURE