Beispiel #1
0
def main():
    parser = argparse.ArgumentParser(description="Watch Bitcoin network for new blocks.")
    parser.add_argument('-s', "--state-dir", help='The directory where state files are stored.')
    parser.add_argument(
        '-f', "--fast-forward", type=int,
        help="block index to fast-forward to (ie. don't download full blocks prior to this one)", default=0
    )
    parser.add_argument(
        '-d', "--depth", type=int,
        help="Minimum depth blocks must be buried before being dropped in blockdir", default=0
    )
    parser.add_argument('-l', "--log-file", help="Path to log file", default=None)
    parser.add_argument("blockdir", help='The directory where new blocks are dropped.')

    args = parser.parse_args()

    asyncio.tasks._DEBUG = True
    logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
    logging.getLogger("asyncio").setLevel(logging.INFO)

    if args.log_file:
        log_file(args.log_file)

    state_dir = args.state_dir
    block_chain_store = BlockChainStore(state_dir)
    network = MAINNET

    if 1:
        host_port_q = dns_bootstrap_host_port_q(network)
    else:
        host_port_q = asyncio.Queue()
        host_port_q.put_nowait(("127.0.0.1", 8333))

    def should_download_block_f(block_hash, block_index):
        return block_index >= args.fast_forward

    last_processed_block = max(get_last_processed_block(state_dir), args.fast_forward)
    update_last_processed_block(state_dir, last_processed_block)

    change_q = asyncio.Queue()
    from pycoin.blockchain.BlockChain import _update_q

    def do_update(blockchain, ops):
        _update_q(change_q, [list(o) for o in ops])

    # block_chain.add_change_callback(do_update)
    # block_chain.add_nodes(block_chain_store.block_tuple_iterator())

    client = Client(
        network, host_port_q, should_download_block_f, block_chain_store, do_update)

    blockfetcher = client.blockfetcher

    # we need to keep block_processor_task referenced in this stack context
    # or the task will be garbage collected
    block_processor_task = asyncio.Task(
        block_processor(
            change_q, blockfetcher, state_dir, args.blockdir, args.depth))

    asyncio.get_event_loop().run_forever()
Beispiel #2
0
def main():
    parser = argparse.ArgumentParser(description="Watch Bitcoin network for new blocks.")
    parser.add_argument('-s', "--state-dir", help='The directory where state files are stored.')
    parser.add_argument(
        '-f', "--fast-forward", type=int,
        help="block index to fast-forward to (ie. don't download full blocks prior to this one)", default=0
    )
    parser.add_argument(
        '-d', "--depth", type=int,
        help="Minimum depth blocks must be buried before being dropped in blockdir", default=1
    )
    parser.add_argument('-l', "--log-file", help="Path to log file", default=None)
    parser.add_argument("blockdir", help='The directory where new blocks are dropped.')

    args = parser.parse_args()

    asyncio.tasks._DEBUG = True
    logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
    logging.getLogger("asyncio").setLevel(logging.INFO)

    if args.log_file:
        log_file(args.log_file)

    state_dir = args.state_dir
    block_chain_store = BlockChainStore(state_dir)

    network = MAINNET

    if 1:
        host_port_q = dns_bootstrap_host_port_q(network)
    else:
        host_port_q = asyncio.Queue()
        host_port_q.put_nowait(("127.0.0.1", 8333))

    should_download_block_f = lambda block_hash, block_index: block_index >= args.fast_forward

    last_processed_block = max(get_last_processed_block(state_dir), args.fast_forward)
    update_last_processed_block(state_dir, last_processed_block)

    change_q = asyncio.Queue()
    from pycoin.blockchain.BlockChain import _update_q

    def do_update(blockchain, ops):
        _update_q(change_q, [list(o) for o in ops])

    client = Client(
        network, host_port_q, should_download_block_f, block_chain_store, do_update)

    blockfetcher = client.blockfetcher

    block_processor_task = asyncio.Task(
        block_processor(
            change_q, blockfetcher, state_dir, args.blockdir, args.depth))

    asyncio.get_event_loop().run_forever()
Beispiel #3
0
    def sync(self, timeout, length_change_callback=None):
        """
        Synchronise the blockchain to the latest headers.

        Args:
            timeout: the timeout to stop after not receiving any new blocks.
            length_change_callback: a function to call with arg (length) when the blockchain length changes.
        """
        self.client = Client(
            network=MAINNET,
            host_port_q=dns_bootstrap_host_port_q(MAINNET),
            should_download_block_f=should_download_block_false,
            block_chain_store=self.bcs,
            blockchain_change_callback=self._blockchain_change_callback,
        )

        self.event_loop = asyncio.get_event_loop()
        t = threading.Thread(target=self._sync_loop,
                             args=(timeout, length_change_callback))
        t.start()
        self.event_loop.run_forever()
