Esempio n. 1
0
 def FH(self, data):  # Fetch Block Headerhash
     data = int(data)
     if 0 < data <= self.factory.chain.height():
         mini_block = {}
         logger.info(
             '<<<Pushing block headerhash of block number %s to node: %s',
             str(data),
             self.transport.getPeer().host)
         mini_block['headerhash'] = self.factory.chain.m_get_block(
             data).blockheader.headerhash
         mini_block['blocknumber'] = data
         self.transport.write(
             self.wrap_message('PH', helper.json_bytestream_ph(mini_block)))
     else:
         if data > self.factory.chain.height():
             logger.info(
                 'FH for a blocknumber is greater than the local chain length..'
             )
             return
Esempio n. 2
0
    def create(self, blocknumber, xmss, slave_public_key, hashchain_terminator=None, first_hash=None, balance=None):
        """
        :param blocknumber:
        :type blocknumber:
        :param xmss:
        :type xmss:
        :param slave_public_key:
        :type slave_public_key:
        :param hashchain_terminator:
        :type hashchain_terminator:
        :param first_hash:
        :type first_hash:
        :param balance:
        :type balance:
        :return:
        :rtype:
        >>> s = StakeTransaction()
        >>> slave = XMSS(4)
        >>> isinstance(s.create(0, XMSS(4), slave.pk(), None, slave.pk(), 10), StakeTransaction)
        True
        """
        if not balance:
            logger.info('Invalid Balance %d', balance)
            raise Exception

        self.slave_public_key = slave_public_key
        self.epoch = blocknumber // config.dev.blocks_per_epoch  # in this block the epoch is..
        self.first_hash = first_hash
        self.balance = balance

        if hashchain_terminator is None:
            self.hash = hashchain_reveal(xmss.get_seed_private(), epoch=self.epoch + 1)
        else:
            self.hash = hashchain_terminator

        tmphash = ''.join([bin2hstr(b) for b in self.hash])

        if self.first_hash is None:
            self.first_hash = tuple()

        self.txhash = str2bin(tmphash + bin2hstr(self.first_hash) + bin2hstr(self.slave_public_key))
        self._process_XMSS(xmss.get_address(), self.txhash, xmss)  # self.hash to be replaced with self.txhash
        return self
Esempio n. 3
0
    def PB(self, data):
        """
        Push Block
        This function processes requested blocks received while syncing.
        Block received under this function are directly added to the main
        chain i.e. chain.m_blockchain
        It is expected to receive only one block for a given blocknumber.
        :return:
        """
        self.factory.pos.last_pb_time = time.time()
        try:
            if self.isNoMoreBlock(data):
                return

            block = Block.from_json(data)

            blocknumber = block.blockheader.blocknumber
            logger.info('>>> Received Block #%d', blocknumber)
            if blocknumber != self.last_requested_blocknum:
                logger.warning('Did not match %s %s',
                               self.last_requested_blocknum,
                               self.conn_identity)
                return

            if blocknumber > self.factory.chain.height():
                if not self.factory.chain.add_block_mainchain(block):
                    logger.warning('PB failed to add block to mainchain')
                    return

            try:
                reactor.download_monitor.cancel()
            except Exception as e:
                logger.warning("PB: %s", e)

            self.factory.pos.randomize_block_fetch(blocknumber + 1)

        except Exception as e:
            logger.error(
                'block rejected - unable to decode serialised data %s',
                self.transport.getPeer().host)
            logger.exception(e)
        return
