Beispiel #1
0
 def run(self):
     if not self.block:
         return
     # start with the nonce already in the block. this should enable
     # multiple Threads to work on the same block with different starting
     # points
     nonce = self.block.nonce
     difficulty = self.block.difficulty
     self.start_time = time.time()
     while True:
         # test if difficulty target is reached
         if stringutil.hex_string_to_int(self.block.hash(
         )) <= stringutil.hex_string_to_int(difficulty):
             self.stop.set()
         else:
             # count the nonce up
             nonce = stringutil.int_to_hex_string(
                 stringutil.hex_string_to_int(nonce) + 1, 16)
             self.block.nonce = nonce
         # look for external interruption
         if self.stop.isSet():
             break
     # capture the time it took to mine
     self.end_time = time.time()
     # log everything
     if self.stop_external.isSet():
         loggerutil.debug("stopped mining block with difficulty " +
                          self.block.difficulty + " after " +
                          str(self.end_time - self.start_time) + " seconds")
     else:
         loggerutil.debug("mined block with difficulty " +
                          self.block.difficulty + " and hash " +
                          self.block.hash() + " in " +
                          str(self.end_time - self.start_time) + " seconds")
 def loop(self):
     """this method loops for ever until it is stopped by force or with the "stop" event"""
     while True:
         if self.stop.isSet():
             loggerutil.debug("shutting down client")
             break
         if self.manage_events():
             loggerutil.debug("shutting down client due to an error")
             break
 def __init__(self, transactions: List[str] = None):
     self.transactions = transactions
     self.root_hash = stringutil.empty_root
     if transactions:
         self._size = len(self.transactions)
         calc_merkle_root(self)
     else:
         self._size = 0
     loggerutil.debug("creating merkle-trie with root: " + self.root())
Beispiel #4
0
 def __init__(self, sender: str, receivers: List[str], amounts: List[int],
              fee: int):
     self.sender = sender
     self.receivers = receivers
     self.amounts = amounts
     self.fee = fee
     self.nonce = 0
     self.signature = ""
     loggerutil.debug("creating transaction: " + self.string())
Beispiel #5
0
 def __init__(self, sender: str, receiver: str, vt_amount: int, nto_amount: int):
     self.sender = sender
     self.receiver = receiver
     self.vt_amount = vt_amount
     self.nto_amount = nto_amount
     self.sender_nonce = 0
     self.receiver_nonce = 0
     self.sender_signature = ""
     self.receiver_signature = ""
     loggerutil.debug("creating VotingTokenTransaction: " + self.string())
 def add_block(self, block):
     """adds a block to the pool, also updating the current height"""
     if not self.blocks[block.heigth]:
         self.blocks[block.height] = [block]
     else:
         self.blocks[block.height].append(block)
         loggerutil.debug("fork detected for height:" + block.height +
                          "block candidats:" + str(self.blocks[block.height]))
     if self.current_height < block.height:
         self.current_height = block.height
    def update(self):
        """updates a client to the current state of the network"""
        self.state = State.UPDATING

        # blocking call, connects this peer to other known peers
        standalone = self.connect()

        if not standalone:
            # blocking calls
            self.current_difficulty = p2p_api.get_current_difficulty()
            self.current_height = p2p_api.get_current_height()
            # get last stable chain height
            # (stable means no forks and 7 confirmations)
            self.stable_height = block_database.get_stable_height()

            loggerutil.debug("client connected")

            # blocking call
            client_net = self.p2p_api.list_peers_in_net(self.peer)
            loggerutil.debug(
                "Client with host {0} - Current state of the net {1}".format(self.peer_host, client_net))

            # init all the pools

            # blocking call only returns list of missing blocks
            self.p2p_api.update_chain(
                self.my_height, self.current_height)

            # go over all the blocks that came along since this client was last
            # online
            for b in block_list:
                self.main_block_pool.add_block(b)

            # not blocking call because peers could have different versions of the
            # pool, makes the p2p api request blocks from different peers and send
            # them all to this client
            self.p2p_api.update_block_pool()

            # not blocking call because peers could have different versions of the
            # pool, makes the p2p api request blocks from different peers and send
            # them all to this client
            self.p2p_api.update_tx_pool()

            # here we should be finished with the update of the client (except for
            # all blocks in pool and tx in pool)
        else:
            self.stable_height = block_database.get_stable_height()
            self.current_height = self.current_height

            if self.stable_height == 0:
                self.main_block_pool.add(
                    client_genesis_generator.generate_genesis_block())