Beispiel #4
0
def main():
    parser = argparse.ArgumentParser(description="Watch Bitcoin network for new blocks.")
    parser.add_argument('-c', "--config-dir", help='The directory where config files are stored.')
    parser.add_argument(
        '-f', "--fast-forward", type=int,
        help="block index to fast-forward to (ie. don't download full blocks prior to this one)", default=0
    )
    parser.add_argument(
        '-d', "--depth", type=int,
        help="Minimum depth blocks must be buried before being dropped in blockdir", default=2
    )
    parser.add_argument( '-l', "--log-file", help="Path to log file", default=None)
    parser.add_argument("blockdir", help='The directory where new blocks are dropped.')

    asyncio.tasks._DEBUG = True
    logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
    logging.getLogger("asyncio").setLevel(logging.INFO)

    if 1:
        host_port_q = dns_bootstrap_host_port_q(MAINNET)
    else:
        host_port_q = asyncio.Queue()
        host_port_q.put_nowait(("127.0.0.1", 8333))

    args = parser.parse_args()

    if args.log_file:
        log_file(args.log_file)

    block_chain_store = BlockChainStore(args.config_dir)
    block_chain = BlockChain(did_lock_to_index_f=block_chain_store.did_lock_to_index)

    locker_task = block_chain_locker(block_chain)
    block_chain.add_nodes(block_chain_store.block_tuple_iterator())

    blockfetcher = Blockfetcher()
    inv_collector = InvCollector()

    block_store = TwoLevelDict()

    @asyncio.coroutine
    def _rotate(block_store):
        while True:
            block_store.rotate()
            yield from asyncio.sleep(1800)
    rotate_task = asyncio.Task(_rotate(block_store))

    blockhandler = BlockHandler(inv_collector, block_chain, block_store,
        should_download_f=lambda block_hash, block_index: block_index >= args.fast_forward)

    last_processed_block = max(get_last_processed_block(config_dir), args.fast_forward)
    update_last_processed_block(config_dir, last_processed_block)

    change_q = asyncio.Queue()
    from pycoinnet.util.BlockChain import _update_q
    block_chain.add_change_callback(lambda blockchain, ops: _update_q(change_q, ops))

    block_processor_task = asyncio.Task(
        block_processor(
            change_q, blockfetcher, args.config_dir, args.blockdir, args.depth)))

    fast_forward_add_peer = fast_forwarder_add_peer_f(block_chain)

    fetcher_task = asyncio.Task(new_block_fetcher(inv_collector, block_chain))

    def create_protocol_callback():
        peer = BitcoinPeerProtocol(MAINNET["MAGIC_HEADER"])
        install_pingpong_manager(peer)
        fetcher = Fetcher(peer)
        peer.add_task(run_peer(
            peer, fetcher, fast_forward_add_peer,
            blockfetcher, inv_collector, blockhandler))
        return peer

    connection_info_q = manage_connection_count(host_port_q, create_protocol_callback, 8)
    show_task = asyncio.Task(show_connection_info(connection_info_q))
    asyncio.get_event_loop().run_forever()