Esempio n. 4
0
    def prepare_winners(self, our_reveal, last_block_number):
        if not self.nodeState.state == NState.synced:
            return
        filtered_reveal_one = []
        reveals = []
        vote_hashes = []
        next_block_num = last_block_number + 1
        for s in self.chain.stake_reveal_one:
            tmp_strongest_headerhash = self.chain.block_chain_buffer.get_strongest_headerhash(last_block_number)
            if s[1] == tmp_strongest_headerhash and s[2] == next_block_num:
                filtered_reveal_one.append(s)
                reveals.append(s[3])
                vote_hashes.append(s[5])

        self.restart_post_block_logic(30)

        if len(filtered_reveal_one) <= 1:
            logger.info('only received one reveal for this block.. blocknum #%s', next_block_num)
            return

        epoch = next_block_num / config.dev.blocks_per_epoch  # +1 = next block
        seed = self.chain.block_chain_buffer.get_epoch_seed(next_block_num)
        winners = self.chain.select_winners(filtered_reveal_one,
                                            topN=3,
                                            seed=seed)

        # reactor.process_blocks = reactor.callLater(30, process_blocks, winners=winners, our_reveal=our_reveal)

        if not (self.p2pFactory.stake and our_reveal):
            return

        if our_reveal in winners:
            block = self.create_new_block(our_reveal,
                                          reveals,
                                          vote_hashes,
                                          last_block_number)
            self.pre_block_logic(block)  # broadcast this block

        if self.chain.pending_tx_pool:
            if len(self.chain.transaction_pool) < 10:
                logger.info('Processing TXNs if any')
                self.process_transactions(5)
Esempio n. 5
0
    def m_add_block(self, block_obj, verify_block_reveal_list=True):
        if len(self.m_blockchain) == 0:
            self.m_read_chain()

        if block_obj.validate_block(
                chain=self,
                verify_block_reveal_list=verify_block_reveal_list) is True:
            if self.state.state_add_block(self, block_obj) is True:
                self.m_blockchain.append(block_obj)
                self.remove_tx_in_block_from_pool(block_obj)
            else:
                logger.info(
                    'last block failed state/stake checks, removed from chain')
                self.state.state_validate_tx_pool(self)
                return False
        else:
            logger.info('m_add_block failed - block failed validation.')
            return False
        self.m_f_sync_chain()
        return True
Esempio n. 6
0
    def select_winners(self, reveals, topN=1, blocknumber=None, block=None, seed=None):
        # FIXME: This is POS related
        winners = None
        if not seed:
            logger.info('Exception raised due to Seed is None')
            raise Exception
        if blocknumber:
            winners = heapq.nsmallest(topN, reveals, key=lambda reveal: self.score(
                stake_address=self.get_sv(self.reveal_to_terminator(reveal, blocknumber, add_loop=1)),
                reveal_one=reveal,
                balance=self.block_chain_buffer.get_st_balance(
                    self.get_sv(self.reveal_to_terminator(reveal, blocknumber, add_loop=1)), blocknumber),
                seed=seed))  # blocknumber+1 as we have one extra hash for the reveal
            return winners

        winners = heapq.nsmallest(topN, reveals, key=lambda reveal: reveal[4])  # reveal[4] is score
        winners_dict = {}
        for winner in winners:
            winners_dict[winner[3]] = winner  # winner[3] is reveal_one
        return winners_dict