Beispiel #8
0
 def __init__(self, sender, receivers: List[str], amounts: List[int], nonce: int, fee: int, signature: str=""):
     # is sender wallet or string
     if isinstance(sender, Wallet):
         self.sender = sender
         self.sender_address = self.sender.address()
     elif isinstance(sender, str):
         self.sender_address = sender
     else:
         raise ValueError("sender must be Wallet or string")
     self.receivers = receivers
     self.amounts = amounts
     self.nonce = nonce
     self.fee = fee
     self.signature = signature
     loggerutil.debug("creating transaction: " + self.string())
def main():
    options = docopt(__doc__, version=VERSION)
    loggerutil.debug("CLI: run command with options: " +
                     str(options).replace("\n", ""))
    # map all the commands to the classes
    if options["test"]:
        TestCommand(options).run()
    elif options["wallet"]:
        WalletCommand(options).run()
    elif options["transaction"]:
        TransactionCommand(options).run()
    elif options["block"]:
        BlockCommand(options).run()
    elif options["client"]:
        ClientCommand(options).run()
Beispiel #10
0
    def add(self, block):
        """adds a block to the pool, also updating the current height"""
        try:
            self.blocks[block.height]
        except:
            self.blocks[block.height] = [block]
            if self.current_height < block.height:
                self.current_height = block.height
            return

        if not block.hash() in [b.hash() for b in self.blocks[block.height]]:
            self.blocks[block.height].append(block)
            loggerutil.debug("fork detected for height:" + str(block.height) +
                             "block candidats:" + str(self.blocks[block.height]))
            if self.current_height < block.height:
                self.current_height = block.height
Beispiel #11
0
    def __init__(self, prev_main_hash: str, prev_shard_hash: str, miner: str,
                 tx_list: List[Transaction]):
        self.prev_main_hash = prev_main_hash
        self.prev_shard_hash = prev_shard_hash
        self.height = 0  # TODO
        self.miner = miner
        self.time = int(time.time() * 1000)

        self.miner_signature = ""
        self.miner_nonce = 0

        if not tx_list or len(tx_list) == 0:
            self.tx_list = []
        else:
            self.tx_list = tx_list
        self.trie = Trie([tx.hash() for tx in self.tx_list])
        self.tx_count = self.trie.size()
        self.tx_merkle_root = self.trie.root()

        loggerutil.debug("created ShardBlock: " + self.string())
Beispiel #12
0
    def __init__(self, prev_hash: str, transactions: List[str], miner: str,
                 difficulty: str, nonce: str):
        self.prev_hash = prev_hash
        self.transactions = transactions
        self.miner = miner
        try:
            self.height = block_database.get_current_height() + 1
        except:
            self.height = 0
        self.difficulty = difficulty
        self.nonce = nonce
        self.reward = "00"
        if not transactions or len(transactions) == 0:
            self.transactions = []
            self.tx_count = 0
            self.tx_merkle_root = stringutil.empty_root
        else:
            trie = Trie(transactions)
            self.tx_count = trie.size()
            self.tx_merkle_root = trie.root()
        self.time = int(time.time() * 1000.0)

        loggerutil.debug("created block: " + self.string())
Beispiel #13
0
    def __init__(self, prev_hash: str, miner: str, difficulty: str,
                 vote_list: List[Vote], shard_list: List[ShardBlock],
                 vtx_list: List[VotingTokenTransaction]):
        self.prev_hash = prev_hash
        self.height = 0  # TODO
        self.miner = miner
        self.time = int(time.time() * 1000)
        self.difficulty = difficulty
        self.nonce = "".join("0" * 16)  # init with nonce = 0

        if not vote_list or len(vote_list) == 0:
            self.vote_list = []
        else:
            self.vote_list = vote_list
        self.vote_trie = Trie([v.hash() for v in self.vote_list])
        self.vote_count = self.vote_trie.size()
        self.vote_merkle_root = self.vote_trie.root()

        if not shard_list or len(shard_list) == 0:
            self.shard_list = []
        else:
            self.shard_list = shard_list
        self.shard_trie = Trie([s.hash() for s in self.shard_list])
        self.shard_count = self.shard_trie.size()
        self.shard_merkle_root = self.shard_trie.root()

        if not vtx_list or len(vtx_list) == 0:
            self.vtx_list = []
        else:
            self.vtx_list = vtx_list
        self.vtx_trie = Trie([vtx.hash() for vtx in self.vtx_list])
        self.vtx_count = self.vtx_trie.size()
        self.vtx_merkle_root = self.vtx_trie.root()

        self.next_shard_producers = []

        loggerutil.debug("created MainBlock: " + self.string())