Beispiel #5
0
    def __init__(self, network, initial_blockchain_view, bloom_filter, block_index_queue=None,
                 filter_f=lambda idx, h: True, host_port_q=None):
        """
        network:
            a value from pycoinnet.helpers.networks
        initial_blockchain_view:
            BlockChainView instance which is update automatically
        bloom_filter:
            the filter sent to remotes
        block_index_queue:
            a Queue which is fed with (block, index) items which need to be processed
        host_port_q:
            a Queue that is being fed potential places to connect
        """

        if host_port_q is None:
            host_port_q = dns_bootstrap_host_port_q(network)

        self.network = network
        self.blockchain_view = initial_blockchain_view
        self.bloom_filter = bloom_filter

        self.block_futures = asyncio.Queue(maxsize=2000)
        if block_index_queue is None:
            block_index_queue = asyncio.Queue()
        self._block_index_queue = block_index_queue
        self.feed_task = asyncio.Task(self.feed_blocks())

        self.blockfetcher = Blockfetcher()
        self.inv_collector = InvCollector()

        if bloom_filter:
            self.get_future = self.blockfetcher.get_merkle_block_future
        else:
            self.get_future = self.blockfetcher.get_block_future

        self.filter_f = filter_f

        self.getheaders_add_peer = getheaders_add_peer_f(self.blockchain_view, self.handle_reorg)

        self.nonce = int.from_bytes(os.urandom(8), byteorder="big")
        self.subversion = "/Notoshi/".encode("utf8")

        @asyncio.coroutine
        def run_peer(peer, fetcher, getheaders_add_peer, blockfetcher, inv_collector):
            yield from asyncio.wait_for(peer.connection_made_future, timeout=None)
            last_block_index = max(0, self.blockchain_view.last_block_index())
            version_parameters = version_data_for_peer(
                peer, local_port=0, last_block_index=last_block_index, nonce=self.nonce,
                subversion=self.subversion)
            version_data = yield from initial_handshake(peer, version_parameters)
            if self.bloom_filter:
                filter_bytes, hash_function_count, tweak = self.bloom_filter.filter_load_params()
                # TODO: figure out flags
                flags = 0
                peer.send_msg(
                    "filterload", filter=filter_bytes, hash_function_count=hash_function_count,
                    tweak=tweak, flags=flags)
            last_block_index = version_data["last_block_index"]
            getheaders_add_peer(peer, last_block_index)
            blockfetcher.add_peer(peer, fetcher, last_block_index)
            inv_collector.add_peer(peer)

        def create_protocol_callback():
            peer = BitcoinPeerProtocol(network["MAGIC_HEADER"])
            install_pingpong_manager(peer)
            fetcher = Fetcher(peer)
            peer.add_task(run_peer(
                peer, fetcher, self.getheaders_add_peer,
                self.blockfetcher, self.inv_collector))
            return peer

        self.connection_info_q = manage_connection_count(host_port_q, create_protocol_callback, 8)
        self.show_task = asyncio.Task(show_connection_info(self.connection_info_q))
Beispiel #6
0
    def __init__(self,
                 network,
                 initial_blockchain_view,
                 bloom_filter,
                 block_index_queue=None,
                 filter_f=lambda idx, h: True,
                 host_port_q=None):
        """
        network:
            a value from pycoinnet.helpers.networks
        initial_blockchain_view:
            BlockChainView instance which is update automatically
        bloom_filter:
            the filter sent to remotes
        block_index_queue:
            a Queue which is fed with (block, index) items which need to be processed
        host_port_q:
            a Queue that is being fed potential places to connect
        """

        if host_port_q is None:
            host_port_q = dns_bootstrap_host_port_q(network)

        self.network = network
        self.blockchain_view = initial_blockchain_view
        self.bloom_filter = bloom_filter

        self.block_futures = asyncio.Queue(maxsize=2000)
        if block_index_queue is None:
            block_index_queue = asyncio.Queue()
        self._block_index_queue = block_index_queue
        self.feed_task = asyncio.Task(self.feed_blocks())

        self.blockfetcher = Blockfetcher()
        self.inv_collector = InvCollector()

        if bloom_filter:
            self.get_future = self.blockfetcher.get_merkle_block_future
        else:
            self.get_future = self.blockfetcher.get_block_future

        self.filter_f = filter_f

        self.getheaders_add_peer = getheaders_add_peer_f(
            self.blockchain_view, self.handle_reorg)

        self.nonce = int.from_bytes(os.urandom(8), byteorder="big")
        self.subversion = "/Notoshi/".encode("utf8")

        @asyncio.coroutine
        def run_peer(peer, fetcher, getheaders_add_peer, blockfetcher,
                     inv_collector):
            yield from asyncio.wait_for(peer.connection_made_future,
                                        timeout=None)
            last_block_index = max(0, self.blockchain_view.last_block_index())
            version_parameters = version_data_for_peer(
                peer,
                local_port=0,
                last_block_index=last_block_index,
                nonce=self.nonce,
                subversion=self.subversion)
            version_data = yield from initial_handshake(
                peer, version_parameters)
            if self.bloom_filter:
                filter_bytes, hash_function_count, tweak = self.bloom_filter.filter_load_params(
                )
                # TODO: figure out flags
                flags = 0
                peer.send_msg("filterload",
                              filter=filter_bytes,
                              hash_function_count=hash_function_count,
                              tweak=tweak,
                              flags=flags)
            last_block_index = version_data["last_block_index"]
            getheaders_add_peer(peer, last_block_index)
            blockfetcher.add_peer(peer, fetcher, last_block_index)
            inv_collector.add_peer(peer)

        def create_protocol_callback():
            peer = BitcoinPeerProtocol(network["MAGIC_HEADER"])
            install_pingpong_manager(peer)
            fetcher = Fetcher(peer)
            peer.add_task(
                run_peer(peer, fetcher, self.getheaders_add_peer,
                         self.blockfetcher, self.inv_collector))
            return peer

        self.connection_info_q = manage_connection_count(
            host_port_q, create_protocol_callback, 8)
        self.show_task = asyncio.Task(
            show_connection_info(self.connection_info_q))