Esempio n. 7
0
    def f_write_m_blockchain(self):
        blocknumber = self.m_blockchain[-1].blockheader.blocknumber
        file_epoch = int(blocknumber // config.dev.blocks_per_chain_file)
        writeable = self.m_blockchain[-config.dev.disk_writes_after_x_blocks:]
        logger.info('Appending data to chain')

        with open(self.get_chaindatafile(file_epoch), 'ab') as myfile:
            for block in writeable:
                jsonBlock = bytes(json_bytestream(block), 'utf-8')
                compressedBlock = bz2.compress(jsonBlock,
                                               config.dev.compression_level)
                pos = myfile.tell()
                blockSize = len(compressedBlock)
                self.update_block_metadata(block.blockheader.blocknumber, pos,
                                           blockSize)
                myfile.write(compressedBlock)
                myfile.write(config.dev.binary_file_delimiter)

        del self.m_blockchain[:-1]
        gc.collect()
Esempio n. 8
0
    def validate_tx(self):
        if not self.validate_subtype(self.subtype, TX_SUBTYPE_STAKE):
            return False

        if not helper.isValidAddress(self.txfrom):
            logger.info('Invalid From Address %s', self.txfrom)
            return False

        if self.first_hash:
            if sha256(self.first_hash) != self.hash[-1]:
                logger.info('First_hash doesnt stake to hashterminator')
                return False

        for i in range(len(self.hash)):
            self.hash[i] = str(self.hash[i])

        if not self.validate_signed_hash():
            return False

        return True
Esempio n. 9
0
    def recv_peers(self, json_data):
        if not config.user.enable_peer_discovery:
            return
        data = helper.json_decode(json_data)
        new_ips = []
        for ip in data:
            if ip not in new_ips:
                new_ips.append(ip.encode('latin1'))

        peer_addresses = self.factory.peer_addresses
        logger.info('%s peers data received: %s',
                    self.transport.getPeer().host, new_ips)
        for node in new_ips:
            if node not in peer_addresses:
                if node != self.transport.getHost().host:
                    peer_addresses.append(node)
                    reactor.connectTCP(node, 9000, self.factory)

        self.factory.update_peer_addresses(peer_addresses)
        return
Esempio n. 10
0
    def next_stakers(self, data=None):
        logger.info('<<< API next_stakers call')

        next_stakers = {'status': 'ok',
                        'stake_list': []}

        for staker in self.factory.state.stake_validators_list.next_sv_list:
            sv = self.factory.state.stake_validators_list.next_sv_list[staker]
            tmp_stakers = {'address': sv.stake_validator,
                           'balance': self.factory.format_qrlamount(sv.balance),
                           'hash_terminator': [],
                           'nonce': sv.nonce}


            for i in range(len(sv.hashchain_terminators)):
                tmp_stakers['hash_terminator'].append(bin2hstr(sv.hashchain_terminators[i]))

            next_stakers['stake_list'].append(tmp_stakers)

        return json_print_telnet(next_stakers)
Esempio n. 11
0
    def LB(self):  # request for last block to be sent
        """
        Last BLock
        Sends the last block from the main chain.
        :return:
        """
        logger.info(
            '<<<Sending last block %s %s bytes to node %s',
            self.factory.chain.m_blockheight(),
            str(
                len(
                    helper.json_bytestream(
                        self.factory.chain.m_get_last_block()))),
            self.transport.getPeer().host)

        self.transport.write(
            self.wrap_message(
                'BK',
                helper.json_bytestream_bk(
                    self.factory.chain.m_get_last_block())))
        return
Esempio n. 12
0
 def connect_peers(self):
     """
     Will connect to all known peers. This is typically the entry point
     It does result in:
     - connectionMade in each protocol (session)
     - :py:meth:startedConnecting
     - :py:meth:clientConnectionFailed
     - :py:meth:clientConnectionLost
     :return:
     :rtype: None
     """
     logger.info('<<<Reconnecting to peer list: %s', self.peer_addresses)
     for peer in self.peer_addresses:
         found = False
         for peer_conn in self.peer_connections:
             if peer == peer_conn.transport.getPeer().host:
                 found = True
                 break
         if found:
             continue
         reactor.connectTCP(peer, 9000, self)
Esempio n. 13
0
    def BK(self, data):  # block received
        try:
            block = Block.from_json(data)
        except Exception as e:
            logger.error(
                'block rejected - unable to decode serialised data %s',
                self.transport.getPeer().host)
            logger.exception(e)
            return
        logger.info('>>>Received block from %s %s %s', self.identity,
                    block.blockheader.blocknumber,
                    block.blockheader.stake_selector)
        if not self.factory.master_mr.isRequested(block.blockheader.headerhash,
                                                  self):
            return

        self.factory.pos.pre_block_logic(block, self.identity)
        self.factory.master_mr.register(block.blockheader.headerhash, data,
                                        'BK')
        self.broadcast(block.blockheader.headerhash, 'BK')
        return
Esempio n. 14
0
    def m_verify_chain_250(
            self,
            verbose=0
    ):  # validate the last 250 blocks or len(m_blockchain)-1..
        n = 0
        if len(self.m_blockchain) > 250:
            x = 250
        else:
            if len(self.m_blockchain) == 1:
                return True
            x = len(self.m_blockchain) - 1

        for block in self.m_read_chain()[-x:]:
            if self.validate_block(block, verbose=verbose) is False:
                logger.info(('block failed:', block.blockheader.blocknumber))
                return False
            n += 1
            if verbose is 1:
                sys.stdout.write('.')
                sys.stdout.flush()
        return True
Esempio n. 15
0
 def f_load_winfo(self):
     try:
         with open(self.wallet_info_filename, 'r') as myfile:
             data = pickle.load(myfile)
     except Exception as e:
         logger.exception(e)
         logger.info('Likely no wallet.info found, creating..')
         self.f_save_winfo()
         return False
     x = 0
     for tree in self.chain.my:
         # if any part of self.chain.my which has loaded from f_read_wallet()
         # on startup is lower than winfo then don't load..
         if not isinstance(tree[1], list):
             if tree[1].get_index() <= data[x][3]:
                 tree[1].set_index(data[x][3])  # update self.chain.my from winfo then save to main file..
             else:
                 return False
             x += 1
     self.f_save_wallet()
     return True
Esempio n. 16
0
    def monitor_bk(self):
        time_diff = time.time() - self.last_pos_cycle
        if (self.nodeState.state == NState.synced
                or self.nodeState.state == NState.unsynced) and 90 < time_diff:
            if self.nodeState.state == NState.synced:
                self.stop_post_block_logic()
                self.reset_everything()
                self.update_node_state(NState.unsynced)
                self.epoch_diff = -1
            elif time.time() - self.last_bk_time > 120:
                self.last_pos_cycle = time.time()
                logger.info(' POS cycle activated by monitor_bk() ')
                self.update_node_state(NState.synced)

        if self.nodeState.state == NState.syncing and time.time(
        ) - self.last_pb_time > 60:
            self.stop_post_block_logic()
            self.reset_everything()
            self.update_node_state(NState.unsynced)
            self.epoch_diff = -1
        reactor.monitor_bk = reactor.callLater(60, self.monitor_bk)
Esempio n. 17
0
    def validate_tx(self):
        if self.subtype != TX_SUBTYPE_TX:
            return False

        # sanity check: this is not how the economy is supposed to work!
        if self.amount <= 0:
            logger.info('State validation failed for %s because negative or zero', self.txhash)
            logger.info('Amount %d', self.amount)
            return False

        txhash = sha256(''.join(self.txfrom + self.txto + str(self.amount) + str(self.fee)))
        txhash = sha256(txhash + self.pubhash)

        # cryptographic checks
        if self.txhash != txhash:
            return False

        if not self.validate_signed_hash():
            return False

        return True
Esempio n. 18
0
    def process_transactions(self, num):
        tmp_num = num
        for tx in self.chain.pending_tx_pool:
            tmp_num -= 1
            tx_peer = tx[1]
            tx = tx[0]
            if not tx.validate_tx():
                logger.info('>>>TX %s failed validate_tx', tx.txhash)
                continue

            block_chain_buffer = self.chain.block_chain_buffer
            tx_state = block_chain_buffer.get_stxn_state(blocknumber=block_chain_buffer.height(),
                                                         addr=tx.txfrom)
            isValidState = tx.state_validate_tx(
                tx_state=tx_state,
                transaction_pool=self.chain.transaction_pool
            )
            if not isValidState:
                logger.info('>>>TX %s failed state_validate', tx.txhash)
                continue

            logger.info('>>>TX - %s from - %s relaying..', tx.txhash, tx_peer.transport.getPeer().host)
            self.chain.add_tx_to_pool(tx)

            txn_msg = tx_peer.wrap_message('TX', tx.transaction_to_json())
            for peer in tx_peer.factory.peer_connections:
                if peer != tx_peer:
                    peer.transport.write(txn_msg)

        for i in range(num - tmp_num):
            del self.chain.pending_tx_pool[0]
            del self.chain.pending_tx_pool_hash[0]
Esempio n. 19
0
    def BM(
        self,
        data=None
    ):  # blockheight map for synchronisation and error correction prior to POS cycle resync..
        if not data:
            logger.info('<<< Sending block_map %s',
                        self.transport.getPeer().host)

            z = {
                'block_number':
                self.factory.chain.m_blockchain[-1].blockheader.blocknumber,
                'headerhash':
                self.factory.chain.m_blockchain[-1].blockheader.headerhash
            }

            self.transport.write(self.wrap_message('BM',
                                                   helper.json_encode(z)))
            return
        else:
            logger.info('>>> Receiving block_map')
            z = helper.json_decode(data)
            block_number = z['block_number']
            headerhash = z['headerhash'].encode('latin1')

            i = [block_number, headerhash, self.transport.getPeer().host]
            logger.info('%s', i)
            if i not in self.factory.chain.blockheight_map:
                self.factory.chain.blockheight_map.append(i)
            return
Esempio n. 20
0
    def search_txhash(self, txhash):  # txhash is unique due to nonce.
        err = {
            'status': 'Error',
            'error': 'txhash not found',
            'method': 'txhash',
            'parameter': txhash
        }
        for tx in self.factory.chain.transaction_pool:
            if tx.txhash == txhash:
                logger.info('%s found in transaction pool..', txhash)
                tx_new = copy.deepcopy(tx)
                self.reformat_txn(tx_new)
                return json_print_telnet(tx_new)

        try:
            txn_metadata = self.factory.chain.state.db.get(txhash)
        except:
            logger.info(
                '%s does not exist in memory pool or local blockchain..',
                txhash)
            return json_print_telnet(err)

        json_tx = json.loads(txn_metadata[0])
        tx = Transaction().from_txdict(json_tx)
        tx_new = copy.deepcopy(tx)
        self.reformat_txn(tx_new)
        logger.info('%s found in block %s', txhash, str(txn_metadata[1]))
        tx_new.status = 'ok'
        return json_print_telnet(tx_new)
Esempio n. 21
0
    def last_unconfirmed_tx(self, data=None):
        logger.info('<<< API last_unconfirmed_tx call')

        addr = {'transactions': []}
        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'last_tx',
            'parameter': data
        }

        if not data:
            data = 1
        try:
            n = int(data)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        tx_num = len(self.factory.chain.transaction_pool)
        while tx_num > 0:
            tx_num -= 1
            tx = self.factory.chain.transaction_pool[tx_num]
            if tx.subtype != TX_SUBTYPE_TX:
                continue
            tmp_txn = {
                'txhash': bin2hstr(tx.txhash),
                'block': 'unconfirmed',
                'timestamp': 'unconfirmed',
                'amount': self._format_qrlamount(tx.amount),
                'type': tx.subtype
            }

            tmp_txn['type'] = Transaction.tx_id_to_name(tmp_txn['type'])
            addr['transactions'].append(tmp_txn)

        addr['status'] = 'ok'
        return json_print_telnet(addr)