Beispiel #14
0
    def run(self):
        loggerutil.debug("client started")

        # blocking call, connects this peer to other known peers
        p2p_api.connect(self.peer)
        loggerutil.debug("client connected")

        # not blocking call because 2 peers could have different versions of
        # the chain
        p2p_api.update_chain(wallet_database.get_current_height())

        # not blocking call because 2 peers could have different versions of
        # the pool
        p2p_api.update_tx_pool()

        loggerutil.debug("client init update")

        self.loop()
    def manage_events(self) -> bool:
        """
        Manages all functionality that has to be asynchronous.
        All these events can be set by the p2p api, the client then handles these events in its own thread

        returns a bool that is only True if the client needs to be shut down in case of an error
        """
        # get data from the p2p
        if self.event_manager.block_received.isSet():
            block = self.p2p_api.get_recv_block(self.peer_host)
            loggerutil.debug(
                "block received event is triggered by: {0}:".format(self.peer_host))
            loggerutil.debug("Block string: {0}".format(block))
            self.event_manager.block_received.clear()
            handle_new_block(block)

        if self.event_manager.tx_received.isSet():
            tx = self.p2p_api.get_recv_tx(self.peer_host)
            loggerutil.debug(
                "transaction received event is triggered by: {0}:".format(self.peer_host))
            loggerutil.debug("Tx string: {0}".format(tx))
            self.event_manager.tx_received.clear()
            handle_new_tx(tx)

        # give data to the p2p
        if self.event_manager.height_request.isSet():
            client_height = len(self.chain) - 1
            self.p2p_api.send_height(self.peer_host, client_height)
            # do stuff
            self.event_manager.height_request.clear()

        if self.event_manager.block_request.isSet():
            # returns list of requested block numbers
            number_list = self.p2p_api.get_requ_block_numbers()
            # get the highest block from the number list
            last_num_from_list = number_list[-1]
            # check if the highest blockchain of a client is the same as from
            # the list
            if len(self.chain) == last_num_from_list:
                # send the blocks that are missing from smaller chains
                for number in number_list:
                    self.p2p_api.send_block(number, self.chain[number - 1])
            # do stuff
            self.event_manager.block_request.clear()

        if self.event_manager.tx_request.isSet():
            # do stuff
            self.event_manager.tx_request.clear()

        if self.event_manager.tx_pool_request.isSet():
            self.p2p_api.send_pool(self.pool.string())
            self.event_manager.tx_pool_request.clear()

        if self.event_manager.bootstr_request.isSet():
            from_block_number, to_block_number, receiver = self.p2p_api.get_requ_bootstr_numbers()
            temp = []
            # fill temp with the blocks from and to
            self.p2p_api.send_bootstr(receiver, temp)
            # do stuff
            self.event_manager.bootstr_request.clear()

        if self.event_manager.connection_lost.isSet():
            # reconnect maybe ? (probably not till milestone 4)
            # do stuff
            self.event_manager.connection_lost.clear()

        if self.event_manager.error.isSet():
            loggerutil.debug("shutdown event is triggered")
            # loggerutil.error(self.p2p_api.get_error_message())
            # shut down the client after logging the error
            self.p2p_api.stop_peer_thread(self.peer)
            return True

        return False
Beispiel #16
0
def test_logger():
    loggerutil.debug("test_logging_debug")
    loggerutil.info("test_logging_info")
    loggerutil.warning("test_logging_warning")
    loggerutil.error("test_logging_error")
        """adds a block to the pool, also updating the current height"""
<<<<<<< HEAD
        if not self.blocks[block.height]:
=======
        try:
            self.blocks[block.height]
        except:
>>>>>>> a29d28bb225d67bd0c4f53a01d573b2d46b59fc5
            self.blocks[block.height] = [block]
            if self.current_height < block.height:
                self.current_height = block.height
            return

        if not block.hash() in [b.hash() for b in self.blocks[block.height]]:
            self.blocks[block.height].append(block)
            loggerutil.debug("fork detected for height:" + str(block.height) +
                             "block candidats:" + str(self.blocks[block.height]))
            if self.current_height < block.height:
                self.current_height = block.height

    def remove(self, block):
        """removes a block from the pool"""
        try:
            self.blocks[block.height]
        except:
            raise ValueError("cant remove block: " + str(block))

        removed = False
        for b in self.blocks[block.height]:
            # only delete the one with equal hash
            if b.hash() == block.hash():
                self.blocks[block.height].remove(b)
 def handle_new_main_block(self, main_block: MainBlock):
     self.main_block_pool.add_block(main_block)
     loggerutil.debug("got new main_block: " + main_block.str())
 def handle_new_shard_block(self, shard_block: ShardBlock):
     self.shard_block_pool.add_block(shard_block)
     loggerutil.debug("got new shard_block: " + shard_block.str())
 def handle_new_vtx(self, vtx: VotingTokenTransaction):
     self.vtx_pool.add_transaction(tx)
     loggerutil.debug("got new vtx: " + vtx.str())
 def handle_new_transaction(self, tx: Transaction):
     self.tx_pool.add_transaction(tx)
     loggerutil.debug("got new tx: " + tx.str())