Esempio n. 22
0
    def BM(self, data=None):  # blockheight map for synchronisation and error correction prior to POS cycle resync..
        """
        Blockheight Map
        Simply maps the peer with their respective blockheight.
        If no data is provided in parameter, the node sends its 
        own current blockheight. 
        :return:
        """
        if not data:
            logger.info('<<< Sending block_map %s', self.transport.getPeer().host)

            z = {'block_number': self.factory.chain.m_blockchain[-1].blockheader.blocknumber,
                 'headerhash': self.factory.chain.m_blockchain[-1].blockheader.headerhash}

            self.transport.write(self.wrap_message('BM', helper.json_encode(z)))
            return
        else:
            logger.info('>>> Receiving block_map')
            z = helper.json_decode(data)
            block_number = z['block_number']
            headerhash = z['headerhash'].encode('latin1')

            i = [block_number, headerhash, self.transport.getPeer().host]
            logger.info('%s', i)
            if i not in self.factory.chain.blockheight_map:
                self.factory.chain.blockheight_map.append(i)
            return
Esempio n. 23
0
    def __next__(self):
        if not self.pending_tx_pool:
            raise StopIteration

        if len(self.transaction_pool) >= config.dev.transaction_pool_size:
            raise StopIteration

        tx = self.pending_tx_pool.pop(0)

        tx_peer = tx[1]
        tx = tx[0]
        if not tx.validate_tx():
            logger.info('>>>TX %s failed validate_tx', tx.txhash)
            return False

        tx_state = self.block_chain_buffer.get_stxn_state(
            blocknumber=self.block_chain_buffer.height(), addr=tx.txfrom)
        isValidState = tx.state_validate_tx(
            tx_state=tx_state, transaction_pool=self.transaction_pool)
        if not isValidState:
            logger.info('>>>TX %s failed state_validate', tx.txhash)
            return False

        logger.info('A TXN has been Processed %s', bin2hstr(tx.txhash))
        self.add_tx_to_pool(tx)

        return True
Esempio n. 24
0
 def BN(self, data):  # request for block (n)
     """Block(n)
     Sends the nth block from mainchain.
     :return:
     """
     if int(data) <= self.factory.chain.m_blockheight():
         logger.info(
             '<<<Sending block number %s %s bytes to node: %s', int(data),
             len(
                 helper.json_bytestream(
                     self.factory.chain.m_get_block(int(data)))),
             self.transport.getPeer().host)
         self.transport.write(
             self.wrap_message(
                 'BK',
                 helper.json_bytestream_bk(
                     self.factory.chain.m_get_block(int(data)))))
     else:
         if int(data) >= self.factory.chain.m_blockheight():
             logger.info(
                 'BN for a blockheight greater than local chain length..')
         else:
             logger.info(
                 'BN request without valid block number %s - closing connection',
                 str(data))
             self.transport.loseConnection()
     return
Esempio n. 25
0
    def process_transactions(self, num):
        tmp_num = num
        for tx in self.buffered_chain.tx_pool.pending_tx_pool:
            tmp_num -= 1
            tx_peer = tx[1]
            tx = tx[0]
            if not tx.validate():
                logger.info('>>>TX %s failed validate_tx', tx.txhash)
                continue

            tx_state = self.buffered_chain.get_stxn_state(
                blocknumber=self.buffered_chain.height, addr=tx.txfrom)

            is_valid_state = tx.validate_extended(
                tx_state=tx_state,
                transaction_pool=self.buffered_chain.tx_pool.transaction_pool)

            if not is_valid_state:
                logger.info('>>>TX %s failed state_validate', tx.txhash)
                continue

            logger.info('>>>TX - %s from - %s relaying..', tx.txhash,
                        tx_peer.transport.getPeer().host)
            self.buffered_chain.tx_pool.add_tx_to_pool(tx)

            txn_msg = tx_peer.wrap_message('TX', tx.to_json())
            for peer in tx_peer.factory.peer_connections:
                if peer != tx_peer:
                    # FIXME: Breaks encapsulation
                    peer.transport.write(txn_msg)

        for i in range(num - tmp_num):
            del self.buffered_chain.tx_pool.pending_tx_pool[0]
            del self.buffered_chain.tx_pool.pending_tx_pool_hash[0]
Esempio n. 26
0
 def reboot(self, data):
     hash_dict = json.loads(data)
     if not ('hash' in hash_dict and 'nonce' in hash_dict
             and 'blocknumber' in hash_dict):
         return
     status, error = self.factory.chain.validate_reboot(
         hash_dict['hash'], hash_dict['nonce'])
     if not status:
         logger.info('status %s', status)
         logger.info('error %s', error)
         return
     for peer in self.factory.peers:
         if peer != self:
             peer.transport.write(self.wrap_message('reboot', data))
     reboot_data = [
         '2920c8ec34f04f59b7df4284a4b41ca8cbec82ccdde331dd2d64cc89156af653',
         hash_dict['nonce']
     ]
     self.factory.chain.state.db.put('reboot_data', reboot_data)
     blocknumber = hash_dict['blocknumber']
     logger.info('Initiating Reboot Sequence..... #%s', blocknumber)
     if blocknumber != 0:
         if blocknumber <= self.factory.chain.height():
             self.factory.pos.update_node_state(NState.unsynced)
             del self.factory.chain.m_blockchain[blocknumber:]
             self.factory.chain.f_write_m_blockchain()
             self.factory.chain.m_load_chain()
             self.factory.pos.update_node_state(NState.synced)
Esempio n. 27
0
    def create_tree(self):
        num_branches = 0
        if self.num_leaves <= 2:  # catch case for which log doesn't do the job
            num_branches = 1
        elif self.num_leaves <= 512:
            num_branches = int(ceil(log(self.num_leaves, 2)))

        self.num_branches = num_branches
        self.tree.append(self.base)

        hashlayer = self.base

        temp_array = []
        for x in range(
                num_branches
        ):  # iterate through each layer of the merkle tree starting with the base layer
            temp_array = []
            cycles = len(hashlayer) % 2 + len(hashlayer) / 2
            y = 0
            # FIXME: Same variable as outer loop??
            for _ in range(cycles):
                if y + 1 == len(hashlayer):
                    temp_array.append(str(hashlayer[y]))
                else:
                    temp_array.append(
                        sha256(str(hashlayer[y]) + str(hashlayer[y + 1])))
                    y = y + 2

            self.tree.append(temp_array)
            hashlayer = temp_array

        self.root = temp_array
        self.height = len(self.tree)

        if self.verbose == 1:
            logger.info('Merkle tree created with %d leaves, %d branches',
                        self.num_leaves, self.num_branches)

        return self.tree
Esempio n. 28
0
    def last_tx(self, data=None):
        logger.info('<<< API last_tx call')

        if not data:
            data = 1

        addr = {'transactions': []}

        error = {'status': 'error', 'error': 'invalid argument', 'method': 'last_tx', 'parameter': data}

        try:
            n = int(data)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        try:
            last_txn = self.factory.state.db.get('last_txn')
        except Exception:
            error['error'] = 'txnhash not found'
            return json_print_telnet(error)

        n = min(len(last_txn), n)
        while n > 0:
            n -= 1
            tx_meta = last_txn[n]
            tx = SimpleTransaction().json_to_transaction(tx_meta[0])
            tmp_txn = {'txhash': bin2hstr(tx.txhash),
                       'block': tx_meta[1],
                       'timestamp': tx_meta[2],
                       'amount': self.factory.format_qrlamount(tx.amount),
                       'type': tx.subtype}

            addr['transactions'].append(tmp_txn)
            addr['status'] = 'ok'

        return json_print_telnet(addr)
Esempio n. 29
0
    def get_st_balance(self, stake_address, blocknumber):
        if stake_address is None:
            logger.error('stake address should not be none, returning None')
            return None

        try:
            if blocknumber - 1 == self.chain.height():
                if stake_address in self.state.stake_validators_list.sv_list:
                    return self.state.stake_validators_list.sv_list[
                        stake_address].balance
                logger.info('Blocknumber not found')
                return None

            return self.blocks[
                blocknumber -
                1][1].stake_validators_list.sv_list[stake_address].balance
        except KeyError:
            self.error_msg('get_st_balance', blocknumber)
        except Exception as e:
            self.error_msg('get_st_balance', blocknumber, e)

        return None
Esempio n. 30
0
    def monitor_bk(self):
        # FIXME: Too complex.. too many nested ifs
        time_diff = time.time() - self.last_pos_cycle
        if (self.sync_state.state == ESyncState.synced or self.sync_state.state == ESyncState.unsynced) and \
                90 < time_diff:

            if self.sync_state.state == ESyncState.synced:
                self.stop_post_block_logic()
                self.update_node_state(ESyncState.unsynced)
                self.epoch_diff = -1
            elif time.time() - self.last_bk_time > 120:
                self.last_pos_cycle = time.time()
                logger.info(' POS cycle activated by monitor_bk() ')
                self.update_node_state(ESyncState.synced)

        if self.sync_state.state == ESyncState.syncing and time.time(
        ) - self.last_pb_time > 60:
            self.stop_post_block_logic()
            self.update_node_state(ESyncState.unsynced)
            self.epoch_diff = -1

        reactor.monitor_bk = reactor.callLater(60, self.monitor_bk)